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

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