xserver: Branch 'xwayland-21.1' - 5 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Oct 19 09:12:30 UTC 2021


 glamor/glamor.c                   |   35 +++++++-----
 glamor/glamor_priv.h              |   10 +++
 glamor/glamor_render.c            |    9 ++-
 hw/xwayland/xwayland-glamor-gbm.c |  110 ++++++++++++++++++++++++++++++++++++--
 hw/xwayland/xwayland-output.c     |    2 
 hw/xwayland/xwayland-shm.c        |   11 +++
 include/dix-config.h.in           |    3 +
 include/meson.build               |    2 
 8 files changed, 160 insertions(+), 22 deletions(-)

New commits:
commit 21e3dc3b5a576d38b549716bda0a6b34612e1f1f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Mon Oct 4 09:36:23 2021 +0200

    xwayland: Set GLVND driver based on GBM backend name
    
    With the GBM backend becoming usable with different drivers such as
    NVIDIA, set the GLVND vendor to the same value as the GBM backend name.
    
    Mesa implementation however returns "drm" so we need to special case
    this value - Basically, for anything other than "drm" we simply assume
    that the GBM backend name is the same as the vendor.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Reviewed-by: James Jones <jajones at nvidia.com>
    Tested-by: James Jones <jajones at nvidia.com>
    (cherry picked from commit 5daf42b48924b1e93d4fe40e600c42ae9835712f)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 386266a4e..466a1b052 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -938,6 +938,7 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
     struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
     EGLint major, minor;
     const GLubyte *renderer;
+    const char *gbm_backend_name;
 
     if (!xwl_gbm->fd_render_node && !xwl_gbm->drm_authenticated) {
         ErrorF("Failed to get wl_drm, disabling Glamor and DRI3\n");
@@ -989,6 +990,11 @@ xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen)
                                 "EXT_image_dma_buf_import_modifiers"))
        xwl_gbm->dmabuf_capable = TRUE;
 
