Commit d85bfa6a authored by Olivier Fourdan's avatar Olivier Fourdan 🛠
Browse files

xwayland/eglstream: Do not always increment pixmap refcnt on commit



Currently, the EGLstream backend would increment the pixmap refcount for
each commit, and decrease that refcount on the wl_buffer release
callback.

But that's relying on the compositor sending us a release callback for
each commit, otherwise the pixmap refcount will keep increasing and the
pixmap will be leaked.

So instead, increment the refcount on the pixmap only when we have not
received a release notification for the wl_buffer, to avoid increasing
the pixmap refcount more than once without a corresponding release
event.

This way, if the pixmap is still in use when released on the X11 side,
the EGL stream will be kept until the compositor releases it.
Signed-off-by: Olivier Fourdan's avatarOlivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer's avatarMichel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer's avatarMichel Dänzer <mdaenzer@redhat.com>
parent b583395c
......@@ -89,6 +89,7 @@ struct xwl_pixmap {
struct xwl_screen *xwl_screen;
struct wl_buffer *buffer;
struct xwl_eglstream_pending_stream *pending_stream;
Bool wait_for_buffer_release;
/* XWL_PIXMAP_EGLSTREAM. */
EGLStreamKHR stream;
......@@ -577,8 +578,16 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
static void
xwl_eglstream_buffer_release_callback(void *data)
{
/* drop the reference we took in post_damage, freeing if necessary */
dixDestroyPixmap(data, 0);
PixmapPtr pixmap = data;
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
assert(xwl_pixmap);
if (xwl_pixmap->wait_for_buffer_release) {
xwl_pixmap->wait_for_buffer_release = FALSE;
/* drop the reference we took in the ready callback, freeing if necessary */
dixDestroyPixmap(pixmap, 0);
}
}
static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
......@@ -606,6 +615,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
xwl_glamor_egl_make_current(xwl_screen);
xwl_pixmap->wait_for_buffer_release = FALSE;
xwl_pixmap->xwl_screen = xwl_screen;
xwl_pixmap->surface = EGL_NO_SURFACE;
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
......@@ -762,8 +772,11 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
goto out;
}
/* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++;
if (!xwl_pixmap->wait_for_buffer_release) {
/* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++;
xwl_pixmap->wait_for_buffer_release = TRUE;
}
out:
/* Restore previous state */
......
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