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>
This commit is contained in:
		
							parent
							
								
									f3eb1684fa
								
							
						
					
					
						commit
						7515c23a41
					
				| 
						 | 
					@ -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,
 | 
				
			||||||
        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 */
 | 
				
			||||||
 | 
					        eglStreamFlushNV(xwl_screen->egl_display,
 | 
				
			||||||
 | 
					                         xwl_pixmap->stream);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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)
 | 
				
			||||||
        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 =
 | 
				
			||||||
 | 
					        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);
 | 
					    xwl_eglstream_init_shaders(xwl_screen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
 | 
					    if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue