xserver: Branch 'master' - 8 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 7 16:23:21 UTC 2024


 hw/xwayland/xwayland-glamor-gbm.c     |   11 +++--
 hw/xwayland/xwayland-glamor.c         |    5 +-
 hw/xwayland/xwayland-glamor.h         |    2 
 hw/xwayland/xwayland-pixmap.h         |    6 ++
 hw/xwayland/xwayland-present.c        |   15 ++++++-
 hw/xwayland/xwayland-screen.h         |    1 
 hw/xwayland/xwayland-window-buffers.c |   70 ++++++++++++++++++----------------
 hw/xwayland/xwayland-window-buffers.h |   10 ++--
 hw/xwayland/xwayland-window.c         |   28 +++++++------
 hw/xwayland/xwayland-window.h         |    2 
 10 files changed, 91 insertions(+), 59 deletions(-)

New commits:
commit 64341c479cb57431f082d86e1d28412dba3ef30e
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Feb 28 10:52:03 2024 +0100

    xwayland/present: Handle clearing damage after flip in xwl_present_execute
    
    Due to DamageReportNonEmpty, damage_report doesn't get called if the
    damage region was already non-empty before the flip. In which case it
    didn't get called before the first draw after the flip either.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1627
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 783b04ff4..3c27333b7 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -35,6 +35,7 @@
 #include "xwayland-screen.h"
 #include "xwayland-shm.h"
 #include "xwayland-window.h"
+#include "xwayland-window-buffers.h"
 #include "xwayland-pixmap.h"
 
 #include "tearing-control-v1-client-protocol.h"
@@ -833,7 +834,6 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
     }
 
     wl_display_flush(xwl_window->xwl_screen->display);
-    xwl_window->present_flipped = TRUE;
     return TRUE;
 }
 
