xserver: Branch 'master' - 4 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Apr 9 14:23:51 UTC 2021


 hw/xwayland/xwayland-glamor-eglstream.c |  207 ++++++++++++++++++++++++++++++-
 hw/xwayland/xwayland-glamor-gbm.c       |  186 +---------------------------
 hw/xwayland/xwayland-glamor.c           |  210 +++++++++++++++++++++++++++++---
 hw/xwayland/xwayland-glamor.h           |   20 ++-
 hw/xwayland/xwayland-present.c          |    5 
 hw/xwayland/xwayland-screen.h           |    1 
 6 files changed, 424 insertions(+), 205 deletions(-)

New commits:
commit 38e875904b039ec1889e7c81eb1d577a4f69b26d
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date:   Thu Dec 3 14:57:51 2020 -0800

    xwayland: implement pixmap_from_buffers for the eglstream backend
    
    Provides an implementation for the pixmap_from_buffers DRI3 function for
    xwayland's eglstream backend. This will be used by the NVIDIA GLX driver
    to pass buffers from client applications to the server. These can then
    be presented using the PRESENT extension.
    
    To hopefully make this less error-prone, we also introduce a "type"
    field for this struct to distinguish between xwl_pixmaps for the new
    DRI3-created pixmaps and those for the existing glamor-created pixmaps.
    
    Additionally, the patch enables wnmd present mode with the eglstream backend.
    This involves creating a wl_buffer for the provided dma-buf before importing it
    into EGL and passing this to the compositor so it can be scanned out directly
    if possible.
    
    Since both backends now support this present mode, the HAS_PRESENT_FLIP flag is
    no longer needed, so it can be removed.
    
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index ccaa59cbe..2d8380e1f 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -37,6 +37,8 @@
 #include <glamor_transfer.h>
 
 #include <xf86drm.h>
+#include <dri3.h>
+#include <drm_fourcc.h>
 
 #include <epoxy/egl.h>
 
@@ -47,6 +49,7 @@
 
 #include "wayland-eglstream-client-protocol.h"
 #include "wayland-eglstream-controller-client-protocol.h"
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
 
 struct xwl_eglstream_pending_stream {
     PixmapPtr pixmap;
@@ -80,12 +83,23 @@ struct xwl_eglstream_private {
     GLuint blit_is_rgba_pos;
 };
 
+enum xwl_pixmap_type {
+    XWL_PIXMAP_EGLSTREAM, /* Pixmaps created by glamor. */
+    XWL_PIXMAP_DMA_BUF, /* Pixmaps allocated through DRI3. */
+};
+
 struct xwl_pixmap {
-    struct wl_buffer *buffer;
+    enum xwl_pixmap_type type;
+    /* add any new <= 4-byte member here to avoid holes on 64-bit */
     struct xwl_screen *xwl_screen;
+    struct wl_buffer *buffer;
 
+    /* XWL_PIXMAP_EGLSTREAM. */
     EGLStreamKHR stream;
     EGLSurface surface;
+
+    /* XWL_PIXMAP_DMA_BUF. */
+    EGLImage image;
 };
 
 static DevPrivateKeyRec xwl_eglstream_private_key;
@@ -289,12 +303,18 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
                        xwl_screen->egl_context);
     }
 
-    if (xwl_pixmap->surface)
+    if (xwl_pixmap->surface != EGL_NO_SURFACE)
         eglDestroySurface(xwl_screen->egl_display, xwl_pixmap->surface);
 
-    eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
+    if (xwl_pixmap->stream != EGL_NO_STREAM_KHR)
+        eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
+
+    if (xwl_pixmap->buffer)
+        wl_buffer_destroy(xwl_pixmap->buffer);
+
+    if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
+        eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
 
-    wl_buffer_destroy(xwl_pixmap->buffer);
     free(xwl_pixmap);
 }
 
@@ -509,9 +529,13 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
         FatalError("Not enough memory to create pixmap\n");
     xwl_pixmap_set_private(pixmap, xwl_pixmap);
 
+    xwl_pixmap->type = XWL_PIXMAP_EGLSTREAM;
+    xwl_pixmap->image = EGL_NO_IMAGE;
+
     xwl_glamor_egl_make_current(xwl_screen);
 
     xwl_pixmap->xwl_screen = xwl_screen;
