xserver: Branch 'xwayland-24.1' - 18 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 4 09:00:55 UTC 2024


 hw/xwayland/meson.build               |    2 
 hw/xwayland/xwayland-dmabuf.c         |    2 
 hw/xwayland/xwayland-glamor-gbm.c     |  149 ++++++++++++++++++++++++++++++
 hw/xwayland/xwayland-glamor-gbm.h     |    8 +
 hw/xwayland/xwayland-types.h          |    1 
 hw/xwayland/xwayland-window-buffers.c |  167 ++++++++++++----------------------
 hw/xwayland/xwayland-window-buffers.h |    7 -
 hw/xwayland/xwayland-window.c         |   67 ++++++++-----
 os/osdep.h                            |    1 
 present/meson.build                   |    7 +
 10 files changed, 276 insertions(+), 135 deletions(-)

New commits:
commit 38060228c18b56019170e45e3dae072ba9781026
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jul 2 18:54:10 2024 +0200

    xwayland: Force disposal of windows buffers for root on destroy
    
    With explicit buffer synchronization in use, the window buffers use a
    file descriptor for event notification to keep the buffer alive for
    synchronization purpose.
    
    When running rootful, the root window (which is visible) is destroyed
    directly from the resource manager on server reset, and the window
    buffer's eventfd will trigger after the window is destroyed, leading to
    a use after free and a crash of the xserver.
    
    To avoid the issue, check whether the window being destroyed is the root
    window in rootless mode, and make sure to force the disposal of the
    window buffers in that case.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1699
    (cherry picked from commit a5e863963e3d8cef2cf84f7c65832adb78040798)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 20f4c1d04..c1566a608 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1646,6 +1646,7 @@ xwl_window_dispose(struct xwl_window *xwl_window)
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct xwl_seat *xwl_seat;
     WindowPtr window = xwl_window->toplevel;
+    ScreenPtr screen = xwl_screen->screen;
 
     compUnredirectWindow(serverClient, window, CompositeRedirectManual);
 
@@ -1688,7 +1689,9 @@ xwl_window_dispose(struct xwl_window *xwl_window)
     xorg_list_del(&xwl_window->link_damage);
     xorg_list_del(&xwl_window->link_window);
 
-    xwl_window_buffers_dispose(xwl_window, FALSE);
+    /* Special case for the root window in rootful mode */
+    xwl_window_buffers_dispose(xwl_window,
+                               (!xwl_screen->rootless && window == screen->root));
 
     if (xwl_window->window_buffers_timer)
         TimerFree(xwl_window->window_buffers_timer);
commit 4942b7c137580523da6dca75247db56534c761e5
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jul 2 18:51:44 2024 +0200

    xwayland/window-buffers: optionally force disposal
    
    For cases (to come) where we would want to force the disposal of the
    window buffers, add a parameter to force the disposal by calling
    dispose() directly instead of maybe_dispose().
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit fa04e15afccc8ef49a00e39c84e26b2f7fca5966)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-dmabuf.c b/hw/xwayland/xwayland-dmabuf.c
index db7dc44ee..e485e5b1c 100644
--- a/hw/xwayland/xwayland-dmabuf.c
+++ b/hw/xwayland/xwayland-dmabuf.c
@@ -752,7 +752,7 @@ xwl_window_dmabuf_feedback_done(void *data,
     /* If the linux-dmabuf v4 per-surface feedback changed, make sure the
      * window buffers get re-created with appropriate parameters.
      */
-    xwl_window_buffers_dispose(xwl_window);
+    xwl_window_buffers_dispose(xwl_window, FALSE);
     xwl_window_realloc_pixmap(xwl_window);
 }
 
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 1a7e78537..2bf6c978c 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -244,8 +244,17 @@ xwl_window_buffers_init(struct xwl_window *xwl_window)
     xorg_list_init(&xwl_window->window_buffers_unavailable);
 }
 
+static void
+xwl_window_buffer_disposal(struct xwl_window_buffer *xwl_window_buffer, Bool force)
+{
+    if (force)
+        xwl_window_buffer_dispose(xwl_window_buffer);
+    else
+        xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+}
+
 void
-xwl_window_buffers_dispose(struct xwl_window *xwl_window)
+xwl_window_buffers_dispose(struct xwl_window *xwl_window, Bool force)
 {
     struct xwl_window_buffer *xwl_window_buffer, *tmp;
 
@@ -257,14 +266,14 @@ xwl_window_buffers_dispose(struct xwl_window *xwl_window)
                                   &xwl_window->window_buffers_available,
                                   link_buffer) {
         xorg_list_del(&xwl_window_buffer->link_buffer);
-        xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+        xwl_window_buffer_disposal(xwl_window_buffer, force);
     }
 
     xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
                                   &xwl_window->window_buffers_unavailable,
                                   link_buffer) {
         xorg_list_del(&xwl_window_buffer->link_buffer);
-        xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+        xwl_window_buffer_disposal(xwl_window_buffer, force);
     }
 
     if (xwl_window->window_buffers_timer)
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index af46eb91b..dabb343c1 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -34,7 +34,7 @@
 void xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window);
 void xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer);
 void xwl_window_buffers_init(struct xwl_window *xwl_window);
-void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
+void xwl_window_buffers_dispose(struct xwl_window *xwl_window, Bool force);
 void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
 PixmapPtr xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync);
 
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index b9074f313..20f4c1d04 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1404,7 +1404,7 @@ xwl_window_update_surface_window(struct xwl_window *xwl_window)
     }
 
     if (surface_window->drawable.depth != xwl_window->surface_window->drawable.depth)
-        xwl_window_buffers_dispose(xwl_window);
+        xwl_window_buffers_dispose(xwl_window, FALSE);
 
     xwl_window->surface_window = surface_window;
     register_damage(xwl_window);
@@ -1688,7 +1688,7 @@ xwl_window_dispose(struct xwl_window *xwl_window)
     xorg_list_del(&xwl_window->link_damage);
     xorg_list_del(&xwl_window->link_window);
 
