xserver: Branch 'xwayland-23.1' - 19 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 1 08:40:45 UTC 2023


 glamor/glamor.c                       |    2 
 hw/xwayland/meson.build               |    6 -
 hw/xwayland/xwayland-cvt.c            |   50 ++++++---
 hw/xwayland/xwayland-glamor-gbm.c     |   69 ++++++++++--
 hw/xwayland/xwayland-glamor.c         |  185 +++++++++++++++++++++++++++++-----
 hw/xwayland/xwayland-glamor.h         |    9 +
 hw/xwayland/xwayland-output.c         |   21 ---
 hw/xwayland/xwayland-screen.c         |    5 
 hw/xwayland/xwayland-window-buffers.c |   17 ++-
 hw/xwayland/xwayland-window.c         |   82 ++++++++-------
 hw/xwayland/xwayland-window.h         |    2 
 hw/xwayland/xwayland.c                |    3 
 include/meson.build                   |    4 
 13 files changed, 337 insertions(+), 118 deletions(-)

New commits:
commit dfaf3af9944484151dce9238afe48fa1d4e29030
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Apr 25 11:33:12 2023 +0200

    xwayland: Use our CVT function for fixed mode as well
    
    Now that our CVT function is able to deal with non-standard modes, we
    can safely use it for the fixed mode as well.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit eb20ba039a1acca8a291eef095388893e327adc0)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 661e1828d..738c3320f 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -1086,11 +1086,8 @@ xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
 {
     RRModePtr *modes = NULL;
     RRModePtr mode;
-    xRRModeInfo mode_info = { 0, };
-    char mode_name[128];
     int i, nmodes, current;
 
-
     modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr));
     if (!modes) {
         ErrorF("Failed to allocated RandR modes\n");
@@ -1115,21 +1112,11 @@ xwl_randr_add_modes_fixed(struct xwl_output *xwl_output,
     }
 
     if (!current) {
-        /* Add the current mode as it's not part of the fake modes.
-         * Not using libcvt as the size is set from the command line and
-         * may not be a valid CVT mode.
-         */
-        mode_info.width = current_width;
-        mode_info.height = current_height;
-        mode_info.hTotal = current_width;
-        mode_info.vTotal = current_height;
-        mode_info.dotClock = 60 * 1000 * 1000;
-
-        snprintf(mode_name, sizeof(mode_name), "%dx%d",
-                 current_width, current_height);
-        mode_info.nameLength = strlen(mode_name);
+        /* Add the current mode as it's not part of the fake modes. */
+        mode = xwayland_cvt(current_width, current_height, 60, 0, 0);
 
-        modes[nmodes++] = RRModeGet(&mode_info, mode_name);
+        if (mode)
+            modes[nmodes++] = mode;
     }
 
     qsort(modes, nmodes, sizeof(RRModePtr), mode_sort);
commit 9d2cc63a9a523147393d0c97013530f978c62e4b
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Apr 24 16:26:19 2023 +0200

    xwayland: Do not round non-standard modes
    
    Currently, Xwayland uses libxcvt to generate the mode info and then
    passes that to RRModeGet() to generate a RRMode.
    
    However, libxcvt may round down the width to match the horizontal
    granularity (8), and that's a problem when the Wayland compositor is
    running a non-standard size (like, e.g. running nested with a custom
    size) because XRandR would report a width smaller than the actual size.
    
    To avoid that, check whether the CVT computed size differs from the
    expected size, and simply fix the hdisplay/vdisplay to match the given
    size if that's the case.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1540
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1549
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit ad2d461dec84b33a7fa0784776f3eee7bd6c55f4)
    (cherry picked from commit 2713383548cc1abf4f578f8d2623da91c52dde84)
    (cherry picked from commit 814a04927d54586ea478ba6ac14eb4fca5667239)

diff --git a/hw/xwayland/xwayland-cvt.c b/hw/xwayland/xwayland-cvt.c
index ba8cbc9d1..4248d3869 100644
--- a/hw/xwayland/xwayland-cvt.c
+++ b/hw/xwayland/xwayland-cvt.c
@@ -29,30 +29,48 @@
 
 #include "xwayland-cvt.h"
 
