|
|
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 |
|