-    xwl_window_buffers_dispose(xwl_window);
+    xwl_window_buffers_dispose(xwl_window, FALSE);
 
     if (xwl_window->window_buffers_timer)
         TimerFree(xwl_window->window_buffers_timer);
@@ -1750,7 +1750,7 @@ xwl_window_set_window_pixmap(WindowPtr window,
          old_pixmap->drawable.height == pixmap->drawable.height))
        return;
 
-    xwl_window_buffers_dispose(xwl_window);
+    xwl_window_buffers_dispose(xwl_window, FALSE);
 }
 
 Bool
commit f834e104aad2abce56867a638c345964946d837f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jul 2 18:49:14 2024 +0200

    xwayland/window-buffers: Move buffer disposal to its own function
    
    No functional change, this is just preparation work for the next commit.
    
    v2: Reshuffle functions (Michel)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 571cb1334274add24d77b2576001f2703b188b41)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 8c8475c0b..1a7e78537 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -102,14 +102,9 @@ xwl_window_buffer_destroy_pixmap(struct xwl_window_buffer *xwl_window_buffer)
     xwl_window_buffer->pixmap = NullPixmap;
 }
 
-static Bool
-xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
+static void
+xwl_window_buffer_dispose(struct xwl_window_buffer *xwl_window_buffer)
 {
-    assert(xwl_window_buffer->refcnt > 0);
-
-    if (--xwl_window_buffer->refcnt)
-        return FALSE;
-
     RegionDestroy(xwl_window_buffer->damage_region);
 
     if (xwl_window_buffer->pixmap) {
@@ -121,6 +116,17 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
 
     xorg_list_del(&xwl_window_buffer->link_buffer);
     free(xwl_window_buffer);
+}
+
+static Bool
+xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
+{
+    assert(xwl_window_buffer->refcnt > 0);
+
+    if (--xwl_window_buffer->refcnt)
+        return FALSE;
+
+    xwl_window_buffer_dispose(xwl_window_buffer);
 
     return TRUE;
 }
commit aa0ea88e131d842f40c561ac25ea6d6fe1394885
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Jul 3 09:55:43 2024 +0200

    xwayland: Make sure we do not leak xwl_window on destroy
    
    Right now, we would dispose the xwl_window and all the data associated
    with it on unrealize.
    
    But not all window destruction go through the unrealize code path, for
    example when the root window (running rootful) is destroyed from the
    resource manager on server reset, we do not get to the unrealize window
    step, but straight to destroy window.
    
    As a result, we are leaking the xwl_window and all the data associated
    with it, for example:
    
    | 65,536 bytes in 1 blocks are possibly lost in loss record 12,462 of 12,488
    |    at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
    |    by 0x48B661C: UnknownInlinedFun (pixman-bits-image.c:1273)
    |    by 0x48B661C: _pixman_bits_image_init (pixman-bits-image.c:1296)
    |    by 0x48B6754: create_bits_image_internal (pixman-bits-image.c:1349)
    |    by 0x64180DE: UnknownInlinedFun (cairo-image-surface.c:380)
    |    by 0x64180DE: UnknownInlinedFun (cairo-image-surface.c:366)
    |    by 0x64180DE: cairo_image_surface_create (cairo-image-surface.c:432)
    |    by 0x6346B44: UnknownInlinedFun (libdecor-gtk.c:467)
    |    by 0x6346B44: libdecor_plugin_gtk_frame_new (libdecor-gtk.c:546)
    |    by 0x4B7F297: libdecor_decorate (libdecor.c:559)
    |    by 0x42C6F3: xwl_create_root_surface (xwayland-window.c:1266)
    |    by 0x42CD97: ensure_surface_for_window (xwayland-window.c:1466)
    |    by 0x42D0D1: xwl_realize_window (xwayland-window.c:1560)
    |    by 0x50858F: compRealizeWindow (compwindow.c:279)
    |    by 0x4FF2A2: MapWindow (window.c:2706)
    |    by 0x4F9E7F: InitRootWindow (window.c:697)
    
    To avoid that issue, check whether there is still an xwl_window
    associated with the X11 window on destroy, and if that's the case,
    dispose the xwl_window.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 0e1a98f52f57111c7259244be86bec92de27b3ce)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 0a43ebc9c..b9074f313 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1927,11 +1927,15 @@ xwl_destroy_window(WindowPtr window)
 {
     ScreenPtr screen = window->drawable.pScreen;
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    struct xwl_window *xwl_window = xwl_window_get(window);
     Bool ret;
 
     if (xwl_screen->present)
         xwl_present_cleanup(window);
 
+    if (xwl_window)
+        xwl_window_dispose(xwl_window);
+
     screen->DestroyWindow = xwl_screen->DestroyWindow;
 
     if (screen->DestroyWindow)
commit 6a916c96583822d26c13634726e3cdf5f7fbd6a4
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Jul 3 09:52:28 2024 +0200

    xwayland: Move xwl_window disposal to its own function
    
    No functional change intended, this is just preparation work for the
    next commit.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 74be7a7f36b57238df9830aed3dc5f8fc2bbbd3d)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 48b129312..0a43ebc9c 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1640,28 +1640,14 @@ release_wl_surface_for_window(struct xwl_window *xwl_window)
         release_wl_surface_for_window_legacy_delay(xwl_window);
 }
 