-RRModePtr
-xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
-             Bool interlaced)
+static void
+xwayland_modeinfo_from_cvt(xRRModeInfo *modeinfo,
+                           int hdisplay, int vdisplay, float vrefresh,
+                           Bool reduced, Bool interlaced)
 {
     struct libxcvt_mode_info *libxcvt_mode_info;
-    char name[128];
-    xRRModeInfo modeinfo;
 
     libxcvt_mode_info =
         libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
 
-    memset(&modeinfo, 0, sizeof modeinfo);
-    modeinfo.width      = libxcvt_mode_info->hdisplay;
-    modeinfo.height     = libxcvt_mode_info->vdisplay;
-    modeinfo.dotClock   = libxcvt_mode_info->dot_clock * 1000.0;
-    modeinfo.hSyncStart = libxcvt_mode_info->hsync_start;
-    modeinfo.hSyncEnd   = libxcvt_mode_info->hsync_end;
-    modeinfo.hTotal     = libxcvt_mode_info->htotal;
-    modeinfo.vSyncStart = libxcvt_mode_info->vsync_start;
-    modeinfo.vSyncEnd   = libxcvt_mode_info->vsync_end;
-    modeinfo.vTotal     = libxcvt_mode_info->vtotal;
-    modeinfo.modeFlags  = libxcvt_mode_info->mode_flags;
+    modeinfo->width      = libxcvt_mode_info->hdisplay;
+    modeinfo->height     = libxcvt_mode_info->vdisplay;
+    modeinfo->dotClock   = libxcvt_mode_info->dot_clock * 1000.0;
+    modeinfo->hSyncStart = libxcvt_mode_info->hsync_start;
+    modeinfo->hSyncEnd   = libxcvt_mode_info->hsync_end;
+    modeinfo->hTotal     = libxcvt_mode_info->htotal;
+    modeinfo->vSyncStart = libxcvt_mode_info->vsync_start;
+    modeinfo->vSyncEnd   = libxcvt_mode_info->vsync_end;
+    modeinfo->vTotal     = libxcvt_mode_info->vtotal;
+    modeinfo->modeFlags  = libxcvt_mode_info->mode_flags;
 
     free(libxcvt_mode_info);
+}
+
+RRModePtr
+xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
+             Bool interlaced)
+{
+    char name[128];
+    xRRModeInfo modeinfo = { 0, };
+
+    xwayland_modeinfo_from_cvt(&modeinfo,
+                               hdisplay, vdisplay, vrefresh, reduced, interlaced);
+
+    /* Horizontal granularity in libxcvt is 8, so if our horizontal size is not
+     * divisible by 8, libxcvt will round it up, and we will advertise a wrong
+     * size to our XRandR clients.
+     * Force the width/height (i.e. simply increase blanking which should not
+     * hurt anything), keeping the rest of the CVT mode timings unchanged.
+     */
+    modeinfo.width = hdisplay;
+    modeinfo.height = vdisplay;
 
     snprintf(name, sizeof name, "%dx%d",
              modeinfo.width, modeinfo.height);
commit 7cfa26d0b26280efafd3797181a97a435ada4c31
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Fri Mar 31 16:01:20 2023 +0200

    xwayland/window: Queue damage after commits are allowed
    
    Compositors may use XWAYLAND_ALLOW_COMMITS to communicate when Xwayland
    may or may not commit new buffers to a wl_surface. If commits are
    denied, then later allowed, we'll only get a buffer attached if there is
    actual damage posted, which might be long after.
    
    This fixes an issue where the window manager would reparent a window
    while denying commits, then after reparenting, allow commits. The window
    in question belonged to a game and took several seconds produce the next
    frame, resulting in an empty window appearing as if it had just
    disappeared.
    
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 9a55c402aa803fb10e39ab4fd18a709d0cd06fd4)

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index b7574eeb5..67485d1d3 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -106,9 +106,21 @@ static void
 xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
                              const char *debug_msg)
 {
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    DamagePtr damage;
+
     xwl_window->allow_commits = allow;
     DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
            xwl_window->window->drawable.id, allow, debug_msg);
+
+    damage = window_get_damage(xwl_window->window);
+    if (allow &&
+        xorg_list_is_empty(&xwl_window->link_damage) &&
+        damage &&
+        RegionNotEmpty(DamageRegion(damage))) {
+        xorg_list_add(&xwl_window->link_damage,
+                      &xwl_screen->damage_window_list);
+    }
 }
 
 static void
commit fe2153e15cd0d99e82843bb9b4348951001ae2b4
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Wed Apr 26 09:37:23 2023 +0200

    xwayland/window: Move set-allow functions lower down
    
    This will make some helper functions in the same file usable without
    extra declarations.
    
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 5ce96a2a733b0a6556e1512fd9a703ede6a7c959)

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 6b7f38605..b7574eeb5 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -56,41 +56,6 @@ static DevPrivateKeyRec xwl_window_private_key;
 static DevPrivateKeyRec xwl_damage_private_key;
 static const char *xwl_surface_tag = "xwl-surface";
 
-static void
-xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
-                             const char *debug_msg)
-{
-    xwl_window->allow_commits = allow;
-    DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
-           xwl_window->window->drawable.id, allow, debug_msg);
-}
-
-static void
-xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
-                                           PropertyPtr prop)
-{
-    static Bool warned = FALSE;
-    CARD32 *propdata;
-
-    if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
-        FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
-
-    if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
-        /* Not properly set, so fall back to safe and glitchy */
-        xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
-
-        if (!warned) {
-            LogMessageVerb(X_WARNING, 0, "Window manager is misusing property %s.\n",
-                           NameForAtom(prop->propertyName));
-            warned = TRUE;
-        }
-        return;
-    }
-
-    propdata = prop->data;
-    xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
-}
-
 struct xwl_window *
 xwl_window_get(WindowPtr window)
 {
@@ -137,6 +102,41 @@ is_surface_from_xwl_window(struct wl_surface *surface)
     return wl_proxy_get_tag((struct wl_proxy *) surface) == &xwl_surface_tag;
 }
 
+static void
+xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
+                             const char *debug_msg)
+{
+    xwl_window->allow_commits = allow;
+    DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
+           xwl_window->window->drawable.id, allow, debug_msg);
+}
+
+static void
+xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
+                                           PropertyPtr prop)
+{
+    static Bool warned = FALSE;
+    CARD32 *propdata;
+
+    if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
+        FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
+
+    if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
+        /* Not properly set, so fall back to safe and glitchy */
+        xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
+
+        if (!warned) {
+            LogMessageVerb(X_WARNING, 0, "Window manager is misusing property %s.\n",
+                           NameForAtom(prop->propertyName));
+            warned = TRUE;
+        }
+        return;
+    }
+
+    propdata = prop->data;
+    xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
+}
+
 void
 xwl_window_update_property(struct xwl_window *xwl_window,
                            PropertyStateRec *propstate)
commit a3a0644d49c1b87df4a86bdcac35fc3bdeb80ac2
Author: Simon Ser <contact at emersion.fr>
Date:   Sat Feb 18 11:29:25 2023 +0100

    build: set _GNU_SOURCE when checking for SO_PEERCRED
    
    SO_PEERCRED is not POSIX, so might be hidden unless _GNU_SOURCE
    is defined.
    
    See [1]: cc.has_header_symbol() does not inherit the project
    arguments.
    
    [1]: https://github.com/mesonbuild/meson/issues/3301
    
    Signed-off-by: Simon Ser <contact at emersion.fr>
    (cherry picked from commit 636c9aa359eab45102c12a9fccb8f60587c7d485)

diff --git a/include/meson.build b/include/meson.build
index ef2ced4df..20b7c1d63 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -180,7 +180,7 @@ if cc.has_header_symbol('sys/socket.h', 'SCM_RIGHTS')
 endif
 
 if conf_data.get('HAVE_GETPEEREID').to_int() == 0 and conf_data.get('HAVE_GETPEERUCRED').to_int() == 0
-    if not cc.has_header_symbol('sys/socket.h', 'SO_PEERCRED')
+    if not cc.has_header_symbol('sys/socket.h', 'SO_PEERCRED', args: '-D_GNU_SOURCE')
         conf_data.set('NO_LOCAL_CLIENT_CRED', 1)
     endif
 endif
commit 73e0510dee175b5c834c1d4c2cb24071b7f84bbf
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Apr 7 11:05:33 2023 +0200

    xwayland: Use the new API to set scanout
    
    If the format and modifiers are from a tranche which supports scanout,
    we can set the corresponding flag to gbm_bo_create_with_modifiers2() to
    benefit from scanout buffers where applicable.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 8f7279ade26961ae790a3345ce11a239c842c773)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 37633ec96..4086e78ba 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -296,10 +296,14 @@ xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
         if (xwl_gbm->dmabuf_capable) {
             uint32_t num_modifiers = 0;
             uint64_t *modifiers = NULL;
+            Bool supports_scanout = FALSE;
 
             if (drawable) {
-                xwl_glamor_get_drawable_modifiers(drawable, format,
-                                                  &num_modifiers, &modifiers);
+                xwl_glamor_get_drawable_modifiers_and_scanout(drawable,
+                                                              format,
+                                                              &num_modifiers,
+                                                              &modifiers,
+                                                              &supports_scanout);
             }
 
             if (num_modifiers == 0) {
@@ -309,9 +313,12 @@ xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
 
             if (num_modifiers > 0) {
 #ifdef GBM_BO_WITH_MODIFIERS2
+                uint32_t usage = GBM_BO_USE_RENDERING;
+                if (supports_scanout)
+                    usage |= GBM_BO_USE_SCANOUT;
                 bo = gbm_bo_create_with_modifiers2(xwl_gbm->gbm, width, height,
                                                    format, modifiers, num_modifiers,
-                                                   GBM_BO_USE_RENDERING);
+                                                   usage);
 #else
                 bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
                                                   format, modifiers, num_modifiers);
commit 1f5cdc9cf146217ec91b793bd1e209fd19c59b9f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Fri Apr 7 11:03:14 2023 +0200

    xwayland: Add xwl_glamor_get_drawable_modifiers_and_scanout()
    
    Add a new API similar to xwl_glamor_get_drawable_modifiers() but also
    returning whether the format and modifiers are from a tranche which
    supports scanout.
    
    This is preparation work for adding scanout support with
    gbm_bo_create_with_modifiers2() when supported.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 967ad0fa1e6b249aef1c21913234c25f97966e98)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 792af6144..3c03b2523 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -327,7 +327,8 @@ xwl_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
 static Bool
 xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, drmDevice *device,
                              uint32_t format, uint32_t *num_modifiers,
-                             uint64_t **modifiers)
+                             uint64_t **modifiers,
+                             Bool *supports_scanout)
 {
     /* Now try to find a matching set of tranches for the window's device */
     for (int i = 0; i < feedback->dev_formats_len; i++) {
@@ -335,8 +336,11 @@ xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, drmDevice *de
 
         if (drmDevicesEqual(dev_formats->drm_dev, device) &&
             xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
-                                         format, num_modifiers, modifiers))
+                                         format, num_modifiers, modifiers)) {
+            if (supports_scanout)
+                *supports_scanout = !!dev_formats->supports_scanout;
             return TRUE;
+        }
     }
 
     return FALSE;