+    xwl_pixmap->surface = EGL_NO_SURFACE;
     xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
     stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
                                               xwl_pixmap->stream);
@@ -552,6 +576,7 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
     struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
 
     if (xwl_pixmap) {
+        assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
         if (pending) {
             /* Wait for the compositor to finish connecting the consumer for
              * this eglstream */
@@ -590,6 +615,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
     };
     GLint saved_vao;
 
+    assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
+
     /* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
      * won't actually draw to it
      */
@@ -636,7 +663,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
 static Bool
 xwl_glamor_eglstream_check_flip(PixmapPtr pixmap)
 {
-    return FALSE;
+    return xwl_pixmap_get(pixmap)->type == XWL_PIXMAP_DMA_BUF;
 }
 
 static void
@@ -681,6 +708,9 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
         xwl_eglstream->controller = wl_registry_bind(
             wl_registry, id, &wl_eglstream_controller_interface, version);
         return TRUE;
+    } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
+        xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
+        return TRUE;
     }
 
     /* no match */
@@ -779,6 +809,163 @@ xwl_eglstream_init_shaders(struct xwl_screen *xwl_screen)
         glGetUniformLocation(xwl_eglstream->blit_prog, "is_rgba");
 }
 
+static int
+xwl_dri3_open_client(ClientPtr client,
+                     ScreenPtr screen,
+                     RRProviderPtr provider,
+                     int *pfd)
+{
+    /* Not supported with this backend. */
+    return BadImplementation;
+}
+
+static PixmapPtr
+xwl_dri3_pixmap_from_fds(ScreenPtr screen,
+                         CARD8 num_fds, const int *fds,
+                         CARD16 width, CARD16 height,
+                         const CARD32 *strides, const CARD32 *offsets,
+                         CARD8 depth, CARD8 bpp,
+                         uint64_t modifier)
+{
+    PixmapPtr pixmap;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    struct xwl_pixmap *xwl_pixmap;
+    unsigned int texture;
+    EGLint image_attribs[48];
+    uint32_t mod_hi = modifier >> 32, mod_lo = modifier & 0xffffffff, format;
+    int attrib = 0, i;
+    struct zwp_linux_buffer_params_v1 *params;
+
+    format = wl_drm_format_for_depth(depth);
+    if (!xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
+        ErrorF("glamor: unsupported format modifier\n");
+        return NULL;
+    }
+
+    xwl_pixmap = calloc(1, sizeof (*xwl_pixmap));
+    if (!xwl_pixmap)
+        return NULL;
+    xwl_pixmap->type = XWL_PIXMAP_DMA_BUF;
+    xwl_pixmap->xwl_screen = xwl_screen;
+
+    xwl_pixmap->buffer = NULL;
+    xwl_pixmap->stream = EGL_NO_STREAM_KHR;
+    xwl_pixmap->surface = EGL_NO_SURFACE;
+
+    params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
+    for (i = 0; i < num_fds; i++) {
+        zwp_linux_buffer_params_v1_add(params, fds[i], i,
+                                       offsets[i], strides[i],
+                                       mod_hi, mod_lo);
+    }
+    xwl_pixmap->buffer =
+        zwp_linux_buffer_params_v1_create_immed(params, width, height,
+                                                format, 0);
+    zwp_linux_buffer_params_v1_destroy(params);
+
+
+    image_attribs[attrib++] = EGL_WIDTH;
+    image_attribs[attrib++] = width;
+    image_attribs[attrib++] = EGL_HEIGHT;
+    image_attribs[attrib++] = height;
+    image_attribs[attrib++] = EGL_LINUX_DRM_FOURCC_EXT;
+    image_attribs[attrib++] = drm_format_for_depth(depth, bpp);
+
+    if (num_fds > 0) {
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+        image_attribs[attrib++] = fds[0];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+        image_attribs[attrib++] = offsets[0];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+        image_attribs[attrib++] = strides[0];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
+        image_attribs[attrib++] = mod_hi;
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
+        image_attribs[attrib++] = mod_lo;
+    }
+    if (num_fds > 1) {
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_FD_EXT;
+        image_attribs[attrib++] = fds[1];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
+        image_attribs[attrib++] = offsets[1];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
+        image_attribs[attrib++] = strides[1];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
+        image_attribs[attrib++] = mod_hi;
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
+        image_attribs[attrib++] = mod_lo;
+    }
+    if (num_fds > 2) {
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_FD_EXT;
+        image_attribs[attrib++] = fds[2];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
+        image_attribs[attrib++] = offsets[2];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
+        image_attribs[attrib++] = strides[2];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
+        image_attribs[attrib++] = mod_hi;
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
+        image_attribs[attrib++] = mod_lo;
+    }
+    if (num_fds > 3) {
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_FD_EXT;
+        image_attribs[attrib++] = fds[3];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
+        image_attribs[attrib++] = offsets[3];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
+        image_attribs[attrib++] = strides[3];
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
+        image_attribs[attrib++] = mod_hi;
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
+        image_attribs[attrib++] = mod_lo;
+    }
+    image_attribs[attrib++] = EGL_NONE;
+
+    xwl_glamor_egl_make_current(xwl_screen);
+
+    /* eglCreateImageKHR will close fds */
+    xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
+                                          EGL_NO_CONTEXT,
+                                          EGL_LINUX_DMA_BUF_EXT,
+                                          NULL, image_attribs);
+    if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) {
+        ErrorF("eglCreateImageKHR failed!\n");
+        if (xwl_pixmap->buffer)
+            wl_buffer_destroy(xwl_pixmap->buffer);
+        free(xwl_pixmap);
+        return NULL;
+    }
+
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
+    glBindTexture(GL_TEXTURE_2D, 0);
+
+    pixmap = glamor_create_pixmap(screen, width, height, depth,
+                                  GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
+    glamor_set_pixmap_texture(pixmap, texture);
+    glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
+    wl_buffer_add_listener(xwl_pixmap->buffer,
+                           &xwl_eglstream_buffer_release_listener,
+                           pixmap);
+    xwl_pixmap_set_private(pixmap, xwl_pixmap);
+
+    return pixmap;
+}
+
+static const dri3_screen_info_rec xwl_dri3_info = {
+    .version = 2,
+    .open = NULL,
+    .pixmap_from_fds = xwl_dri3_pixmap_from_fds,
+    .fds_from_pixmap = NULL,
+    .open_client = xwl_dri3_open_client,
+    .get_formats = xwl_glamor_get_formats,
+    .get_modifiers = xwl_glamor_get_modifiers,
+    .get_drawable_modifiers = glamor_get_drawable_modifiers,
+};
+
 static Bool
 xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
 {
@@ -858,6 +1045,11 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
 
     xwl_eglstream_init_shaders(xwl_screen);
 
+    if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
+        !dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
+        ErrorF("DRI3 initialization failed. Performance will be affected.\n");
+    }
+
     return TRUE;
 error:
     xwl_eglstream_cleanup(xwl_screen);
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 1b1d517da..12d820e44 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -969,7 +969,6 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
     xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
     xwl_screen->gbm_backend.check_flip = NULL;
     xwl_screen->gbm_backend.is_available = TRUE;