+    gbm_backend_name = gbm_device_get_backend_name(xwl_gbm->gbm);
+    /* Mesa uses "drm" as backend name, in that case, just do nothing */
+    if (gbm_backend_name && strcmp(gbm_backend_name, "drm") != 0)
+        xwl_screen->glvnd_vendor = gbm_backend_name;
+
     return TRUE;
 error:
     if (xwl_screen->egl_display != EGL_NO_DISPLAY) {
commit ab1c873f9d2445d7ed46d71c3589b4c448a6cc12
Author: James Jones <jajones at nvidia.com>
Date:   Fri Mar 26 12:50:08 2021 -0700

    Use EGL_LINUX_DMA_BUF_EXT to create GBM bo EGLImages
    
    Xwayland was passing GBM bos directly to
    eglCreateImageKHR using the EGL_NATIVE_PIXMAP_KHR
    target. Given the EGL GBM platform spec claims it
    is invalid to create a EGLSurface from a native
    pixmap on the GBM platform, implying there is no
    mapping between GBM objects and EGL's concept of
    native pixmaps, this seems a bit questionable.
    
    This change modifies the bo import function to
    extract all the required data from the bo and then
    imports it as a dma-buf instead when the dma-buf +
    modifiers path is available.
    
    Signed-off-by: James Jones <jajones at nvidia.com>
    Reviewed-by: Simon Ser <contact at emersion.fr>
    (cherry picked from commit f15729376d7c7ef183bd8f77156c281ff84c2bd9)

diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 12d820e44..386266a4e 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -120,6 +120,55 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
     PixmapPtr pixmap;
     struct xwl_pixmap *xwl_pixmap;
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+#ifdef GBM_BO_FD_FOR_PLANE
+    struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
+    uint64_t modifier = gbm_bo_get_modifier(bo);
+    const int num_planes = gbm_bo_get_plane_count(bo);
+    int fds[GBM_MAX_PLANES];
+    int plane;
+    int attr_num = 0;
+    EGLint img_attrs[64] = {0};
+    enum PlaneAttrs {
+        PLANE_FD,
+        PLANE_OFFSET,
+        PLANE_PITCH,
+        PLANE_MODIFIER_LO,
+        PLANE_MODIFIER_HI,
+        NUM_PLANE_ATTRS
+    };
+    static const EGLint planeAttrs[][NUM_PLANE_ATTRS] = {
+        {
+            EGL_DMA_BUF_PLANE0_FD_EXT,
+            EGL_DMA_BUF_PLANE0_OFFSET_EXT,
+            EGL_DMA_BUF_PLANE0_PITCH_EXT,
+            EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
+            EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
+        },
+        {
+            EGL_DMA_BUF_PLANE1_FD_EXT,
+            EGL_DMA_BUF_PLANE1_OFFSET_EXT,
+            EGL_DMA_BUF_PLANE1_PITCH_EXT,
+            EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
+            EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
+        },
+        {
+            EGL_DMA_BUF_PLANE2_FD_EXT,
+            EGL_DMA_BUF_PLANE2_OFFSET_EXT,
+            EGL_DMA_BUF_PLANE2_PITCH_EXT,
+            EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
+            EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
+        },
+        {
+            EGL_DMA_BUF_PLANE3_FD_EXT,
+            EGL_DMA_BUF_PLANE3_OFFSET_EXT,
+            EGL_DMA_BUF_PLANE3_PITCH_EXT,
+            EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
+            EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
+        },
+    };
+
+    for (plane = 0; plane < num_planes; plane++) fds[plane] = -1;
+#endif
 
     xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
     if (xwl_pixmap == NULL)
@@ -138,10 +187,57 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
     xwl_glamor_egl_make_current(xwl_screen);
     xwl_pixmap->bo = bo;
     xwl_pixmap->buffer = NULL;
-    xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
-                                          xwl_screen->egl_context,
-                                          EGL_NATIVE_PIXMAP_KHR,
-                                          xwl_pixmap->bo, NULL);
+
+#ifdef GBM_BO_FD_FOR_PLANE
+    if (xwl_gbm->dmabuf_capable) {
+#define ADD_ATTR(attrs, num, attr)                                      \
+        do {                                                            \
+            assert(((num) + 1) < (sizeof(attrs) / sizeof((attrs)[0]))); \
+            (attrs)[(num)++] = (attr);                                  \
+        } while (0)
+        ADD_ATTR(img_attrs, attr_num, EGL_WIDTH);
+        ADD_ATTR(img_attrs, attr_num, gbm_bo_get_width(bo));
+        ADD_ATTR(img_attrs, attr_num, EGL_HEIGHT);
+        ADD_ATTR(img_attrs, attr_num, gbm_bo_get_height(bo));
+        ADD_ATTR(img_attrs, attr_num, EGL_LINUX_DRM_FOURCC_EXT);
+        ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo));
+
+        for (plane = 0; plane < num_planes; plane++) {
+            fds[plane] = gbm_bo_get_fd_for_plane(bo, plane);
+            ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]);
+            ADD_ATTR(img_attrs, attr_num, fds[plane]);
+            ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]);
+            ADD_ATTR(img_attrs, attr_num, gbm_bo_get_offset(bo, plane));
+            ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_PITCH]);
+            ADD_ATTR(img_attrs, attr_num, gbm_bo_get_stride_for_plane(bo, plane));
+            ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_LO]);
+            ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier & 0xFFFFFFFFULL));
+            ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_HI]);
+            ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier >> 32ULL));
+        }
+        ADD_ATTR(img_attrs, attr_num, EGL_NONE);
+#undef ADD_ATTR
+
+        xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
+                                              EGL_NO_CONTEXT,
+                                              EGL_LINUX_DMA_BUF_EXT,
+                                              NULL,
+                                              img_attrs);
+
+        for (plane = 0; plane < num_planes; plane++) {
+            close(fds[plane]);
+            fds[plane] = -1;
+        }
+    }
+    else
+#endif
+    {
+        xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
+                                              xwl_screen->egl_context,
+                                              EGL_NATIVE_PIXMAP_KHR,
+                                              xwl_pixmap->bo, NULL);
+    }
+
     if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
       goto error;
 
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index a7fead0d5..6fdfba903 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -443,6 +443,9 @@
 /* GBM has modifiers support */
 #undef GBM_BO_WITH_MODIFIERS
 
+/* GBM has gbm_bo_get_fd_for_plane function */
+#undef GBM_BO_FD_FOR_PLANE
+
 /* Glamor can use eglQueryDmaBuf* functions */
 #undef GLAMOR_HAS_EGL_QUERY_DMABUF
 