@@ -360,7 +364,8 @@ xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
         main_dev = xwl_screen_get_main_dev(xwl_screen);
 
         return xwl_get_modifiers_for_device(&xwl_screen->default_feedback, main_dev,
-                                            format, num_modifiers, modifiers);
+                                            format, num_modifiers, modifiers,
+                                            NULL);
     } else {
         return xwl_get_modifiers_for_format(xwl_screen->formats, xwl_screen->num_formats,
                                             format, num_modifiers, modifiers);
@@ -368,8 +373,11 @@ xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
 }
 
 Bool
-xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
-                                  uint32_t *num_modifiers, uint64_t **modifiers)
+xwl_glamor_get_drawable_modifiers_and_scanout(DrawablePtr drawable,
+                                              uint32_t format,
+                                              uint32_t *num_modifiers,
+                                              uint64_t **modifiers,
+                                              Bool *supports_scanout)
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(drawable->pScreen);
     struct xwl_window *xwl_window;
@@ -377,6 +385,8 @@ xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
 
     *num_modifiers = 0;
     *modifiers = NULL;
+    if (supports_scanout)
+        *supports_scanout = FALSE;
 
     /* We can only return per-drawable modifiers if the compositor supports feedback */
     if (xwl_screen->dmabuf_protocol_version < 4)
@@ -394,7 +404,18 @@ xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
     main_dev = xwl_screen_get_main_dev(xwl_screen);
 
     return xwl_get_modifiers_for_device(&xwl_window->feedback, main_dev,
-                                        format, num_modifiers, modifiers);
+                                        format, num_modifiers, modifiers,
+                                        supports_scanout);
+
+}
+
+Bool
+xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
+                                  uint32_t *num_modifiers, uint64_t **modifiers)
+{
+    return xwl_glamor_get_drawable_modifiers_and_scanout(drawable,
+                                                         format, num_modifiers,
+                                                         modifiers, NULL);
 
 }
 
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index c2eed95e9..313d7faf1 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -142,6 +142,11 @@ Bool xwl_glamor_get_formats(ScreenPtr screen,
                             CARD32 *num_formats, CARD32 **formats);
 Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
                               uint32_t *num_modifiers, uint64_t **modifiers);
+Bool xwl_glamor_get_drawable_modifiers_and_scanout(DrawablePtr drawable,
+                                                   uint32_t format,
+                                                   uint32_t *num_modifiers,
+                                                   uint64_t **modifiers,
+                                                   Bool *supports_scanout);
 Bool xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
                                        uint32_t *num_modifiers, uint64_t **modifiers);
 Bool xwl_glamor_check_flip(PixmapPtr pixmap);
commit 474ba97bab1ad0b7bed0aa3b8172155bea1a3c75
Author: Simon Ser <contact at emersion.fr>
Date:   Wed Feb 1 15:50:15 2023 +0100

    xwayland: use gbm_bo_create_with_modifiers2()
    
    This allows us to pass flags to the function, avoiding the forced
    implicit GBM_BO_USE_SCANOUT which happens with the older version.
    
    Signed-off-by: Simon Ser <contact at emersion.fr>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit f31ca9238f845a1d9bea5b4410c0597ffe70e8d1)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 83318fe62..37633ec96 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -307,9 +307,16 @@ xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
                                          &num_modifiers, &modifiers);
             }
 
-            if (num_modifiers > 0)
+            if (num_modifiers > 0) {
+#ifdef GBM_BO_WITH_MODIFIERS2
+                bo = gbm_bo_create_with_modifiers2(xwl_gbm->gbm, width, height,
+                                                   format, modifiers, num_modifiers,
+                                                   GBM_BO_USE_RENDERING);
+#else
                 bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
                                                   format, modifiers, num_modifiers);
+#endif
+            }
             free(modifiers);
         }
 #endif
diff --git a/include/meson.build b/include/meson.build
index c8a28ac4f..ef2ced4df 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -107,6 +107,8 @@ conf_data.set('GBM_BO_WITH_MODIFIERS',
               build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 17.1') ? '1' : false)
 conf_data.set('GBM_BO_FD_FOR_PLANE',
               build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 21.1') ? '1' : false)
+conf_data.set('GBM_BO_WITH_MODIFIERS2',
+              build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 21.3') ? '1' : false)
 
 conf_data.set_quoted('SERVER_MISC_CONFIG_PATH', serverconfigdir)
 conf_data.set_quoted('PROJECTROOT', get_option('prefix'))
commit 8448a414043d457194e45341cce074627c718c13
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Apr 6 16:13:17 2023 +0200

    xwayland: Fix build without GBM
    
    The present code in Xwayland cannot be used without GBM, so if GBM is
    not available (or too old), the build would fail.
    
    Make sure we do not use the present code without GBM support.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit da0de3caf62023d2b507ed3d66a0b0daa7104c4a)

diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index e24f39a75..b76d205b2 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -97,7 +97,10 @@ if build_glamor
         srcs += 'xwayland-glx.c'
     endif
     if gbm_dep.found()
-        srcs += 'xwayland-glamor-gbm.c'
+        srcs += [
+                  'xwayland-glamor-gbm.c',
+                  'xwayland-present.c'
+                ]
     endif
     if build_eglstream
         eglstream_protodir = eglstream_dep.get_pkgconfig_variable('pkgdatadir')
@@ -111,7 +114,6 @@ if build_glamor
 
         srcs += 'xwayland-glamor-eglstream.c'
     endif
-    srcs += 'xwayland-present.c'
     if build_xv
         srcs += 'xwayland-glamor-xv.c'
     endif
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index 46ab4fed7..ac7238b96 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -943,10 +943,11 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
            xwl_screen->glamor = 0;
         }
     }
