90 lines
3.3 KiB
Diff
90 lines
3.3 KiB
Diff
|
From 7b06e468b37164eeaa18fc32cba801de0eee4eb1 Mon Sep 17 00:00:00 2001
|
||
|
From: Olivier Fourdan <ofourdan@redhat.com>
|
||
|
Date: Tue, 4 May 2021 10:56:38 +0200
|
||
|
Subject: [PATCH xserver 19/27] xwayland/eglstream: Do not always increment
|
||
|
pixmap refcnt on commit
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
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 <ofourdan@redhat.com>
|
||
|
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
|
||
|
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
|
||
|
(cherry picked from commit d85bfa6ab7495281516f3a4b05dc1ff0b2c4bf91)
|
||
|
---
|
||
|
hw/xwayland/xwayland-glamor-eglstream.c | 21 +++++++++++++++++----
|
||
|
1 file changed, 17 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
|
||
|
index 6721acfe8..64f4e31f5 100644
|
||
|
--- a/hw/xwayland/xwayland-glamor-eglstream.c
|
||
|
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
|
||
|
@@ -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 */
|
||
|
--
|
||
|
2.31.1
|
||
|
|