-Bool
-xwl_unrealize_window(WindowPtr window)
+static void
+xwl_window_dispose(struct xwl_window *xwl_window)
 {
-    ScreenPtr screen = window->drawable.pScreen;
-    struct xwl_screen *xwl_screen;
-    struct xwl_window *xwl_window;
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct xwl_seat *xwl_seat;
-    Bool ret;
-
-    xwl_screen = xwl_screen_get(screen);
+    WindowPtr window = xwl_window->toplevel;
 
-    xwl_window = xwl_window_get(window);
-    if (xwl_window)
-        compUnredirectWindow(serverClient, window, CompositeRedirectManual);
-
-    screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
-    ret = (*screen->UnrealizeWindow) (window);
-    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
-    screen->UnrealizeWindow = xwl_unrealize_window;
-
-    if (!xwl_window)
-        return ret;
+    compUnredirectWindow(serverClient, window, CompositeRedirectManual);
 
     xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) {
         if (xwl_seat->focus_window == xwl_window)
@@ -1701,7 +1687,6 @@ xwl_unrealize_window(WindowPtr window)
     release_wl_surface_for_window(xwl_window);
     xorg_list_del(&xwl_window->link_damage);
     xorg_list_del(&xwl_window->link_window);
-    unregister_damage(xwl_window);
 
     xwl_window_buffers_dispose(xwl_window);
 
@@ -1715,6 +1700,25 @@ xwl_unrealize_window(WindowPtr window)
 
     free(xwl_window);
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
+}
+
+Bool
+xwl_unrealize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    struct xwl_window *xwl_window = xwl_window_get(window);
+    Bool ret;
+
+    if (xwl_window) {
+        unregister_damage(xwl_window);
+        xwl_window_dispose(xwl_window);
+    }
+
+    screen->UnrealizeWindow = xwl_screen->UnrealizeWindow;
+    ret = (*screen->UnrealizeWindow) (window);
+    xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
+    screen->UnrealizeWindow = xwl_unrealize_window;
 
     return ret;
 }
commit 8f611b0f22d4aeb1c35deb8935648e0dddf2c6c6
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 18 14:02:03 2024 +0200

    xwayland/window-buffers: Set syncpnts for all pixmaps
    
    The wp_linux_drm_syncobj_v1 protocol states that :
    
    | If at surface commit time there is a pending buffer attached but no
    | pending release timeline point set, the no_release_point protocol
    | error is raised.
    
    So we need to set a release timeline point in any case from the swap
    pixmap routine, even for the early out code paths.
    
    Failing to do so may cause a Wayland protocol error that is fatal to the
    Wayland client, in this case Xwayland:
    
    | wp_linux_drm_syncobj_surface_v1: error 4: No Acquire point provided
    | (EE) failed to dispatch Wayland events: Protocol error
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1688
    Fixes: 87bf2cafcc - xwayland: add support for wp_linux_drm_syncobj_v1
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit bc9bf563603c4cd22e30448cb03c20a6a86b0364)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index ad2cef156..8c8475c0b 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -414,6 +414,8 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
         if (xwl_is_client_pixmap(window_pixmap)) {
             xwl_window_buffer->pixmap = NULL;
             xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+            if (handle_sync)
+                xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, NULL);
             return window_pixmap;
         }
     } else {
@@ -424,8 +426,11 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
         window_pixmap->refcnt++;
         xwl_window_realloc_pixmap(xwl_window);
 
-        if (!xwl_window_buffer)
+        if (!xwl_window_buffer) {
+            if (handle_sync)
+                xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, NULL);
             return window_pixmap;
+        }
     }
 
     xwl_window_buffer->pixmap = window_pixmap;
commit 33486519dcc0417dbfe5243017ab215e4548e0ba
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 18 13:58:45 2024 +0200

    xwayland/window-buffers: Move code to submit pixmaps
    
    Move the code which takes care of submitting pixmaps and the
    synchronization points to its own function.
    
    This will allow to reuse that code from different code path.
    
    No functional change intended.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 33330f0dc96c126895e2670b22de4d7980a60283)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index e3f8ffe21..ad2cef156 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -349,6 +349,32 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
     screen->DestroyPixmap(window_pixmap);
 }
 
+static Bool
+xwl_window_handle_pixmap_sync(struct xwl_window *xwl_window,
+                              PixmapPtr pixmap,
+                              struct xwl_window_buffer *xwl_window_buffer)
+{
+    Bool implicit_sync = TRUE;
+#ifdef XWL_HAS_GLAMOR
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
+        if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, pixmap)) {
+            implicit_sync = FALSE;
+            /* wait until the release fence is available before re-using this buffer */
+            xwl_glamor_gbm_wait_release_fence(xwl_window, pixmap, xwl_window_buffer);
+        } else {
+            /* If glamor does not support implicit sync and we can't use
+             * explicit sync, wait for the GPU to be idle before presenting.
+             * Note that buffer re-use will still be unsynchronized :(
+             */
+            glamor_finish(xwl_screen->screen);
+        }
+    }
+#endif /* XWL_HAS_GLAMOR */
+    return implicit_sync;
+}
+
 PixmapPtr
 xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
 {
@@ -356,7 +382,6 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
     WindowPtr surface_window = xwl_window->surface_window;
     struct xwl_window_buffer *xwl_window_buffer;
     PixmapPtr window_pixmap;
-    Bool implicit_sync = TRUE;
 
     window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (surface_window);
 
@@ -408,23 +433,8 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
     /* Hold a reference on the buffer until it's released by the compositor */
     xwl_window_buffer->refcnt++;
 
-#ifdef XWL_HAS_GLAMOR
-    if (handle_sync && !xwl_glamor_supports_implicit_sync(xwl_screen)) {
-        if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, window_pixmap)) {
-            implicit_sync = FALSE;
-            /* wait until the release fence is available before re-using this buffer */
-            xwl_glamor_gbm_wait_release_fence(xwl_window, window_pixmap, xwl_window_buffer);
-        } else {
-            /* If glamor does not support implicit sync and we can't use
-             * explicit sync, wait for the GPU to be idle before presenting.
-             * Note that buffer re-use will still be unsynchronized :(
-             */
-            glamor_finish(xwl_screen->screen);
-        }
-    }
-#endif /* XWL_HAS_GLAMOR */
-
-    if (implicit_sync) {
+    if (handle_sync &&
+        xwl_window_handle_pixmap_sync(xwl_window, window_pixmap, xwl_window_buffer)) {
         xwl_pixmap_set_buffer_release_cb(xwl_window_buffer->pixmap,
                                          xwl_window_buffer_release_callback,
                                          xwl_window_buffer);
commit 6636b7c0039d295a97e0db4b4ac54f92952ee489
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jul 2 12:36:01 2024 +0200

    xwayland/window-buffers: Do not always set syncpnts
    
    The function xwl_window_swap_pixmap() can be called from two places,
    either from xwl_window_attach_buffer() or from damage_report().
    
    When called from xwl_window_attach_buffer(), the new buffer is attached
    and the surface committed.
    
    However, when called from damage_report(), a new buffer might not be
    attached before the surface is committed.
    
    That's fine with implicit synchronization, but if we use explicit
    synchronization, committing a surface without a new buffer attached but
    with a release timeline point set is a protocol error:
    
    | If at surface commit time there is a pending release timeline point
    | set but no pending buffer attached, a no_buffer error is raised.
    
    To avoid such an issue, add a new parameter to xwl_window_swap_pixmap()
    to hint whether it should set the synchronization points, and have the
    synchronization points set only from xwl_window_attach_buffer().
    
    v2: Rename param to handle_sync (Michel)
    
    Suggested-by: Michel Dänzer <mdaenzer at redhat.com>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit aab01c73914eeadf75672ab954538cd34d07e817)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 442e9e2fd..e3f8ffe21 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -350,7 +350,7 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
 }
 
 PixmapPtr
