From 0fd093d8a8be420077111883d72643f8cedc3ffd Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Sun, 8 Mar 2026 17:33:19 +0100 Subject: [PATCH] wlr_linux_drm_syncobj_v1: Lock surface state until acquire signal For surfaces utilizing linux-drm-syncobj-v1, we currently wait for the acquire point to have materialized before applying surface state. If a client provides a buffer that will take considerable time to render, using this buffer for composition or direct scanout will cause the compositor to miss frames, making the entire user experience stutter. By waiting for the acquire point to be signaled before allowing the surface state to take effect and thereby allow usage of the buffer, the user experience remains smooth even under such high-load scenarios. For very low-load scenarios where the client only submitted materialized fences, this comes at a slight scheduling overhead. --- types/wlr_linux_drm_syncobj_v1.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/types/wlr_linux_drm_syncobj_v1.c b/types/wlr_linux_drm_syncobj_v1.c index 53fc2fd43..604fe70fc 100644 --- a/types/wlr_linux_drm_syncobj_v1.c +++ b/types/wlr_linux_drm_syncobj_v1.c @@ -232,15 +232,14 @@ static void surface_commit_handle_surface_destroy(struct wl_listener *listener, surface_commit_destroy(commit); } -// Block the surface commit until the fence materializes +// Block the surface commit until the fence signals static bool lock_surface_commit(struct wlr_linux_drm_syncobj_surface_v1 *surface, struct wlr_drm_syncobj_timeline *timeline, uint64_t point) { - uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE; - - bool already_materialized = false; - if (!wlr_drm_syncobj_timeline_check(timeline, point, flags, &already_materialized)) { + bool already_signaled = false; + if (!wlr_drm_syncobj_timeline_check(timeline, point, + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, &already_signaled)) { return false; - } else if (already_materialized) { + } else if (already_signaled) { return true; } @@ -253,7 +252,7 @@ static bool lock_surface_commit(struct wlr_linux_drm_syncobj_surface_v1 *surface struct wl_display *display = wl_client_get_display(client); struct wl_event_loop *loop = wl_display_get_event_loop(display); if (!wlr_drm_syncobj_timeline_waiter_init(&commit->waiter, timeline, point, - flags, loop, surface_commit_handle_waiter_ready)) { + 0, loop, surface_commit_handle_waiter_ready)) { free(commit); return false; }