xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 20 12:52:05 UTC 2021


 hw/xwayland/xwayland-glamor-eglstream.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

New commits:
commit 7515c23a416825f0db51f9b445279b12d5918ebf
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date:   Tue May 11 17:00:21 2021 -0400

    xwayland/eglstream: flush stream after eglSwapBuffers
    
    When eglSwapBuffers inserts a new frame into a window's stream, there may be a
    delay before the state of the consumer end of the stream is updated to reflect
    this. If the subsequent wl_surface_attach, wl_surface_damage, wl_surface_commit
    calls are received by the compositor before then, it will (typically) re-use
    the previous frame acquired from the stream instead of the latest one.
    
    This can leave the window displaying out-of-date contents, which might never be
    updated thereafter.
    
    To fix this, after calling eglSwapBuffers, xwl_glamor_eglstream_post_damage
    should call eglStreamFlushNV. This call will block until it can be guaranteed
    that the state of the consumer end of the stream has been updated to reflect
    that a new frame is available.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1171
    
    Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2d0827709..c583a1390 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -72,6 +72,7 @@ struct xwl_eglstream_private {
     SetWindowPixmapProcPtr SetWindowPixmap;
 
     Bool have_egl_damage;
+    Bool have_egl_stream_flush;
 
     GLint blit_prog;
     GLuint blit_vao;
@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
         goto out;
     }
 
+#ifdef EGL_NV_stream_flush
+    if (xwl_eglstream->have_egl_stream_flush)
+        /* block until stream state is updated on the compositor's side */
+        eglStreamFlushNV(xwl_screen->egl_display,
+                         xwl_pixmap->stream);
+#endif
+
     if (!xwl_pixmap->wait_for_buffer_release) {
         /* hang onto the pixmap until the compositor has released it */
         pixmap->refcnt++;
@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
         ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance "
                "will be affected\n");
 
+#ifdef EGL_NV_stream_flush
+    xwl_eglstream->have_egl_stream_flush =
+        epoxy_has_egl_extension(xwl_screen->egl_display,
+                                "EGL_NV_stream_flush");
+#else
+    xwl_eglstream->have_egl_stream_flush = FALSE;
+#endif /* EGL_NV_stream_flush */
+
+    if (!xwl_eglstream->have_egl_stream_flush)
+        ErrorF("EGL_NV_stream_flush not available, "
+               "this may cause visible corruption.\n");
+
     xwl_eglstream_init_shaders(xwl_screen);
 
     if (epoxy_has_gl_extension("GL_OES_EGL_image") &&


More information about the xorg-commit mailing list