@@ -890,6 +890,8 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 
             if (xwl_present_flip(vblank, damage)) {
                 WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
+                struct xwl_window *xwl_window = xwl_window_from_window(window);
+                struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
                 PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
 
                 /* Replace window pixmap with flip pixmap */
@@ -906,10 +908,19 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                 vblank->pixmap->refcnt++;
                 dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
 
-                /* Report damage */
+                /* Report damage, let damage_report ignore it though */
+                xwl_screen->ignore_damage = TRUE;
                 DamageDamageRegion(&vblank->window->drawable, damage);
+                xwl_screen->ignore_damage = FALSE;
                 RegionDestroy(damage);
 
+                /* Clear damage region, to ensure damage_report is called before
+                 * any drawing to the window
+                 */
+                xwl_window_buffer_add_damage_region(xwl_window);
+                RegionEmpty(xwl_window_get_damage_region(xwl_window));
+                xorg_list_del(&xwl_window->link_damage);
+
                 /* Put pending flip at the flip queue head */
                 xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
 
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index a53d18bad..993b3cb12 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -90,6 +90,7 @@ struct xwl_screen {
     struct xorg_list seat_list;
     struct xorg_list damage_window_list;
     struct xorg_list window_list;
+    Bool ignore_damage;
 
     int wayland_fd;
     struct wl_display *display;
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index d19b383d0..c8b62db6e 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -194,17 +194,8 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
         return;
 
     xwl_screen = xwl_window->xwl_screen;
-
-    if (xwl_window->present_flipped) {
-        /* This damage is from a Present flip, which already committed a new
-         * buffer for the surface, so we don't need to do anything in response
-         */
-        xwl_window_buffer_add_damage_region(xwl_window);
-        RegionEmpty(DamageRegion(pDamage));
-        xorg_list_del(&xwl_window->link_damage);
-        xwl_window->present_flipped = FALSE;
+    if (xwl_screen->ignore_damage)
         return;
-    }
 
     if (xorg_list_is_empty(&xwl_window->link_damage))
         xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 827a0fd53..03d3fed14 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -111,7 +111,6 @@ struct xwl_window {
     struct wl_output *wl_output;
     struct wl_output *wl_output_fullscreen;
     struct xorg_list frame_callback_list;
-    Bool present_flipped;
 #ifdef XWL_HAS_LIBDECOR
     struct libdecor_frame *libdecor_frame;
 #endif
commit 6b290fa5d9a1c3e28c64bac97701ef287630d964
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Feb 22 12:21:29 2024 +0100

    xwayland: Replace window pixmap as needed for drawing operation
    
    We must not modify the contents of a client pixmap.
    
    If there's an available window buffer, we re-use that for the window
    pixmap. Otherwise we just allocate a new one.
    
    This also avoids Present client hangs due to xwl_present_buffer_release
    not getting called for the buffer release event.
    
    v2:
    * Use xwl_pixmap_get_buffer_release_cb instead of keeping track of the
      flip pixmap in xwl_window.
    * Dispose of xwl_window_buffer in xwl_window_swap_pixmap called from
      damage_report.
    v3:
    * Use xwl_window->surface_pixmap in damage_report.
    v4:
    * Don't re-use client pixmaps as window buffers.
    * Clear xwl_window_buffer->pixmap before calling
      xwl_window_buffer_maybe_dispose in xwl_window_swap_pixmap, to prevent
      it from clearing the buffer release callback.
    v5:
    * Keep using xwl_window_buffers_get_pixmap in xwl_window_attach_buffer.
    * Always keep a reference to the old window pixmap in _swap_pixmap,
      drop it in damage_report.
    
    Fixes: 6779ec5bf67a ("xwayland: Use window pixmap as a window buffer")
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1633
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1644
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-pixmap.h b/hw/xwayland/xwayland-pixmap.h
index 95eb4e1a2..036b532ef 100644
--- a/hw/xwayland/xwayland-pixmap.h
+++ b/hw/xwayland/xwayland-pixmap.h
@@ -45,4 +45,10 @@ void xwl_pixmap_del_buffer_release_cb(PixmapPtr pixmap);
 void xwl_pixmap_buffer_release_cb(void *data, struct wl_buffer *wl_buffer);
 Bool xwl_pixmap_init(void);
 
+static inline Bool
+xwl_is_client_pixmap(PixmapPtr pixmap)
+{
+    return clients[CLIENT_ID(pixmap->drawable.id)] != serverClient;
+}
+
 #endif /* XWAYLAND_PIXMAP_H */
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 1fedaef19..47f27126d 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -78,8 +78,7 @@ xwl_window_buffer_new(struct xwl_window *xwl_window)
     xwl_window_buffer->pixmap = NullPixmap;
     xwl_window_buffer->refcnt = 1;
 
-    xorg_list_append(&xwl_window_buffer->link_buffer,
-                     &xwl_window->window_buffers_available);
+    xorg_list_init(&xwl_window_buffer->link_buffer);
 
     return xwl_window_buffer;
 }
@@ -331,7 +330,7 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
     screen->DestroyPixmap(window_pixmap);
 }
 
-static PixmapPtr
+PixmapPtr
 xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
@@ -360,17 +359,27 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
         }
 
         RegionEmpty(xwl_window_buffer->damage_region);
+        xorg_list_del(&xwl_window_buffer->link_buffer);
+        xwl_window_set_pixmap(xwl_window->window, xwl_window_buffer->pixmap);
+
+        /* Can't re-use client pixmap as a window buffer */
+        if (xwl_is_client_pixmap(window_pixmap)) {
+            xwl_window_buffer->pixmap = NULL;
+            xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+            return window_pixmap;
+        }
     } else {
+        /* Can't re-use client pixmap as a window buffer */
+        if (!xwl_is_client_pixmap(window_pixmap))
+            xwl_window_buffer = xwl_window_buffer_new(xwl_window);
+
         window_pixmap->refcnt++;
         xwl_window_realloc_pixmap(xwl_window);
 
-        xwl_window_buffer = xwl_window_buffer_new(xwl_window);
         if (!xwl_window_buffer)
             return window_pixmap;
     }
 
