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

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