-
+#ifdef GLAMOR_HAS_GBM
     if (xwl_screen->glamor && xwl_screen->rootless)
         xwl_screen->present = xwl_present_init(pScreen);
-#endif
+#endif /* GLAMOR_HAS_GBM */
+#endif /* XWL_HAS_GLAMOR */
 
     if (!xwl_screen->glamor) {
         xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
commit b9ebae110c0d4574d1409bac51d580c4a994e292
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Apr 6 16:12:54 2023 +0200

    glamor: Fix build without GBM
    
    The functions glamor_egl_fd_from_pixmap()/glamor_egl_fds_from_pixmap()
    are not available without GBM support.
    
    So if GBM is not available or too old, the code would fail to link
    trying to find the references to those functions.
    
    Make sure we skip that code when glamor is built without GBM.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit c24910d0e138dc1dc58c0c0cdc10b49a1ed85975)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 0cbc89ee4..617766c2a 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -1003,6 +1003,7 @@ _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
                         uint32_t *strides, uint32_t *offsets,
                         CARD32 *size, uint64_t *modifier)
 {
+#ifdef GLAMOR_HAS_GBM
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -1030,6 +1031,7 @@ _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
     default:
         break;
     }
+#endif /* GLAMOR_HAS_GBM */
     return 0;
 }
 
commit 87c1df306b13856d66192f63becbba4f2b0ca8cc
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 8 11:46:13 2023 +0100

    xwayland: Make Wayland logs non-fatal
    
    The Wayland library may log warnings, we do not need to make that fatal
    to the Xserver.
    
    By killing the Xserver whenever a warning is raised, we hide other log
    messages that might be also interesting.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 62b1fac0b5c5b9eeeca7a66cba6398c211acc504)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index fc2b696d1..ca75ad7f1 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -289,14 +289,13 @@ wm_selection_callback(CallbackListPtr *p, void *data, void *arg)
     DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
 }
 
-_X_NORETURN
 static void _X_ATTRIBUTE_PRINTF(1, 0)
 xwl_log_handler(const char *format, va_list args)
 {
     char msg[256];
 
     vsnprintf(msg, sizeof msg, format, args);
-    FatalError("%s", msg);
+    ErrorF("XWAYLAND: %s", msg);
 }
 
 #ifdef XWL_HAS_XWAYLAND_EXTENSION
commit 070f6a99f5eb0241256cedcdf9f38c3b69e1957a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Mar 23 14:31:04 2023 +0100

    xwayland: Recycle buffers when dmabuf feedback changes
    
    Whenever the linux-dmabuf v4 feedback changes, we need to recreate the
    existing buffers so they use the current linux-dmabuf v4 feedback.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 81458a86bf9320a6d40d5cba64f66840f15eb26c)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index b714f9be0..792af6144 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -43,6 +43,7 @@
 #include "xwayland-glx.h"
 #include "xwayland-screen.h"
 #include "xwayland-window.h"
+#include "xwayland-window-buffers.h"
 
 #include <sys/mman.h>
 
@@ -757,6 +758,11 @@ xwl_window_dmabuf_feedback_done(void *data,
     DebugF("XWAYLAND: Window 0x%x can%s get implicit scanout support\n",
             xwl_window->window->drawable.id,
             xwl_window->has_implicit_scanout_support ? "" : "not");
+
+    /* If the linux-dmabuf v4 per-surface feedback changed, recycle the
+     * window buffers so that they get re-created with appropriate parameters.
+     */
+    xwl_window_buffers_recycle(xwl_window);
 }
 
 static void
commit 1cb6417f74f2e9f6147d0ad92798f914a3b5aa4c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 28 18:01:06 2023 +0200

    xwayland: Try the Xwayland glamor hook to create pixmaps
    
    When creating the window buffer's backing pixmap, try the Xwayland
    glamor hook first and fallback to the regular CreatePixmap() code path
    otherwise.
    
    That allows to enable direct scanout if possible, either through the
    regular dmabuf v4 code path, or from the implicit fallback code path.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 684580d06f9ea0724d4da9a4876509909b0fa791)

diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index f04c79a8a..f7bb571bb 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -328,12 +328,19 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
             pBox++;
         }
     } else {
+#ifdef XWL_HAS_GLAMOR
+        /* Try the xwayland/glamor direct hook first */
         xwl_window_buffer->pixmap =
-            (*xwl_screen->screen->CreatePixmap) (window_pixmap->drawable.pScreen,
-                                                 window_pixmap->drawable.width,
-                                                 window_pixmap->drawable.height,
-                                                 window_pixmap->drawable.depth,
-                                                 CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+            xwl_glamor_create_pixmap_for_window(xwl_window);
+#endif /* XWL_HAS_GLAMOR */
+        if (!xwl_window_buffer->pixmap) {
+            xwl_window_buffer->pixmap =
+                (*xwl_screen->screen->CreatePixmap) (window_pixmap->drawable.pScreen,
+                                                     window_pixmap->drawable.width,
+                                                     window_pixmap->drawable.height,
+                                                     window_pixmap->drawable.depth,
+                                                     CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+        }
 
         if (!xwl_window_buffer->pixmap)
             return window_pixmap;
commit c69a0527cbfdfdd07090d142aa5d77a845493652
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 22 10:37:52 2023 +0100

    xwayland: Create scanout capable BO with the fallback path
    
    Before linux_dmabuf v4 support was added, the BO were created using
    gbm_bo_create_with_modifiers() which incidentally creates scanout
    capable buffers.
    
    We now need to replicate that explicitly when using the fallback path,
    with buffers window, otherwise direct scanout will not be possible in
    that case.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1535
    Suggested-by: Michel Dänzer <mdaenzer at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 111d318fc2262c03c289be172696264622e50156)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 1474eb15d..83318fe62 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -278,7 +278,8 @@ static PixmapPtr
 xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
                                       DrawablePtr drawable,
                                       int width, int height, int depth,
-                                      unsigned int hint)
+                                      unsigned int hint,
+                                      Bool implicit_scanout)
 {
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
     struct gbm_bo *bo = NULL;
@@ -313,9 +314,11 @@ xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
         }
 #endif
         if (bo == NULL) {
+            uint32_t usage = GBM_BO_USE_RENDERING;
             implicit = TRUE;
-            bo = gbm_bo_create(xwl_gbm->gbm, width, height, format,
-                               GBM_BO_USE_RENDERING);
+            if (implicit_scanout)
+                usage |= GBM_BO_USE_SCANOUT;
+            bo = gbm_bo_create(xwl_gbm->gbm, width, height, format, usage);
         }
 
         if (bo) {
@@ -342,21 +345,19 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
                              unsigned int hint)
 {
     return xwl_glamor_gbm_create_pixmap_internal(xwl_screen_get(screen), NULL,
-                                                 width, height, depth, hint);
+                                                 width, height, depth, hint, FALSE);
 }
 
 static PixmapPtr
 xwl_glamor_gbm_create_pixmap_for_window(struct xwl_window *xwl_window)
 {
-   if (xwl_window->window == NullWindow)
-        return NullPixmap;
-
     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,
-                                                 CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+                                                 CREATE_PIXMAP_USAGE_BACKING_PIXMAP,
+                                                 xwl_window->has_implicit_scanout_support);
 }
 
 static Bool
commit 6aa9981825e980463d182179873b4524f5ddd168
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 28 17:57:31 2023 +0200

    xwayland: Add create_pixmap_for_window() to GBM backend
    
    Add the implementation for create_pixmap_for_window() in the GBM glamor
    backend.
    
    To do so, we just rename the existing xwl_glamor_gbm_create_pixmap() as
    internal and add an optional drawable parameter, so that it can be used
    either from the regular CreatePixmap code path, or from the new direct
    Xwayland glamor's hook.
    
    v2: Fallback to xwl_glamor_get_modifiers() if
        xwl_glamor_get_drawable_modifiers() returned 0 modifiers. (Michel)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 9730fb64ea05c620c90a23eb9999128e43752ec1)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 04cb5bc23..1474eb15d 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -275,11 +275,11 @@ error:
 }
 
 static PixmapPtr
-xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
-                             int width, int height, int depth,
-                             unsigned int hint)
+xwl_glamor_gbm_create_pixmap_internal(struct xwl_screen *xwl_screen,
+                                      DrawablePtr drawable,
+                                      int width, int height, int depth,
+                                      unsigned int hint)
 {
-    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
     struct gbm_bo *bo = NULL;
     PixmapPtr pixmap = NULL;
@@ -293,10 +293,18 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
 
 #ifdef GBM_BO_WITH_MODIFIERS
         if (xwl_gbm->dmabuf_capable) {
-            uint32_t num_modifiers;
+            uint32_t num_modifiers = 0;
             uint64_t *modifiers = NULL;
 
-            xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
+            if (drawable) {
+                xwl_glamor_get_drawable_modifiers(drawable, format,
+                                                  &num_modifiers, &modifiers);
+            }
+
+            if (num_modifiers == 0) {
+                xwl_glamor_get_modifiers(xwl_screen->screen, format,
+                                         &num_modifiers, &modifiers);
+            }
 
             if (num_modifiers > 0)
                 bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
@@ -311,7 +319,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
         }
 
         if (bo) {
-            pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth, implicit);
+            pixmap = xwl_glamor_gbm_create_pixmap_for_bo(xwl_screen->screen, bo, depth, implicit);
 
             if (!pixmap) {
                 gbm_bo_destroy(bo);
@@ -323,11 +331,34 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
     }
 
     if (!pixmap)
-        pixmap = glamor_create_pixmap(screen, width, height, depth, hint);
+        pixmap = glamor_create_pixmap(xwl_screen->screen, width, height, depth, hint);
 
     return pixmap;
 }
 
