From 33a9a1cacea79f1a1dd92b1ebefacd549b7bbe4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 28 Nov 2024 18:05:06 +0100 Subject: [PATCH] cogl/onscreen: Call _cogl_context_update_sync after the buffer swap Indirectly via cogl_framebuffer_flush, since we also need to call glFlush now. Need to do it in cogl_onscreen_egl_swap_* because meta_onscreen_native_swap_buffers_with_damage uses cogl_context_get_latest_sync_fd. Doing it before the swap was problematic because the swap may do GPU work of its own, which wasn't covered by the EGL sync object created in _cogl_context_update_sync. This could result in visual artifacts. See the discussion starting at https://gitlab.freedesktop.org/mesa/mesa/-/issues/11996#note_2678104 for details. For similar reasons, move the cogl_framebuffer_finish calls after the swap as well. As a bonus, this eliminates one of 3 GPU work flushes to the kernel per frame with the Mesa radeonsi driver, because the glFlush/glFinish call in cogl_framebuffer_flush/finish doesn't have any GPU work to flush after SwapBuffers. Part-of: --- cogl/cogl/cogl-onscreen.c | 16 ++++++---------- cogl/cogl/winsys/cogl-onscreen-egl.c | 6 ++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index 155445774..b0703e767 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -289,17 +289,15 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, _cogl_framebuffer_flush_journal (framebuffer); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - else - _cogl_context_update_sync (context); - cogl_framebuffer_discard_buffers (framebuffer, COGL_BUFFER_BIT_DEPTH | COGL_BUFFER_BIT_STENCIL); klass->swap_buffers_with_damage (onscreen, region, info, user_data); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) + cogl_framebuffer_finish (framebuffer); + if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) { g_autoptr (CoglFrameInfo) pending_info = NULL; @@ -341,11 +339,6 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, _cogl_framebuffer_flush_journal (framebuffer); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - else - _cogl_context_update_sync (context); - /* This should only be called if the winsys advertises COGL_WINSYS_FEATURE_SWAP_REGION */ g_return_if_fail (klass->swap_region); @@ -356,6 +349,9 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen, klass->swap_region (onscreen, region, info, user_data); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) + cogl_framebuffer_finish (framebuffer); + if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) { g_autoptr (CoglFrameInfo) pending_info = NULL; diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c index b2d2d86a2..4a3171276 100644 --- a/cogl/cogl/winsys/cogl-onscreen-egl.c +++ b/cogl/cogl/winsys/cogl-onscreen-egl.c @@ -236,6 +236,9 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen, n_rectangles, egl_rectangles) == EGL_FALSE) g_warning ("Error reported by eglSwapBuffersRegion"); + + /* Update latest sync object after buffer swap */ + cogl_framebuffer_flush (framebuffer); } static void @@ -339,6 +342,9 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, } else eglSwapBuffers (egl_renderer->edpy, priv->egl_surface); + + /* Update latest sync object after buffer swap */ + cogl_framebuffer_flush (framebuffer); } void