diff --git a/include/meson.build b/include/meson.build
index d3f2db840..885b3cef7 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -96,6 +96,8 @@ conf_data.set('GLAMOR_HAS_GBM_LINEAR',
               build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 10.6'))
 conf_data.set('GBM_BO_WITH_MODIFIERS',
               build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 17.1'))
+conf_data.set('GBM_BO_FD_FOR_PLANE',
+              build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 21.1'))
 
 conf_data.set_quoted('SERVER_MISC_CONFIG_PATH', serverconfigdir)
 conf_data.set_quoted('PROJECTROOT', get_option('prefix'))
commit ce6d68d23daa76d03fac3cf878dc4adb32f9fd92
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Sep 16 10:18:03 2021 +0200

    xwayland/shm: Avoid integer overflow on large pixmaps
    
    Xwayland's xwl_shm_create_pixmap() computes the size of the shared
    memory pool to create using a size_t, yet the Wayland protocol uses an
    integer for that size.
    
    If the pool size becomes larger than INT32_MAX, we end up asking Wayland
    to create a shared memory pool of negative size which in turn will raise
    a protocol error which terminates the Wayland connection, and therefore
    Xwayland.
    
    Avoid that issue early by return a NULL pixmap in that case, which will
    trigger a BadAlloc error, but leave Xwayland alive.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 079c5ccbcd07c5e8d51239b79dc3cfed46fef506)

diff --git a/hw/xwayland/xwayland-shm.c b/hw/xwayland/xwayland-shm.c
index cf7e97ca3..ff128316d 100644
--- a/hw/xwayland/xwayland-shm.c
+++ b/hw/xwayland/xwayland-shm.c
@@ -234,6 +234,15 @@ xwl_shm_create_pixmap(ScreenPtr screen,
         (width == 0 && height == 0) || depth < 15)
         return fbCreatePixmap(screen, width, height, depth, hint);
 
+    stride = PixmapBytePad(width, depth);
+    size = stride * height;
+    /* Size in the protocol is an integer, make sure we don't exceed
+     * INT32_MAX or else the Wayland compositor will raise an error and
+     * kill the Wayland connection!
+     */
+    if (size > INT32_MAX)
+        return NULL;
+
     pixmap = fbCreatePixmap(screen, 0, 0, depth, hint);
     if (!pixmap)
         return NULL;
@@ -242,8 +251,6 @@ xwl_shm_create_pixmap(ScreenPtr screen,
     if (xwl_pixmap == NULL)
         goto err_destroy_pixmap;
 
-    stride = PixmapBytePad(width, depth);
-    size = stride * height;
     xwl_pixmap->buffer = NULL;
     xwl_pixmap->size = size;
     fd = os_create_anonymous_file(size);
commit 588d127c5448a43848b217c290c76fc415554667
Author: Povilas Kanapickas <povilas at radix.lt>
Date:   Mon Sep 6 22:41:32 2021 +0300

    glamor: Fix handling of 1-bit pixmaps
    
    Since 8702c938b33b9ec180d64754eb922515c7c4a98b the pixmap formats are
    handled in a single place. In the process of conversion the difference
    between pixmap formats that can be uploaded and those that can be
    rendered on GL side has been lost. This affects only 1-bit pixmaps: as
    they aren't supported on GL, but can be converted to a R8 or A8 format
    for rendering (see glamor_get_tex_format_type_from_pictformat()).
    
    To work around this we add a separate flag that specifies whether the
    format actually supports rendering in GL, convert all checks to use this
    flag and then add 1-bit pixmap formats that don't support rendering in
    GL.
    
    Fixes: 8702c938b33b9ec180d64754eb922515c7c4a98b
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1210
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>
    Tested-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Povilas Kanapickas <povilas at radix.lt>
    (cherry picked from commit e59e24c8779de65db87b8c07bc3f2abb479be082)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b8406f42d..177871a10 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -216,7 +216,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
              w <= glamor_priv->glyph_max_dim &&
              h <= glamor_priv->glyph_max_dim)
          || (w == 0 && h == 0)
-         || !glamor_priv->formats[depth].format))
+         || !glamor_priv->formats[depth].rendering_supported))
         return fbCreatePixmap(screen, w, h, depth, usage);
     else
         pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
@@ -461,7 +461,8 @@ glamor_format_for_pixmap(PixmapPtr pixmap)
 
 static void
 glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
-                  GLenum internalformat, GLenum format, GLenum type)
+                  GLenum internalformat, GLenum format, GLenum type,
+                  Bool rendering_supported)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     struct glamor_format *f = &glamor_priv->formats[depth];
@@ -476,7 +477,7 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
      * Note that we can't just create a pixmap because we're in
      * screeninit.
      */