-    xorg_list_del(&xwl_window_buffer->link_buffer);
-    xwl_window_set_pixmap(xwl_window->window, xwl_window_buffer->pixmap);
     xwl_window_buffer->pixmap = window_pixmap;
 
     /* Hold a reference on the buffer until it's released by the compositor */
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index b1a737094..ac4c9aa6e 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -31,10 +31,13 @@
 
 #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);
 void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
+PixmapPtr xwl_window_swap_pixmap(struct xwl_window *xwl_window);
 PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window);
 
 #endif /* XWAYLAND_WINDOW_BUFFERS_H */
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index ea2a986ae..d19b383d0 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -188,6 +188,7 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
     WindowPtr window = data;
     struct xwl_window *xwl_window = xwl_window_get(window);
     struct xwl_screen *xwl_screen;
+    PixmapPtr window_pixmap;
 
     if (!xwl_window)
         return;
@@ -207,6 +208,10 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
 
     if (xorg_list_is_empty(&xwl_window->link_damage))
         xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
+
+    window_pixmap = xwl_screen->screen->GetWindowPixmap(xwl_window->window);
+    if (xwl_is_client_pixmap(window_pixmap))
+        xwl_screen->screen->DestroyPixmap(xwl_window_swap_pixmap(xwl_window));
 }
 
 static void
@@ -227,7 +232,6 @@ register_damage(WindowPtr window)
     }
 
     DamageRegister(&window->drawable, damage);
-    DamageSetReportAfterOp(damage, TRUE);
 
     dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, damage);
 
commit 0e29cccf3681bd3a9d29a889eea46b0a6044d294
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Feb 19 17:13:28 2024 +0100

    xwayland: Re-use xwl_window_realloc_pixmap in xwl_window_swap_pixmap
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index caf020aac..1fedaef19 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -336,7 +336,7 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct xwl_window_buffer *xwl_window_buffer;
-    PixmapPtr window_pixmap, new_window_pixmap;
+    PixmapPtr window_pixmap;
 
     window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
 
@@ -348,11 +348,9 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
         BoxPtr pBox = RegionRects(full_damage);
         int nBox = RegionNumRects(full_damage);
 
-        new_window_pixmap = xwl_window_buffer->pixmap;
-
         while (nBox--) {
             copy_pixmap_area(window_pixmap,
-                             new_window_pixmap,
+                             xwl_window_buffer->pixmap,
                              pBox->x1 + xwl_window->window->borderWidth,
                              pBox->y1 + xwl_window->window->borderWidth,
                              pBox->x2 - pBox->x1,
@@ -363,21 +361,16 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 
         RegionEmpty(xwl_window_buffer->damage_region);
     } else {
-        xwl_window_buffer = xwl_window_buffer_new(xwl_window);
+        window_pixmap->refcnt++;
+        xwl_window_realloc_pixmap(xwl_window);
 
-        new_window_pixmap = xwl_window_allocate_pixmap(xwl_window);
-        if (!new_window_pixmap) {
-            xwl_window_buffer_maybe_dispose(xwl_window_buffer);
+        xwl_window_buffer = xwl_window_buffer_new(xwl_window);
+        if (!xwl_window_buffer)
             return window_pixmap;
-        }
-
-        copy_pixmap_area(window_pixmap,
-                         new_window_pixmap,
-                         0, 0,
-                         window_pixmap->drawable.width,
-                         window_pixmap->drawable.height);
     }
 
+    xorg_list_del(&xwl_window_buffer->link_buffer);
+    xwl_window_set_pixmap(xwl_window->window, xwl_window_buffer->pixmap);
     xwl_window_buffer->pixmap = window_pixmap;
 
     /* Hold a reference on the buffer until it's released by the compositor */
@@ -386,12 +379,9 @@ xwl_window_swap_pixmap(struct xwl_window *xwl_window)
                                      xwl_window_buffer_release_callback,
                                      xwl_window_buffer);
 
-    xorg_list_del(&xwl_window_buffer->link_buffer);
     xorg_list_append(&xwl_window_buffer->link_buffer,
                      &xwl_window->window_buffers_unavailable);
 
