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

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