xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Mar 15 01:20:30 UTC 2024


 hw/xwayland/meson.build       |    6 
 hw/xwayland/xwayland-dmabuf.c |  804 ++++++++++++++++++++++++++++++++++++++++++
 hw/xwayland/xwayland-dmabuf.h |  115 ++++++
 hw/xwayland/xwayland-glamor.c |  730 --------------------------------------
 hw/xwayland/xwayland-glamor.h |   17 
 hw/xwayland/xwayland-screen.c |    4 
 hw/xwayland/xwayland-screen.h |    7 
 hw/xwayland/xwayland-window.c |   43 --
 hw/xwayland/xwayland-window.h |   50 --
 9 files changed, 934 insertions(+), 842 deletions(-)

New commits:
commit 722ea5d0008e937c38911bdc29bc7a1c10e7dcf8
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Apr 6 11:34:51 2023 +0200

    xwayland: Move dmabuf code to its own source file
    
    The dmabuf support code is scattered across different source files,
    making it hard to follow and bloating unrelated sources.
    
    Move the dmabuf related source code to its own source files.
    
    This is just a cleanup aimed at helping with code readability, no
    functional change intended.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1111>

diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index cd608e1e1..10a884e8b 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -104,7 +104,11 @@ endif
 xwayland_glamor = []
 eglstream_srcs = []
 if build_xwayland_glamor
