Blame SOURCES/0019-xwayland-eglstream-Do-not-always-increment-pixmap-re.patch

b6a310
From 7b06e468b37164eeaa18fc32cba801de0eee4eb1 Mon Sep 17 00:00:00 2001
b6a310
From: Olivier Fourdan <ofourdan@redhat.com>
b6a310
Date: Tue, 4 May 2021 10:56:38 +0200
b6a310
Subject: [PATCH xserver 19/27] xwayland/eglstream: Do not always increment
b6a310
 pixmap refcnt on commit
b6a310
MIME-Version: 1.0
b6a310
Content-Type: text/plain; charset=UTF-8
b6a310
Content-Transfer-Encoding: 8bit
b6a310
b6a310
Currently, the EGLstream backend would increment the pixmap refcount for
b6a310
each commit, and decrease that refcount on the wl_buffer release
b6a310
callback.
b6a310
b6a310
But that's relying on the compositor sending us a release callback for
b6a310
each commit, otherwise the pixmap refcount will keep increasing and the
b6a310
pixmap will be leaked.
b6a310
b6a310
So instead, increment the refcount on the pixmap only when we have not
b6a310
received a release notification for the wl_buffer, to avoid increasing
b6a310
the pixmap refcount more than once without a corresponding release
b6a310
event.
b6a310
b6a310
This way, if the pixmap is still in use when released on the X11 side,
b6a310
the EGL stream will be kept until the compositor releases it.
b6a310
b6a310
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
b6a310
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
b6a310
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
b6a310
(cherry picked from commit d85bfa6ab7495281516f3a4b05dc1ff0b2c4bf91)
b6a310
---
b6a310
 hw/xwayland/xwayland-glamor-eglstream.c | 21 +++++++++++++++++----
b6a310
 1 file changed, 17 insertions(+), 4 deletions(-)
b6a310
b6a310
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
index 6721acfe8..64f4e31f5 100644
b6a310
--- a/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
b6a310
@@ -89,6 +89,7 @@ struct xwl_pixmap {
b6a310
     struct xwl_screen *xwl_screen;
b6a310
     struct wl_buffer *buffer;
b6a310
     struct xwl_eglstream_pending_stream *pending_stream;
b6a310
+    Bool wait_for_buffer_release;
b6a310
 
b6a310
     /* XWL_PIXMAP_EGLSTREAM. */
b6a310
     EGLStreamKHR stream;
b6a310
@@ -577,8 +578,16 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
b6a310
 static void
b6a310
 xwl_eglstream_buffer_release_callback(void *data)
b6a310
 {
b6a310
-    /* drop the reference we took in post_damage, freeing if necessary */
b6a310
-    dixDestroyPixmap(data, 0);
b6a310
+    PixmapPtr pixmap = data;
b6a310
+    struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
b6a310
+
b6a310
+    assert(xwl_pixmap);
b6a310
+
b6a310
+    if (xwl_pixmap->wait_for_buffer_release) {
b6a310
+        xwl_pixmap->wait_for_buffer_release = FALSE;
b6a310
+        /* drop the reference we took in the ready callback, freeing if necessary */
b6a310
+        dixDestroyPixmap(pixmap, 0);
b6a310
+    }
b6a310
 }
b6a310
 
b6a310
 static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
b6a310
@@ -606,6 +615,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
b6a310
 
b6a310
     xwl_glamor_egl_make_current(xwl_screen);
b6a310
 
b6a310
+    xwl_pixmap->wait_for_buffer_release = FALSE;
b6a310
     xwl_pixmap->xwl_screen = xwl_screen;
b6a310
     xwl_pixmap->surface = EGL_NO_SURFACE;
b6a310
     xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
b6a310
@@ -762,8 +772,11 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
b6a310
         goto out;
b6a310
     }
b6a310
 
b6a310
-    /* hang onto the pixmap until the compositor has released it */
b6a310
-    pixmap->refcnt++;
b6a310
+    if (!xwl_pixmap->wait_for_buffer_release) {
b6a310
+        /* hang onto the pixmap until the compositor has released it */
b6a310
+        pixmap->refcnt++;
b6a310
+        xwl_pixmap->wait_for_buffer_release = TRUE;
b6a310
+    }
b6a310
 
b6a310
 out:
b6a310
     /* Restore previous state */
b6a310
-- 
b6a310
2.31.1
b6a310