-xwl_window_swap_pixmap(struct xwl_window *xwl_window)
+xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     WindowPtr surface_window = xwl_window->surface_window;
@@ -409,7 +409,7 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
     xwl_window_buffer->refcnt++;
 
 #ifdef XWL_HAS_GLAMOR
-    if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
+    if (handle_sync && !xwl_glamor_supports_implicit_sync(xwl_screen)) {
         if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, window_pixmap)) {
             implicit_sync = FALSE;
             /* wait until the release fence is available before re-using this buffer */
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index ee26d3244..af46eb91b 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -36,6 +36,6 @@ void xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer);
 void xwl_window_buffers_init(struct xwl_window *xwl_window);
 void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
 void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
-PixmapPtr xwl_window_swap_pixmap(struct xwl_window *xwl_window);
+PixmapPtr xwl_window_swap_pixmap(struct xwl_window *xwl_window, Bool handle_sync);
 
 #endif /* XWAYLAND_WINDOW_BUFFERS_H */
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index c2bd792e4..48b129312 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -316,7 +316,7 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
 
     window_pixmap = xwl_screen->screen->GetWindowPixmap(xwl_window->surface_window);
     if (xwl_is_client_pixmap(window_pixmap))
-        xwl_screen->screen->DestroyPixmap(xwl_window_swap_pixmap(xwl_window));
+        xwl_screen->screen->DestroyPixmap(xwl_window_swap_pixmap(xwl_window, FALSE));
 }
 
 static void
@@ -1952,7 +1952,7 @@ xwl_window_attach_buffer(struct xwl_window *xwl_window)
     PixmapPtr pixmap;
     int i;
 
-    pixmap = xwl_window_swap_pixmap(xwl_window);
+    pixmap = xwl_window_swap_pixmap(xwl_window, TRUE);
     buffer = xwl_pixmap_get_wl_buffer(pixmap);
 
     if (!buffer) {
commit 4382a4f84e9239b5e1a62ea6192f589e032dd113
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 18 11:26:26 2024 +0200

    xwayland/window-buffers: Use synchronization from GLAMOR/GBM
    
    Now that we have the buffer synchronization implemented in the
    GLAMOR/GBM code, switch to use that code.
    
    At this point, there is still not functional change intended, this is
    still preparation work for a fix that is still to come.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 256cef8b201047ba4d840043e89573f4574c24df)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 0b9861fbb..442e9e2fd 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -31,6 +31,7 @@
 #include "xwayland-window.h"
 #include "xwayland-pixmap.h"
 #include "xwayland-screen.h"
+#include "xwayland-glamor-gbm.h"
 #include "xwayland-window-buffers.h"
 #ifdef XWL_HAS_GLAMOR
 #include "glamor.h"
@@ -47,11 +48,6 @@ struct xwl_window_buffer {
     struct xwl_window *xwl_window;
     PixmapPtr pixmap;
     RegionPtr damage_region;
-#ifdef XWL_HAS_GLAMOR
-    struct dri3_syncobj *syncobj;
-    uint64_t timeline_point;
-    int efd;
-#endif /* XWL_HAS_GLAMOR */
     int refcnt;
     uint32_t time;
     struct xorg_list link_buffer;
@@ -90,9 +86,6 @@ xwl_window_buffer_new(struct xwl_window *xwl_window)
     xwl_window_buffer->damage_region = RegionCreate(NullBox, 1);
     xwl_window_buffer->pixmap = NullPixmap;
     xwl_window_buffer->refcnt = 1;
-#ifdef XWL_HAS_GLAMOR
-    xwl_window_buffer->efd = -1;
-#endif /* XWL_HAS_GLAMOR */
 
     xorg_list_init(&xwl_window_buffer->link_buffer);
 
@@ -119,18 +112,12 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
 
     RegionDestroy(xwl_window_buffer->damage_region);
 
-    if (xwl_window_buffer->pixmap)
-        xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
-
+    if (xwl_window_buffer->pixmap) {
 #ifdef XWL_HAS_GLAMOR
-    if (xwl_window_buffer->syncobj)
-        xwl_window_buffer->syncobj->free(xwl_window_buffer->syncobj);
-
-    if (xwl_window_buffer->efd >= 0) {
-        SetNotifyFd(xwl_window_buffer->efd, NULL, 0, NULL);
-        close(xwl_window_buffer->efd);
-    }
+        xwl_glamor_gbm_dispose_syncpts(xwl_window_buffer->pixmap);
 #endif /* XWL_HAS_GLAMOR */
+        xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
+    }
 
     xorg_list_del(&xwl_window_buffer->link_buffer);
     free(xwl_window_buffer);
@@ -244,20 +231,6 @@ xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer)
     xwl_window_buffer_release_callback(xwl_window_buffer);
 }
 
