Blame SOURCES/0004-xwayland-implement-pixmap_from_buffers-for-the-eglst.patch

4c4b8b
From 6d1529b8d6b3e7c8bf758b670e2122a6af4d5346 Mon Sep 17 00:00:00 2001
4c4b8b
From: Erik Kurzinger <ekurzinger@nvidia.com>
4c4b8b
Date: Thu, 3 Dec 2020 14:57:51 -0800
4c4b8b
Subject: [PATCH xserver 04/27] xwayland: implement pixmap_from_buffers for the
4c4b8b
 eglstream backend
4c4b8b
MIME-Version: 1.0
4c4b8b
Content-Type: text/plain; charset=UTF-8
4c4b8b
Content-Transfer-Encoding: 8bit
4c4b8b
4c4b8b
Provides an implementation for the pixmap_from_buffers DRI3 function for
4c4b8b
xwayland's eglstream backend. This will be used by the NVIDIA GLX driver
4c4b8b
to pass buffers from client applications to the server. These can then
4c4b8b
be presented using the PRESENT extension.
4c4b8b
4c4b8b
To hopefully make this less error-prone, we also introduce a "type"
4c4b8b
field for this struct to distinguish between xwl_pixmaps for the new
4c4b8b
DRI3-created pixmaps and those for the existing glamor-created pixmaps.
4c4b8b
4c4b8b
Additionally, the patch enables wnmd present mode with the eglstream backend.
4c4b8b
This involves creating a wl_buffer for the provided dma-buf before importing it
4c4b8b
into EGL and passing this to the compositor so it can be scanned out directly
4c4b8b
if possible.
4c4b8b
4c4b8b
Since both backends now support this present mode, the HAS_PRESENT_FLIP flag is
4c4b8b
no longer needed, so it can be removed.
4c4b8b
4c4b8b
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
4c4b8b
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
4c4b8b
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
4c4b8b
(cherry picked from commit 38e875904b039ec1889e7c81eb1d577a4f69b26d)
4c4b8b
---
4c4b8b
 hw/xwayland/xwayland-glamor-eglstream.c | 202 +++++++++++++++++++++++-
4c4b8b
 hw/xwayland/xwayland-glamor-gbm.c       |   3 +-
4c4b8b
 hw/xwayland/xwayland-glamor.c           |  12 --
4c4b8b
 hw/xwayland/xwayland-glamor.h           |   6 +-
4c4b8b
 hw/xwayland/xwayland-present.c          |   5 +-
4c4b8b
 5 files changed, 204 insertions(+), 24 deletions(-)
4c4b8b
4c4b8b
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
index ccaa59cbe..2d8380e1f 100644
4c4b8b
--- a/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
4c4b8b
@@ -37,6 +37,8 @@
4c4b8b
 #include <glamor_transfer.h>
4c4b8b
 
4c4b8b
 #include <xf86drm.h>
4c4b8b
+#include <dri3.h>
4c4b8b
+#include <drm_fourcc.h>
4c4b8b
 
4c4b8b
 #include <epoxy/egl.h>
4c4b8b
 
4c4b8b
@@ -47,6 +49,7 @@
4c4b8b
 
4c4b8b
 #include "wayland-eglstream-client-protocol.h"
4c4b8b
 #include "wayland-eglstream-controller-client-protocol.h"
4c4b8b
+#include "linux-dmabuf-unstable-v1-client-protocol.h"
4c4b8b
 
