Blame SOURCES/0022-xwayland-eglstream-flush-stream-after-eglSwapBuffers.patch

b6a310
From 29cba30948cda34e744314343109964ff9ed515c Mon Sep 17 00:00:00 2001
b6a310
From: Erik Kurzinger <ekurzinger@nvidia.com>
b6a310
Date: Tue, 11 May 2021 17:00:21 -0400
b6a310
Subject: [PATCH xserver 22/27] xwayland/eglstream: flush stream after
b6a310
 eglSwapBuffers
b6a310
b6a310
When eglSwapBuffers inserts a new frame into a window's stream, there may be a
b6a310
delay before the state of the consumer end of the stream is updated to reflect
b6a310
this. If the subsequent wl_surface_attach, wl_surface_damage, wl_surface_commit
b6a310
calls are received by the compositor before then, it will (typically) re-use
b6a310
the previous frame acquired from the stream instead of the latest one.
b6a310
b6a310
This can leave the window displaying out-of-date contents, which might never be
b6a310
updated thereafter.
b6a310
b6a310
To fix this, after calling eglSwapBuffers, xwl_glamor_eglstream_post_damage
b6a310
should call eglStreamFlushNV. This call will block until it can be guaranteed
b6a310
that the state of the consumer end of the stream has been updated to reflect
b6a310
that a new frame is available.
b6a310
b6a310
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1171
b6a310
b6a310
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
b6a310
(cherry picked from commit 7515c23a416825f0db51f9b445279b12d5918ebf)
b6a310
---
b6a310
 hw/xwayland/xwayland-glamor-eglstream.c | 20 ++++++++++++++++++++
b6a310
 1 file changed, 20 insertions(+)
b6a310
b6a310
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
index 2d0827709..c583a1390 100644
b6a310
--- a/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
@@ -72,6 +72,7 @@ struct xwl_eglstream_private {
b6a310
     SetWindowPixmapProcPtr SetWindowPixmap;
b6a310
 
b6a310
     Bool have_egl_damage;
b6a310
+    Bool have_egl_stream_flush;
b6a310
 
b6a310
     GLint blit_prog;
b6a310
     GLuint blit_vao;
b6a310
@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
b6a310
         goto out;
b6a310
     }
b6a310
 
b6a310
+#ifdef EGL_NV_stream_flush
b6a310
+    if (xwl_eglstream->have_egl_stream_flush)
b6a310
+        /* block until stream state is updated on the compositor's side */
b6a310
+        eglStreamFlushNV(xwl_screen->egl_display,
b6a310
+                         xwl_pixmap->stream);
b6a310
+#endif
b6a310
+
b6a310
     if (!xwl_pixmap->wait_for_buffer_release) {
b6a310
         /* hang onto the pixmap until the compositor has released it */
b6a310
         pixmap->refcnt++;
b6a310
@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
b6a310
         ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance "
b6a310
                "will be affected\n");
b6a310
 
b6a310
+#ifdef EGL_NV_stream_flush
b6a310
+    xwl_eglstream->have_egl_stream_flush =
b6a310
+        epoxy_has_egl_extension(xwl_screen->egl_display,
b6a310
+                                "EGL_NV_stream_flush");
b6a310
+#else
b6a310
+    xwl_eglstream->have_egl_stream_flush = FALSE;
b6a310
+#endif /* EGL_NV_stream_flush */
b6a310
+
b6a310
+    if (!xwl_eglstream->have_egl_stream_flush)
b6a310
+        ErrorF("EGL_NV_stream_flush not available, "
b6a310
+               "this may cause visible corruption.\n");
b6a310
+
b6a310
     xwl_eglstream_init_shaders(xwl_screen);
b6a310
 
b6a310
     if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
b6a310
-- 
b6a310
2.31.1
b6a310