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

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