4c4b8b
 struct xwl_eglstream_pending_stream {
4c4b8b
     PixmapPtr pixmap;
4c4b8b
@@ -80,12 +83,23 @@ struct xwl_eglstream_private {
4c4b8b
     GLuint blit_is_rgba_pos;
4c4b8b
 };
4c4b8b
 
4c4b8b
+enum xwl_pixmap_type {
4c4b8b
+    XWL_PIXMAP_EGLSTREAM, /* Pixmaps created by glamor. */
4c4b8b
+    XWL_PIXMAP_DMA_BUF, /* Pixmaps allocated through DRI3. */
4c4b8b
+};
4c4b8b
+
4c4b8b
 struct xwl_pixmap {
4c4b8b
-    struct wl_buffer *buffer;
4c4b8b
+    enum xwl_pixmap_type type;
4c4b8b
+    /* add any new <= 4-byte member here to avoid holes on 64-bit */
4c4b8b
     struct xwl_screen *xwl_screen;
4c4b8b
+    struct wl_buffer *buffer;
4c4b8b
 
4c4b8b
+    /* XWL_PIXMAP_EGLSTREAM. */
4c4b8b
     EGLStreamKHR stream;
4c4b8b
     EGLSurface surface;
4c4b8b
+
4c4b8b
+    /* XWL_PIXMAP_DMA_BUF. */
4c4b8b
+    EGLImage image;
4c4b8b
 };
4c4b8b
 
4c4b8b
 static DevPrivateKeyRec xwl_eglstream_private_key;
4c4b8b
@@ -289,12 +303,18 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
4c4b8b
                        xwl_screen->egl_context);
4c4b8b
     }
4c4b8b
 
4c4b8b
-    if (xwl_pixmap->surface)
4c4b8b
+    if (xwl_pixmap->surface != EGL_NO_SURFACE)
4c4b8b
         eglDestroySurface(xwl_screen->egl_display, xwl_pixmap->surface);
4c4b8b
 
4c4b8b
-    eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
4c4b8b
+    if (xwl_pixmap->stream != EGL_NO_STREAM_KHR)
4c4b8b
+        eglDestroyStreamKHR(xwl_screen->egl_display, xwl_pixmap->stream);
4c4b8b
+
4c4b8b
+    if (xwl_pixmap->buffer)
4c4b8b
+        wl_buffer_destroy(xwl_pixmap->buffer);
4c4b8b
+
4c4b8b
+    if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
4c4b8b
+        eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
4c4b8b
 
4c4b8b
-    wl_buffer_destroy(xwl_pixmap->buffer);
4c4b8b
     free(xwl_pixmap);
4c4b8b
 }
4c4b8b
 
4c4b8b
@@ -509,9 +529,13 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
4c4b8b
         FatalError("Not enough memory to create pixmap\n");
4c4b8b
     xwl_pixmap_set_private(pixmap, xwl_pixmap);
4c4b8b
 
4c4b8b
+    xwl_pixmap->type = XWL_PIXMAP_EGLSTREAM;
4c4b8b
+    xwl_pixmap->image = EGL_NO_IMAGE;
4c4b8b
+
4c4b8b
     xwl_glamor_egl_make_current(xwl_screen);
4c4b8b
 
4c4b8b
     xwl_pixmap->xwl_screen = xwl_screen;
4c4b8b
+    xwl_pixmap->surface = EGL_NO_SURFACE;
4c4b8b
     xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
4c4b8b
     stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
4c4b8b
                                               xwl_pixmap->stream);
4c4b8b
@@ -552,6 +576,7 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
4c4b8b
     struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
4c4b8b
 