-#ifdef XWL_HAS_GLAMOR
-static void
-xwl_window_buffers_release_fence_avail(int fd, int xevents, void *data)
-{
-    struct xwl_window_buffer *xwl_window_buffer = data;
-
-    SetNotifyFd(fd, NULL, 0, NULL);
-    close(fd);
-    xwl_window_buffer->efd = -1;
-
-    xwl_window_buffer_release_callback(data);
-}
-#endif /* XWL_HAS_GLAMOR */
-
 void
 xwl_window_buffers_init(struct xwl_window *xwl_window)
 {
@@ -376,46 +349,6 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
     screen->DestroyPixmap(window_pixmap);
 }
 
-#ifdef XWL_HAS_GLAMOR
-static Bool
-xwl_window_buffers_set_syncpts(struct xwl_window_buffer *xwl_window_buffer)
-{
-    struct xwl_window *xwl_window = xwl_window_buffer->xwl_window;
-    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-    uint64_t acquire_point = ++xwl_window_buffer->timeline_point;
-    uint64_t release_point = ++xwl_window_buffer->timeline_point;
-
-    if (!xwl_window_buffer->syncobj) {
-        struct dri3_syncobj *syncobj = xwl_glamor_dri3_syncobj_create(xwl_screen);
-        if (!syncobj)
-            goto fail;
-        xwl_window_buffer->syncobj = syncobj;
-    }
-
-    int fence_fd = xwl_glamor_get_fence(xwl_screen);
-    if (fence_fd >= 0)
-        xwl_window_buffer->syncobj->import_fence(xwl_window_buffer->syncobj,
-                                                 acquire_point, fence_fd);
-    else
-        goto fail;
-
-    xwl_glamor_dri3_syncobj_passthrough(xwl_window,
-                                        xwl_window_buffer->syncobj,
-                                        xwl_window_buffer->syncobj,
-                                        acquire_point,
-                                        release_point);
-    return TRUE;
-
-fail:
-    /* can't use explicit sync, we will do a glFinish() before presenting */
-    if (xwl_window_buffer->syncobj) {
-        xwl_window_buffer->syncobj->free(xwl_window_buffer->syncobj);
-        xwl_window_buffer->syncobj = NULL;
-    }
-    return FALSE;
-}
-#endif /* XWL_HAS_GLAMOR */
-
 PixmapPtr
 xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 {
@@ -434,17 +367,9 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
         RegionPtr full_damage = xwl_window_buffer->damage_region;
         BoxPtr pBox = RegionRects(full_damage);
         int nBox = RegionNumRects(full_damage);
-
 #ifdef XWL_HAS_GLAMOR
-        if (xwl_window_buffer->syncobj) {
-            int fence_fd =
-                xwl_window_buffer->syncobj->export_fence(xwl_window_buffer->syncobj,
-                                                         xwl_window_buffer->timeline_point);
-            xwl_glamor_wait_fence(xwl_screen, fence_fd);
-            close(fence_fd);
-        }
+        xwl_glamor_gbm_wait_syncpts(xwl_window_buffer->pixmap);
 #endif /* XWL_HAS_GLAMOR */
-
         while (nBox--) {
             copy_pixmap_area(window_pixmap,
                              xwl_window_buffer->pixmap,
@@ -485,21 +410,17 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 
 #ifdef XWL_HAS_GLAMOR
     if (!xwl_glamor_supports_implicit_sync(xwl_screen)) {
-        if (xwl_screen->explicit_sync && xwl_window_buffers_set_syncpts(xwl_window_buffer)) {
+        if (xwl_screen->explicit_sync && xwl_glamor_gbm_set_syncpts(xwl_window, window_pixmap)) {
             implicit_sync = FALSE;
             /* wait until the release fence is available before re-using this buffer */
-            xwl_window_buffer->efd = eventfd(0, EFD_CLOEXEC);
-            SetNotifyFd(xwl_window_buffer->efd, xwl_window_buffers_release_fence_avail,
-                        X_NOTIFY_READ, xwl_window_buffer);
-            xwl_window_buffer->syncobj->submitted_eventfd(xwl_window_buffer->syncobj,
-                                                          xwl_window_buffer->timeline_point,
-                                                          xwl_window_buffer->efd);
-        } else
+            xwl_glamor_gbm_wait_release_fence(xwl_window, window_pixmap, xwl_window_buffer);
+        } else {
             /* If glamor does not support implicit sync and we can't use
              * explicit sync, wait for the GPU to be idle before presenting.
              * Note that buffer re-use will still be unsynchronized :(
              */
             glamor_finish(xwl_screen->screen);
+        }
     }
 #endif /* XWL_HAS_GLAMOR */
 
commit 1539f208e2a74e3b728da9b3eeba49337c5f213c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 18 11:11:34 2024 +0200

    xwayland/glamor/gbm: Copy explicit sync code to GLAMOR/GBM
    
    Copy the code to deal with synchronization objects from the window
    buffers to the GLAMOR/GBM code.
    
    The idea is to deal with synchronizations for all pixmaps, even when
    there is no window buffer involved.
    
    This is still preparation work for the following commits, no functional
    change intended at this point.
    
    v2: Use a "xwl_window_buffer *" instead of a "void *data" (Michel)
    v3: Bail early if there's no xwl_window_buffer (Michel)
    v4: Rename xwl_window_submit_pixmap() to
        xwl_glamor_gbm_wait_release_fence() (Michel)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit cc021aca9985c9105fa0bed58920393723599dd4)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 8307f74b1..ebc990b57 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -32,6 +32,8 @@
 
 #include <fcntl.h>
 #include <errno.h>
+#include <poll.h>
+#include <sys/eventfd.h>
 #include <sys/stat.h>
 #include <xf86drm.h>
 #include <drm_fourcc.h>
@@ -55,6 +57,7 @@
 #include "xwayland-glamor-gbm.h"
 #include "xwayland-pixmap.h"
 #include "xwayland-screen.h"
+#include "xwayland-window-buffers.h"
 
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
 #include "linux-drm-syncobj-v1-client-protocol.h"
@@ -82,6 +85,12 @@ struct xwl_pixmap {
     unsigned int texture;
     struct gbm_bo *bo;
     Bool implicit_modifier;
+#ifdef DRI3
+    struct dri3_syncobj *syncobj;
+    uint64_t timeline_point;
+    int efd;
+    struct xwl_window_buffer *xwl_window_buffer;
+#endif /* DRI3 */
 };
 
 static DevPrivateKeyRec xwl_gbm_private_key;
@@ -225,6 +234,9 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
     xwl_pixmap->bo = bo;
     xwl_pixmap->buffer = NULL;
     xwl_pixmap->implicit_modifier = implicit_modifier;
+#ifdef XWL_HAS_GLAMOR
+    xwl_pixmap->efd = -1;
+#endif /* XWL_HAS_GLAMOR */
 
 #ifdef GBM_BO_FD_FOR_PLANE
     if (xwl_gbm->dmabuf_capable) {
@@ -445,6 +457,7 @@ xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
         eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
         if (xwl_pixmap->bo)
            gbm_bo_destroy(xwl_pixmap->bo);
+        xwl_glamor_gbm_dispose_syncpts(pixmap);
         free(xwl_pixmap);
     }
 
@@ -1388,6 +1401,21 @@ xwl_glamor_gbm_has_egl_extension(void)
             epoxy_has_egl_extension(NULL, "EGL_KHR_platform_gbm"));
 }
 
