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

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