4c4b8b
     if (xwl_pixmap) {
4c4b8b
+        assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
4c4b8b
         if (pending) {
4c4b8b
             /* Wait for the compositor to finish connecting the consumer for
4c4b8b
              * this eglstream */
4c4b8b
@@ -590,6 +615,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
4c4b8b
     };
4c4b8b
     GLint saved_vao;
4c4b8b
 
4c4b8b
+    assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
4c4b8b
+
4c4b8b
     /* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
4c4b8b
      * won't actually draw to it
4c4b8b
      */
4c4b8b
@@ -636,7 +663,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
4c4b8b
 static Bool
4c4b8b
 xwl_glamor_eglstream_check_flip(PixmapPtr pixmap)
4c4b8b
 {
4c4b8b
-    return FALSE;
4c4b8b
+    return xwl_pixmap_get(pixmap)->type == XWL_PIXMAP_DMA_BUF;
4c4b8b
 }
4c4b8b
 
4c4b8b
 static void
4c4b8b
@@ -681,6 +708,9 @@ xwl_glamor_eglstream_init_wl_registry(struct xwl_screen *xwl_screen,
4c4b8b
         xwl_eglstream->controller = wl_registry_bind(
4c4b8b
             wl_registry, id, &wl_eglstream_controller_interface, version);
4c4b8b
         return TRUE;
4c4b8b
+    } else if (strcmp(name, "zwp_linux_dmabuf_v1") == 0) {
4c4b8b
+        xwl_screen_set_dmabuf_interface(xwl_screen, id, version);
4c4b8b
+        return TRUE;
4c4b8b
     }
4c4b8b
 
4c4b8b
     /* no match */
4c4b8b
@@ -779,6 +809,163 @@ xwl_eglstream_init_shaders(struct xwl_screen *xwl_screen)
4c4b8b
         glGetUniformLocation(xwl_eglstream->blit_prog, "is_rgba");
4c4b8b
 }
4c4b8b
 