-    srcs += 'xwayland-glamor.c'
+    srcs += [
+              'xwayland-glamor.c',
+              'xwayland-dmabuf.h',
+              'xwayland-dmabuf.c'
+            ]
     if gbm_dep.found()
         srcs += [
                   'xwayland-glamor-gbm.c',
diff --git a/hw/xwayland/xwayland-dmabuf.c b/hw/xwayland/xwayland-dmabuf.c
new file mode 100644
index 000000000..7617a0e5f
--- /dev/null
+++ b/hw/xwayland/xwayland-dmabuf.c
@@ -0,0 +1,804 @@
+/*
+ * Copyright © 2011-2014 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <xwayland-config.h>
+
+#include <sys/mman.h>
+
+#include <drm_fourcc.h>
+#include <wayland-util.h>
+
+#include "xwayland-dmabuf.h"
+#include "xwayland-screen.h"
+#include "xwayland-types.h"
+#include "xwayland-window-buffers.h"
+
+#include "drm-client-protocol.h"
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
+
+void
+xwl_device_formats_destroy(struct xwl_device_formats *dev_formats)
+{
+    for (int j = 0; j < dev_formats->num_formats; j++)
+        free(dev_formats->formats[j].modifiers);
+    free(dev_formats->formats);
+    drmFreeDevice(&dev_formats->drm_dev);
+}
+
+void
+xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback)
+{
+    if (xwl_feedback->dev_formats_len == 0)
+        return;
+
+    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
+        struct xwl_device_formats *dev_format = &xwl_feedback->dev_formats[i];
+        xwl_device_formats_destroy(dev_format);
+    }
+    free(xwl_feedback->dev_formats);
+    xwl_feedback->dev_formats = NULL;
+    xwl_feedback->dev_formats_len = 0;
+}
+
+void
+xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback)
+{
+    munmap(xwl_feedback->format_table.entry,
+           xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
+    xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
+
+    if (xwl_feedback->dmabuf_feedback)
+        zwp_linux_dmabuf_feedback_v1_destroy(xwl_feedback->dmabuf_feedback);
+
+    xwl_feedback->dmabuf_feedback = NULL;
+}
+
+static Bool
+xwl_glamor_is_modifier_supported_in_formats(struct xwl_format *formats, int num_formats,
+                                            uint32_t format, uint64_t modifier)
+{
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    for (i = 0; i < num_formats; i++) {
+        if (formats[i].format == format) {
+            xwl_format = &formats[i];
+            break;
+        }
+    }
+
+    if (xwl_format) {
+        for (i = 0; i < xwl_format->num_modifiers; i++) {
+            if (xwl_format->modifiers[i] == modifier) {
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+static Bool
+xwl_feedback_is_modifier_supported(struct xwl_dmabuf_feedback *xwl_feedback,
+                                   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))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+Bool
+xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
+                                 uint32_t format, uint64_t modifier)
+{
+    struct xwl_window *xwl_window;
+
+    /*
+     * If we are using dmabuf v4, then we need to check in the main
+     * device and per-window format lists. For older protocol
+     * versions we can just check the list returned by the dmabuf.modifier
+     * events in xwl_screen
+     */
+    if (xwl_screen->dmabuf_protocol_version < 4) {
+        return xwl_glamor_is_modifier_supported_in_formats(xwl_screen->formats,
+                                                           xwl_screen->num_formats,
+                                                           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, FALSE))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+uint32_t
+wl_drm_format_for_depth(int depth)
+{
+    switch (depth) {
+    case 15:
+        return WL_DRM_FORMAT_XRGB1555;
+    case 16:
+        return WL_DRM_FORMAT_RGB565;
+    case 24:
+        return WL_DRM_FORMAT_XRGB8888;
+    case 30:
+        return WL_DRM_FORMAT_ARGB2101010;
+    default:
+        ErrorF("unexpected depth: %d\n", depth);
+    case 32:
+        return WL_DRM_FORMAT_ARGB8888;
+    }
+}
+
+static drmDevice *
+xwl_screen_get_main_dev(struct xwl_screen *xwl_screen)
+{
+    /*
+     * If we have gbm then get our main device from it. Otherwise use what
+     * the compositor told us.
+     */
+    if (xwl_screen->gbm_backend.is_available)
+        return xwl_screen->gbm_backend.get_main_device(xwl_screen);
+    else
+        return xwl_screen->default_feedback.main_dev;
+}
+
+static Bool
+xwl_dmabuf_get_formats(struct xwl_format *format_array, int format_array_len,
+                       CARD32 *num_formats, CARD32 **formats)
+{
+    *num_formats = 0;
+    *formats = NULL;
+
+    if (format_array_len == 0)
+       return TRUE;
+
+    *formats = calloc(format_array_len, sizeof(CARD32));
+    if (*formats == NULL)
+        return FALSE;
+
+    for (int i = 0; i < format_array_len; i++)
+       (*formats)[i] = format_array[i].format;
+    *num_formats = format_array_len;
+
+    return TRUE;
+}
+
+static Bool
+xwl_dmabuf_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, drmDevice *device,
+                                  CARD32 *num_formats, CARD32 **formats)
+{
+    CARD32 *ret = NULL;
+    uint32_t count = 0;
+
+    /* go through all matching sets of tranches for the window's device */
+    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
+        if (drmDevicesEqual(xwl_feedback->dev_formats[i].drm_dev, device)) {
+            struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
+
+            /* Append the formats from this tranche to the list */
+            ret = xnfreallocarray(ret, count + dev_formats->num_formats, sizeof(CARD32));
+
+            for (int j = 0; j < dev_formats->num_formats; j++) {
+                Bool found = FALSE;
+
+                /* Check if this format is already present in the list */
+                for (int k = 0; k < count; k++) {
+                    if (ret[k] == dev_formats->formats[j].format) {
+                        found = TRUE;
+                        break;
+                    }
+                }
+
+                /* If this format has not yet been added, do so now */
+                if (!found)
+                    ret[count++] = dev_formats->formats[j].format;
+            }
+        }
+    }
+
+    *num_formats = count;
+    *formats = ret;
+
+    return TRUE;
+}
+
+Bool
+xwl_glamor_get_formats(ScreenPtr screen,
+                       CARD32 *num_formats, CARD32 **formats)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+
+    /* Explicitly zero the count as the caller may ignore the return value */
+    *num_formats = 0;
+
+    if (!xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->dmabuf_protocol_version >= 4) {
+        drmDevice *main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+        return xwl_dmabuf_get_formats_for_device(&xwl_screen->default_feedback, main_dev,
+                                          num_formats, formats);
+    }
+
+    return xwl_dmabuf_get_formats(xwl_screen->formats, xwl_screen->num_formats,
+                           num_formats, formats);
+}
+
+static Bool
+xwl_dmabuf_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
+                                    uint32_t format, uint32_t *num_modifiers,
+                                    uint64_t **modifiers)
+{
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    *num_modifiers = 0;
+    *modifiers = NULL;
+
+    if (num_formats == 0)
+       return TRUE;
+
+    for (i = 0; i < num_formats; i++) {
+       if (format_array[i].format == format) {
+          xwl_format = &format_array[i];
+          break;
+       }
+    }
+
+    if (!xwl_format ||
+        (xwl_format->num_modifiers == 1 &&
+         xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
+        return FALSE;
+
+    *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
+    if (*modifiers == NULL)
+        return FALSE;
+
+    for (i = 0; i < xwl_format->num_modifiers; i++)
+       (*modifiers)[i] = xwl_format->modifiers[i];
+    *num_modifiers = xwl_format->num_modifiers;
+
+    return TRUE;
+}
+
+static Bool
+xwl_dmabuf_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback,
+                                    drmDevice *device,
+                                    uint32_t format, uint32_t *num_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++) {
+        struct xwl_device_formats *dev_formats = &feedback->dev_formats[i];
+
+        if (drmDevicesEqual(dev_formats->drm_dev, device) &&
+            xwl_dmabuf_get_modifiers_for_format(dev_formats->formats,
+                                                dev_formats->num_formats,
+                                                format, num_modifiers, modifiers)) {
+            if (supports_scanout)
+                *supports_scanout = !!dev_formats->supports_scanout;
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+Bool
+xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
+                         uint32_t *num_modifiers, uint64_t **modifiers)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    drmDevice *main_dev;
+
+    /* Explicitly zero the count as the caller may ignore the return value */
+    *num_modifiers = 0;
+    *modifiers = NULL;
+
+    if (!xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->dmabuf_protocol_version >= 4) {
+        main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+        return xwl_dmabuf_get_modifiers_for_device(&xwl_screen->default_feedback, main_dev,
+                                                   format, num_modifiers, modifiers, NULL);
+    } else {
+        return xwl_dmabuf_get_modifiers_for_format(xwl_screen->formats, xwl_screen->num_formats,
+                                                   format, num_modifiers, modifiers);
+    }
+}
+
+Bool
+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;
+    drmDevice *main_dev;
+
+    *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)
+        return TRUE;
+
+    if (drawable->type != DRAWABLE_WINDOW || !xwl_screen->dmabuf)
+        return FALSE;
+
+    xwl_window = xwl_window_from_window((WindowPtr)drawable);
+
+    /* couldn't find drawable for window */
+    if (!xwl_window)
+        return FALSE;
+
+    main_dev = xwl_screen_get_main_dev(xwl_screen);
+
+    return xwl_dmabuf_get_modifiers_for_device(&xwl_window->feedback, main_dev,
+                                               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);
+
+}
+
+static void
+xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+                         uint32_t format)
+{
+}
+
+static void
+xwl_add_format_and_mod_to_list(struct xwl_format **formats,
+                               uint32_t *num_formats,
+                               uint32_t format,
+                               uint64_t modifier)
+{
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    for (i = 0; i < *num_formats; i++) {
+        if ((*formats)[i].format == format) {
+            xwl_format = &(*formats)[i];
+            break;
+        }
+    }
+
+    if (xwl_format == NULL) {
+        (*num_formats)++;
+        *formats = xnfrealloc(*formats, *num_formats * sizeof(*xwl_format));
+        xwl_format = &(*formats)[*num_formats - 1];
+        xwl_format->format = format;
+        xwl_format->num_modifiers = 0;
+        xwl_format->modifiers = NULL;
+    }
+
+    for (i = 0; i < xwl_format->num_modifiers; i++) {
+        /* don't add it if the modifier already exists */
+        if (xwl_format->modifiers[i] == modifier)
+            return;
+    }
+
+    xwl_format->num_modifiers++;
+    xwl_format->modifiers = xnfrealloc(xwl_format->modifiers,
+                                       xwl_format->num_modifiers * sizeof(uint64_t));
+    xwl_format->modifiers[xwl_format->num_modifiers - 1]  = modifier;
+}
+
+static void
+xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+                           uint32_t format, uint32_t modifier_hi,
+                           uint32_t modifier_lo)
+{
+    struct xwl_screen *xwl_screen = data;
+
+    xwl_add_format_and_mod_to_list(&xwl_screen->formats, &xwl_screen->num_formats,
+                                   format,
+                                   ((uint64_t)modifier_hi << 32 | (uint64_t)modifier_lo));
+}
+
+static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
+    .format = xwl_dmabuf_handle_format,
+    .modifier = xwl_dmabuf_handle_modifier
+};
+
+/*
+ * We need to check if the compositor is resending all of the tranche
+ * information. Each tranche event will call this method to see
+ * if the existing format info should be cleared before refilling.
+ */
+static void
+xwl_check_reset_tranche_info(struct xwl_dmabuf_feedback *xwl_feedback)
+{
+    if (!xwl_feedback->feedback_done)
+        return;
+
+    xwl_feedback->feedback_done = FALSE;
+
+    xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
+}
+
+static void
+xwl_dmabuf_feedback_main_device(void *data,
+                                struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                struct wl_array *dev)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+    dev_t devid;
+
+    xwl_check_reset_tranche_info(xwl_feedback);
+
+    assert(dev->size == sizeof(dev_t));
+    memcpy(&devid, dev->data, sizeof(dev_t));
+
+    if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->main_dev) != 0)
+        ErrorF("linux_dmabuf_feedback.main_device: Failed to fetch DRM device\n");
+}
+
+static void
+xwl_dmabuf_feedback_tranche_target_device(void *data,
+                                          struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                          struct wl_array *dev)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+    dev_t devid;
+
+    xwl_check_reset_tranche_info(xwl_feedback);
+
+    assert(dev->size == sizeof(dev_t));
+    memcpy(&devid, dev->data, sizeof(dev_t));
+
+    if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->tmp_tranche.drm_dev) != 0)
+        ErrorF("linux_dmabuf_feedback.tranche_target_device: Failed to fetch DRM device\n");
+}
+
+static void
+xwl_dmabuf_feedback_tranche_flags(void *data,
+                                  struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                  uint32_t flags)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+
+    xwl_check_reset_tranche_info(xwl_feedback);
+
+    if (flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT)
+        xwl_feedback->tmp_tranche.supports_scanout = TRUE;
+}
+
+static void
+xwl_dmabuf_feedback_tranche_formats(void *data,
+                                    struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
+                                    struct wl_array *indices)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+    struct xwl_device_formats *tranche = &xwl_feedback->tmp_tranche;
+    uint16_t *index;
+
+    xwl_check_reset_tranche_info(xwl_feedback);
+
+    wl_array_for_each(index, indices) {
+        if (*index >= xwl_feedback->format_table.len) {
+            ErrorF("linux_dmabuf_feedback.tranche_formats: Index given to us by the compositor"
+                   " is too large to fit in the format table\n");
+            continue;
+        }
+
+        /* Look up this format/mod in the format table */
+        struct xwl_format_table_entry *entry = &xwl_feedback->format_table.entry[*index];
+
+        /* Add it to the in-progress tranche */
+        xwl_add_format_and_mod_to_list(&tranche->formats, &tranche->num_formats,
+                                       entry->format,
+                                       entry->modifier);
+    }
+}
+
+static void
+xwl_append_to_tranche(struct xwl_device_formats *dst, struct xwl_device_formats *src)
+{
+    struct xwl_format *format;
+
+    for (int i = 0; i < src->num_formats; i++) {
+        format = &src->formats[i];
+
+        for (int j = 0; j < format->num_modifiers; j++)
+            xwl_add_format_and_mod_to_list(&dst->formats, &dst->num_formats,
+                                           format->format,
+                                           format->modifiers[j]);
+    }
+}
+
+static void
+xwl_dmabuf_feedback_tranche_done(void *data,
+                                 struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+    struct xwl_device_formats *tranche;
+    int appended = FALSE;
+
+    /*
+     * No need to call xwl_check_reset_tranche_info, the other events should have been
+     * triggered first
+     */
+
+    if (xwl_feedback->tmp_tranche.drm_dev == NULL) {
+        xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
+        goto out;
+    }
+
+    /*
+     * First check if there is an existing tranche for this device+flags combo. We
+     * will combine it with this tranche, since we can only send one modifier list
+     * in DRI3 but the compositor may report multiple tranches per device (KDE
+     * does this)
+     */
+    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
+        tranche = &xwl_feedback->dev_formats[i];
+        if (tranche->drm_dev == xwl_feedback->tmp_tranche.drm_dev &&
+            tranche->supports_scanout == xwl_feedback->tmp_tranche.supports_scanout) {
+            appended = TRUE;
+
+            /* Add all format/mods to this tranche */
+            xwl_append_to_tranche(tranche, &xwl_feedback->tmp_tranche);
+
+            /* Now free our temp tranche's allocations */
+            xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
+
+            break;
+        }
+    }
+
+    if (!appended) {
+        xwl_feedback->dev_formats_len++;
+        xwl_feedback->dev_formats = xnfrealloc(xwl_feedback->dev_formats,
+                                               sizeof(struct xwl_device_formats) *
+                                               xwl_feedback->dev_formats_len);
+
+        /* copy the temporary tranche into the official array */
+        memcpy(&xwl_feedback->dev_formats[xwl_feedback->dev_formats_len - 1],
+               &xwl_feedback->tmp_tranche,
+               sizeof(struct xwl_device_formats));
+    }
+
+out:
+    /* reset the tranche */
+    memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats));
+}
+
+static void
+xwl_dmabuf_feedback_done(void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+
+    xwl_feedback->feedback_done = TRUE;
+    xwl_feedback->unprocessed_feedback_pending = TRUE;
+}
+
+static void
+xwl_dmabuf_feedback_format_table(void *data,
+                                 struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+                                 int32_t fd, uint32_t size)
+{
+    struct xwl_dmabuf_feedback *xwl_feedback = data;
+    /* Unmap the old table */
+    if (xwl_feedback->format_table.entry) {
+        munmap(xwl_feedback->format_table.entry,
+               xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
+    }
+
+    assert(size % sizeof(struct xwl_format_table_entry) == 0);
+    xwl_feedback->format_table.len = size / sizeof(struct xwl_format_table_entry);
+    xwl_feedback->format_table.entry = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+    close(fd);
+
+    if (xwl_feedback->format_table.entry == MAP_FAILED) {
+        ErrorF("linux_dmabuf_feedback.format_table: Could not map the format"
+               " table: Compositor bug or out of resources\n");
+        xwl_feedback->format_table.len = 0;
+    }
+}
+
+static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_dmabuf_feedback_listener = {
+    .done = xwl_dmabuf_feedback_done,
+    .format_table = xwl_dmabuf_feedback_format_table,
+    .main_device = xwl_dmabuf_feedback_main_device,
+    .tranche_done = xwl_dmabuf_feedback_tranche_done,
+    .tranche_target_device = xwl_dmabuf_feedback_tranche_target_device,
+    .tranche_formats = xwl_dmabuf_feedback_tranche_formats,
+    .tranche_flags = xwl_dmabuf_feedback_tranche_flags,
+};
+
+Bool
+xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
+                                uint32_t id, uint32_t version)
+{
+    /* We either support versions 3 or 4. 4 is needed for dmabuf feedback */
+    int supported_version = version >= 4 ? 4 : 3;
+
+    if (version < 3)
+        return FALSE;
+
+    xwl_screen->dmabuf =
+        wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, supported_version);
+    xwl_screen->dmabuf_protocol_version = supported_version;
+    zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
+
+    /* If the compositor supports it, request the default feedback hints */
+    if (version >= 4) {
+        xwl_screen->default_feedback.dmabuf_feedback =
+            zwp_linux_dmabuf_v1_get_default_feedback(xwl_screen->dmabuf);
+        if (!xwl_screen->default_feedback.dmabuf_feedback)
+            return FALSE;
+
+        zwp_linux_dmabuf_feedback_v1_add_listener(xwl_screen->default_feedback.dmabuf_feedback,
+                                                  &xwl_dmabuf_feedback_listener,
+                                                  &xwl_screen->default_feedback);
+    }
+
+    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;
+    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");
+
+    /* 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_realloc_pixmap(xwl_window);
+}
+
+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;
+}
diff --git a/hw/xwayland/xwayland-dmabuf.h b/hw/xwayland/xwayland-dmabuf.h
new file mode 100644
index 000000000..ca0dcd706
--- /dev/null
+++ b/hw/xwayland/xwayland-dmabuf.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2011-2014 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef XWAYLAND_DMABUF_H
+#define XWAYLAND_DMABUF_H
+
+#include <xwayland-config.h>
+
+#include <X11/X.h>
+#include <dix.h>
+#include <xf86drm.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "xwayland-types.h"
+
+struct xwl_format {
+    uint32_t format;
+    int num_modifiers;
+    uint64_t *modifiers;
+};
+
+struct xwl_format_table_entry {
+    uint32_t format;
+    uint32_t pad;
+    uint64_t modifier;
+};
+
+struct xwl_device_formats {
+    drmDevice *drm_dev;
+    uint32_t num_formats;
+    struct xwl_format *formats;
+    Bool supports_scanout;
+};
+
+struct xwl_format_table {
+    /* This is mmapped from the fd given to us by the compositor */
+    int len;
+    struct xwl_format_table_entry *entry;
+};
+
+/*
+ * Helper struct for sharing dmabuf feedback logic between
+ * a screen and a window. The screen will get the default
+ * feedback, and a window will get a per-surface feedback.
+ */
+struct xwl_dmabuf_feedback {
+    struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
+    struct xwl_format_table format_table;
+    drmDevice *main_dev;
+    /*
+     * This will be filled in during wl events and copied to
+     * dev_formats on dmabuf_feedback.tranche_done
+     */
+    struct xwl_device_formats tmp_tranche;
+    int feedback_done;
+    int dev_formats_len;
+    struct xwl_device_formats *dev_formats;
+    /*
+     * This flag is used to identify if the feedback
+     * has been resent. If this is true, then the xwayland
+     * clients need to be sent PresentCompleteModeSuboptimalCopy
+     * to tell them to re-request modifiers.
+     */
+    int unprocessed_feedback_pending;
+};
+
+void xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback);
+void xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback);
+void xwl_device_formats_destroy(struct xwl_device_formats *dev_formats);
+
+Bool xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window);
+Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
+                                     uint32_t id, uint32_t version);
+Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
+                                      uint32_t format, uint64_t modifier);
+uint32_t wl_drm_format_for_depth(int depth);
+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);
+
+#endif /* XWAYLAND_DMABUF_H */
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 28f848a3d..73ac9df49 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -40,9 +40,8 @@
 #endif
 
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
-#include "drm-client-protocol.h"
-#include <drm_fourcc.h>
 
