If the manual redirection was done by xwl_present_maybe_redirect_window,
we are in control.
This allows xwl_present_maybe_redirect_window to work as intended again.
Previously, xwl_window_update_surface_window would ignore the window
redirected by xwl_present_maybe_redirect_window, which would result in
xwl_present_maybe_redirect_window undoing the redirection and bailing.
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1570>
A later commit will use these to (un)redirect the surface window on
demand.
Not used yet, so no functional change intended.
v2:
* Use "surface_window_damage" instead of "surf_win_damage".
(Olivier Fourdan)
* Slightly simplify logic in xwl_unrealize_window.
v3:
* Add comment in xwl_present_maybe_unredirect_window explaining why we
use a timer. (Olivier Fourdan)
v4:
* Rename unredir_timer field to unredirect_timer.
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
When a present request is received, Xwayland will check if there is an
existing request targeting the same window and msc and scrap the older
request if so. Alas, this does not interact well the older fence-based
or newer syncobj-based synchronization features of the Present
extension.
Since execution of a request may be delayed for an unknown length of
time while waiting for a fence to be signaled, the target msc computed
upon receiving a request may not match the actual msc at which the
request is executed. Therefore, we cannot determine in advance whether a
more recently received request will make an older request redundant.
This change removes the code to scrap pending present requests.
We must also ensure requests are executed in the correct order even if
their fences are signaled out of order. To achieve this, whenever
execution of a request needs to wait for a fence, execution of any
later-received requests will be blocked until the earlier request is
ready. The blocked requests will be added to a list tracked in the
xwl_present_window struct. Once the earlier request's fence is signaled,
any blocked requests will be re-executed.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
If a presentation request is delayed while waiting for a fence, the
original target msc may no longer be correct. Instead, we should compute
a new target msc in xwl_present_re_execute.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
After executing a PresentPixmap request using the copy path, Xwayland
will clear the vblank's pixmap field and re-queue it for the next msc so
that on the next frame a PresentCompleteNotify event will be delivered
to the client by present_execute_post.
While this does work, since the pixmap field of the vblank will be NULL
when present_execute_post is called, the mode reported in the event will
always be PresentCompleteModeSkip, even if the request *was* actually
executed with a copy.
To fix this, we introduce a new "copy_executed" flag in the
xwl_present_event struct. If xwl_present_execute sees that this flag is
set, it will fall straight through to present_execute_post like it does
if the window or pixmap is NULL. So, after executing a request with
present_execute_copy, instead of clearing the pixmap field we will set
the copy_executed flag to true. This will cause present_execute_post to
report the correct completion mode to the client when the
PresentCompleteNotify event is delivered on the next frame.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1254>
This allows e.g.
xfwm4 --vblank=xpresent
to hit the page flip path instead of copies.
In the future, Mesa might also use the Present extension with software
rendering.
It could happen with the following call path:
frame_callback
xwl_present_frame_callback
xwl_present_msc_bump
xwl_present_execute
xwl_present_flip
xwl_window_create_frame_callback
The nested loop called xwl_present_reset_timer, which may end up calling
xorg_list_del for the entry after the one frame_callback started the
chain for. This resulted in the outer loop never terminating, because
its next element wasn't hooked up to the list anymore.
We avoid this by calling xwl_present_reset_timer as needed in
frame_callback, and bailing from xwl_window_create_frame_callback if it
was called from the former.
We also catch nested calls and FatalError if they ever happen again due
to another bug.
v2:
* Leave xwl_present_reset_timer call in xwl_present_frame_callback,
needed if xwl_present_msc_bump didn't hook up the window to the frame
callback list again.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1442
Even if there's no pending frame callback yet.
Without this, if there was no pending frame callback yet in
xwl_present_queue_vblank, xwl_present_msc_bump would only get called
from xwl_present_timer_callback, resulting in the MSC ticking at ~58
Hertz.
Doing this requires some adjustments elsewhere:
1. xwl_present_reset_timer needs to check for a pending frame callback
as well.
2. xwl_window_create_frame_callback needs to call
xwl_present_reset_timer for all child windows hooked up to
frame_callback_list, to make sure the timer length takes the pending
frame callback into account.
3. xwl_present_flip needs to hook up the window to frame_callback_list
before calling xwl_window_create_frame_callback, for 2. to work.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1309
Fixes: 9b31358c52 ("xwayland: Use frame callbacks for Present vblank events")
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
If the Wayland compositor doesn't send a pending frame event, e.g.
because the Wayland surface isn't visible anywhere, it could happen that
the timer kept getting pushed back and never fired. This resulted in an
enormous list of pending vblank events, which could take minutes to
process when the frame event finally arrived.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1110
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Tested-by: Jaap Buurman <jaapbuurman@gmail.com>
We are handling two cases here: the active flip or the pending flip.
For the pending flip (event->pending == TRUE), we called
xwl_present_release_pixmap.
For the active flip (event->pending == FALSE), we called
xwl_present_release_event. However, xwl_present_flip_notify_vblank
already unhooked event->vblank.event_queue. So this was effectively the
same as calling xwl_present_release_pixmap.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Use present_vblank_rec::event_queue instead.
The changes in xwl_present_execute shouldn't really be needed, since
we should never hit queue_vblank in present_execute_wait. But let's be
safe rather than sorry, plus this simplifies the code.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Can just call xwl_present_execute directly.
This allows dropping the window member from struct xwl_present_window as
well.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
This allows for various simplifications.
Use the pointer to the struct memory as the event ID. In contrast to
the SCMD code for Xorg (where pending DRM events cannot be cancelled),
this is safe here, because we can destroy pending Wayland callbacks. So
we can't get a callback with a stale pointer to freed memory.
Remove xwl_present_window::release_list in favour of
present_vblank_rec::window_list.
Remove xwl_present_event::xwl_present_window in favour of
present_vblank_rec::window.
xwl_present_free_event is never called for a NULL pointer anymore, no
need to check.
v2:
* Restore DestroyWindow wrapping order to make sure
present_destroy_window doesn't call xwl_present_abort_vblank.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
We can call xwl_present_free_event unconditionally from
xwl_present_abort_vblank, since the sync_callback is already destroyed
in xwl_present_cleanup.
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
This will allow eliminating indirections and making the Xwayland Present
code more efficient and easier to follow.
While this technically changes the Xorg video driver ABI, I don't know
of any drivers using the dropped present_wnmd_* symbols, and I doubt a
Xorg driver could make use of them as is anyway.
(As a bonus, Xorg no longer links any Xwayland specific Present code)
v2:
* Wrap DestroyWindow before initializing Present, so that
present_destroy_window runs before xwl_present_cleanup. Avoids crash
due to present_destroy_window calling xwl_present_* functions when
xwl_present_window was already freed. (Olivier Fourdan)
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Rename the lists release_queue to release_list and event_list to
wait_list.
The prior names release_queue and event_list were ambiguous: in both are event-
like vblanks which can be removed from the lists in random order. In the
release_queue can be flips that are already released but still wait for the
sync or frame callback but normally the release comes later. In the event_list
are queued events waiting for a later msc.
Signed-off-by: Roman Gilg <subdiff@gmail.com>
These events aren't reachable after xwl_present_cleanup, so they're
leaked if we don't free them first.
This requires storing the pixmap pointer in struct xwl_present_window.
Luckily, the buffer pointer isn't used for anything, so just replace
that.
v2:
* Bump pixmap reference count in xwl_present_flip and drop it in
xwl_present_free_event, fixes use-after-free in the latter due to the
pixmap already being destroyed.
Reviewed-by: Dave Airlie <airlied@redhat.com>
We were only calling xwl_present_unrealize_window for the toplevel
window, but the list can contain entries from child windows as well,
in which case we were leaving dangling pointers to freed memory.
Closes: https://gitlab.freedesktop.org/xorg/xserver/issues/1000
Fixes: c5067feaee "xwayland: Use single frame callback for Present
flips and normal updates"
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Tested-by: Olivier Fourdan <ofourdan@redhat.com>
Move the Xwayland Present declarations to their own header file.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>