summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Kurzinger <ekurzinger@nvidia.com>2021-05-11 17:00:21 -0400
committerOlivier Fourdan <ofourdan@redhat.com>2021-06-21 11:16:58 +0200
commitf4720f1c42cb9fec3edfa8e871f8557b038e2aad (patch)
tree049283a57187119c5648ab8dcefa18374cd176e4
parentb2963fccc186b384af22891a7f73892c93a7ba39 (diff)
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@nvidia.com> (cherry picked from commit 7515c23a416825f0db51f9b445279b12d5918ebf)
-rw-r--r--hw/xwayland/xwayland-glamor-eglstream.c20
1 files changed, 20 insertions, 0 deletions
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") &&