4c4b8b
+static int
4c4b8b
+xwl_dri3_open_client(ClientPtr client,
4c4b8b
+                     ScreenPtr screen,
4c4b8b
+                     RRProviderPtr provider,
4c4b8b
+                     int *pfd)
4c4b8b
+{
4c4b8b
+    /* Not supported with this backend. */
4c4b8b
+    return BadImplementation;
4c4b8b
+}
4c4b8b
+
4c4b8b
+static PixmapPtr
4c4b8b
+xwl_dri3_pixmap_from_fds(ScreenPtr screen,
4c4b8b
+                         CARD8 num_fds, const int *fds,
4c4b8b
+                         CARD16 width, CARD16 height,
4c4b8b
+                         const CARD32 *strides, const CARD32 *offsets,
4c4b8b
+                         CARD8 depth, CARD8 bpp,
4c4b8b
+                         uint64_t modifier)
4c4b8b
+{
4c4b8b
+    PixmapPtr pixmap;
4c4b8b
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
4c4b8b
+    struct xwl_pixmap *xwl_pixmap;
4c4b8b
+    unsigned int texture;
4c4b8b
+    EGLint image_attribs[48];
4c4b8b
+    uint32_t mod_hi = modifier >> 32, mod_lo = modifier & 0xffffffff, format;
4c4b8b
+    int attrib = 0, i;
4c4b8b
+    struct zwp_linux_buffer_params_v1 *params;
4c4b8b
+
4c4b8b
+    format = wl_drm_format_for_depth(depth);
4c4b8b
+    if (!xwl_glamor_is_modifier_supported(xwl_screen, format, modifier)) {
4c4b8b
+        ErrorF("glamor: unsupported format modifier\n");
4c4b8b
+        return NULL;
4c4b8b
+    }
4c4b8b
+
4c4b8b
+    xwl_pixmap = calloc(1, sizeof (*xwl_pixmap));
4c4b8b
+    if (!xwl_pixmap)
4c4b8b
+        return NULL;
4c4b8b
+    xwl_pixmap->type = XWL_PIXMAP_DMA_BUF;
4c4b8b
+    xwl_pixmap->xwl_screen = xwl_screen;
4c4b8b
+
4c4b8b
+    xwl_pixmap->buffer = NULL;
4c4b8b
+    xwl_pixmap->stream = EGL_NO_STREAM_KHR;
4c4b8b
+    xwl_pixmap->surface = EGL_NO_SURFACE;
4c4b8b
+
4c4b8b
+    params = zwp_linux_dmabuf_v1_create_params(xwl_screen->dmabuf);
4c4b8b
+    for (i = 0; i < num_fds; i++) {
4c4b8b
+        zwp_linux_buffer_params_v1_add(params, fds[i], i,
4c4b8b
+                                       offsets[i], strides[i],
4c4b8b
+                                       mod_hi, mod_lo);
4c4b8b
+    }
4c4b8b
+    xwl_pixmap->buffer =
4c4b8b
+        zwp_linux_buffer_params_v1_create_immed(params, width, height,
4c4b8b
+                                                format, 0);
4c4b8b
+    zwp_linux_buffer_params_v1_destroy(params);
4c4b8b
+
4c4b8b
+
4c4b8b
+    image_attribs[attrib++] = EGL_WIDTH;
4c4b8b
+    image_attribs[attrib++] = width;
4c4b8b
+    image_attribs[attrib++] = EGL_HEIGHT;
4c4b8b
+    image_attribs[attrib++] = height;
4c4b8b
+    image_attribs[attrib++] = EGL_LINUX_DRM_FOURCC_EXT;
4c4b8b
+    image_attribs[attrib++] = drm_format_for_depth(depth, bpp);
4c4b8b
+
4c4b8b
+    if (num_fds > 0) {
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_FD_EXT;
4c4b8b
+        image_attribs[attrib++] = fds[0];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
4c4b8b
+        image_attribs[attrib++] = offsets[0];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
4c4b8b
+        image_attribs[attrib++] = strides[0];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_hi;
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_lo;
4c4b8b
+    }
4c4b8b
+    if (num_fds > 1) {
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_FD_EXT;
4c4b8b
+        image_attribs[attrib++] = fds[1];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
4c4b8b
+        image_attribs[attrib++] = offsets[1];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
4c4b8b
+        image_attribs[attrib++] = strides[1];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_hi;
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_lo;
4c4b8b
+    }
4c4b8b
+    if (num_fds > 2) {
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_FD_EXT;
4c4b8b
+        image_attribs[attrib++] = fds[2];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
4c4b8b
+        image_attribs[attrib++] = offsets[2];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
4c4b8b
+        image_attribs[attrib++] = strides[2];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_hi;
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_lo;
4c4b8b
+    }
4c4b8b
+    if (num_fds > 3) {
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_FD_EXT;
4c4b8b
+        image_attribs[attrib++] = fds[3];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
4c4b8b
+        image_attribs[attrib++] = offsets[3];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
4c4b8b
+        image_attribs[attrib++] = strides[3];
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_hi;
4c4b8b
+        image_attribs[attrib++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
4c4b8b
+        image_attribs[attrib++] = mod_lo;
4c4b8b
+    }
4c4b8b
+    image_attribs[attrib++] = EGL_NONE;
4c4b8b
+
4c4b8b
+    xwl_glamor_egl_make_current(xwl_screen);
4c4b8b
+
4c4b8b
+    /* eglCreateImageKHR will close fds */
4c4b8b
+    xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
4c4b8b
+                                          EGL_NO_CONTEXT,
4c4b8b
+                                          EGL_LINUX_DMA_BUF_EXT,
4c4b8b
+                                          NULL, image_attribs);
4c4b8b
+    if (xwl_pixmap->image == EGL_NO_IMAGE_KHR) {
4c4b8b
+        ErrorF("eglCreateImageKHR failed!\n");
4c4b8b
+        if (xwl_pixmap->buffer)
4c4b8b
+            wl_buffer_destroy(xwl_pixmap->buffer);
4c4b8b
+        free(xwl_pixmap);
4c4b8b
+        return NULL;
4c4b8b
+    }
4c4b8b
+
4c4b8b
+    glGenTextures(1, &texture);
4c4b8b
+    glBindTexture(GL_TEXTURE_2D, texture);
4c4b8b
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4c4b8b
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4c4b8b
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
4c4b8b
+    glBindTexture(GL_TEXTURE_2D, 0);
4c4b8b
+
4c4b8b
+    pixmap = glamor_create_pixmap(screen, width, height, depth,
4c4b8b
+                                  GLAMOR_CREATE_PIXMAP_NO_TEXTURE);
4c4b8b
+    glamor_set_pixmap_texture(pixmap, texture);
4c4b8b
+    glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
4c4b8b
+    wl_buffer_add_listener(xwl_pixmap->buffer,
4c4b8b
+                           &xwl_eglstream_buffer_release_listener,
4c4b8b
+                           pixmap);
4c4b8b
+    xwl_pixmap_set_private(pixmap, xwl_pixmap);
4c4b8b
+
4c4b8b
+    return pixmap;
4c4b8b
+}
4c4b8b
+
4c4b8b
+static const dri3_screen_info_rec xwl_dri3_info = {
4c4b8b
+    .version = 2,
4c4b8b
+    .open = NULL,
4c4b8b
+    .pixmap_from_fds = xwl_dri3_pixmap_from_fds,
4c4b8b
+    .fds_from_pixmap = NULL,
4c4b8b
+    .open_client = xwl_dri3_open_client,
4c4b8b
+    .get_formats = xwl_glamor_get_formats,
4c4b8b
+    .get_modifiers = xwl_glamor_get_modifiers,
4c4b8b
+    .get_drawable_modifiers = glamor_get_drawable_modifiers,
4c4b8b
+};
4c4b8b
+
4c4b8b
 static Bool
