426 lines
16 KiB
Diff
426 lines
16 KiB
Diff
|
From 6d1529b8d6b3e7c8bf758b670e2122a6af4d5346 Mon Sep 17 00:00:00 2001
|
||
|
From: Erik Kurzinger <ekurzinger@nvidia.com>
|
||
|
Date: Thu, 3 Dec 2020 14:57:51 -0800
|
||
|
Subject: [PATCH xserver 04/27] xwayland: implement pixmap_from_buffers for the
|
||
|
eglstream backend
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
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@redhat.com>
|
||
|
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
|
||
|
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
|
||
|
(cherry picked from commit 38e875904b039ec1889e7c81eb1d577a4f69b26d)
|
||
|
---
|
||
|
hw/xwayland/xwayland-glamor-eglstream.c | 202 +++++++++++++++++++++++-
|
||
|
hw/xwayland/xwayland-glamor-gbm.c | 3 +-
|
||
|
hw/xwayland/xwayland-glamor.c | 12 --
|
||
|
hw/xwayland/xwayland-glamor.h | 6 +-
|
||
|
hw/xwayland/xwayland-present.c | 5 +-
|
||
|
5 files changed, 204 insertions(+), 24 deletions(-)
|
||
|
|
||
|
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))
|
||
|
--
|
||
|
2.31.1
|
||
|
|