+#ifdef DRI3
+static void
+xwl_glamor_gbm_release_fence_avail(int fd, int xevents, void *data)
+{
+    struct xwl_pixmap *xwl_pixmap = data;
+    struct xwl_window_buffer *xwl_window_buffer = xwl_pixmap->xwl_window_buffer;
+
+    SetNotifyFd(fd, NULL, 0, NULL);
+    close(fd);
+    xwl_pixmap->efd = -1;
+
+    xwl_window_buffer_release(xwl_window_buffer);
+}
+#endif /* DRI3 */
+
 Bool
 xwl_glamor_supports_implicit_sync(struct xwl_screen *xwl_screen)
 {
@@ -1403,6 +1431,122 @@ xwl_glamor_supports_syncobjs(struct xwl_screen *xwl_screen)
         xwl_gbm_get(xwl_screen)->supports_syncobjs;
 }
 
+Bool
+xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap)
+{
+#ifdef DRI3
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+    uint64_t acquire_point;
+    uint64_t release_point;
+    int fence_fd;
+
+    if (!xwl_screen->glamor)
+        return FALSE;
+
+    if (!xwl_pixmap) {
+        ErrorF("XWAYLAND: Failed to set synchronization point, no backing xwl_pixmap!\n");
+        return FALSE;
+    }
+
+    acquire_point = ++xwl_pixmap->timeline_point;
+    release_point = ++xwl_pixmap->timeline_point;
+
+    if (!xwl_pixmap->syncobj) {
+        struct dri3_syncobj *syncobj = xwl_glamor_dri3_syncobj_create(xwl_screen);
+        if (!syncobj)
+            goto fail;
+        xwl_pixmap->syncobj = syncobj;
+    }
+
+    fence_fd = xwl_glamor_get_fence(xwl_screen);
+    if (fence_fd >= 0)
+        xwl_pixmap->syncobj->import_fence(xwl_pixmap->syncobj, acquire_point, fence_fd);
+    else
+        goto fail;
+
+    xwl_glamor_dri3_syncobj_passthrough(xwl_window,
+                                        xwl_pixmap->syncobj,
+                                        xwl_pixmap->syncobj,
+                                        acquire_point,
+                                        release_point);
+    return TRUE;
+
+fail:
+    /* can't use explicit sync, we will do a glFinish() before presenting */
+    if (xwl_pixmap->syncobj) {
+        xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
+        xwl_pixmap->syncobj = NULL;
+    }
+#endif /* DRI3 */
+    return FALSE;
+}
+
+void
+xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap)
+{
+#ifdef DRI3
+    struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+    struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+
+    if (!xwl_screen->glamor || !xwl_pixmap)
+        return;
+
+    if (xwl_pixmap->syncobj) {
+        xwl_pixmap->syncobj->free(xwl_pixmap->syncobj);
+        xwl_pixmap->syncobj = NULL;
+    }
+
+    if (xwl_pixmap->efd >= 0) {
+        SetNotifyFd(xwl_pixmap->efd, NULL, 0, NULL);
+        close(xwl_pixmap->efd);
+    }
+#endif /* DRI3 */
+}
+
+void
+xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap)
+{
+#ifdef DRI3
+    struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+    struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+    int fence_fd;
+
+    if (!xwl_screen->glamor || !xwl_pixmap)
+        return;
+
+    if (xwl_pixmap->syncobj) {
+        fence_fd = xwl_pixmap->syncobj->export_fence(xwl_pixmap->syncobj,
+                                                     xwl_pixmap->timeline_point);
+        xwl_glamor_wait_fence(xwl_screen, fence_fd);
+        close(fence_fd);
+    }
+#endif /* DRI3 */
+}
+
+void
+xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
+                                  PixmapPtr pixmap,
+                                  struct xwl_window_buffer *xwl_window_buffer)
+{
+#ifdef DRI3
+    struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+    struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+
+    if (!xwl_screen->glamor || !xwl_pixmap || !xwl_window_buffer)
+        return;
+
+    xwl_pixmap->xwl_window_buffer = xwl_window_buffer;
+    /* wait until the release fence is available before re-using this buffer */
+    xwl_pixmap->efd = eventfd(0, EFD_CLOEXEC);
+    SetNotifyFd(xwl_pixmap->efd, xwl_glamor_gbm_release_fence_avail, X_NOTIFY_READ,
+                xwl_pixmap);
+    xwl_pixmap->syncobj->submitted_eventfd(xwl_pixmap->syncobj,
+                                           xwl_pixmap->timeline_point,
+                                           xwl_pixmap->efd);
+#endif /* DRI3 */
+}
+
 static Bool
 xwl_glamor_try_to_make_context_current(struct xwl_screen *xwl_screen)
 {
diff --git a/hw/xwayland/xwayland-glamor-gbm.h b/hw/xwayland/xwayland-glamor-gbm.h
index 9083f2578..b346a0ba6 100644
--- a/hw/xwayland/xwayland-glamor-gbm.h
+++ b/hw/xwayland/xwayland-glamor-gbm.h
@@ -42,4 +42,12 @@ Bool xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen);
 Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen);
 drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen);
 