4c4b8b
 xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
4c4b8b
 {
4c4b8b
@@ -858,6 +1045,11 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
4c4b8b
 
4c4b8b
     xwl_eglstream_init_shaders(xwl_screen);
4c4b8b
 
4c4b8b
+    if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
4c4b8b
+        !dri3_screen_init(xwl_screen->screen, &xwl_dri3_info)) {
4c4b8b
+        ErrorF("DRI3 initialization failed. Performance will be affected.\n");
4c4b8b
+    }
4c4b8b
+
4c4b8b
     return TRUE;
4c4b8b
 error:
4c4b8b
     xwl_eglstream_cleanup(xwl_screen);
4c4b8b
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
4c4b8b
index 1b1d517da..12d820e44 100644
4c4b8b
--- a/hw/xwayland/xwayland-glamor-gbm.c
4c4b8b
+++ b/hw/xwayland/xwayland-glamor-gbm.c
4c4b8b
@@ -969,7 +969,6 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
4c4b8b
     xwl_screen->gbm_backend.get_wl_buffer_for_pixmap = xwl_glamor_gbm_get_wl_buffer_for_pixmap;
4c4b8b
     xwl_screen->gbm_backend.check_flip = NULL;
4c4b8b
     xwl_screen->gbm_backend.is_available = TRUE;
4c4b8b
-    xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_HAS_PRESENT_FLIP |
4c4b8b
-                                            XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
4c4b8b
+    xwl_screen->gbm_backend.backend_flags = XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH |
4c4b8b
                                             XWL_EGL_BACKEND_NEEDS_N_BUFFERING;
4c4b8b
 }
4c4b8b
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
4c4b8b
index 060471f01..9e44d5106 100644
4c4b8b
--- a/hw/xwayland/xwayland-glamor.c
4c4b8b
+++ b/hw/xwayland/xwayland-glamor.c
4c4b8b
@@ -362,16 +362,6 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
4c4b8b
     return 0;
4c4b8b
 }
4c4b8b
 
4c4b8b
-Bool
4c4b8b
-xwl_glamor_has_present_flip(struct xwl_screen *xwl_screen)
4c4b8b
-{
4c4b8b
-    if (!xwl_screen->glamor || !xwl_screen->egl_backend)
4c4b8b
-        return FALSE;
4c4b8b
-
4c4b8b
-    return (xwl_screen->egl_backend->backend_flags &
4c4b8b
-                XWL_EGL_BACKEND_HAS_PRESENT_FLIP);
4c4b8b
-}
4c4b8b
-
4c4b8b
 Bool