-    xwl_window_set_pixmap(xwl_window->window, new_window_pixmap);
-
     if (xorg_list_is_empty(&xwl_window->window_buffers_available))
         TimerCancel(xwl_window->window_buffers_timer);
 
commit 44527c254916ac81e4b80f8f75ee3df83fdcb4fe
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Feb 22 10:52:12 2024 +0100

    xwayland: Refactor xwl_window_swap_pixmap out of _buffers_get_pixmap
    
    There will be another caller in a later commit.
    
    v2:
    * Bump xwl_window_buffer->refcnt in xwl_window_swap_pixmap, to prevent
      xwl_window_set_pixmap from disposing of it.
    v3:
    * Go back to bumping xwl_window_buffer->refcnt in
      xwl_window_buffers_get_pixmap. xwl_window_set_pixmap should no longer
      dispose of it now that xwl_glamor_gbm_create_pixmap_for_window is
      fixed, and xwl_window_swap_pixmap forgot to bump it if
      xwl_window_buffer_get_available returned NULL.
    v4:
    * Unlink xwl_window_buffer from xwl_window->window_buffers_available
      before calling xwl_window_set_pixmap in xwl_window_swap_pixmap, or
      that might dispose of it.
    v5:
    * xwl_window_swap_pixmap does everything xwl_window_buffer_get_available
      did before, except for just using the window pixmap if
      !xwl_glamor_needs_n_buffering.
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 292981f29..caf020aac 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -331,8 +331,8 @@ xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
     screen->DestroyPixmap(window_pixmap);
 }
 
-PixmapPtr
-xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window)
+static PixmapPtr
+xwl_window_swap_pixmap(struct xwl_window *xwl_window)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct xwl_window_buffer *xwl_window_buffer;
@@ -340,11 +340,6 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window)
 
     window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
 
-#ifdef XWL_HAS_GLAMOR
-    if (!xwl_glamor_needs_n_buffering(xwl_screen))
-        return window_pixmap;
-#endif /* XWL_HAS_GLAMOR */
-
     xwl_window_buffer_add_damage_region(xwl_window);
 
     xwl_window_buffer = xwl_window_buffer_get_available(xwl_window);
@@ -402,3 +397,16 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window)
 
     return xwl_window_buffer->pixmap;
 }
+
+PixmapPtr
+xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window)
+{
+#ifdef XWL_HAS_GLAMOR
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    if (!xwl_glamor_needs_n_buffering(xwl_screen))
+        return xwl_screen->screen->GetWindowPixmap(xwl_window->window);
+#endif /* XWL_HAS_GLAMOR */
+
+    return xwl_window_swap_pixmap(xwl_window);
+}
commit af4b64d227d7f4c7034109b3cbcdf364df882267
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Feb 22 10:19:54 2024 +0100

    xwayland: Rename xwl_window_recycle_pixmap to xwl_window_realloc_pixmap
    
    It doesn't recycle anything but allocates a new pixmap from scratch.
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 657578a8f..28f848a3d 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -790,7 +790,7 @@ xwl_window_dmabuf_feedback_done(void *data,
      * window buffers get re-created with appropriate parameters.
      */
     xwl_window_buffers_dispose(xwl_window);
-    xwl_window_recycle_pixmap(xwl_window);
+    xwl_window_realloc_pixmap(xwl_window);
 }
 
 static void
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 5af0d6748..292981f29 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -309,7 +309,7 @@ xwl_window_allocate_pixmap(struct xwl_window *xwl_window)
 }
 
 void
-xwl_window_recycle_pixmap(struct xwl_window *xwl_window)
+xwl_window_realloc_pixmap(struct xwl_window *xwl_window)
 {
     PixmapPtr window_pixmap, new_window_pixmap;
     WindowPtr window;
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index 200c47767..b1a737094 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_buffers_init(struct xwl_window *xwl_window);
 void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
-void xwl_window_recycle_pixmap(struct xwl_window *xwl_window);
+void xwl_window_realloc_pixmap(struct xwl_window *xwl_window);
 PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window);
 
 #endif /* XWAYLAND_WINDOW_BUFFERS_H */