+/* Explicit buffer synchronization points */
+Bool xwl_glamor_gbm_set_syncpts(struct xwl_window *xwl_window, PixmapPtr pixmap);
+void xwl_glamor_gbm_dispose_syncpts(PixmapPtr pixmap);
+void xwl_glamor_gbm_wait_syncpts(PixmapPtr pixmap);
+void xwl_glamor_gbm_wait_release_fence(struct xwl_window *xwl_window,
+                                       PixmapPtr pixmap,
+                                       struct xwl_window_buffer *xwl_window_buffer);
+
 #endif /* XWAYLAND_GLAMOR_GBM_H */
commit b1734ae7377a68486e7bcd738b1822e8533cd018
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 18 11:05:16 2024 +0200

    xwayland/window-buffers: Add xwl_window_buffer_release()
    
    We want to decorrelate the explicit buffer synchronization from the
    window buffers, and move that to the GLAMOR/GBM code instead.
    
    To do that, we need to be able to invoke the xwl_window_buffer's
    release_callback() routine from outside the window buffer code.
    
    For that purpose, introduce xwl_window_buffer_release() which calls
    xwl_window_buffer_release_callback() for us.
    
    This is preparation work for the following changes, no functional change
    intended at this point.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit b5082073b0ca49c27b1b6525760f9b3e0bca61c2)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 2e8b0859c..0b9861fbb 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -238,6 +238,12 @@ xwl_window_buffer_release_callback(void *data)
                  xwl_window);
 }
 
+void
+xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer)
+{
+    xwl_window_buffer_release_callback(xwl_window_buffer);
+}
+
 #ifdef XWL_HAS_GLAMOR
 static void
 xwl_window_buffers_release_fence_avail(int fd, int xevents, void *data)
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index c43712a13..ee26d3244 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -32,6 +32,7 @@
 #include "xwayland-types.h"
 
 void xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window);
+void xwl_window_buffer_release(struct xwl_window_buffer *xwl_window_buffer);
 void xwl_window_buffers_init(struct xwl_window *xwl_window);
 void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
 void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
commit 23400afb72767d845b466853d8c30fbb2939c0ad
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Jun 20 17:12:45 2024 +0200

    xwayland/window-buffers: Promote xwl_window_buffer
    
    Make the (opaque) definition of the xwl_window_buffer generally
    available.
    
    No functional change.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 0e0472a0050f1ec19673f9e04531c41d816e386d)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-types.h b/hw/xwayland/xwayland-types.h
index 73a674633..d3fd2a0fc 100644
--- a/hw/xwayland/xwayland-types.h
+++ b/hw/xwayland/xwayland-types.h
@@ -31,5 +31,6 @@ struct xwl_window;
 struct xwl_screen;
 struct xwl_drm_lease;
 struct xwl_output;
+struct xwl_window_buffer;
 
 #endif /* XWAYLAND_TYPES_H */
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index 8b463e671..c43712a13 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -31,8 +31,6 @@
 
 #include "xwayland-types.h"
 
-struct xwl_window_buffer;
-
 void xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window);
 void xwl_window_buffers_init(struct xwl_window *xwl_window);
 void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
commit 05f44115232390b96bff49af363bc5c73feedfd2
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 4 17:26:29 2024 +0200

    xwayland: Stop on first unmapped child
    
    If a child window of the same size is unmapped, we should stop walking
    the tree looking for the surface window to use.
    
    Whatever lies beneath is not visible anyway.
    
    This also fixes an issue with the Damage list becoming corrupted when
    destroying a window, because the first thing that DeleteWindow() does
    is to unmap the window and crush the window tree underneath it.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Fixes: 3a0fc268 - xwayland: Add xwl_window::surface_window
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1680
    (cherry picked from commit 32e16082c5297776a56e9fade91f72e603adda89)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 84291c622..c2bd792e4 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1351,6 +1351,9 @@ xwl_window_update_surface_window(struct xwl_window *xwl_window)
         if (!RegionEqual(&window->winSize, &surface_window->winSize))
             break;
 
+        if (!window->mapped)
+            break;
+
         /* The surface window must be top-level for its window pixmap */
         window_pixmap = screen->GetWindowPixmap(window);
         if (window_pixmap == surface_pixmap)
commit fbd40e878ba4691542916a9bba38ec825007534f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Jun 4 17:02:57 2024 +0200

    xwayland: Do not use manual redirect windows as surface window
    
    While walking the window tree looking for the surface window to use, we
    should ignore windows using manual redirection.
    
    If a client manually redirects a window, it has control over how the
    contents of that window are presented. It's not safe to present them
    directly to the Wayland compositor.
    
    v2: break instead of continue, reword commit message (Michel)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Fixes: 3a0fc268 - xwayland: Add xwl_window::surface_window
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1677
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1679
    (cherry picked from commit 0509b13fa22f56af4539214e3da5be2348d945ce)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 05f45e16f..84291c622 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1365,6 +1365,9 @@ xwl_window_update_surface_window(struct xwl_window *xwl_window)
         if (window->drawable.depth == 32)
             continue;
 
+        if (window->redirectDraw == RedirectDrawManual)
+            break;
+
         surface_window = window;
     }
 