+#include "xwayland-dmabuf.h"
 #include "xwayland-glamor.h"
 #include "xwayland-screen.h"
 #include "xwayland-window.h"
@@ -104,733 +103,6 @@ xwl_glamor_check_flip(WindowPtr present_window, PixmapPtr pixmap)
     return TRUE;
 }
 
-static Bool
-xwl_glamor_is_modifier_supported_in_formats(struct xwl_format *formats, int num_formats,
-                                            uint32_t format, uint64_t modifier)
-{
-    struct xwl_format *xwl_format = NULL;
-    int i;
-
-    for (i = 0; i < num_formats; i++) {
-        if (formats[i].format == format) {
-            xwl_format = &formats[i];
-            break;
-        }
-    }
-
-    if (xwl_format) {
-        for (i = 0; i < xwl_format->num_modifiers; i++) {
-            if (xwl_format->modifiers[i] == modifier) {
-                return TRUE;
-            }
-        }
-    }
-
-    return FALSE;
-}
-
-static Bool
-xwl_feedback_is_modifier_supported(struct xwl_dmabuf_feedback *xwl_feedback,
-                                   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))
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-
-Bool
-xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
-                                 uint32_t format, uint64_t modifier)
-{
-    struct xwl_window *xwl_window;
-
-    /*
-     * If we are using dmabuf v4, then we need to check in the main
-     * device and per-window format lists. For older protocol
-     * versions we can just check the list returned by the dmabuf.modifier
-     * events in xwl_screen
-     */
-    if (xwl_screen->dmabuf_protocol_version < 4) {
-        return xwl_glamor_is_modifier_supported_in_formats(xwl_screen->formats,
-                                                           xwl_screen->num_formats,
-                                                           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, FALSE))
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-uint32_t
-wl_drm_format_for_depth(int depth)
-{
-    switch (depth) {
-    case 15:
-        return WL_DRM_FORMAT_XRGB1555;
-    case 16:
-        return WL_DRM_FORMAT_RGB565;
-    case 24:
-        return WL_DRM_FORMAT_XRGB8888;
-    case 30:
-        return WL_DRM_FORMAT_ARGB2101010;
-    default:
-        ErrorF("unexpected depth: %d\n", depth);
-    case 32:
-        return WL_DRM_FORMAT_ARGB8888;
-    }
-}
-
-static drmDevice *
-xwl_screen_get_main_dev(struct xwl_screen *xwl_screen)
-{
-    /*
-     * If we have gbm then get our main device from it. Otherwise use what
-     * the compositor told us.
-     */
-    if (xwl_screen->gbm_backend.is_available)
-        return xwl_screen->gbm_backend.get_main_device(xwl_screen);
-    else
-        return xwl_screen->default_feedback.main_dev;
-}
-
-static Bool
-xwl_get_formats(struct xwl_format *format_array, int format_array_len,
-               CARD32 *num_formats, CARD32 **formats)
-{
-    *num_formats = 0;
-    *formats = NULL;
-
-    if (format_array_len == 0)
-       return TRUE;
-
-    *formats = calloc(format_array_len, sizeof(CARD32));
-    if (*formats == NULL)
-        return FALSE;
-
-    for (int i = 0; i < format_array_len; i++)
-       (*formats)[i] = format_array[i].format;
-    *num_formats = format_array_len;
-
-    return TRUE;
-}
-
-static Bool
-xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, drmDevice *device,
-                           CARD32 *num_formats, CARD32 **formats)
-{
-    CARD32 *ret = NULL;
-    uint32_t count = 0;
-
-    /* go through all matching sets of tranches for the window's device */
-    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
-        if (drmDevicesEqual(xwl_feedback->dev_formats[i].drm_dev, device)) {
-            struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
-
-            /* Append the formats from this tranche to the list */
-            ret = xnfreallocarray(ret, count + dev_formats->num_formats, sizeof(CARD32));
-
-            for (int j = 0; j < dev_formats->num_formats; j++) {
-                bool found = false;
-
-                /* Check if this format is already present in the list */
-                for (int k = 0; k < count; k++) {
-                    if (ret[k] == dev_formats->formats[j].format) {
-                        found = true;
-                        break;
-                    }
-                }
-
-                /* If this format has not yet been added, do so now */
-                if (!found)
-                    ret[count++] = dev_formats->formats[j].format;
-            }
-        }
-    }
-
-    *num_formats = count;
-    *formats = ret;
-
-    return TRUE;
-}
-
-Bool
-xwl_glamor_get_formats(ScreenPtr screen,
-                       CARD32 *num_formats, CARD32 **formats)
-{
-    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-
-    /* Explicitly zero the count as the caller may ignore the return value */
-    *num_formats = 0;
-
-    if (!xwl_screen->dmabuf)
-        return FALSE;
-
-    if (xwl_screen->dmabuf_protocol_version >= 4) {
-        drmDevice *main_dev = xwl_screen_get_main_dev(xwl_screen);
-
-        return xwl_get_formats_for_device(&xwl_screen->default_feedback, main_dev,
-                                          num_formats, formats);
-    }
-
-    return xwl_get_formats(xwl_screen->formats, xwl_screen->num_formats,
-                           num_formats, formats);
-}
-
-static Bool
-xwl_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
-                             uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers)
-{
-    struct xwl_format *xwl_format = NULL;
-    int i;
-
-    *num_modifiers = 0;
-    *modifiers = NULL;
-
-    if (num_formats == 0)
-       return TRUE;
-
-    for (i = 0; i < num_formats; i++) {
-       if (format_array[i].format == format) {
-          xwl_format = &format_array[i];
-          break;
-       }
-    }
-
-    if (!xwl_format ||
-        (xwl_format->num_modifiers == 1 &&
-         xwl_format->modifiers[0] == DRM_FORMAT_MOD_INVALID))
-        return FALSE;
-
-    *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t));
-    if (*modifiers == NULL)
-        return FALSE;
-
-    for (i = 0; i < xwl_format->num_modifiers; i++)
-       (*modifiers)[i] = xwl_format->modifiers[i];
-    *num_modifiers = xwl_format->num_modifiers;
-
-    return TRUE;
-}
-
-static Bool
-xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, drmDevice *device,
-                             uint32_t format, uint32_t *num_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++) {
-        struct xwl_device_formats *dev_formats = &feedback->dev_formats[i];
-
-        if (drmDevicesEqual(dev_formats->drm_dev, device) &&
-            xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
-                                         format, num_modifiers, modifiers)) {
-            if (supports_scanout)
-                *supports_scanout = !!dev_formats->supports_scanout;
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-Bool
-xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
-                         uint32_t *num_modifiers, uint64_t **modifiers)
-{
-    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-    drmDevice *main_dev;
-
-    /* Explicitly zero the count as the caller may ignore the return value */
-    *num_modifiers = 0;
-    *modifiers = NULL;
-
-    if (!xwl_screen->dmabuf)
-        return FALSE;
-
-    if (xwl_screen->dmabuf_protocol_version >= 4) {
-        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,
-                                            NULL);
-    } else {
-        return xwl_get_modifiers_for_format(xwl_screen->formats, xwl_screen->num_formats,
-                                            format, num_modifiers, modifiers);
-    }
-}
-
-Bool
-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;
-    drmDevice *main_dev;
-
-    *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)
-        return TRUE;
-
-    if (drawable->type != DRAWABLE_WINDOW || !xwl_screen->dmabuf)
-        return FALSE;
-
-    xwl_window = xwl_window_from_window((WindowPtr)drawable);
-
-    /* couldn't find drawable for window */
-    if (!xwl_window)
-        return FALSE;
-
-    main_dev = xwl_screen_get_main_dev(xwl_screen);
-
-    return xwl_get_modifiers_for_device(&xwl_window->feedback, main_dev,
-                                        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);
-
-}
-
-static void
-xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
-                         uint32_t format)
-{
-}
-
-static void
-xwl_add_format_and_mod_to_list(struct xwl_format **formats,
-                               uint32_t *num_formats,
-                               uint32_t format,
-                               uint64_t modifier)
-{
-    struct xwl_format *xwl_format = NULL;
-    int i;
-
-    for (i = 0; i < *num_formats; i++) {
-        if ((*formats)[i].format == format) {
-            xwl_format = &(*formats)[i];
-            break;
-        }
-    }
-
-    if (xwl_format == NULL) {
-        (*num_formats)++;
-        *formats = xnfrealloc(*formats, *num_formats * sizeof(*xwl_format));
-        xwl_format = &(*formats)[*num_formats - 1];
-        xwl_format->format = format;
-        xwl_format->num_modifiers = 0;
-        xwl_format->modifiers = NULL;
-    }
-
-    for (i = 0; i < xwl_format->num_modifiers; i++) {
-        /* don't add it if the modifier already exists */
-        if (xwl_format->modifiers[i] == modifier)
-            return;
-    }
-
-    xwl_format->num_modifiers++;
-    xwl_format->modifiers = xnfrealloc(xwl_format->modifiers,
-                                       xwl_format->num_modifiers * sizeof(uint64_t));
-    xwl_format->modifiers[xwl_format->num_modifiers - 1]  = modifier;
-}
-
-static void
-xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
-                           uint32_t format, uint32_t modifier_hi,
-                           uint32_t modifier_lo)
-{
-    struct xwl_screen *xwl_screen = data;
-
-    xwl_add_format_and_mod_to_list(&xwl_screen->formats, &xwl_screen->num_formats,
-                                   format,
-                                   ((uint64_t)modifier_hi << 32 | (uint64_t)modifier_lo));
-}
-
-static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
-    .format = xwl_dmabuf_handle_format,
-    .modifier = xwl_dmabuf_handle_modifier
-};
-
-/*
- * We need to check if the compositor is resending all of the tranche
- * information. Each tranche event will call this method to see
- * if the existing format info should be cleared before refilling.
- */
-static void
-xwl_check_reset_tranche_info(struct xwl_dmabuf_feedback *xwl_feedback)
-{
-    if (!xwl_feedback->feedback_done)
-        return;
-
-    xwl_feedback->feedback_done = false;
-
-    xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
-}
-
-static void
-xwl_dmabuf_feedback_main_device(void *data,
-                                struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
-                                struct wl_array *dev)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-    dev_t devid;
-
-    xwl_check_reset_tranche_info(xwl_feedback);
-
-    assert(dev->size == sizeof(dev_t));
-    memcpy(&devid, dev->data, sizeof(dev_t));
-
-    if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->main_dev) != 0)
-        ErrorF("linux_dmabuf_feedback.main_device: Failed to fetch DRM device\n");
-}
-
-static void
-xwl_dmabuf_feedback_tranche_target_device(void *data,
-                                          struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
-                                          struct wl_array *dev)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-    dev_t devid;
-
-    xwl_check_reset_tranche_info(xwl_feedback);
-
-    assert(dev->size == sizeof(dev_t));
-    memcpy(&devid, dev->data, sizeof(dev_t));
-
-    if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->tmp_tranche.drm_dev) != 0)
-        ErrorF("linux_dmabuf_feedback.tranche_target_device: Failed to fetch DRM device\n");
-}
-
-static void
-xwl_dmabuf_feedback_tranche_flags(void *data,
-                                  struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
-                                  uint32_t flags)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-
-    xwl_check_reset_tranche_info(xwl_feedback);
-
-    if (flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT)
-        xwl_feedback->tmp_tranche.supports_scanout = true;
-}
-
-static void
-xwl_dmabuf_feedback_tranche_formats(void *data,
-                                    struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback,
-                                    struct wl_array *indices)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-    struct xwl_device_formats *tranche = &xwl_feedback->tmp_tranche;
-    uint16_t *index;
-
-    xwl_check_reset_tranche_info(xwl_feedback);
-
-    wl_array_for_each(index, indices) {
-        if (*index >= xwl_feedback->format_table.len) {
-            ErrorF("linux_dmabuf_feedback.tranche_formats: Index given to us by the compositor"
-                   " is too large to fit in the format table\n");
-            continue;
-        }
-
-        /* Look up this format/mod in the format table */
-        struct xwl_format_table_entry *entry = &xwl_feedback->format_table.entry[*index];
-
-        /* Add it to the in-progress tranche */
-        xwl_add_format_and_mod_to_list(&tranche->formats, &tranche->num_formats,
-                                       entry->format,
-                                       entry->modifier);
-    }
-}
-
-static void
-xwl_append_to_tranche(struct xwl_device_formats *dst, struct xwl_device_formats *src)
-{
-    struct xwl_format *format;
-
-    for (int i = 0; i < src->num_formats; i++) {
-        format = &src->formats[i];
-
-        for (int j = 0; j < format->num_modifiers; j++)
-            xwl_add_format_and_mod_to_list(&dst->formats, &dst->num_formats,
-                                           format->format,
-                                           format->modifiers[j]);
-    }
-}
-
-static void
-xwl_dmabuf_feedback_tranche_done(void *data,
-                                 struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-    struct xwl_device_formats *tranche;
-    int appended = false;
-
-    /*
-     * No need to call xwl_check_reset_tranche_info, the other events should have been
-     * triggered first
-     */
-
-    if (xwl_feedback->tmp_tranche.drm_dev == NULL) {
-        xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
-        goto out;
-    }
-
-    /*
-     * First check if there is an existing tranche for this device+flags combo. We
-     * will combine it with this tranche, since we can only send one modifier list
-     * in DRI3 but the compositor may report multiple tranches per device (KDE
-     * does this)
-     */
-    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
-        tranche = &xwl_feedback->dev_formats[i];
-        if (tranche->drm_dev == xwl_feedback->tmp_tranche.drm_dev &&
-            tranche->supports_scanout == xwl_feedback->tmp_tranche.supports_scanout) {
-            appended = true;
-
-            /* Add all format/mods to this tranche */
-            xwl_append_to_tranche(tranche, &xwl_feedback->tmp_tranche);
-
-            /* Now free our temp tranche's allocations */
-            xwl_device_formats_destroy(&xwl_feedback->tmp_tranche);
-
-            break;
-        }
-    }
-
-    if (!appended) {
-        xwl_feedback->dev_formats_len++;
-        xwl_feedback->dev_formats = xnfrealloc(xwl_feedback->dev_formats,
-                                               sizeof(struct xwl_device_formats) *
-                                               xwl_feedback->dev_formats_len);
-
-        /* copy the temporary tranche into the official array */
-        memcpy(&xwl_feedback->dev_formats[xwl_feedback->dev_formats_len - 1],
-               &xwl_feedback->tmp_tranche,
-               sizeof(struct xwl_device_formats));
-    }
-
-out:
-    /* reset the tranche */
-    memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats));
-}
-
-static void
-xwl_dmabuf_feedback_done(void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-
-    xwl_feedback->feedback_done = true;
-    xwl_feedback->unprocessed_feedback_pending = true;
-}
-
-static void
-xwl_dmabuf_feedback_format_table(void *data,
-                                 struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
-                                 int32_t fd, uint32_t size)
-{
-    struct xwl_dmabuf_feedback *xwl_feedback = data;
-    /* Unmap the old table */
-    if (xwl_feedback->format_table.entry) {
-        munmap(xwl_feedback->format_table.entry,
-               xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
-    }
-
-    assert(size % sizeof(struct xwl_format_table_entry) == 0);
-    xwl_feedback->format_table.len = size / sizeof(struct xwl_format_table_entry);
-    xwl_feedback->format_table.entry = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
-    close(fd);
-
-    if (xwl_feedback->format_table.entry == MAP_FAILED) {
-        ErrorF("linux_dmabuf_feedback.format_table: Could not map the format"
-               " table: Compositor bug or out of resources\n");
-        xwl_feedback->format_table.len = 0;
-    }
-}
-
-static const struct zwp_linux_dmabuf_feedback_v1_listener xwl_dmabuf_feedback_listener = {
-    .done = xwl_dmabuf_feedback_done,
-    .format_table = xwl_dmabuf_feedback_format_table,
-    .main_device = xwl_dmabuf_feedback_main_device,
-    .tranche_done = xwl_dmabuf_feedback_tranche_done,
-    .tranche_target_device = xwl_dmabuf_feedback_tranche_target_device,
-    .tranche_formats = xwl_dmabuf_feedback_tranche_formats,
-    .tranche_flags = xwl_dmabuf_feedback_tranche_flags,
-};
-
-Bool
-xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
-                                uint32_t id, uint32_t version)
-{
-    /* We either support versions 3 or 4. 4 is needed for dmabuf feedback */
-    int supported_version = version >= 4 ? 4 : 3;
-
-    if (version < 3)
-        return FALSE;
-
-    xwl_screen->dmabuf =
-        wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, supported_version);
-    xwl_screen->dmabuf_protocol_version = supported_version;
-    zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
-
-    /* If the compositor supports it, request the default feedback hints */
-    if (version >= 4) {
-        xwl_screen->default_feedback.dmabuf_feedback =
-            zwp_linux_dmabuf_v1_get_default_feedback(xwl_screen->dmabuf);
-        if (!xwl_screen->default_feedback.dmabuf_feedback)
-            return FALSE;
-
-        zwp_linux_dmabuf_feedback_v1_add_listener(xwl_screen->default_feedback.dmabuf_feedback,
-                                                  &xwl_dmabuf_feedback_listener,
-                                                  &xwl_screen->default_feedback);
-    }
-
-    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;
-    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");
-
-    /* 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_realloc_pixmap(xwl_window);
-}
-
-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,
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 5513230ff..cadc62f6f 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -126,9 +126,6 @@ Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
 
 Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
                                   uint32_t id, uint32_t version);
-Bool xwl_dmabuf_setup_feedback_for_window(struct xwl_window *xwl_window);
-Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
-                                     uint32_t id, uint32_t version);
 struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap);
 void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                                  struct wl_registry *registry,
@@ -142,20 +139,6 @@ 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);
 Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
-Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
-                                      uint32_t format, uint64_t modifier);
-uint32_t wl_drm_format_for_depth(int depth);
-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(WindowPtr present_window, PixmapPtr pixmap);
 PixmapPtr xwl_glamor_create_pixmap_for_window (struct xwl_window *xwl_window);
 
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index 5c71b55e2..d40fc270a 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -219,9 +219,9 @@ xwl_close_screen(ScreenPtr screen)
     struct xwl_output *xwl_output, *next_xwl_output;
     struct xwl_seat *xwl_seat, *next_xwl_seat;
     struct xwl_wl_surface *xwl_wl_surface, *xwl_wl_surface_next;
-
+#ifdef XWL_HAS_GLAMOR
     xwl_dmabuf_feedback_destroy(&xwl_screen->default_feedback);
-
+#endif
     DeleteCallback(&PropertyStateCallback, xwl_property_callback, screen);
     XaceDeleteCallback(XACE_PROPERTY_ACCESS, xwl_access_property_callback, screen);
 
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index 993b3cb12..63740a8e2 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -38,17 +38,12 @@
 #include "xwayland-output.h"
 #include "xwayland-glamor.h"
 #include "xwayland-drm-lease.h"
+#include "xwayland-dmabuf.h"
 
 #ifdef XWL_HAS_LIBDECOR
 #include <libdecor.h>
 #endif
 
-struct xwl_format {
-    uint32_t format;
-    int num_modifiers;
-    uint64_t *modifiers;
-};
-
 struct xwl_screen {
     int width;
     int height;
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index c8b62db6e..fda98fa18 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -45,6 +45,7 @@
 #include "xwayland-window.h"
 #include "xwayland-window-buffers.h"
 #include "xwayland-shm.h"
+#include "xwayland-dmabuf.h"
 
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
 #include "tearing-control-v1-client-protocol.h"
@@ -1097,43 +1098,6 @@ release_wl_surface_for_window(struct xwl_window *xwl_window)
         release_wl_surface_for_window_legacy_delay(xwl_window);
 }
 
-void
-xwl_device_formats_destroy(struct xwl_device_formats *dev_formats)
-{
-    for (int j = 0; j < dev_formats->num_formats; j++)
-        free(dev_formats->formats[j].modifiers);
-    free(dev_formats->formats);
-    drmFreeDevice(&dev_formats->drm_dev);
-}
-
-void
-xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback)
-{
-    if (xwl_feedback->dev_formats_len == 0)
-        return;
-
-    for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
-        struct xwl_device_formats *dev_format = &xwl_feedback->dev_formats[i];
-        xwl_device_formats_destroy(dev_format);
-    }
-    free(xwl_feedback->dev_formats);
-    xwl_feedback->dev_formats = NULL;
-    xwl_feedback->dev_formats_len = 0;
-}
-
-void
-xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback)
-{
-    munmap(xwl_feedback->format_table.entry,
-           xwl_feedback->format_table.len * sizeof(struct xwl_format_table_entry));
-    xwl_dmabuf_feedback_clear_dev_formats(xwl_feedback);
-
-    if (xwl_feedback->dmabuf_feedback)
-        zwp_linux_dmabuf_feedback_v1_destroy(xwl_feedback->dmabuf_feedback);
-
-    xwl_feedback->dmabuf_feedback = NULL;
-}
-
 Bool
 xwl_unrealize_window(WindowPtr window)
 {
@@ -1175,11 +1139,14 @@ xwl_unrealize_window(WindowPtr window)
 
     if (xwl_window_has_viewport_enabled(xwl_window))
         xwl_window_disable_viewport(xwl_window);
-
+#ifdef XWL_HAS_GLAMOR
     xwl_dmabuf_feedback_destroy(&xwl_window->feedback);
 
+#ifdef GLAMOR_HAS_GBM
     if (xwl_window->xwl_screen->present)
         xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
+#endif /* GLAMOR_HAS_GBM */
+#endif /* XWL_HAS_GLAMOR */
 
     if (xwl_window->tearing_control)
         wp_tearing_control_v1_destroy(xwl_window->tearing_control);
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 03d3fed14..7c70bb9ed 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -41,6 +41,7 @@
 #include <xf86drm.h>
 
 #include "xwayland-types.h"