-    if (glamor_priv->is_gles) {
+    if (rendering_supported && glamor_priv->is_gles) {
         unsigned fbo, tex;
         int read_format, read_type;
         GLenum status;
@@ -521,6 +522,7 @@ glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
     f->internalformat = internalformat;
     f->format = format;
     f->type = type;
+    f->rendering_supported = rendering_supported;
 }
 
 /* Set up the GL format/types that glamor will use for the various depths
@@ -551,11 +553,15 @@ glamor_setup_formats(ScreenPtr screen)
      * only falling back to a8 if we can't do them.
      */
     if (glamor_priv->is_gles || epoxy_has_gl_extension("GL_ARB_texture_rg")) {
+        glamor_add_format(screen, 1, PICT_a1,
+                          GL_R8, GL_RED, GL_UNSIGNED_BYTE, FALSE);
         glamor_add_format(screen, 8, PICT_a8,
-                          GL_R8, GL_RED, GL_UNSIGNED_BYTE);
+                          GL_R8, GL_RED, GL_UNSIGNED_BYTE, TRUE);
     } else {
+        glamor_add_format(screen, 1, PICT_a1,
+                          GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, FALSE);
         glamor_add_format(screen, 8, PICT_a8,
-                          GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
+                          GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, TRUE);
     }
 
     if (glamor_priv->is_gles) {
@@ -569,40 +575,41 @@ glamor_setup_formats(ScreenPtr screen)
          * disable render accel for now.
          */
         glamor_add_format(screen, 15, PICT_x1r5g5b5,
-                          GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
+                          GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, TRUE);
     } else {
         glamor_add_format(screen, 15, PICT_x1r5g5b5,
-                          GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
+                          GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, TRUE);
     }
 
     glamor_add_format(screen, 16, PICT_r5g6b5,
-                      GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
+                      GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, TRUE);
 
     if (glamor_priv->is_gles) {
         assert(X_BYTE_ORDER == X_LITTLE_ENDIAN);
         glamor_add_format(screen, 24, PICT_x8b8g8r8,
-                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
+                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, TRUE);
         glamor_add_format(screen, 32, PICT_a8b8g8r8,
-                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
+                          GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, TRUE);
     } else {
         glamor_add_format(screen, 24, PICT_x8r8g8b8,
-                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
+                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, TRUE);
         glamor_add_format(screen, 32, PICT_a8r8g8b8,
-                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
+                          GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, TRUE);
     }
 
     if (glamor_priv->is_gles) {
         glamor_add_format(screen, 30, PICT_x2b10g10r10,
-                          GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
+                          GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, TRUE);
     } else {
         glamor_add_format(screen, 30, PICT_x2r10g10b10,
-                          GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV);
+                          GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, TRUE);
     }
 
     glamor_priv->cbcr_format.depth = 16;
     glamor_priv->cbcr_format.internalformat = GL_RG8;
     glamor_priv->cbcr_format.format = GL_RG;
     glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
+    glamor_priv->cbcr_format.rendering_supported = TRUE;
 }
 
 /** Set up glamor for an already-configured GL context. */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 6ccc1c04c..5662ecb2c 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -170,6 +170,11 @@ struct glamor_format {
      * transferred using format/type.
      */
     CARD32 render_format;
+    /**
+     * Whether rendering is supported in GL at all (i.e. without pixel data conversion
+     * just before upload)
+     */
+    Bool rendering_supported;
 };
 
 struct glamor_saved_procs {
@@ -215,6 +220,11 @@ typedef struct glamor_screen_private {
     Bool can_copyplane;
     int max_fbo_size;
 
+    /**
+     * Stores information about supported formats. Note, that this list contains all
+     * supported pixel formats, including these that are not supported on GL side
+     * directly, but are converted to another format instead.
+     */
     struct glamor_format formats[33];
     struct glamor_format cbcr_format;
 
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index be0741a99..2af65bf93 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -773,14 +773,19 @@ glamor_render_format_is_supported(PicturePtr picture)
 {
     PictFormatShort storage_format;
     glamor_screen_private *glamor_priv;
+    struct glamor_format *f;
 
     /* Source-only pictures should always work */
     if (!picture->pDrawable)
         return TRUE;
 
     glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
-    storage_format =
-        glamor_priv->formats[picture->pDrawable->depth].render_format;
+    f = &glamor_priv->formats[picture->pDrawable->depth];
+
+    if (!f->rendering_supported)
+        return FALSE;
+
+    storage_format = f->render_format;
 
     switch (picture->format) {
     case PICT_a2r10g10b10:
commit 9521820e7b15d9a90ab28dd389653b85b8f9abf3
Author: Simon Ser <contact at emersion.fr>
Date:   Mon Jul 5 15:30:16 2021 +0200

    xwayland: fix xdg_output leak
    
    The xdg_output wasn't cleaned up when destroying the xwl_output.
    
    Signed-off-by: Simon Ser <contact at emersion.fr>
    (cherry picked from commit 6f63873da55de33e51c1f6849a65501e380f19bc)

diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c
index 52c505057..ef705bc01 100644
--- a/hw/xwayland/xwayland-output.c
+++ b/hw/xwayland/xwayland-output.c
@@ -701,6 +701,8 @@ err:
 void
 xwl_output_destroy(struct xwl_output *xwl_output)
 {
+    if (xwl_output->xdg_output)
+        zxdg_output_v1_destroy(xwl_output->xdg_output);
     wl_output_destroy(xwl_output->output);
     free(xwl_output);
 }


More information about the xorg-commit mailing list