commit 526dcbe1205916957fafb7e8f493b4aaa7297d93
Author: Chenx Dust <chenx_dust at outlook.com>
Date:   Tue Jun 11 21:22:44 2024 +0800

    xwayland: fix segment fault in `xwl_glamor_gbm_init_main_dev`
    
    Function `xwl_glamor_gbm_init_main_dev` does not check whether
    `xwl_screen->default_feedback.main_dev` a.k.a. `main_dev` is a
    valid pointer. This result in some special situation where main
    linux-dmabuf device is not accessible, such as KWin nested desktop,
    raising segment fault.
    
    This commit add a null pointer check to prevent crashing.
    
    Signed-off-by: Chenx Dust <chenx_dust at outlook.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1683
    Fixes: d7f1909e - xwayland/glamor/gbm: make wl_drm optional
    See-also: https://bugzilla.redhat.com/2284141
    (cherry picked from commit 7605833315c05488eca30ed0a70a2a1430e89bbc)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index b30cff935..8307f74b1 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -1514,6 +1514,11 @@ xwl_glamor_gbm_init_main_dev(struct xwl_screen *xwl_screen)
     }
 
     main_dev = xwl_screen->default_feedback.main_dev;
+    if (!main_dev) {
+        ErrorF("No main linux-dmabuf device advertised by compositor\n");
+        return FALSE;
+    }
+
     if (!(main_dev->available_nodes & (1 << DRM_NODE_RENDER))) {
         ErrorF("Main linux-dmabuf device has no render node\n");
         return FALSE;
commit 1d21f8db26d79b842078a66ff0c58dbf01a73c25
Author: Fotios Valasiadis <fvalasiad at gmail.com>
Date:   Thu May 23 01:58:17 2024 +0300

    os: Explicitly include X11/Xmd.h for CARD32 definition to fix building on i686
    
    Noticed this after trying to update to xorg-server-xwayland-24.1.0 in void linux https://github.com/void-linux/void-packages/pull/50457
    
    Signed-off-by: Fotios Valasiadis <fvalasiad at gmail.com>
    (cherry picked from commit af6180b2c918b1993b8f4f6d6be3ec81759832cb)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/os/osdep.h b/os/osdep.h
index 705416de3..ecc6bccc0 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -60,6 +60,7 @@ SOFTWARE.
 #include <limits.h>
 #include <stddef.h>
 #include <X11/Xos.h>
+#include <X11/Xmd.h>
 
 /* If EAGAIN and EWOULDBLOCK are distinct errno values, then we check errno
  * for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
commit 59bf93c77059393053418cdad1bb4c6904c7db17
Author: Rouven Czerwinski <rouven at czerwinskis.de>
Date:   Tue May 14 07:59:58 2024 +0200

    xwayland: remove includedir from pkgconfig
    
    Before this change, the xwayland pkgconfig file will always contain an
    includedir directive, even though xwayland is not a linkable shared
    library:
    
      prefix=/nix/store/3spcjqp5zcyg8arz6dnsj59fal5yk3jy-xwayland-23.2.6
      includedir=${prefix}/include
    
      exec_prefix=${prefix}
      xwayland=/nix/store/3spcjqp5zcyg8arz6dnsj59fal5yk3jy-xwayland-23.2.6/bin/Xwayland
      […]
      Cflags: -I${includedir}
    
    According to a bug reporter this trips up cmake [1], which expects that
    the include directory exists, which it does not since xwayland does not
    install any header files.
    
    Add the dataonly directive to pkgsconfig.generate() which will remove
    the default "." subdir and ensures that includedir is not set inside the
    pkgconfig file. Additionally enforce the install directory to
    $libdir/pkgconfig, since it otherwise will be installed to
    $datadir/pkgconfig, which precludes programs from finding the pkgconfig
    because share/pkgconfig is usually not included in the search path.
    
    The resulting pkgconfig does not contain an includedir:
    
      prefix=/nix/store/p7xhdzl65hfhzf36vxykzp2i9cyy7y6c-xwayland-23.2.6
    
      exec_prefix=${prefix}
      xwayland=/nix/store/p7xhdzl65hfhzf36vxykzp2i9cyy7y6c-xwayland-23.2.6/bin/Xwayland
      have_glamor=true
      have_eglstream=true
      have_initfd=true
      have_listenfd=true
      have_verbose=true
      have_terminate_delay=true
      have_no_touch_pointer_emulation=true
      have_force_xrandr_emulation=true
      have_geometry=true
      have_fullscreen=true
      have_host_grab=true
      have_decorate=false
      have_enable_ei_portal=true
      have_byteswappedclients=true
    
      Name: Xwayland
      Description: X Server for Wayland
      Version: 23.2.6
    
    [1]: https://github.com/NixOS/nixpkgs/pull/309075#issuecomment-2108381428
    
    Signed-off-by: Rouven Czerwinski <rouven at czerwinskis.de>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 9df084c8d164903924f1e8ecfa05f74c985773d3)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index 59b2d2793..337b7409a 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -189,6 +189,8 @@ pkgconfig.generate(
     filebase: 'xwayland',
     name: 'Xwayland',
     description: 'X Server for Wayland',
+    dataonly: true,
+    install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
     variables: [
         'exec_prefix=${prefix}',
         'xwayland=' + xwayland_path + '/Xwayland',
commit dc2e34aa0e7aabb6285a3ecef7b787078088025b
Author: Matthieu Herrb <matthieu at herrb.eu>
Date:   Sun May 19 18:12:47 2024 +0200

    present: On *BSD, epoll-shim is needed to emulate eventfd()
    
    Signed-off-by: Matthieu Herrb <matthieu at herrb.eu>
    (cherry picked from commit 89c3f35d9277724b9816910bc72d73fa4e208f1b)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1569>

diff --git a/present/meson.build b/present/meson.build
index 8bcaf51f9..faeac3074 100644
--- a/present/meson.build
+++ b/present/meson.build
@@ -16,11 +16,18 @@ hdrs_present = [
     'presentext.h',
 ]
 
+if host_machine.system() in ['freebsd', 'openbsd']
+   epoll_dep = dependency('epoll-shim')
+else
+   epoll_dep = []
+endif
+
 libxserver_present = static_library('libxserver_present',
     srcs_present,
     include_directories: inc,
     dependencies: [
         common_dep,
+	epoll_dep,
         dependency('presentproto', version: '>= 1.2')
     ],
 )


More information about the xorg-commit mailing list