+static PixmapPtr
+xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
+                             int width, int height, int depth,
+                             unsigned int hint)
+{
+    return xwl_glamor_gbm_create_pixmap_internal(xwl_screen_get(screen), NULL,
+                                                 width, height, depth, hint);
+}
+
+static PixmapPtr
+xwl_glamor_gbm_create_pixmap_for_window(struct xwl_window *xwl_window)
+{
+   if (xwl_window->window == NullWindow)
+        return NullPixmap;
+
+    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,
+                                                 CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+}
+
 static Bool
 xwl_glamor_gbm_destroy_pixmap(PixmapPtr pixmap)
 {
@@ -1205,4 +1236,5 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
     xwl_screen->gbm_backend.is_available = TRUE;
     xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
                                             XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
+    xwl_screen->gbm_backend.create_pixmap_for_window = xwl_glamor_gbm_create_pixmap_for_window;
 }
commit 6af05c71de273de7f34bb9412d41b58e8c97a999
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 28 17:54:46 2023 +0200

    xwayland: Add a direct hook to create pixmaps with glamor
    
    With linux dmabuf v4 support, for direct scanout support, we need more
    context that just what CreatePixmap() provides, as we need the actual
    drawable to invoke xwl_glamor_get_drawable_modifiers().
    
    Add a specific hook in Xwayland's glamor implementation that we can use
    for that purpose.
    
    This is preparation work for the direct scanout fixes.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 1ac3dd77d5adbcc0eb4365b2ff08460826ec1be1)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index af227bb03..b714f9be0 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -919,6 +919,20 @@ xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen)
                 XWL_EGL_BACKEND_NEEDS_N_BUFFERING);
 }
 
+PixmapPtr
+xwl_glamor_create_pixmap_for_window(struct xwl_window *xwl_window)
+{
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    if (!xwl_screen->glamor || !xwl_screen->egl_backend)
+        return NullPixmap;
+
+    if (xwl_screen->egl_backend->create_pixmap_for_window)
+        return xwl_screen->egl_backend->create_pixmap_for_window(xwl_window);
+    else
+        return NullPixmap;
+}
+
 void
 xwl_glamor_init_backends(struct xwl_screen *xwl_screen, Bool use_eglstream)
 {
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 0ecd25b38..c2eed95e9 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -104,6 +104,9 @@ struct xwl_egl_backend {
      * is set up on.
      */
     drmDevice *(*get_main_device)(struct xwl_screen *xwl_screen);
+
+    /* Direct hook to create the backing pixmap for a window */
+    PixmapPtr (*create_pixmap_for_window)(struct xwl_window *xwl_window);
 };
 
 #ifdef XWL_HAS_GLAMOR
@@ -142,6 +145,7 @@ Bool xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
 Bool xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format,
                                        uint32_t *num_modifiers, uint64_t **modifiers);
 Bool xwl_glamor_check_flip(PixmapPtr pixmap);
+PixmapPtr xwl_glamor_create_pixmap_for_window (struct xwl_window *xwl_window);
 
 #ifdef XV
 /* glamor Xv Adaptor */
commit 2f7624ef2d8066d876b1253888a100ef8b5deb15
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 28 14:12:53 2023 +0200

    xwayland: Check for implicit scanout availability
    
    With implicit modifiers, DRM_FORMAT_MOD_INVALID is an allowed modifier,
    to indicate that the server can support the format.
    
    When looking for a scanout capable tranche with implicit modifiers, we
    ought to check for the availability of a tranche with an invalid
    modifier for the given format.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit a4c700231dfbd20a7d48b64ff64e8cc40a6c22bc)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index db1434ffb..af227bb03 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -747,8 +747,16 @@ xwl_window_dmabuf_feedback_done(void *data,
                                 struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
 {
     struct xwl_window *xwl_window = data;
+    uint32_t format = wl_drm_format_for_depth(xwl_window->window->drawable.depth);
 
     xwl_dmabuf_feedback_done(&xwl_window->feedback, dmabuf_feedback);
+
+    xwl_window->has_implicit_scanout_support =
+        xwl_feedback_is_modifier_supported(&xwl_window->feedback, format,
+                                           DRM_FORMAT_MOD_INVALID, TRUE);
+    DebugF("XWAYLAND: Window 0x%x can%s get implicit scanout support\n",
+            xwl_window->window->drawable.id,
+            xwl_window->has_implicit_scanout_support ? "" : "not");
 }
 
 static void
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 65dfb69ff..92c700e41 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -119,6 +119,8 @@ struct xwl_window {
 #endif
     struct xwayland_surface_v1 *xwayland_surface;
     struct xwl_dmabuf_feedback feedback;
+    /* If TRUE, the window buffer format supports scanout with implicit modifier */
+    Bool has_implicit_scanout_support;
 };
 
 struct xwl_window *xwl_window_get(WindowPtr window);
commit 5340f14fa29c219e4e52cc43d2d20d0539407d94
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Mar 28 14:18:36 2023 +0200

    xwayland: Check for scanout support in tranches
    
    The helper function xwl_feedback_is_modifier_supported() walks all the
    formats of a feeedback tranche and checks for format/modifier support
    availability.
    
    Add scanout support to that so that a caller can easily restrict the
    tranches to those which support scanout.
    
    This is preparation work for the implicit scanout support, no functional
    change.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 79ab129fdf28c4ef3468f078e46e920120c878b4)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 1552834a7..db1434ffb 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -124,11 +124,15 @@ xwl_glamor_is_modifier_supported_in_formats(struct xwl_format *formats, int num_
 
 static Bool
 xwl_feedback_is_modifier_supported(struct xwl_dmabuf_feedback *xwl_feedback,
-                                   uint32_t format, uint64_t modifier)
+                                   uint32_t format, uint64_t modifier,
+                                   int supports_scanout)
 {
     for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
         struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
 
+        if (supports_scanout && !dev_formats->supports_scanout)
+            continue;
+
         if (xwl_glamor_is_modifier_supported_in_formats(dev_formats->formats,
                                                         dev_formats->num_formats,
                                                         format, modifier))
@@ -157,11 +161,11 @@ xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
                                                            format, modifier);
     }
 
