Despite all the careful planning of the kernel, a link may become
insufficient to handle the currently-set mode. At this point, the
kernel should mark this particular configuration as being broken
and potentially prune the mode before setting the offending connector's
link-status to BAD and send the userspace a hotplug event. This may
happen right after a modeset or later on.
Upon receiving a hot-plug event, we iterate through the connectors to
re-apply the currently-set mode on all the connectors that have a
link-status property set to BAD. The kernel may be able to get the
link to work by dropping to using a lower link bpp (with the same
display bpp). However, the modeset may fail if the kernel has pruned
the mode, so to make users aware of this problem a warning is outputed
in the logs to warn about having a potentially-black display.
This patch does not modify the current behaviour of always propagating
the events to the randr clients. This allows desktop environments to
re-probe the connectors and select a new resolution based on the new
(currated) mode list if a mode disapeared. This behaviour is expected in
order to pass the Display Port compliance tests.
Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
DRM_EVENT_CONTEXT_VERSION is the latest context version supported by
whatever version of libdrm is present. modesetting was blindly asserting
it supported whatever version that may be, even if it actually didn't.
With libdrm 2.4.78, setting a higher context version than 2 will attempt
to call the page_flip_handler2 vfunc if it was non-NULL, which being a
random chunk of stack memory, it might well have been.
Set the version as 2, which should be bumped only with the appropriate
version checks.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Daniel Stone <daniels@collabora.com>
Currently if modesetting ever fails to set a hardware cursor it will switch
to using a software cursor and never go back. Change this to only
permanently switch to a software cursor if -ENXIO is returned (which means
hardware cursors not supported), and to otherwise still try a hardware
cursor first every time a new one is set. This is needed because hardware
may be able to handle some cursors in hardware and others not, or virtual
hardware may be able to handle hardware cursors at some times and not
others.
Changes since v1, v2 and v3:
* take into account the switch to load_cursor_argb_check
* keep the permanent software cursor fall-back if -ENXIO is returned
* move parts of v3 into separate patches
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Michael Thayer <michael.thayer@oracle.com>
Based on v4 by Alexandre Courbot <acourbot@nvidia.com>
There is currently no reliable way to report failure to set a HW
cursor. Still such failures can happen if e.g. the MODE_CURSOR DRM
ioctl fails (which currently happens at least with modesetting on Tegra
for format incompatibility reasons).
As failures are currently handled by setting the HW cursor size to
(0,0), the fallback to SW cursor will not happen until the next time the
cursor changes and xf86CursorSetCursor() is called again. In the
meantime, the cursor will be invisible to the user.
This patch addresses that by adding _xf86CrtcFuncs::set_cursor_check and
_xf86CursorInfoRec::ShowCursorCheck hook variants that return booleans.
This allows to propagate errors up to xf86CursorSetCursor(), which can
then fall back to using the SW cursor immediately.
v5:
- Removed parts of patch already committed as part of 14c21ea1.
- Adjusted code slightly to match surrounding code.
- Effectively reverted af916477 which is made unnecessary by this patch.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Michael Thayer <michael.thayer@oracle.com>
Commit c7e8d4a6ee had already unifdef
MODESETTING_OUTPUT_SLAVE_SUPPORT but commit
9257b1252d didn't notice that.
Signed-off-by: Nikhil Mahale <nmahale@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Add a missing ifdef needed for --disable-glamor.
Signed-off-by: Mihail Konev <k.mvc@ya.ru>
Reviewed-by: Jon Turney <jon.turney@dronecode.org.uk>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This change effectively reverts commit 074cf58. We were falling back from
drmModeSetCursor2() to drmModeSetCursor() whenever the first failed. This
fall-back only makes sense on pre-mid-2013 kernels which implemented the
cursor_set hook but not cursor_set2, and in this case the call to
drmModeSetCursor2() will always return -EINVAL. Specifically, a return
value of -ENXIO usually means that neither are supported.
Signed-off-by: Michael Thayer <michael.thayer@oracle.com>
[hdegoede@redhat.com: initialize ret to -EINVAL]
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
We get multiple udev events for actions like docking a laptop into its
station or plugging a monitor to the station. By consuming as much
events as we can, we reduce the number of output re-evalutions.
I.e. having a Lenovo X250 in a ThinkPad Ultra Dock and plugging a
monitor to the station generates 5 udev events. Or having 2 monitors
attached to the station and docking the laptop generates 7 events.
It depends on the timing how many events can consumed at once.
Signed-off-by: Daniel Martin <consume.noise@gmail.com>
[hdegoede@redhat.com: Keep goto out so that we always call RRGetInfo()]
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
A couple of memory leaks fixes and avoiding bit shifting on an
unitialized value.
[hdegoede@redhat.com: Split out some non free fixes in separate patches]
[hdegoede@redhat.com: Don't touch ancient (and weird) os/rpcauth.c code]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
When using secondary GPU outputs the primary GPU's blockhandler
will copy changes from its framebuffer to a pixmap shared with the
secondary GPU.
In reverse prime setups the secondary GPU's blockhandler will do another
copy from the shared pixmap to its own framebuffer.
Before this commit, if the primary GPU's blockhandler would run after
the secondary GPU's blockhandler and no events were pending, then the
secondary GPU's blockhandler would not run until some events came in
(WaitForSomething() would block in the poll call), resulting in the
secondary GPU output sometimes showing stale contents (e.g. a just closed
window) for easily up to 10 seconds.
This commit fixes this by setting the timeout passed into the
blockhandler to 0 if any shared pixmaps were updated by the primary GPU,
forcing an immediate re-run of all blockhandlers.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
When using reverse prime we do 2 copies, 1 from the primary GPU's
framebuffer to a shared pixmap and 1 from the shared pixmap to the
secondary GPU's framebuffer.
This means that on the primary GPU side the copy MUST be finished,
before we start the second copy (before the secondary GPU's driver
starts processing the damage on the shared pixmap).
This fixes secondary outputs sometimes showning (some) old fb contents,
because of the 2 copies racing with each other, for an example of
what this looks like see:
https://fedorapeople.org/~jwrdegoede/IMG_20160915_130555.jpg
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Move ms_flush_drm_events out of GLAMOR ifdef.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97586
Signed-off-by: Qiang Yu <Qiang.Yu@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This fixes glxgears running at 1 fps when fully covering a slave-output
and the modesetting driver is used for the master gpu.
Reported-by: Peter Wu <peter@lekensteyn.nl>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
99% of the code in ms_covering_crtc is video-driver agnostic. Add a
screen_is_ms parameter when when FALSE skips the one ms specific check,
this will allow calling ms_covering_crtc on slave GPUs.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Implement the CreateBuffer2 / DestroyBuffer2 / CopyRegion2 DRI2InfoRec
version 9 callbacks, this is necessary for being an offload source
provider with DRI2.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
If a frontbuffer drawable already has a pixmap, make sure it was created
on the right screen.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The "if (pixmap) ..." block this commit removes is inside an
"if (pixmap == NULL) ..." block, so it will never execute.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Remove unused arguments from ms_covering_crtc, make it static as it is
only used in vblank.c.
While at it also change its first argument from a ScrnInfoPtr to a
ScreenPtr, this makes the next patch in this patch-set cleaner.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
glamor_fd_from_pixmap() may return a tiled bo, which is not suitable
for sharing with another GPU as tiling usually is GPU specific.
Switch to glamor_shareable_fd_from_pixmap(), which always returns a
linear bo. This fixes mis-rendering when running the mode setting
driver on the master gpu in a dual-gpu setup and running an opengl
app with DRI_PRIME=1.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
The common page flip handle framework can be shared with DRI2
page flip.
Signed-off-by: Qiang Yu <Qiang.Yu@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
When Xorg gets started directly from a wayland-gdm the crtc still has the
wayland hw cursor set. Combine this with Xorg immediately falling back to
a sw cursor because a slave-output has a monitor attached at startup; and
we end up with the wayland hardware cursor overlay fixed in its last
position + the Xorg sw cursor resulting in 2 cursors.
This commit fixes this by hiding any left-over cursors when initializing
the crtc.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
The modesetting driver may be driving 2 screens (slave and master
gpu), which may have different behavior wrt hardware cursor support.
So stop using static variables and instead store the hw-cursor support
related data in a per screen struct. While at it actually make it per
crtc data as in theory different crtc's could have different hw-cursor
support.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Embarassingly, it looks like I introduced this dead function in
commit 13c7d53df8 a year ago.
Nothing ever used it, not even then.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
This uses the wrapper in case we need to emulate poll with select
as we do on Windows.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This error code can mean we're submitting more rects at once than the
driver can handle. If that happens, resubmit one at a time.
v2: Make the rect submit loop more error-proof (Walter Harms)
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Michael Thayer <michael.thayer@oracle.com>
With no users of the interface needing the readmask anymore, we can
remove it from the argument passed to these functions.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This is a cleanup, proposed by Adam Jackson, but wasn't merged with
the original NotifyFD changes.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Commit 80e64dae: "modesetting: Implement PRIME syncing as a sink" originally was
supposed to have this line, but it was dropped as part of the merge process.
Foregoing the NULL assignment causes a ton of problems with dereferencing
uninitialized memory.
Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
In newer laptops with switchable graphics, the GPU may have 0 outputs,
in this case the modesetting driver should still load if the GPU is
SourceOffload capable, so that it can be used as an offload source provider.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
When a card has import capability it can be an offload _sink_, not
a source and vice versa for export capability.
This commit fixes the modesetting driver to properly set these
capabilities, this went unnoticed sofar because most gpus have both
import and export capability.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
Server GPUs often have a VNC feature attached to allow remote console.
The controller implementing this feature is usually not very powerful,
and we can easily swamp it with work. This is made somewhat worse by
damage over-reporting the size of the dirty region, and a whole lot
worse by applications (or shells) that update the screen with identical
pixel content as was already there.
Fix this by double-buffering the shadow fb, using memcmp to identify
dirty tiles on each update pass. Since both shadows are in host memory
the memcmp is cheap, and worth it given the win in network bandwidth.
The tile size is somewhat arbitrarily chosen to be one cacheline wide at
32bpp on Intel Core.
By default we enable this behaviour for (a subset of) known server GPUs;
the heuristic could use work.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
24bpp front buffers tend to be the least well tested path for client
rendering. On the qemu cirrus emulation, and on some Matrox G200 server
chips, the hardware can't do 32bpp at all. It's better to just allocate
a 32bpp shadow and downconvert in the upload hook than expose a funky
pixmap format to clients.
[ajax: Ported from RHEL and separate modesetting driver, lifted kbpp
into the drmmode struct, cleaned up commit message, fixed 16bpp]
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlied <airlied@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
[hdegoede@redhat.com: rebase, also use kbpp for rotate shadow fb]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
With the previous patch, the modesetting driver can now return whether
the driver supports hw cursor. However, it alone doesn't suffice,
unfortunately. drmmode_load_cursor_argb_check() is called in the
following chain:
xf86CursorSetCursor()
-> xf86SetCursor()
-> xf86DriverLoadCursorARGB()
-> xf86_load_cursor_argb()
-> xf86_crtc_load_cursor_argb()
-> drmmode_load_cursor_argb_check()
*but* at first with drmmode_crtc->cursor_up = FALSE. Then the
function doesn't actually set the cursor but returns TRUE
unconditionally. The actual call of drmmode_set_cursor() is done at
first via the show_cursor callback, and there is no check of sw cursor
fallback any longer at this place. Since it's called only once per
cursor setup, so the xserver still thinks as if the hw cursor is
supported.
This patch is an ad hoc fix to correct the behavior somehow: it does
call drmmode_set_cursor() at the very first time even if cursor_up is
FALSE, then quickly hides again. In that way, whether the hw cursor
is supported is evaluated in the right place at the right time.
Of course, it might be more elegant if we have a more proper mechanism
to fall back to sw cursor at any call path. But it'd need more
rework, so I leave this workaround as is for now.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The modesetting driver still has an everlasting bug of invisible
cursor on cirrus and other KMS drivers where no hardware cursor is
supported. This patch is a part of an attempt to address it.
This patch particularly converts the current load_cursor_argb callback
of modesetting driver to load_cursor_argb_check so that it can return
whether the driver handles the hw cursor or falls back to the sw
cursor.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
[hdegoede@redhat.com: Add extra comment suggested by Kenneth]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The error value isn't always -EINVAL, e.g. the kernel drm core returns
-ENXIO when the corresponding ops doesn't exist. Without this fix,
DRM_IOCTL_MODE_CURSOR2 would be dealt as success even if it
shouldn't.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Implements (Start/Stop)FlippingPixmapTracking, PresentSharedPixmap, and
RequestSharedPixmapNotifyDamage, the source functions for PRIME
synchronization and double buffering. Allows modesetting driver to be used
as a source with PRIME synchronization.
v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Move disabling of reverse PRIME on sink to sink commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
Reverse PRIME seems to be designed with discrete graphics as a sink in
mind, designed to do an extra copy from sysmem to vidmem to prevent a
discrete chip from needing to scan out from sysmem.
The criteria it used to detect this case is if we are a GPU screen and
Glamor accelerated. It's possible for i915 to fulfill these conditions,
despite the fact that the additional copy doesn't make sense for i915.
Normally, you could just set AccelMethod = none as an option for the device
and call it a day. However, when running with modesetting as both the sink
and the source, Glamor must be enabled.
Ideally, you would be able to set AccelMethod individually for devices
using the same driver, but there seems to be a bug in X option parsing that
makes all devices on a driver inherit the options from the first detected
device. Thus, glamor needs to be enabled for all or for none until that bug
(if it's even a bug) is fixed.
Nonetheless, it probably doesn't make sense to do the extra copy on i915
even if Glamor is enabled for the device, so this is more user friendly by
not requiring users to disable acceleration for i915.
v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Unchanged
v6: Rebase onto ToT
v7: NULL check and free drmVersionPtr
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
UDL (USB 2.0 DisplayLink DRM driver) and other drivers for USB transport devices
have strange semantics when it comes to vblank events, due to their inability to
get the actual vblank info.
When doing a page flip, UDL instantly raises a vblank event without waiting for
vblank. It also has no support for DRM_IOCTL_WAIT_VBLANK, and has some strange
behavior with how it handles damage when page flipping.
It's possible to get something semi-working by hacking around these issues,
but even then there isn't much value-add vs single buffered PRIME, and it
reduces maintainability and adds additional risks to the modesetting driver
when running with more well-behaved DRM drivers.
Work needs to be done on UDL in order to properly support synchronized
PRIME. For now, just blacklist it, causing RandR to fall back to
unsynchronized PRIME.
This patch originally blacklisted UDL by name, but it was pointed out that there
are other USB transport device drivers with similar limitations, so it was
expanded to blacklist all USB transport devices.
v1: N/A
v2: N/A
v3: Initial commit
v4: Move check to driver.c for consistency/visibility
v5: Refactor to accomodate earlier changes
v6: Rebase onto ToT
v7: Expand to blacklist all USB transport devices, not just UDL
Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
DPMS would prevent page flip / vblank events from being raised, freezing
the screen until PRIME flipping was reinitialized. To handle DPMS cleanly,
suspend PRIME page flipping when DPMS mode is not on, and resume it when
DPMS mode is on.
v1: Initial commit
v2: Moved flipping_active check from previous commit to here
v3: Unchanged
v4: Unchanged
v5: Move flipping_active check to sink support commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
Implements (Enable/Disable)SharedPixmapFlipping and
SharedPixmapNotifyDamage, the sink functions for PRIME synchronization and
double buffering. Allows modesetting driver to be used as a sink with PRIME
synchronization.
Changes dispatch_slave_dirty to flush damage from both scanout pixmaps.
Changes drmmode_set_scanout_pixmap*() functions to
drmmode_set_target_scanout_pixmap*() that take an additional parameter
PixmapPtr *target. Then, treat *target as it did prime_pixmap. This allows
me to use it to explicitly set both prime_pixmap and prime_pixmap_back
individually. drmmode_set_scanout_pixmap() without the extra parameter
remains to cover the single-buffered case, but only works if we aren't
already double buffered.
driver.c:
Add plumbing for rr(Enable/Disable)SharedPixmapFlipping and
SharedPixmapNotifyDamage.
Change dispatch_dirty_crtc to dispatch_dirty_pixmap, which functions the
same but flushes damage associated with a ppriv instead of the crtc, and
chanage dispatch_slave_dirty to use it on both scanout pixmaps if
applicable.
drmmode_display.h:
Add flip_seq field to msPixmapPrivRec to keep track of the event handler
associated with a given pixmap, if any.
Add wait_for_damage field to msPixmapPrivRec to keep track if we have
requested a damage notification from the source.
Add enable_flipping field to drmmode_crtc_private_rec to keep track if
flipping is enabled or disabled.
Add prime_pixmap_back to drmmode_crtc_private_rec to keep track of back
buffer internally.
Add declarations for drmmode_SetupPageFlipFence(),
drmmode_EnableSharedPixmapFlipping(),
drmmode_DisableSharedPixmapFlipping, drmmode_SharedPixmapFlip(), and
drmmode_SharedPixmapPresentOnVBlank().
Move slave damage from crtc to ppriv.
drmmode_display.c:
Change drmmode_set_scanout_pixmap*() functions to
drmmode_set_target_scanout_pixmap*() that take an additional parameter
PixmapPtr *target for explicitly setting different scanout pixmaps.
Add definitions for functions drmmode_SharedPixmapFlip(),
drmmode_SharedPixmapPresentOnVBlank(),
drmmode_SharedPixmapPresent(),
drmmode_SharedPixmapVBlankEventHandler(),
drmmode_SharedPixmapVBlankEventAbort(),
drmmode_EnableSharedPixmapFlipping(), and
drmmode_DisableSharedPixmapFlipping,
drmmode_InitSharedPixmapFlipping(), and
drmmode_FiniSharedPixmapFlipping, along with struct
vblank_event_args.
The control flow is as follows:
pScrPriv->rrEnableSharedPixmapFlipping() makes its way to
drmmode_EnableSharedPixmapFlipping(), which sets enable_flipping to
TRUE and sets both scanout pixmaps prime_pixmap and
prime_pixmap_back.
When setting a mode, if prime_pixmap is defined, modesetting
driver will call drmmode_InitSharedPixmapFlipping(), which if
flipping is enabled will call drmmode_SharedPixmapPresent() on
scanout_pixmap_back.
drmmode_SharedPixmapPresent() requests that for the source to
present on the given buffer using master->PresentSharedPixmap(). If
it succeeds, it will then attempt to flip to that buffer using
drmmode_SharedPixmapFlip(). Flipping shouldn't fail, but if it
does, it will raise a warning and try drmmode_SharedPixmapPresent()
again on the next vblank using
drmmode_SharedPixmapPresentOnVBlank().
master->PresentSharedPixmap() could fail, in most cases because
there is no outstanding damage on the mscreenpix tracked by the
shared pixmap. In this case, drmmode_SharedPixmapPresent() will
attempt to use master->RequestSharedPixmapNotifyDamage() to request
for the source driver to call slave->SharedPixmapNotifyDamage() in
response to damage on mscreenpix. This will ultimately call
into drmmode_SharedPixmapPresentOnVBlank() to retry
drmmode_SharedPixmapPresent() on the next vblank after
accumulating damage.
drmmode_SharedPixmapFlip() sets up page flip event handler by
packing struct vblank_event_args with the necessary parameters, and
registering drmmode_SharedPixmapVBlankEventHandler() and
drmmode_SharedPixmapVBlankEventAbort() with the modesetting DRM
event handler queue. Then, it uses the drmModePageFlip() to flip on
the next vblank and raise an event.
drmmode_SharedPixmapPresentOnVBlank() operates similarly to
drmmode_SharedPixmapFlip(), but uses drmWaitVBlank() instead of
drmModePageFlip() to raise the event without flipping.
On the next vblank, DRM will raise an event that will ultimately be
handled by drmmode_SharedPixmapVBlankEventHandler(). If we flipped,
it will update prime_pixmap and prime_pixmap_back to reflect that
frontTarget is now being displayed, and use
drmmode_SharedPixmapPresent(backTarget) to start the process again
on the now-hidden shared pixmap. If we didn't flip, it will just
use drmmode_SharedPixmapPresent(frontTarget) to start the process
again on the still-hidden shared pixmap.
Note that presentation generally happens asynchronously, so with
these changes alone tearing is reduced, but we can't always
guarantee that the present will finish before the flip. These
changes are meant to be paired with changes to the sink DRM driver
that makes flips wait on fences attached to dmabuf backed buffers.
The source driver is responsible for attaching the fences and
signaling them when presentation is finished.
Note that because presentation is requested in response to a
vblank, PRIME sources will now conform to the sink's refresh rate.
At teardown, pScrPriv->rrDisableSharedPixmapFlipping() will be
called, making its way to drmmode_FiniSharedPixmapFlipping().
There, the event handlers for prime_pixmap and prime_pixmap_back
are aborted, freeing the left over parameter structure. Then,
prime_pixmap and prime_pixmap back are unset as scanout pixmaps.
Register and tear down slave damage per-scanout pixmap instead of
per-crtc.
v1: Initial commit
v2: Renamed PresentTrackedFlippingPixmap to PresentSharedPixmap
Renamed flipSeq to flip_seq
Warn if flip failed
Use SharedPixmapNotifyDamage to retry on next vblank after damage
v3: Refactor to accomodate moving (rr)StartFlippingPixmapTracking and
(rr)(Enable/Disable)SharedPixmapFlipping to rrScrPrivRec from ScreenRec
Do damage tracking on both scanout pixmaps
v4: Tweaks to commit message
v5: Revise for internal storage of prime pixmap ptrs
Move disabling for reverse PRIME from source commit to here
Use drmmode_set_target_scanout_pixmap*() to set scanout pixmaps
internally to EnableSharedPixmapFlipping().
Don't support flipping if ms->drmmode.pageflip == FALSE.
Move flipping_active check to this commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
ms->drmmode.pageflip was only loaded from options if ms->drmmode.glamor was
defined, otherwise it would always assume FALSE.
PRIME Synchronization requires ms->drmmode.pageflip even if we aren't using
glamor, so load it unconditionally.
v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
drmmode_set_scanout_pixmap_(cpu/gpu) would only do teardown if ppix ==
NULL. This meant that if there were consecutive calls to
SetScanoutPixmap(ppix != NULL) without calls to SetScanoutPixmap(ppix ==
NULL) in between, earlier calls would be leaked. RRReplaceScanoutPixmap()
does this today.
Instead, when setting a scanout pixmap, always do teardown of the existing
scanout pixmap before setting up the new one. Then, if there is no new one
to set up, stop there.
This maintains the previous behavior in all cases except those with
multiple consecutive calls to SetScanoutPixmap(ppix != NULL).
v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
modesetting relied on randr_crtc->scanout_pixmap being consistent with
calls to SetScanoutPixmap, which is very fragile and makes a lot of
assumptions about the caller's behavior.
For example, RRReplaceScanoutPixmap(), when dropping off with !size_fits,
will set randr_crtc->scanout_pixmap = NULL and then call SetScanoutPixmap.
Without this patch, drmmode_set_scanout_pixmap_(cpu/gpu) will think that
there is no scanout pixmap to tear down, because it's already been set to
NULL.
By keeping track of the scanout pixmap in its internal state, modesetting
can avoid these types of bugs and reduce constraints on calling
conventions.
v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
[fix copied from 40191d82370e in xf86-video-ati]
Without this, we end up setting rotated CRTCs back to their previous
framebuffer right after we perform a rotation. Reproducer:
- Have two monitors connected at the same resolution
- Rotate one monitor from normal straight to inverted
- Watch as the monitor you didn't rotate either freezes or shows intense
flickering
Signed-off-by: Lyude <cpaul@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>