+#include "xwayland-dmabuf.h"
 
 struct xwl_wl_surface {
     OsTimerPtr wl_surface_destroy_timer;
@@ -48,51 +49,6 @@ struct xwl_wl_surface {
     struct xorg_list link;
 };
 
-struct xwl_format_table_entry {
-    uint32_t format;
-    uint32_t pad;
-    uint64_t modifier;
-};
-
-struct xwl_device_formats {
-    drmDevice *drm_dev;
-    int supports_scanout;
-    uint32_t num_formats;
-    struct xwl_format *formats;
-};
-
-struct xwl_format_table {
-    /* This is mmapped from the fd given to us by the compositor */
-    int len;
-    struct xwl_format_table_entry *entry;
-};
-
-/*
- * Helper struct for sharing dmabuf feedback logic between
- * a screen and a window. The screen will get the default
- * feedback, and a window will get a per-surface feedback.
- */
-struct xwl_dmabuf_feedback {
-    struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
-    struct xwl_format_table format_table;
-    drmDevice *main_dev;
-    /*
-     * This will be filled in during wl events and copied to
-     * dev_formats on dmabuf_feedback.tranche_done
-     */
-    struct xwl_device_formats tmp_tranche;
-    int feedback_done;
-    int dev_formats_len;
-    struct xwl_device_formats *dev_formats;
-    /*
-     * This flag is used to identify if the feedback
-     * has been resent. If this is true, then the xwayland
-     * clients need to be sent PresentCompleteModeSuboptimalCopy
-     * to tell them to re-request modifiers.
-     */
-    int unprocessed_feedback_pending;
-};
-
 struct xwl_window {
     struct xwl_screen *xwl_screen;
     struct wl_surface *surface;
@@ -155,8 +111,4 @@ void xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface);
 
 Bool xwl_window_init(void);
 
-void xwl_dmabuf_feedback_destroy(struct xwl_dmabuf_feedback *xwl_feedback);
-void xwl_dmabuf_feedback_clear_dev_formats(struct xwl_dmabuf_feedback *xwl_feedback);
-void xwl_device_formats_destroy(struct xwl_device_formats *dev_formats);
-
 #endif /* XWAYLAND_WINDOW_H */


More information about the xorg-commit mailing list