commit 716805e3ad7b56c3d1cafb63002b7c26cd8b63bd
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Feb 19 18:43:47 2024 +0100

    xwayland: Call xwl_window_buffer_add_damage_region from damage_report
    
    Before clearing the damage region. Otherwise the damage region from a
    Present flip may be ignored when replacing the window pixmap.
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 8751de918..5af0d6748 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -113,7 +113,7 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
     return TRUE;
 }
 
-static void
+void
 xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window)
 {
     RegionPtr region = xwl_window_get_damage_region(xwl_window);
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index a2ff5fdb1..200c47767 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -31,6 +31,7 @@
 
 #include "xwayland-types.h"
 
+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);
 void xwl_window_recycle_pixmap(struct xwl_window *xwl_window);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index da614f57f..ea2a986ae 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -198,6 +198,7 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
         /* This damage is from a Present flip, which already committed a new
          * buffer for the surface, so we don't need to do anything in response
          */
+        xwl_window_buffer_add_damage_region(xwl_window);
         RegionEmpty(DamageRegion(pDamage));
         xorg_list_del(&xwl_window->link_damage);
         xwl_window->present_flipped = FALSE;
commit c1c5bf382e497eb3641354e54384731c1d7198b9
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Feb 19 16:39:13 2024 +0100

    xwayland: Do not plumb damage region through function parameters
    
    Each function can get the damage region from the xwl_window instead.
    Add xwl_window_get_damage_region helper for this.
    
    v2:
    * Use xwl_window_get_damage_region in xwl_window_attach_buffer as well
      (Olivier Fourdan)
    
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 28a8e7bc9..657578a8f 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -874,9 +874,10 @@ xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
 
 Bool
 xwl_glamor_post_damage(struct xwl_window *xwl_window,
-                       PixmapPtr pixmap, RegionPtr region)
+                       PixmapPtr pixmap)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    RegionPtr region = xwl_window_get_damage_region(xwl_window);
 
     if (xwl_screen->egl_backend->post_damage)
         return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 97e8fb664..5513230ff 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -137,7 +137,7 @@ void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
 Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
                                  struct xwl_egl_backend *xwl_egl_backend);
 Bool xwl_glamor_post_damage(struct xwl_window *xwl_window,
-                            PixmapPtr pixmap, RegionPtr region);
+                            PixmapPtr pixmap);
 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 40e19e349..8751de918 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -114,9 +114,9 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
 }
 
 static void
-xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window,
-                                    RegionPtr damage_region)
+xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window)
 {
+    RegionPtr region = xwl_window_get_damage_region(xwl_window);
     struct xwl_window_buffer *xwl_window_buffer;
 
     /* Add damage region to all buffers */
@@ -125,14 +125,14 @@ xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window,
                              link_buffer) {
         RegionUnion(xwl_window_buffer->damage_region,
                     xwl_window_buffer->damage_region,
-                    damage_region);
+                    region);
     }
     xorg_list_for_each_entry(xwl_window_buffer,
                              &xwl_window->window_buffers_unavailable,
                              link_buffer) {
         RegionUnion(xwl_window_buffer->damage_region,
                     xwl_window_buffer->damage_region,
-                    damage_region);
+                    region);
     }
 }
 
@@ -332,8 +332,7 @@ xwl_window_recycle_pixmap(struct xwl_window *xwl_window)
 }
 
 PixmapPtr
-xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
-                              RegionPtr damage_region)
+xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window)
 {
     struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
     struct xwl_window_buffer *xwl_window_buffer;
@@ -346,7 +345,7 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
         return window_pixmap;
 #endif /* XWL_HAS_GLAMOR */
 
-    xwl_window_buffer_add_damage_region(xwl_window, damage_region);
+    xwl_window_buffer_add_damage_region(xwl_window);
 
     xwl_window_buffer = xwl_window_buffer_get_available(xwl_window);
     if (xwl_window_buffer) {
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index c795564bd..a2ff5fdb1 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -30,12 +30,10 @@
 #include <xwayland-config.h>
 
 #include "xwayland-types.h"
-#include "regionstr.h"
 
 void xwl_window_buffers_init(struct xwl_window *xwl_window);
 void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
 void xwl_window_recycle_pixmap(struct xwl_window *xwl_window);
-PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
-                                        RegionPtr damage_region);
+PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window);
 
 #endif /* XWAYLAND_WINDOW_BUFFERS_H */
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index d2434de8f..da614f57f 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -77,6 +77,12 @@ window_get_damage(WindowPtr window)
     return dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key);
 }
 
+RegionPtr
+xwl_window_get_damage_region(struct xwl_window *xwl_window)
+{
+    return DamageRegion(window_get_damage(xwl_window->window));
+}
+
 struct xwl_window *
 xwl_window_from_window(WindowPtr window)
 {
@@ -1380,8 +1386,7 @@ xwl_window_attach_buffer(struct xwl_window *xwl_window)
     PixmapPtr pixmap;
     int i;
 
-    region = DamageRegion(window_get_damage(xwl_window->window));
-    pixmap = xwl_window_buffers_get_pixmap(xwl_window, region);
+    pixmap = xwl_window_buffers_get_pixmap(xwl_window);
     buffer = xwl_pixmap_get_wl_buffer(pixmap);
 
     if (!buffer) {
@@ -1391,7 +1396,7 @@ xwl_window_attach_buffer(struct xwl_window *xwl_window)
 
 #ifdef XWL_HAS_GLAMOR
     if (xwl_screen->glamor) {
-        if (!xwl_glamor_post_damage(xwl_window, pixmap, region)) {
+        if (!xwl_glamor_post_damage(xwl_window, pixmap)) {
             ErrorF("glamor: Failed to post damage\n");
             return FALSE;
         }
@@ -1404,6 +1409,7 @@ xwl_window_attach_buffer(struct xwl_window *xwl_window)
      * connection. If we flood it too much anyway, this could
      * abort in libwayland-client.
      */
+    region = xwl_window_get_damage_region(xwl_window);
     if (RegionNumRects(region) > 256) {
         box = RegionExtents(region);
         xwl_surface_damage(xwl_screen, xwl_window->surface,
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 3370c45aa..827a0fd53 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -123,6 +123,7 @@ struct xwl_window {
 };
 
 struct xwl_window *xwl_window_get(WindowPtr window);
+RegionPtr xwl_window_get_damage_region(struct xwl_window *xwl_window);
 struct xwl_window *xwl_window_from_window(WindowPtr window);
 
 Bool is_surface_from_xwl_window(struct wl_surface *surface);
commit 913631071ed613a7a94e6a9126a52ac5adc7ec86
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Feb 22 20:46:03 2024 +0100

    xwayland: Use border width in xwl_glamor_gbm_create_pixmap_for_window
    
    Otherwise the pixmap is too small for a window with non-0 border width.
    
    Fixes: 9730fb64ea05 ("xwayland: Add create_pixmap_for_window() to GBM backend")
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1314>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 7dbc9d24e..30eb953d6 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -396,11 +396,14 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
 static PixmapPtr
 xwl_glamor_gbm_create_pixmap_for_window(struct xwl_window *xwl_window)
 {
+    WindowPtr window = xwl_window->window;
+    unsigned border_width = 2 * window->borderWidth;
+
     return xwl_glamor_gbm_create_pixmap_internal(xwl_window->xwl_screen,
-                                                 &xwl_window->window->drawable,
-                                                 xwl_window->window->drawable.width,
-                                                 xwl_window->window->drawable.height,
-                                                 xwl_window->window->drawable.depth,
+                                                 &window->drawable,
+                                                 window->drawable.width + border_width,
+                                                 window->drawable.height + border_width,
+                                                 window->drawable.depth,
                                                  CREATE_PIXMAP_USAGE_BACKING_PIXMAP,
                                                  xwl_window->has_implicit_scanout_support);
 }


More information about the xorg-commit mailing list