-    xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_HAS_PRESENT_FLIP |
-                                            XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
+    xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
                                             XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
 }
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 060471f01..9e44d5106 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -362,16 +362,6 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
     return 0;
 }
 
-Bool
-xwl_glamor_has_present_flip(struct xwl_screen *xwl_screen)
-{
-    if (!xwl_screen->glamor || !xwl_screen->egl_backend)
-        return FALSE;
-
-    return (xwl_screen->egl_backend->backend_flags &
-                XWL_EGL_BACKEND_HAS_PRESENT_FLIP);
-}
-
 Bool
 xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen)
 {
@@ -430,8 +420,6 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
 #ifdef XWL_HAS_EGLSTREAM
     if (xwl_screen->eglstream_backend.is_available &&
         xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
-        ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
-        ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
         xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
         return TRUE;
     }
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index a86b30b40..26ab78f04 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -34,9 +34,8 @@
 
 typedef enum _xwl_egl_backend_flags {
     XWL_EGL_BACKEND_NO_FLAG = 0,
-    XWL_EGL_BACKEND_HAS_PRESENT_FLIP = (1 << 0),
-    XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 1),
-    XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 2),
+    XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
+    XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
 } xwl_egl_backend_flags;
 
 struct xwl_egl_backend {
@@ -122,7 +121,6 @@ void xwl_glamor_post_damage(struct xwl_window *xwl_window,
                             PixmapPtr pixmap, RegionPtr region);
 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
-Bool xwl_glamor_has_present_flip(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,
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 666ea15e7..7ba7efc11 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -404,6 +404,9 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
     if (!xwl_window)
         return FALSE;
 
+    if (!xwl_glamor_check_flip(pixmap))
+        return FALSE;
+
     /* Can't flip if the window pixmap doesn't match the xwl_window parent
      * window's, e.g. because a client redirected this window or one of its
      * parents.
@@ -540,7 +543,7 @@ xwl_present_init(ScreenPtr screen)
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
 
-    if (!xwl_glamor_has_present_flip(xwl_screen))
+    if (!xwl_screen->glamor || !xwl_screen->egl_backend)
         return FALSE;
 
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
commit bc99dd2127f12f1aae55971c09a2792eeaa98444
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date:   Wed Mar 3 11:56:41 2021 +0100

    xwayland: Add check_flip() glamor backend function
    
    This is preliminary work for hardware accelerated rendering with the
    NVIDIA driver.
    
    This exposes a new glamor backend function, check_flip, which can be
    used to control whether flipping is supported for the given pixmap.
    
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>

diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 9b2c2c43f..ccaa59cbe 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -633,6 +633,12 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
     pixmap->refcnt++;
 }
 
+static Bool
+xwl_glamor_eglstream_check_flip(PixmapPtr pixmap)
+{
+    return FALSE;
+}
+
 static void
 xwl_eglstream_display_handle_caps(void *data,
                                   struct wl_eglstream_display *disp,
@@ -942,6 +948,7 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
     xwl_screen->eglstream_backend.get_wl_buffer_for_pixmap = xwl_glamor_eglstream_get_wl_buffer_for_pixmap;
     xwl_screen->eglstream_backend.post_damage = xwl_glamor_eglstream_post_damage;
     xwl_screen->eglstream_backend.allow_commits = xwl_glamor_eglstream_allow_commits;
+    xwl_screen->eglstream_backend.check_flip = xwl_glamor_eglstream_check_flip;
     xwl_screen->eglstream_backend.is_available = TRUE;
     xwl_screen->eglstream_backend.backend_flags = XWL_EGL_BACKEND_NO_FLAG;
 }
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 455b755ca..1b1d517da 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -967,6 +967,7 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
     xwl_screen->gbm_backend.init_egl = xwl_glamor_gbm_init_egl;
     xwl_screen->gbm_backend.init_screen = xwl_glamor_gbm_init_screen;
     xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
+    xwl_screen->gbm_backend.check_flip = NULL;
     xwl_screen->gbm_backend.is_available = TRUE;
     xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_HAS_PRESENT_FLIP |
                                             XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index d8bf1bd5d..060471f01 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -79,6 +79,17 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
     xwl_screen->glamor_ctx = glamor_ctx;
 }
 
+Bool
+xwl_glamor_check_flip(PixmapPtr pixmap)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen);
+
+    if (xwl_screen->egl_backend->check_flip)
+        return xwl_screen->egl_backend->check_flip(pixmap);
+
+    return TRUE;
+}
+
 Bool
 xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
                                  uint32_t format, uint64_t modifier)
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 1637a0733..a86b30b40 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -92,6 +92,11 @@ struct xwl_egl_backend {
      * callback is optional.
      */
     Bool (*allow_commits)(struct xwl_window *xwl_window);
+
+    /* Called by Xwayland to check whether the given pixmap can be
+     * presented by xwl_present_flip. If not implemented, assumed TRUE.
+     */
+    Bool (*check_flip)(PixmapPtr pixmap);
 };
 
 #ifdef XWL_HAS_GLAMOR
@@ -127,6 +132,7 @@ 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_check_flip(PixmapPtr pixmap);
 
 #ifdef XV
 /* glamor Xv Adaptor */
commit 400d4d0fdd55192f394e1a8273dfb2423c895ec0
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date:   Fri Feb 12 12:09:27 2021 -0800

    xwayland: move formats and modifiers functions to common glamor code
    
    This is preliminary work for hardware accelerated rendering with the
    NVIDIA driver.
    
    This moves the modifiers and formats functions previously only available
    to the GBM backend to the common glamor code so that it can be used by
    both the GBM and EGLStream backends.
    
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 73c69727e..455b755ca 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -97,25 +97,6 @@ gbm_format_for_depth(int depth)
     }
 }
 