4c4b8b
 xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen)
4c4b8b
 {
4c4b8b
@@ -430,8 +420,6 @@ xwl_glamor_select_eglstream_backend(struct xwl_screen *xwl_screen)
4c4b8b
 #ifdef XWL_HAS_EGLSTREAM
4c4b8b
     if (xwl_screen->eglstream_backend.is_available &&
4c4b8b
         xwl_glamor_has_wl_interfaces(xwl_screen, &xwl_screen->eglstream_backend)) {
4c4b8b
-        ErrorF("glamor: Using nvidia's EGLStream interface, direct rendering impossible.\n");
4c4b8b
-        ErrorF("glamor: Performance may be affected. Ask your vendor to support GBM!\n");
4c4b8b
         xwl_screen->egl_backend = &xwl_screen->eglstream_backend;
4c4b8b
         return TRUE;
4c4b8b
     }
4c4b8b
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
4c4b8b
index a86b30b40..26ab78f04 100644
4c4b8b
--- a/hw/xwayland/xwayland-glamor.h
4c4b8b
+++ b/hw/xwayland/xwayland-glamor.h
4c4b8b
@@ -34,9 +34,8 @@
4c4b8b
 
4c4b8b
 typedef enum _xwl_egl_backend_flags {
4c4b8b
     XWL_EGL_BACKEND_NO_FLAG = 0,
4c4b8b
-    XWL_EGL_BACKEND_HAS_PRESENT_FLIP = (1 << 0),
4c4b8b
-    XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 1),
4c4b8b
-    XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 2),
4c4b8b
+    XWL_EGL_BACKEND_NEEDS_BUFFER_FLUSH = (1 << 0),
4c4b8b
+    XWL_EGL_BACKEND_NEEDS_N_BUFFERING = (1 << 1),
4c4b8b
 } xwl_egl_backend_flags;
4c4b8b
 
4c4b8b
 struct xwl_egl_backend {
4c4b8b
@@ -122,7 +121,6 @@ void xwl_glamor_post_damage(struct xwl_window *xwl_window,
4c4b8b
                             PixmapPtr pixmap, RegionPtr region);
4c4b8b
 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
4c4b8b
 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
4c4b8b
-Bool xwl_glamor_has_present_flip(struct xwl_screen *xwl_screen);
4c4b8b
 Bool xwl_glamor_needs_buffer_flush(struct xwl_screen *xwl_screen);
4c4b8b
 Bool xwl_glamor_needs_n_buffering(struct xwl_screen *xwl_screen);
4c4b8b
 Bool xwl_glamor_is_modifier_supported(struct xwl_screen *xwl_screen,
4c4b8b
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
4c4b8b
index 666ea15e7..7ba7efc11 100644
4c4b8b
--- a/hw/xwayland/xwayland-present.c
4c4b8b
+++ b/hw/xwayland/xwayland-present.c
4c4b8b
@@ -404,6 +404,9 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
4c4b8b
     if (!xwl_window)
4c4b8b
         return FALSE;
4c4b8b
 
4c4b8b
+    if (!xwl_glamor_check_flip(pixmap))
4c4b8b
+        return FALSE;
4c4b8b
+
4c4b8b
     /* Can't flip if the window pixmap doesn't match the xwl_window parent
4c4b8b
      * window's, e.g. because a client redirected this window or one of its
4c4b8b
      * parents.
4c4b8b
@@ -540,7 +543,7 @@ xwl_present_init(ScreenPtr screen)
4c4b8b
 {
4c4b8b
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
4c4b8b
 
4c4b8b
-    if (!xwl_glamor_has_present_flip(xwl_screen))
4c4b8b
+    if (!xwl_screen->glamor || !xwl_screen->egl_backend)
4c4b8b
         return FALSE;
4c4b8b
 
4c4b8b
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
4c4b8b
-- 
4c4b8b
2.31.1
4c4b8b