summaryrefslogtreecommitdiff
path: root/hw/xwayland/xwayland-present.c
AgeCommit message (Collapse)AuthorFilesLines
2024-04-10xwayland/present: Check window & source pixmap depth match lastMichel Dänzer1-10/+10
Preparation for next commit, no functional change intended. Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
2024-04-10xwayland/present: Add xwl_present_maybe_(un)redirect_windowMichel Dänzer1-0/+63
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>
2024-04-10xwayland: Add xwl_window::surface_windowMichel Dänzer1-1/+1
It may track a non-toplevel window which fully covers the area of the window pixmap / Wayland surface. It is now used instead of xwl_window::toplevel for updating the Wayland surface contents. The surface_window can now hit the Present page flip path while it's automatically redirected. v2: * Use "surface_window" instead of "surf_win". (Olivier Fourdan) * Add comment describing surface_window, and describe what surface_window/toplevel are useful for respectively. (Olivier Fourdan) * Use surface_window in xwl_realize_window. v3: * Backtrack up to the closest opaque ancestor in xwl_window_update_surface_window. (Olivier Fourdan) v4: * Clean up logic for determining the surface window in xwl_window_update_surface_window, and document it better. * Handle window_get_damage(xwl_window->surface_window) returning NULL in xwl_window_update_surface_window. * Call xwl_window_update_surface_window after xwl_window_buffers_init in ensure_surface_for_window, since the former may call xwl_window_buffers_dispose. * Rename surf/win_pix to surface/window_pixmap in xwl_window_update_surface_window. Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
2024-04-10xwayland: Pass xwl_window to xwl_glamor_dri3_syncobj_passthroughMichel Dänzer1-1/+1
Preparation for later changes, no functional change intended. Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
2024-04-10xwayland: Rename xwl_window::window to ::toplevelMichel Dänzer1-2/+2
It's always the toplevel window, i.e. either the root window or a child of it. Preparation for later commits, no functional change. v2: (Olivier Fourdan) * Fix debug build. * Add comment describing ::toplevel. Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1300>
2024-04-09xwayland: don't scrap pending present requestsErik Kurzinger1-37/+56
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>
2024-04-09xwayland: add support for wp_linux_drm_syncobj_v1Erik Kurzinger1-6/+78
This protocol allows for explicit synchronization of GPU operations by Wayland clients and the compositor. Xwayland can make use of this to ensure any rendering it initiates has completed before the target image is accessed by the compositor, without having to rely on kernel-level implicit synchronization. Furthermore, for X11 clients that also support explicit synchronization using the mechanisms exposed in the DRI3 and Present extensions, this Wayland protocol allows us to simply forward the timeline, acquire, and release points directly to the compositor, ideally avoiding any premature stalls in the presentation pipeline. Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
2024-04-09xwayland: support DRI3 1.4 and Present 1.4Erik Kurzinger1-5/+58
Together, DRI3 1.4 and Present 1.4 allow clients to explicitly synchronize GPU rendering with presentation using DRM syncobjs. Here we add the necessary support to Xwayland's glamor and Present infrastructure to enable this functionality. Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
2024-04-09Present: add PresentCapabilitySyncobj and PresentPixmapSyncedErik Kurzinger1-2/+16
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
2024-04-09xwayland: re-compute target msc during xwl_present_re_executeErik Kurzinger1-10/+42
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>
2024-04-09xwayland: add workaround for drivers that don't support impicit syncXaver Hugl1-1/+4
Without either implicit or explicit synchronization, the result of rendering is pretty much undefined, and many glitches can appear. This still doesn't synchronize buffer release, but it works around most glitches until explicit sync is supported. Signed-off-by: Xaver Hugl <xaver.hugl@kde.org> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
2024-03-14xwayland: correctly report PresentCompleteModeCopyErik Kurzinger1-4/+7
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>
2024-03-06xwayland/present: Handle clearing damage after flip in xwl_present_executeMichel Dänzer1-2/+13
Due to DamageReportNonEmpty, damage_report doesn't get called if the damage region was already non-empty before the flip. In which case it didn't get called before the first draw after the flip either. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1627 Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>
2024-01-22xwayland: Enable Present extension support also without glamorMichel Dänzer1-8/+19
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.
2024-01-22xwayland/present: Update screen pixmap in xwl_present_executeMichel Dänzer1-0/+5
If the screen pixmap was also the toplevel window pixmap. This can't happen yet, it will with the next commit though.
2023-09-26xwayland/present: Handle NULL window_priv in xwl_present_cleanupMichel Dänzer1-3/+5
This can happen if the window has never completed a Present operation. Fixes: 42301760802e ("xwayland/present: Embed present_vblank_rec in xwl_present_event")
2023-07-18xwayland/glamor: Require equal pixmap depths in xwl_glamor_check_flipMichel Dänzer1-1/+1
This will be needed with the next commit: If a child window completely obscures a toplevel ancestor of different depth, the child window can use page flipping only if the depth of the presented pixmap matches that of the window's backing pixmap, or the former may contain pixel values which are not suitable for the toplevel window's depth.
2023-06-19xwayland: add support for wp-tearing-control-v1Xaver Hugl1-3/+18
Signed-off-by: Xaver Hugl <xaver.hugl@gmail.com> Acked-by: Michel Dänzer <mdaenzer@redhat.com> Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2023-06-06xwayland: Stop using event address as event_idJessica Clarke1-1/+2
Nothing should be relying on this anymore, so use a counter like other places in the tree instead. This ensures that the event_id doesn't get cast back into a pointer again in future, and also may be slightly less confusing in cases where calloc reuses an address as debug logs would show the same event_id for those but now they will be distinct. Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
2023-06-06xwayland: Stop relying on event_id being a valid pointerJessica Clarke1-3/+15
On traditional 32-bit and 64-bit architectures, uint64_t can be abused to hold a uintptr_t and be cast back to a valid pointer. However, on CHERI, and thus Arm's Morello prototype, pointers are capabilities, which contain a traditional address alongside additional metadata, including a tag bit that ensures it cannot be forged (the only way to get a capability with the tag bit set is by using instructions that take in another valid capability with sufficient bounds/permissions/etc for the request, and any other operation, like overwriting individual bytes in memory, will give a capability whose tag is clear). Casting a pointer to a uintptr_t is fine as uintptr_t is represented as a capability, but casting to a uint64_t yields just the address, losing the metadata and tag. Thus, when cast back to a uintptr_t, the capability remains invalid and faults on any attempt to dereference. As with various other places in the tree, address this by searching for the pointer in a list so that we no longer rely on this undefined behaviour. Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
2023-06-06xwayland: Pass vblank pointer itself to xwl_present_flipJessica Clarke1-10/+6
All these arguments other than damage come from the vblank itself so passing the vblank simplifies the caller. Moreover, we pass the event_id solely so we can get back to the event, which is just the (extended) vblank, so passing the vblank avoids that round trip. Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
2023-06-06xwayland: Avoid gratuitous round trip through event_idJessica Clarke1-3/+9
By adding a new xwl_present_event_from_vblank function we can avoid turning the vblank into an event_id, and also abstract away the exact encoding for event_id from most places. Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
2023-03-27xwayland: Prevent nested xwl_present_for_each_frame_callback callsMichel Dänzer1-0/+15
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
2023-03-27xwayland: Refactor xwl_present_for_each_frame_callback helperMichel Dänzer1-0/+12
Preparation for following changes, no functional change intended.
2023-01-20xwayland: Send PresentCompleteModeSuboptimalCopy if dmabuf feedback was resentAustin Shafer1-1/+28
If the dmabuf protocol's feedback object gave us a new list of modifiers, send PresentCompleteModeSuboptimalCopy to the client to inform them that they need to call GetSupportedModifiers. Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2022-06-21xwayland/present: Do not send two idle notify events for flip pixmapsMichel Dänzer1-1/+9
Could happen if the buffer release event was already processed before xwl_present_flips_stop. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1351 Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2022-03-17xwayland: Always hook up frame_callback_list in xwl_present_queue_vblankMichel Dänzer1-7/+10
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: 9b31358c52e9 ("xwayland: Use frame callbacks for Present vblank events") Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2022-03-15xwayland: Clear timer_armed in xwl_present_unrealize_windowMichel Dänzer1-0/+3
Without this, xwl_present_reset_timer would call xwl_present_timer_callback if the timer was originally armed over a second ago. xwl_present_timer_callback would call xwl_present_msc_bump, which could end up hooking up the window to xwl_window->frame_callback_list again. This would lead to use-after-free in xwl_present_cleanup: Invalid write of size 8 at 0x42B65C: __xorg_list_del (list.h:183) by 0x42B693: xorg_list_del (list.h:204) by 0x42C041: xwl_present_cleanup (xwayland-present.c:354) by 0x423669: xwl_destroy_window (xwayland-window.c:770) by 0x4FDDC5: compDestroyWindow (compwindow.c:620) by 0x5233FB: damageDestroyWindow (damage.c:1590) by 0x501C5F: DbeDestroyWindow (dbe.c:1326) by 0x4EF35B: FreeWindowResources (window.c:1018) by 0x4EF687: DeleteWindow (window.c:1086) by 0x4E24B3: doFreeResource (resource.c:885) by 0x4E2ED7: FreeClientResources (resource.c:1151) by 0x4ACBA4: CloseDownClient (dispatch.c:3546) Address 0x12f44980 is 144 bytes inside a block of size 160 free'd at 0x48470E4: free (vg_replace_malloc.c:872) by 0x423115: xwl_unrealize_window (xwayland-window.c:621) by 0x4FCDD8: compUnrealizeWindow (compwindow.c:292) by 0x4F3F5C: UnrealizeTree (window.c:2805) by 0x4F424B: UnmapWindow (window.c:2863) by 0x4EF58C: DeleteWindow (window.c:1075) by 0x4E24B3: doFreeResource (resource.c:885) by 0x4E2ED7: FreeClientResources (resource.c:1151) by 0x4ACBA4: CloseDownClient (dispatch.c:3546) by 0x5E27EE: ClientReady (connection.c:599) by 0x5E6CB7: ospoll_wait (ospoll.c:657) by 0x5DE6CD: WaitForSomething (WaitFor.c:208) Block was alloc'd at at 0x4849464: calloc (vg_replace_malloc.c:1328) by 0x4229CE: ensure_surface_for_window (xwayland-window.c:439) by 0x4231E8: xwl_window_set_window_pixmap (xwayland-window.c:647) by 0x5232D6: damageSetWindowPixmap (damage.c:1565) by 0x4FC7BC: compSetPixmapVisitWindow (compwindow.c:129) by 0x4EDB3F: TraverseTree (window.c:441) by 0x4FC851: compSetPixmap (compwindow.c:151) by 0x4F8C1A: compAllocPixmap (compalloc.c:616) by 0x4FC938: compCheckRedirect (compwindow.c:174) by 0x4FCD1D: compRealizeWindow (compwindow.c:274) by 0x4F36EC: RealizeTree (window.c:2606) by 0x4F39F5: MapWindow (window.c:2683) Fixes: 288ec0e046c4 ("xwayland/present: Run fallback timer callback after more than a second") Tested-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-12-24xwayland/present: Run fallback timer callback after more than a secondMichel Dänzer1-5/+24
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>
2021-09-17xwayland/present: Move xwl_present_reset_timer call out of xwl_present_flipMichel Dänzer1-3/+4
xwl_present_reset_timer checks if the pending flip is synchronous, so we need to call it after adding the pending flip to the flip queue. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1219 Fixes: b2a06e0700fa "xwayland/present: Drop sync_flip member of struct xwl_present_window" Tested-by: Olivier Fourdan <ofourdan@redhat.com> Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09present: Drop flip_idler member from present_vblank_recMichel Dänzer1-11/+13
It's redundant with the pixmap member of struct xwl_present_event. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Use present_vblank_ptr instead of xwl_present_event*Michel Dänzer1-12/+9
Where the latter isn't really needed. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Fold xwl_present_release_event into _free_eventMichel Dänzer1-15/+2
The only difference was unhooking from the vblank.event_queue list, which is already done by xwl_present_flip_notify_vblank in xwl_present_msc_bump.
2021-07-09xwayland/present: Drop target_msc member from struct xwl_present_eventMichel Dänzer1-5/+3
Use present_vblank_rec::exec_msc instead. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Drop pending member from struct xwl_present_eventMichel Dänzer1-9/+1
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>
2021-07-09xwayland/present: Drop list member from struct xwl_present_eventMichel Dänzer1-12/+6
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>
2021-07-09xwayland/present: Drop exec_queue member from struct xwl_present_windowMichel Dänzer1-5/+0
Doesn't serve any purpose anymore. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Fold xwl_present_event_notify into its callerMichel Dänzer1-33/+5
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>
2021-07-09xwayland/present: Use exec_queue for deferring completion eventsMichel Dänzer1-9/+5
We clear the vblank->pixmap field, so next time xwl_present_execute falls through to present_execute_post. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Fold xwl_present_idle_notify into its callerMichel Dänzer1-33/+14
Allows simplification by avoiding indirection. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Drop sync_flip member of struct xwl_present_windowMichel Dänzer1-7/+7
The same information can be determined from the flip queue. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwaland/present: Drop flip_pending member of struct xwl_present_windowMichel Dänzer1-29/+33
Use the first element of the flip_queue list for the same purpose. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Fold xwl_present_flip_notify into its callersMichel Dänzer1-20/+2
No need for them to be separate anymore. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Embed present_vblank_rec in xwl_present_eventMichel Dänzer1-149/+83
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>
2021-07-09xwayland/present: Drop abort member of struct xwl_present_eventMichel Dänzer1-7/+4
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>
2021-07-09xwayland/present: Simplify calls to Xwayland-private functionsMichel Dänzer1-41/+20
Change parameter types to what's really needed, or just fold the function into its only caller. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Rename present_wnmd_* functions to xwl_present_*Michel Dänzer1-65/+65
The WNMD indirection is gone. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09present: Remove present_wnmd_info_recMichel Dänzer1-6/+0
Doesn't serve any purpose anymore. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Merge present_wnmd_flips_stop & xwl_present_flips_stopMichel Dänzer1-17/+6
Just use the latter instead of the former elsewhere. No need for them to be separate anymore. Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09xwayland/present: Fold present_wnmd_get_ust_msc into its callersMichel Dänzer1-20/+14
Just use xwl_present_get_ust_msc directly. No need for the indirection anymore. Acked-by: Olivier Fourdan <ofourdan@redhat.com>