-static 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 char
 is_device_path_render_node (const char *device_path)
 {
@@ -214,7 +195,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
             uint32_t num_modifiers;
             uint64_t *modifiers = NULL;
 
-            glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
+            xwl_glamor_get_modifiers(screen, format, &num_modifiers, &modifiers);
             bo = gbm_bo_create_with_modifiers(xwl_gbm->gbm, width, height,
                                               format, modifiers, num_modifiers);
             free(modifiers);
@@ -277,8 +258,6 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
     unsigned short width = pixmap->drawable.width;
     unsigned short height = pixmap->drawable.height;
     uint32_t format;
-    struct xwl_format *xwl_format = NULL;
-    Bool modifier_supported = FALSE;
     int prime_fd;
     int num_planes;
     uint32_t strides[4];
@@ -317,23 +296,8 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
     offsets[0] = 0;
 #endif
 
-    for (i = 0; i < xwl_screen->num_formats; i++) {
-       if (xwl_screen->formats[i].format == format) {
-          xwl_format = &xwl_screen->formats[i];
-          break;
-       }
-    }
-
-    if (xwl_format) {
-        for (i = 0; i < xwl_format->num_modifiers; i++) {
-            if (xwl_format->modifiers[i] == modifier) {
-                modifier_supported = TRUE;
-                break;
-            }
-        }
-    }
-
-    if (xwl_screen->dmabuf && modifier_supported) {
+    if (xwl_screen->dmabuf &&
+        xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
         struct zwp_linux_buffer_params_v1 *params;
 
         params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
@@ -592,83 +556,14 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
     return -1;
 }
 
-_X_EXPORT Bool
-glamor_get_formats(ScreenPtr screen,
-                   CARD32 *num_formats, CARD32 **formats)
-{
-    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-    int i;
-
-    /* Explicitly zero the count as the caller may ignore the return value */
-    *num_formats = 0;
-
-    if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
-        return FALSE;
-
-    if (xwl_screen->num_formats == 0)
-       return TRUE;
-
-    *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
-    if (*formats == NULL)
-        return FALSE;
-
-    for (i = 0; i < xwl_screen->num_formats; i++)
-       (*formats)[i] = xwl_screen->formats[i].format;
-    *num_formats = xwl_screen->num_formats;
-
-    return TRUE;
-}
-
-_X_EXPORT Bool
-glamor_get_modifiers(ScreenPtr screen, uint32_t format,
-                     uint32_t *num_modifiers, uint64_t **modifiers)
-{
-    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
-    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-    struct xwl_format *xwl_format = NULL;
-    int i;
-
-    /* Explicitly zero the count as the caller may ignore the return value */
-    *num_modifiers = 0;
-
-    if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
-        return FALSE;
-
-    if (xwl_screen->num_formats == 0)
-       return TRUE;
-
-    for (i = 0; i < xwl_screen->num_formats; i++) {
-       if (xwl_screen->formats[i].format == format) {
-          xwl_format = &xwl_screen->formats[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 const dri3_screen_info_rec xwl_dri3_info = {
     .version = 2,
     .open = NULL,
     .pixmap_from_fds = glamor_pixmap_from_fds,
     .fds_from_pixmap = glamor_fds_from_pixmap,
     .open_client = xwl_dri3_open_client,
-    .get_formats = glamor_get_formats,
-    .get_modifiers = glamor_get_modifiers,
+    .get_formats = xwl_glamor_get_formats,
+    .get_modifiers = xwl_glamor_get_modifiers,
     .get_drawable_modifiers = glamor_get_drawable_modifiers,
 };
 
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index cce0c911e..d8bf1bd5d 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -79,6 +79,117 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
     xwl_screen->glamor_ctx = glamor_ctx;
 }
 
+Bool
+xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
+                                 uint32_t format, uint64_t modifier)
+{
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    for (i = 0; i < xwl_screen->num_formats; i++) {
+        if (xwl_screen->formats[i].format == format) {
+            xwl_format = &xwl_screen->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;
+}
+
+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;
+    }
+}
+
+Bool
+xwl_glamor_get_formats(ScreenPtr screen,
+                       CARD32 *num_formats, CARD32 **formats)
+{
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    int i;
+
+    /* Explicitly zero the count as the caller may ignore the return value */
+    *num_formats = 0;
+
+    if (!xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->num_formats == 0)
+       return TRUE;
+
+    *formats = calloc(xwl_screen->num_formats, sizeof(CARD32));
+    if (*formats == NULL)
+        return FALSE;
+
+    for (i = 0; i < xwl_screen->num_formats; i++)
+       (*formats)[i] = xwl_screen->formats[i].format;
+    *num_formats = xwl_screen->num_formats;
+
+    return TRUE;
+}
+
+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);
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    /* Explicitly zero the count as the caller may ignore the return value */
+    *num_modifiers = 0;
+
+    if (!xwl_screen->dmabuf)
+        return FALSE;
+
+    if (xwl_screen->num_formats == 0)
+       return TRUE;
+
+    for (i = 0; i < xwl_screen->num_formats; i++) {
+       if (xwl_screen->formats[i].format == format) {
+          xwl_format = &xwl_screen->formats[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 void
 xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
                          uint32_t format)
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index e017fce80..1637a0733 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -120,7 +120,13 @@ void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 Bool xwl_glamor_has_present_flip(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);
 
 #ifdef XV
 /* glamor Xv Adaptor */
commit ae225417c0a0828ffb24e11eb4b968c34692e25a
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 3 09:55:12 2021 +0100

    xwayland: Move dmabuf interface to common glamor code
    
    This is preliminary work for hardware accelerated rendering with the
    NVIDIA driver.
    
    The EGLStream backend can possibly also use the dmabuf interface, so
    move the relevant code from the GBM specific source to the common bits.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 221bf268a..73c69727e 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -56,7 +56,6 @@ struct xwl_gbm_private {
     char *device_name;
     struct gbm_device *gbm;
     struct wl_drm *drm;
-    struct zwp_linux_dmabuf_v1 *dmabuf;
     int drm_fd;
     int fd_render_node;
     Bool drm_authenticated;
@@ -334,10 +333,10 @@ xwl_glamor_gbm_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
         }
     }
 
-    if (xwl_gbm->dmabuf && modifier_supported) {
+    if (xwl_screen->dmabuf && modifier_supported) {
         struct zwp_linux_buffer_params_v1 *params;
 
-        params = zwp_linux_dmabuf_v1_create_params(xwl_gbm->dmabuf);
+        params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
         for (i = 0; i < num_planes; i++) {
             zwp_linux_buffer_params_v1_add(params, prime_fd, i,
                                            offsets[i], strides[i],
@@ -604,7 +603,7 @@ glamor_get_formats(ScreenPtr screen,
     /* Explicitly zero the count as the caller may ignore the return value */
     *num_formats = 0;
 
-    if (!xwl_gbm->dmabuf_capable || !xwl_gbm->dmabuf)
+    if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
         return FALSE;
 
     if (xwl_screen->num_formats == 0)
@@ -633,7 +632,7 @@ glamor_get_modifiers(ScreenPtr screen, uint32_t format,
     /* Explicitly zero the count as the caller may ignore the return value */
     *num_modifiers = 0;
 
-    if (!xwl_gbm->dmabuf_capable || !xwl_gbm->dmabuf)
+    if (!xwl_gbm->dmabuf_capable || !xwl_screen->dmabuf)
         return FALSE;
 
     if (xwl_screen->num_formats == 0)
@@ -797,54 +796,6 @@ static const struct wl_drm_listener xwl_drm_listener = {
     xwl_drm_handle_capabilities
 };
 
-static void
-xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
-                         uint32_t format)
-{
-}
-
-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;
-    struct xwl_format *xwl_format = NULL;
-    int i;
-
-    for (i = 0; i < xwl_screen->num_formats; i++) {
-        if (xwl_screen->formats[i].format == format) {
-            xwl_format = &xwl_screen->formats[i];
-            break;
-        }
-    }
-
-    if (xwl_format == NULL) {
-       xwl_screen->num_formats++;
-       xwl_screen->formats = realloc(xwl_screen->formats,
-                                     xwl_screen->num_formats * sizeof(*xwl_format));
-       if (!xwl_screen->formats)
-          return;
-       xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
-       xwl_format->format = format;
-       xwl_format->num_modifiers = 0;
-       xwl_format->modifiers = NULL;
-    }
-
-    xwl_format->num_modifiers++;
-    xwl_format->modifiers = realloc(xwl_format->modifiers,
-                                    xwl_format->num_modifiers * sizeof(uint64_t));
-    if (!xwl_format->modifiers)
-       return;
-    xwl_format->modifiers[xwl_format->num_modifiers - 1]  = (uint64_t) modifier_lo;
-    xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
-}
-
-static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
-    .format   = xwl_dmabuf_handle_format,
-    .modifier = xwl_dmabuf_handle_modifier
-};
-
 Bool
 xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
                              uint32_t id, uint32_t version)
@@ -862,22 +813,6 @@ xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
     return TRUE;
 }
 
-Bool
-xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
-                                uint32_t id, uint32_t version)
-{
-    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
-
-    if (version < 3)
-        return FALSE;
-
-    xwl_gbm->dmabuf =
-        wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
-    zwp_linux_dmabuf_v1_add_listener(xwl_gbm->dmabuf, &xwl_dmabuf_listener, xwl_screen);
-
-    return TRUE;
-}
-
 static Bool
 xwl_glamor_gbm_init_wl_registry(struct xwl_screen *xwl_screen,
                                 struct wl_registry *wl_registry,
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index bcd07a1a5..cce0c911e 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -35,6 +35,10 @@
 #include "glx_extinit.h"
 #endif
 
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
+#include "drm-client-protocol.h"
+#include <drm_fourcc.h>
+
 #include "xwayland-glamor.h"
 #include "xwayland-glx.h"
 #include "xwayland-screen.h"
@@ -75,6 +79,68 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
     xwl_screen->glamor_ctx = glamor_ctx;
 }
 
+static void
+xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
+                         uint32_t format)
+{
+}
+
+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;
+    struct xwl_format *xwl_format = NULL;
+    int i;
+
+    for (i = 0; i < xwl_screen->num_formats; i++) {
+        if (xwl_screen->formats[i].format == format) {
+            xwl_format = &xwl_screen->formats[i];
+            break;
+        }
+    }
+
+    if (xwl_format == NULL) {
+        xwl_screen->num_formats++;
+        xwl_screen->formats = realloc(xwl_screen->formats,
+                                      xwl_screen->num_formats * sizeof(*xwl_format));
+        if (!xwl_screen->formats)
+            return;
+        xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1];
+        xwl_format->format = format;
+        xwl_format->num_modifiers = 0;
+        xwl_format->modifiers = NULL;
+    }
+
+    xwl_format->num_modifiers++;
+    xwl_format->modifiers = realloc(xwl_format->modifiers,
+                                    xwl_format->num_modifiers * sizeof(uint64_t));
+    if (!xwl_format->modifiers)
+        return;
+    xwl_format->modifiers[xwl_format->num_modifiers - 1]  = (uint64_t) modifier_lo;
+    xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32;
+}
+
+static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = {
+    .format = xwl_dmabuf_handle_format,
+    .modifier = xwl_dmabuf_handle_modifier
+};
+
+Bool
+xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
+                                uint32_t id, uint32_t version)
+{
+    if (version < 3)
+        return FALSE;
+
+    xwl_screen->dmabuf =
+        wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 3);
+    zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen);
+
+    return TRUE;
+}
+
 void
 xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                             struct wl_registry *registry,
@@ -89,11 +155,11 @@ xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
                                                  version)) {
         /* no-op */
     } else if (xwl_screen->eglstream_backend.is_available &&
-             xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
-                                                            registry,
-                                                            id,
-                                                            interface,
-                                                            version)) {
+               xwl_screen->eglstream_backend.init_wl_registry(xwl_screen,
+                                                              registry,
+                                                              id,
+                                                              interface,
+                                                              version)) {
         /* no-op */
     }
 }
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index 8d0b12705..5fe4712bd 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -83,6 +83,7 @@ struct xwl_screen {
     struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
     struct zwp_pointer_constraints_v1 *pointer_constraints;
     struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
+    struct zwp_linux_dmabuf_v1 *dmabuf;
     struct zxdg_output_manager_v1 *xdg_output_manager;
     struct wp_viewporter *viewporter;
     uint32_t serial;


More information about the xorg-commit mailing list