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

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