-    if (xwl_feedback_is_modifier_supported(&xwl_screen->default_feedback, format, modifier))
+    if (xwl_feedback_is_modifier_supported(&xwl_screen->default_feedback, format, modifier, FALSE))
         return TRUE;
 
     xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) {
-        if (xwl_feedback_is_modifier_supported(&xwl_window->feedback, format, modifier))
+        if (xwl_feedback_is_modifier_supported(&xwl_window->feedback, format, modifier, FALSE))
             return TRUE;
     }
 
commit 1a32a8c2afb9dbbe930cbc7779ff7a7ea94626a6
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Mar 27 11:20:12 2023 +0200

    xwayland: Use a dedicated feedback callback for windows
    
    Separate the callbacks for the default's feedback from the one for
    regular windows.
    
    This is preparation work to recreate the window buffer of feedback
    updates, no functional change.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    (cherry picked from commit 1a0cc25d488dee3c5972d9f0828d5eadfcdbe713)

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index edb028978..1552834a7 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -659,24 +659,6 @@ static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_dmabuf_feedback_li
     .tranche_flags = xwl_dmabuf_feedback_tranche_flags,
 };
 
-Bool
-xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window)
-{
-    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
-
-    xwl_window->feedback.dmabuf_feedback =
-        zwp_linux_dmabuf_v1_get_surface_feedback(xwl_screen->dmabuf, xwl_window->surface);
-
-    if (!xwl_window->feedback.dmabuf_feedback)
-        return FALSE;
-
-    zwp_linux_dmabuf_feedback_v1_add_listener(xwl_window->feedback.dmabuf_feedback,
-                                              &xwl_dmabuf_feedback_listener,
-                                              &xwl_window->feedback);
-
-    return TRUE;
-}
-
 Bool
 xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
                                 uint32_t id, uint32_t version)
@@ -707,6 +689,102 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
     return TRUE;
 }
 
+static void
+xwl_window_dmabuf_feedback_main_device(void *data,
+                                       struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                       struct wl_array *dev)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_main_device(&xwl_window->feedback, dmabuf_feedback, dev);
+}
+
+static void
+xwl_window_dmabuf_feedback_tranche_target_device(void *data,
+                                                 struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                                 struct wl_array *dev)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_tranche_target_device(&xwl_window->feedback, dmabuf_feedback, dev);
+}
+
+static void
+xwl_window_dmabuf_feedback_tranche_flags(void *data,
+                                         struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                         uint32_t flags)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_tranche_flags(&xwl_window->feedback, dmabuf_feedback, flags);
+}
+
+static void
+xwl_window_dmabuf_feedback_tranche_formats(void *data,
+                                           struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                           struct wl_array *indices)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_tranche_formats(&xwl_window->feedback, dmabuf_feedback, indices);
+}
+
+static void
+xwl_window_dmabuf_feedback_tranche_done(void *data,
+                                        struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_tranche_done(&xwl_window->feedback, dmabuf_feedback);
+}
+
+static void
+xwl_window_dmabuf_feedback_done(void *data,
+                                struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_done(&xwl_window->feedback, dmabuf_feedback);
+}
+
+static void
+xwl_window_dmabuf_feedback_format_table(void *data,
+                                        struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                        int32_t fd, uint32_t size)
+{
+    struct xwl_window *xwl_window = data;
+
+    xwl_dmabuf_feedback_format_table(&xwl_window->feedback, dmabuf_feedback, fd, size);
+}
+
+static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_window_dmabuf_feedback_listener = {
+    .done = xwl_window_dmabuf_feedback_done,
+    .format_table = xwl_window_dmabuf_feedback_format_table,
+    .main_device = xwl_window_dmabuf_feedback_main_device,
+    .tranche_done = xwl_window_dmabuf_feedback_tranche_done,
+    .tranche_target_device = xwl_window_dmabuf_feedback_tranche_target_device,
+    .tranche_formats = xwl_window_dmabuf_feedback_tranche_formats,
+    .tranche_flags = xwl_window_dmabuf_feedback_tranche_flags,
+};
+
+Bool
+xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window)
+{
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+
+    xwl_window->feedback.dmabuf_feedback =
+        zwp_linux_dmabuf_v1_get_surface_feedback(xwl_screen->dmabuf, xwl_window->surface);
+
+    if (!xwl_window->feedback.dmabuf_feedback)
+        return FALSE;
+
+    zwp_linux_dmabuf_feedback_v1_add_listener(xwl_window->feedback.dmabuf_feedback,
+                                              &xwl_window_dmabuf_feedback_listener,
+                                              xwl_window);
+
+    return TRUE;
+}
+
 void
 xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                             struct wl_registry *registry,


More information about the xorg-commit mailing list