Commit 7515c23a authored by Erik Kurzinger's avatar Erik Kurzinger Committed by Olivier Fourdan
Browse files

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: xorg/xserver#1171

Signed-off-by: Erik Kurzinger's avatarErik Kurzinger <>
parent f3eb1684
Pipeline #322957 passed with stages
in 5 minutes and 34 seconds
...@@ -72,6 +72,7 @@ struct xwl_eglstream_private { ...@@ -72,6 +72,7 @@ struct xwl_eglstream_private {
SetWindowPixmapProcPtr SetWindowPixmap; SetWindowPixmapProcPtr SetWindowPixmap;
Bool have_egl_damage; Bool have_egl_damage;
Bool have_egl_stream_flush;
GLint blit_prog; GLint blit_prog;
GLuint blit_vao; GLuint blit_vao;
...@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window, ...@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
goto out; 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 */
if (!xwl_pixmap->wait_for_buffer_release) { if (!xwl_pixmap->wait_for_buffer_release) {
/* hang onto the pixmap until the compositor has released it */ /* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++; pixmap->refcnt++;
...@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen) ...@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance " ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance "
"will be affected\n"); "will be affected\n");
#ifdef EGL_NV_stream_flush
xwl_eglstream->have_egl_stream_flush =
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); xwl_eglstream_init_shaders(xwl_screen);
if (epoxy_has_gl_extension("GL_OES_EGL_image") && if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment