import xorg-x11-server-Xwayland-21.1.1-6.el8

This commit is contained in:
CentOS Sources 2021-11-09 05:01:22 -05:00 committed by Stepan Oksanichenko
commit e959ffdc0a
32 changed files with 3561 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/xwayland-21.1.1.tar.xz

View File

@ -0,0 +1 @@
4eb5e22033c0c80c35480c9466e8041e914cac3a SOURCES/xwayland-21.1.1.tar.xz

View File

@ -0,0 +1,257 @@
From c7853c6de126f6794946c592deed205c0ddad2d9 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 3 Mar 2021 09:55:12 +0100
Subject: [PATCH xserver 01/27] 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@redhat.com>
(cherry picked from commit ae225417c0a0828ffb24e11eb4b968c34692e25a)
---
hw/xwayland/xwayland-glamor-gbm.c | 73 ++---------------------------
hw/xwayland/xwayland-glamor.c | 76 +++++++++++++++++++++++++++++--
hw/xwayland/xwayland-screen.h | 1 +
3 files changed, 76 insertions(+), 74 deletions(-)
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;
--
2.31.1

View File

@ -0,0 +1,36 @@
From 8c74023712a9e0d79ec669738b726e7dc821de68 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 23 Jun 2021 11:35:17 +0200
Subject: [PATCH xserver 1/2] xwayland/eglstream: Keep pending stream if the
pixmap didn't change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the pixmap does not actually change in set_window_pixmap(), there is
no need to invalidate the pending stream, if there's one.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 2be9f795bc15012dc912f595003e01bb6aa66f54)
---
hw/xwayland/xwayland-glamor-eglstream.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 0affc954c..2eae9494c 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -377,7 +377,7 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
* attached, so the stream would be useless.
*/
old_pixmap = (*screen->GetWindowPixmap) (window);
- if (old_pixmap)
+ if (old_pixmap && old_pixmap != pixmap)
xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
--
2.31.1

View File

@ -0,0 +1,292 @@
From d9005a02e9c109e57dcc81b51de3b5778915af26 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 30 Apr 2021 09:56:05 +0200
Subject: [PATCH xserver 2/2] xwayland/eglstream: Remove stream validity
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To avoid an EGL stream in the wrong state, if the window pixmap changed
before the stream was connected, we would still keep the pending stream
but mark it as invalid. Once the callback is received, the pending would
be simply discarded.
But all of this is actually to avoid a bug in egl-wayland, there should
not be any problem with Xwayland destroying an EGL stream while the
compositor is still using it.
With that bug now fixed in egl-wayland 1.1.7, we can safely drop all
that logic from Xwayland EGLstream backend.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1189
(cherry picked from commit 7d509b6f342d9732b567dc4efa867ea24919853b)
---
hw/xwayland/xwayland-glamor-eglstream.c | 165 ++++--------------------
1 file changed, 28 insertions(+), 137 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2eae9494c..8d18caaf5 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -52,15 +52,6 @@
#include "wayland-eglstream-controller-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
-struct xwl_eglstream_pending_stream {
- PixmapPtr pixmap;
- WindowPtr window;
-
- struct wl_callback *cb;
-
- Bool is_valid;
-};
-
struct xwl_eglstream_private {
EGLDeviceEXT egl_device;
struct wl_eglstream_display *display;
@@ -90,7 +81,7 @@ struct xwl_pixmap {
/* add any new <= 4-byte member here to avoid holes on 64-bit */
struct xwl_screen *xwl_screen;
struct wl_buffer *buffer;
- struct xwl_eglstream_pending_stream *pending_stream;
+ struct wl_callback *pending_cb;
Bool wait_for_buffer_release;
/* XWL_PIXMAP_EGLSTREAM. */
@@ -301,20 +292,12 @@ xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
free(xwl_pixmap);
}
-static void
-xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream *pending)
-{
- if (pending->cb)
- wl_callback_destroy(pending->cb);
- free(pending);
-}
-
static void
xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
{
- if (xwl_pixmap->pending_stream) {
- xwl_glamor_eglstream_destroy_pending_stream(xwl_pixmap->pending_stream);
- xwl_pixmap->pending_stream = NULL;
+ if (xwl_pixmap->pending_cb) {
+ wl_callback_destroy(xwl_pixmap->pending_cb);
+ xwl_pixmap->pending_cb = NULL;
}
}
@@ -338,27 +321,13 @@ xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
}
static void
-xwl_eglstream_maybe_set_pending_stream_invalid(PixmapPtr pixmap)
+xwl_eglstream_cancel_pending_stream(PixmapPtr pixmap)
{
struct xwl_pixmap *xwl_pixmap;
- struct xwl_eglstream_pending_stream *pending;
xwl_pixmap = xwl_pixmap_get(pixmap);
- if (!xwl_pixmap)
- return;
-
- pending = xwl_pixmap->pending_stream;
- if (!pending)
- return;
-
- pending->is_valid = FALSE;
-
- /* The compositor may still be using the stream, so we can't destroy
- * it yet. We'll only have a guarantee that the stream is safe to
- * destroy once we receive the pending wl_display_sync() for this
- * stream
- */
- pending->pixmap->refcnt++;
+ if (xwl_pixmap)
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
}
static void
@@ -378,7 +347,7 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
*/
old_pixmap = (*screen->GetWindowPixmap) (window);
if (old_pixmap && old_pixmap != pixmap)
- xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
+ xwl_eglstream_cancel_pending_stream(old_pixmap);
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
(*xwl_screen->screen->SetWindowPixmap)(window, pixmap);
@@ -464,68 +433,19 @@ xwl_eglstream_print_error(EGLDisplay egl_display,
}
}
-/* Because we run asynchronously with our wayland compositor, it's possible
- * that an X client event could cause us to begin creating a stream for a
- * pixmap/window combo before the stream for the pixmap this window
- * previously used has been fully initialized. An example:
- *
- * - Start processing X client events.
- * - X window receives resize event, causing us to create a new pixmap and
- * begin creating the corresponding eglstream. This pixmap is known as
- * pixmap A.
- * - X window receives another resize event, and again changes its current
- * pixmap causing us to create another corresponding eglstream for the same
- * window. This pixmap is known as pixmap B.
- * - Start handling events from the wayland compositor.
- *
- * Since both pixmap A and B will have scheduled wl_display_sync events to
- * indicate when their respective streams are connected, we will receive each
- * callback in the original order the pixmaps were created. This means the
- * following would happen:
- *
- * - Receive pixmap A's stream callback, attach its stream to the surface of
- * the window that just orphaned it.
- * - Receive pixmap B's stream callback, fall over and fail because the
- * window's surface now incorrectly has pixmap A's stream attached to it.
- *
- * We work around this problem by keeping a pending stream associated with
- * the xwl_pixmap, which itself is associated with the window pixmap.
- * In the scenario listed above, this should happen:
- *
- * - Begin processing X events...
- * - A window is resized, a new window pixmap is created causing us to
- * add an eglstream (known as eglstream A) waiting for its consumer
- * to finish attachment.
- * - Resize on same window happens. We invalidate the previously pending
- * stream on the old window pixmap.
- * A new window pixmap is attached to the window and another pending
- * stream is created for that new pixmap (known as eglstream B).
- * - Begin processing Wayland events...
- * - Receive invalidated callback from compositor for eglstream A, destroy
- * stream.
- * - Receive callback from compositor for eglstream B, create producer.
- * - Success!
- */
static void
xwl_eglstream_consumer_ready_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
- struct xwl_eglstream_pending_stream *pending = data;
- PixmapPtr pixmap = pending->pixmap;
+ PixmapPtr pixmap = data;
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
wl_callback_destroy(callback);
- pending->cb = NULL;
-
- if (!pending->is_valid) {
- xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
- dixDestroyPixmap(pixmap, 0);
- return;
- }
+ xwl_pixmap->pending_cb = NULL;
xwl_glamor_egl_make_current(xwl_screen);
@@ -541,42 +461,16 @@ xwl_eglstream_consumer_ready_callback(void *data,
ErrorF("eglstream: Failed to create EGLSurface for pixmap\n");
xwl_eglstream_print_error(xwl_screen->egl_display,
xwl_pixmap->stream, eglGetError());
- goto out;
+ } else {
+ DebugF("eglstream: completes eglstream for pixmap %p, congrats!\n",
+ pixmap);
}
-
- DebugF("eglstream: win %d completes eglstream for pixmap %p, congrats!\n",
- pending->window->drawable.id, pending->pixmap);
-
-out:
- xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
}
static const struct wl_callback_listener consumer_ready_listener = {
xwl_eglstream_consumer_ready_callback
};
-static struct xwl_eglstream_pending_stream *
-xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
-{
- struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
- struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
- struct xwl_eglstream_pending_stream *pending_stream;
-
- DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
- window->drawable.id, pixmap);
-
- pending_stream = calloc(1, sizeof(*pending_stream));
- pending_stream->window = window;
- pending_stream->pixmap = pixmap;
- pending_stream->is_valid = TRUE;
-
- pending_stream->cb = wl_display_sync(xwl_screen->display);
- wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
- pending_stream);
-
- return pending_stream;
-}
-
static void
xwl_eglstream_buffer_release_callback(void *data)
{
@@ -656,9 +550,9 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
wl_eglstream_controller_attach_eglstream_consumer(
xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer);
- xwl_pixmap->pending_stream =
- xwl_eglstream_queue_pending_stream(window, pixmap);
-
+ xwl_pixmap->pending_cb = wl_display_sync(xwl_screen->display);
+ wl_callback_add_listener(xwl_pixmap->pending_cb, &consumer_ready_listener,
+ pixmap);
fail:
if (stream_fd >= 0)
close(stream_fd);
@@ -673,25 +567,22 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap) {
- struct xwl_eglstream_pending_stream *pending = xwl_pixmap->pending_stream;
-
- if (pending) {
+ if (xwl_pixmap->pending_cb) {
/* Wait for the compositor to finish connecting the consumer for
* this eglstream */
- assert(pending->is_valid);
-
return FALSE;
- } else {
- if (xwl_pixmap->surface != EGL_NO_SURFACE ||
- xwl_pixmap->type == XWL_PIXMAP_DMA_BUF)
- return TRUE;
-
- /* The pending stream got removed, we have a xwl_pixmap and
- * yet we do not have a surface.
- * So something went wrong with the surface creation, retry.
- */
- xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
}
+
+ if (xwl_pixmap->surface != EGL_NO_SURFACE ||
+ xwl_pixmap->type == XWL_PIXMAP_DMA_BUF) {
+ return TRUE;
+ }
+
+ /* The pending stream got removed, we have a xwl_pixmap and
+ * yet we do not have a surface.
+ * So something went wrong with the surface creation, retry.
+ */
+ xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
}
/* Glamor pixmap has no backing stream yet; begin making one and disallow
--
2.31.1

View File

@ -0,0 +1,330 @@
From ec91c17a881eaf69c4109f050e7bb9928906c52e Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Fri, 12 Feb 2021 12:09:27 -0800
Subject: [PATCH xserver 02/27] xwayland: move formats and modifiers functions
to common glamor code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit 400d4d0fdd55192f394e1a8273dfb2423c895ec0)
---
hw/xwayland/xwayland-glamor-gbm.c | 115 ++----------------------------
hw/xwayland/xwayland-glamor.c | 111 ++++++++++++++++++++++++++++
hw/xwayland/xwayland-glamor.h | 8 ++-
3 files changed, 123 insertions(+), 111 deletions(-)
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 */
--
2.31.1

View File

@ -0,0 +1,112 @@
From c42d3e8edc85856f95c971d5fbc5d59011c23cdc Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Wed, 3 Mar 2021 11:56:41 +0100
Subject: [PATCH xserver 03/27] xwayland: Add check_flip() glamor backend
function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit bc99dd2127f12f1aae55971c09a2792eeaa98444)
---
hw/xwayland/xwayland-glamor-eglstream.c | 7 +++++++
hw/xwayland/xwayland-glamor-gbm.c | 1 +
hw/xwayland/xwayland-glamor.c | 11 +++++++++++
hw/xwayland/xwayland-glamor.h | 6 ++++++
4 files changed, 25 insertions(+)
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 */
--
2.31.1

View File

@ -0,0 +1,425 @@
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

View File

@ -0,0 +1,61 @@
From 43d1648dc71d01628a6a65a62364c1a3994a88a8 Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Tue, 27 Apr 2021 07:23:44 -0400
Subject: [PATCH xserver 05/27] xwayland-eglstream: fix X11 rendering to
flipping GL / VK window
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a window is being used for direct rendering with OpenGL or Vulkan, and is
using the flipping path for presentation, it's pixmap will be set to a dma-buf
backed pixmap created by the client-side GL driver. However, this means that
xwl_glamor_eglstream_post_damage won't work since it requires that the pixmap
has an EGLSurface that it can render to, which dma-buf backed pixmaps do not.
In this case, though, xwl_glamor_eglstream_post_damage is not necessary since
glamor will have rendered directly to the pixmap, so we can simply pass it
directly to the compositor. There's no need for the intermediate copy we
normally do in that function.
Therefore, this change adds an early-return case to post_damage for dma-buf
backed pixmaps, and removes the corresponding asserts from that function and
allow_commits.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 4f6fbd5009ae533cf0b3bbe382502254f9276a01)
---
hw/xwayland/xwayland-glamor-eglstream.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2d8380e1f..17295f3bd 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -576,7 +576,6 @@ 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 */
@@ -615,7 +614,12 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
};
GLint saved_vao;
- assert(xwl_pixmap->type == XWL_PIXMAP_EGLSTREAM);
+ if (xwl_pixmap->type != XWL_PIXMAP_EGLSTREAM)
+ /* This can happen if a client does X11 rendering on a
+ * flipping OpenGL or Vulkan window. In that case, we don't
+ * need to do the copy below.
+ */
+ return;
/* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
* won't actually draw to it
--
2.31.1

View File

@ -0,0 +1,53 @@
From 95224f0f92bc516983038a6326fba041cdef6e75 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 29 Mar 2021 14:22:56 +0200
Subject: [PATCH xserver 06/27] xwayland/eglstream: Check buffer creation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
EGLStream wl_eglstream_display_create_stream() may fail, yet Xwayland
would try to attach the buffer which may cause a fatal Wayland protocol
error raised by the compositor.
Check if the buffer creation worked, and fail gracefully otherwise (like
wayland-eglsurface does).
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 4f0889e98306d30a37aba0fadb1fd3790c13205a)
---
hw/xwayland/xwayland-glamor-eglstream.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 17295f3bd..c6e17bf8b 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -548,6 +548,10 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
stream_fd,
WL_EGLSTREAM_HANDLE_TYPE_FD,
&stream_attribs);
+ if (!xwl_pixmap->buffer) {
+ ErrorF("eglstream: Failed to create buffer\n");
+ goto fail;
+ }
wl_buffer_add_listener(xwl_pixmap->buffer,
&xwl_eglstream_buffer_release_listener,
@@ -562,7 +566,9 @@ xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
- close(stream_fd);
+fail:
+ if (stream_fd >= 0)
+ close(stream_fd);
}
static Bool
--
2.31.1

View File

@ -0,0 +1,88 @@
From 8a07b3e391bbed0b7d8f2ed37928b362eec3beee Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 29 Mar 2021 15:01:15 +0200
Subject: [PATCH xserver 07/27] xwayland: Check buffer prior to attaching it
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the buffer is NULL, do not even try to attach it, and risk a Wayland
protocol error which would be fatal to us.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 25d2f4948f0abd39e099b8ac69b7cb1dab38a10a)
---
hw/xwayland/xwayland-cursor.c | 11 +++++++++--
hw/xwayland/xwayland-present.c | 7 ++++++-
hw/xwayland/xwayland-window.c | 5 +++++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index fac8840e6..c4457cc2a 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -162,8 +162,15 @@ static void
xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
struct xwl_cursor *xwl_cursor, PixmapPtr pixmap)
{
- wl_surface_attach(xwl_cursor->surface,
- xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0);
+ struct wl_buffer *buffer;
+
+ buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
+ if (!buffer) {
+ ErrorF("cursor: Error getting buffer\n");
+ return;
+ }
+
+ wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
xwl_seat->x_cursor->bits->width,
xwl_seat->x_cursor->bits->height);
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 7ba7efc11..83d67517a 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -443,6 +443,12 @@ xwl_present_flip(WindowPtr present_window,
if (!xwl_window)
return FALSE;
+ buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
+ if (!buffer) {
+ ErrorF("present: Error getting buffer\n");
+ return FALSE;
+ }
+
damage_box = RegionExtents(damage);
event = malloc(sizeof *event);
@@ -450,7 +456,6 @@ xwl_present_flip(WindowPtr present_window,
return FALSE;
pixmap->refcnt++;
- buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
event->event_id = event_id;
event->xwl_present_window = xwl_present_window;
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index d0c7c581d..af4290ec7 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -805,6 +805,11 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
#endif
buffer = xwl_shm_pixmap_get_wl_buffer(pixmap);
+ if (!buffer) {
+ ErrorF("Error getting buffer\n");
+ return;
+ }
+
#ifdef XWL_HAS_GLAMOR
if (xwl_screen->glamor)
xwl_glamor_post_damage(xwl_window, pixmap, region);
--
2.31.1

View File

@ -0,0 +1,38 @@
From 85638273f23338d06776cdb7bb422440f690038a Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 30 Mar 2021 08:48:25 +0200
Subject: [PATCH xserver 08/27] glamor: Dump backtrace on GL error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currrently, when a GL error is triggered, glamor would log the error
which may not be sufficient to trace it back to the cause of the error.
Also dump the backtrace which may give more information as to where the
error comes from.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 3b265c59a6456f6e4abfb9e1694237bc56f1776a)
---
glamor/glamor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 3baef4b9f..b8406f42d 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -414,6 +414,7 @@ glamor_debug_output_callback(GLenum source,
LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
screen->myNum, length, message);
+ xorg_backtrace();
}
/**
--
2.31.1

View File

@ -0,0 +1,125 @@
From c28bb0e879775aec83f5554522724eee592685dc Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 31 Mar 2021 13:57:45 +0200
Subject: [PATCH xserver 09/27] xwayland/glamor: Add return status to
post_damage
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the glamor backend failed to post damage, the caller should do the
same to avoid a failure to attach the buffer to the Wayland surface.
Change the API of Xwayland's glamor backend post_damage() to return a
status so that xwl_window_post_damage() can tell whether the callee
failed.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 252cbad316f43edc08aa5c844789398a58ba270c)
---
hw/xwayland/xwayland-glamor-eglstream.c | 6 ++++--
hw/xwayland/xwayland-glamor.c | 6 ++++--
hw/xwayland/xwayland-glamor.h | 4 ++--
hw/xwayland/xwayland-window.c | 8 ++++++--
4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index c6e17bf8b..f64d05064 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -605,7 +605,7 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
return FALSE;
}
-static void
+static Bool
xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region)
{
@@ -625,7 +625,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
* flipping OpenGL or Vulkan window. In that case, we don't
* need to do the copy below.
*/
- return;
+ return TRUE;
/* Unbind the framebuffer BEFORE binding the EGLSurface, otherwise we
* won't actually draw to it
@@ -668,6 +668,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
/* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++;
+
+ return TRUE;
}
static Bool
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 9e44d5106..e940f9fd7 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -304,14 +304,16 @@ xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap)
return NULL;
}
-void
+Bool
xwl_glamor_post_damage(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
if (xwl_screen->egl_backend->post_damage)
- xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
+ return xwl_screen->egl_backend->post_damage(xwl_window, pixmap, region);
+
+ return TRUE;
}
Bool
diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h
index 26ab78f04..cf3c4fba3 100644
--- a/hw/xwayland/xwayland-glamor.h
+++ b/hw/xwayland/xwayland-glamor.h
@@ -83,7 +83,7 @@ struct xwl_egl_backend {
* you should implement blitting from the glamor pixmap to the wayland
* pixmap here. Otherwise, this callback is optional.
*/
- void (*post_damage)(struct xwl_window *xwl_window,
+ Bool (*post_damage)(struct xwl_window *xwl_window,
PixmapPtr pixmap, RegionPtr region);
/* Called by Xwayland to confirm with the egl backend that the given
@@ -117,7 +117,7 @@ void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
uint32_t version);
Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
struct xwl_egl_backend *xwl_egl_backend);
-void xwl_glamor_post_damage(struct xwl_window *xwl_window,
+Bool 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);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index af4290ec7..00f161eda 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -811,8 +811,12 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
}
#ifdef XWL_HAS_GLAMOR
- if (xwl_screen->glamor)
- xwl_glamor_post_damage(xwl_window, pixmap, region);
+ if (xwl_screen->glamor) {
+ if (!xwl_glamor_post_damage(xwl_window, pixmap, region)) {
+ ErrorF("glamor: Failed to post damage\n");
+ return;
+ }
+ }
#endif
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
--
2.31.1

View File

@ -0,0 +1,74 @@
From 070abe64b15db831802a842aa1965403eb24679e Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 31 Mar 2021 09:49:35 +0200
Subject: [PATCH xserver 10/27] xwayland/eglstream: Check framebuffer status
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The EGLStream backend would sometime generate GL errors trying to draw
to the framebuffer, which gives an invalid buffer, which in turn would
generate a Wayland error from the compositor which is fatal to the
client.
Check the framebuffer status and bail out early if it's not complete,
to avoid getting into trouble later.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 85244d2a2081d61a2e4a06e847041f638de01e3f)
---
hw/xwayland/xwayland-glamor-eglstream.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index f64d05064..64fe93b7c 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -619,6 +619,7 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
box->x2 - box->x1, box->y2 - box->y1
};
GLint saved_vao;
+ int status;
if (xwl_pixmap->type != XWL_PIXMAP_EGLSTREAM)
/* This can happen if a client does X11 rendering on a
@@ -652,6 +653,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
glUniform1i(xwl_eglstream->blit_is_rgba_pos,
pixmap->drawable.depth >= 32);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ ErrorF("eglstream: Framebuffer incomplete 0x%X, not posting damage\n", status);
+ status = FALSE;
+ goto out;
+ }
+
/* Blit rendered image into EGLStream surface */
glDrawBuffer(GL_BACK);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -662,14 +670,16 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
else
eglSwapBuffers(xwl_screen->egl_display, xwl_pixmap->surface);
+ /* hang onto the pixmap until the compositor has released it */
+ pixmap->refcnt++;
+ status = TRUE;
+
+out:
/* Restore previous state */
glBindVertexArray(saved_vao);
glBindTexture(GL_TEXTURE_2D, 0);
- /* hang onto the pixmap until the compositor has released it */
- pixmap->refcnt++;
-
- return TRUE;
+ return status;
}
static Bool
--
2.31.1

View File

@ -0,0 +1,138 @@
From 9966356963803db35997f26330fb1245777012a1 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 15 Apr 2021 10:59:36 +0200
Subject: [PATCH xserver 11/27] xwayland/eglstream: Small refactoring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some functions are called "callback" whereas they are not longer
callback functions or "unref" while they no longer deal with a reference
counter anymore, which is quite confusing. Rename those functions to be
more explicit.
Also, the pending streams can be destroyed in different places, move the
common code to separate function to avoid duplicating code and help with
readability of the code.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 823f3254fabd16e5e721da57cd260beac9b8f8bd)
---
hw/xwayland/xwayland-glamor-eglstream.c | 42 ++++++++++++++-----------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 64fe93b7c..9abb7b779 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -287,7 +287,7 @@ xwl_glamor_egl_device_has_egl_extensions(void *device,
}
static void
-xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
+xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
{
struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
@@ -319,7 +319,17 @@ xwl_eglstream_unref_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
}
static void
-xwl_glamor_eglstream_del_pending_stream_cb(struct xwl_pixmap *xwl_pixmap)
+xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream *pending)
+{
+ if (pending->cb)
+ wl_callback_destroy(pending->cb);
+ xwl_eglstream_window_set_pending(pending->window, NULL);
+ xorg_list_del(&pending->link);
+ free(pending);
+}
+
+static void
+xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
{
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_pixmap->xwl_screen);
@@ -328,10 +338,7 @@ xwl_glamor_eglstream_del_pending_stream_cb(struct xwl_pixmap *xwl_pixmap)
xorg_list_for_each_entry(pending,
&xwl_eglstream->pending_streams, link) {
if (pending->xwl_pixmap == xwl_pixmap) {
- wl_callback_destroy(pending->cb);
- xwl_eglstream_window_set_pending(pending->window, NULL);
- xorg_list_del(&pending->link);
- free(pending);
+ xwl_glamor_eglstream_destroy_pending_stream(pending);
break;
}
}
@@ -343,9 +350,9 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap)
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap && pixmap->refcnt == 1) {
- xwl_glamor_eglstream_del_pending_stream_cb(xwl_pixmap);
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
+ xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
xwl_pixmap_del_buffer_release_cb(pixmap);
- xwl_eglstream_unref_pixmap_stream(xwl_pixmap);
}
return glamor_destroy_pixmap(pixmap);
}
@@ -432,8 +439,6 @@ xwl_eglstream_consumer_ready_callback(void *data,
struct xwl_eglstream_pending_stream *pending;
Bool found = FALSE;
- wl_callback_destroy(callback);
-
xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
if (pending->cb == callback) {
found = TRUE;
@@ -442,8 +447,11 @@ xwl_eglstream_consumer_ready_callback(void *data,
}
assert(found);
+ wl_callback_destroy(callback);
+ pending->cb = NULL;
+
if (!pending->is_valid) {
- xwl_eglstream_unref_pixmap_stream(pending->xwl_pixmap);
+ xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
goto out;
}
@@ -462,9 +470,7 @@ xwl_eglstream_consumer_ready_callback(void *data,
pending->window->drawable.id, pending->pixmap);
out:
- xwl_eglstream_window_set_pending(pending->window, NULL);
- xorg_list_del(&pending->link);
- free(pending);
+ xwl_glamor_eglstream_destroy_pending_stream(pending);
}
static const struct wl_callback_listener consumer_ready_listener = {
@@ -514,8 +520,8 @@ static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
};
static void
-xwl_eglstream_create_pending_stream(struct xwl_screen *xwl_screen,
- WindowPtr window, PixmapPtr pixmap)
+xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
+ WindowPtr window, PixmapPtr pixmap)
{
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
@@ -599,8 +605,8 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
/* Glamor pixmap has no backing stream yet; begin making one and disallow
* commits until then
*/
- xwl_eglstream_create_pending_stream(xwl_screen, xwl_window->window,
- pixmap);
+ xwl_eglstream_create_pixmap_and_stream(xwl_screen, xwl_window->window,
+ pixmap);
return FALSE;
}
--
2.31.1

View File

@ -0,0 +1,150 @@
From e8f7568016249822bb95c87447ded6abb724c13b Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 1 Apr 2021 08:46:52 +0200
Subject: [PATCH xserver 12/27] xwayland/eglstream: Add more error checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
eglCreateStreamKHR() can fail and return EGL_NO_STREAM_KHR, in which
case there is no point in trying to create a buffer from it.
Similarly, eglCreateStreamProducerSurfaceKHR() also fail and return
EGL_NO_SURFACE, which in turn will be used in eglMakeCurrent() as
draw/read surface, and therefore would mean no draw/read buffer.
In those cases, log the error, and bail out early. That won't solve the
issue but will help with investigating the root cause of issues with
EGLStream backend.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit cc596bcfb273eeab82ac3d59867668af8bad2abf)
---
hw/xwayland/xwayland-glamor-eglstream.c | 93 +++++++++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 9abb7b779..77b24a4b4 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -387,6 +387,84 @@ xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
xwl_screen->screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
}
+static const char *
+xwl_eglstream_get_error_str(EGLint error)
+{
+ switch (error) {
+ case EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL_BAD_STATE_KHR:
+ return "EGL_BAD_STATE_KHR";
+ case EGL_BAD_STREAM_KHR:
+ return "EGL_BAD_STREAM_KHR";
+ case EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ default:
+ return "Unknown error";
+ }
+}
+
+static const char *
+xwl_eglstream_get_stream_state_str(EGLint state)
+{
+ switch (state) {
+ case EGL_STREAM_STATE_CREATED_KHR:
+ return "EGL_STREAM_STATE_CREATED_KHR";
+ case EGL_STREAM_STATE_CONNECTING_KHR:
+ return "EGL_STREAM_STATE_CONNECTING_KHR";
+ case EGL_STREAM_STATE_EMPTY_KHR:
+ return "EGL_STREAM_STATE_EMPTY_KHR";
+ case EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR:
+ return "EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR";
+ case EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR:
+ return "EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR";
+ case EGL_STREAM_STATE_DISCONNECTED_KHR:
+ return "EGL_STREAM_STATE_DISCONNECTED_KHR";
+ default:
+ return "Unknown state";
+ }
+}
+
+static EGLint
+xwl_eglstream_get_state(EGLDisplay egl_display, EGLStreamKHR egl_stream)
+{
+ EGLint state;
+
+ eglQueryStreamKHR(egl_display, egl_stream, EGL_STREAM_STATE_KHR, &state);
+ if (!eglQueryStreamKHR(egl_display, egl_stream,
+ EGL_STREAM_STATE_KHR, &state)) {
+ EGLint state_error = eglGetError();
+ ErrorF("eglstream: Failed to query state - error 0x%X: %s\n",
+ state_error, xwl_eglstream_get_error_str(state_error));
+ return EGL_FALSE;
+ }
+
+ return state;
+}
+
+
+static void
+xwl_eglstream_print_error(EGLDisplay egl_display,
+ EGLStreamKHR egl_stream, EGLint error)
+{
+ ErrorF("eglstream: error 0x%X: %s\n", error,
+ xwl_eglstream_get_error_str(error));
+
+ if (error == EGL_BAD_STATE_KHR) {
+ EGLint state = xwl_eglstream_get_state(egl_display, egl_stream);
+ ErrorF("eglstream: stream state 0x%X: %s\n", state,
+ xwl_eglstream_get_stream_state_str(state));
+ }
+}
+
/* Because we run asynchronously with our wayland compositor, it's possible
* that an X client event could cause us to begin creating a stream for a
* pixmap/window combo before the stream for the pixmap this window
@@ -466,6 +544,13 @@ xwl_eglstream_consumer_ready_callback(void *data,
EGL_NONE
});
+ if (xwl_pixmap->surface == EGL_NO_SURFACE) {
+ ErrorF("eglstream: Failed to create EGLSurface for pixmap\n");
+ xwl_eglstream_print_error(xwl_screen->egl_display,
+ xwl_pixmap->stream, eglGetError());
+ goto out;
+ }
+
DebugF("eglstream: win %d completes eglstream for pixmap %p, congrats!\n",
pending->window->drawable.id, pending->pixmap);
@@ -543,8 +628,16 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
xwl_pixmap->xwl_screen = xwl_screen;
xwl_pixmap->surface = EGL_NO_SURFACE;
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
+ if (xwl_pixmap->stream == EGL_NO_STREAM_KHR) {
+ ErrorF("eglstream: Couldn't create EGL stream.\n");
+ goto fail;
+ }
stream_fd = eglGetStreamFileDescriptorKHR(xwl_screen->egl_display,
xwl_pixmap->stream);
+ if (stream_fd == EGL_NO_FILE_DESCRIPTOR_KHR) {
+ ErrorF("eglstream: Couldn't get EGL stream file descriptor.\n");
+ goto fail;
+ }
wl_array_init(&stream_attribs);
xwl_pixmap->buffer =
--
2.31.1

View File

@ -0,0 +1,323 @@
From 90188c2648edb137f3564bdea53012355473f105 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 16 Apr 2021 10:38:23 +0200
Subject: [PATCH xserver 13/27] xwayland/eglstream: Dissociate pending stream
from window
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Previously, we would have pending streams associated with top level X11
windows, keeping temporary accounting for the pending streams before
they get fully initialized for the xwl_pixmap which would be associated
with X11 pixmaps.
If the window content changes before the stream is ready, the
corresponding pending stream would be marked as invalid and the pending
stream would be eventually removed once the stream becomes ready.
Since commit affc47452 - "xwayland: Drop the separate refcount for the
xwl_pixmap", we no longer keep a separate reference counter for the
xwl_pixmap, but rather tie it to the X11 pixmap lifespan. Yet, the
pending stream would still be associated with the X11 toplevel window.
Dissociate the pending streams from the X11 toplevel window, to keep it
tied only to the xwl_pixmap so that we can have:
- pixmap <-> xwl_pixmap
- xwl_pixmap <-> pending stream
Of course, the pending streams remain temporary and get removed as soon
as the ready callback is triggered, but the pending streams are not
linked to the X11 window anymore which can change their content, and
therefore their X11 pixmap at any time.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit cb61ecc7291cfbed2f76d4437cd7450b8e4dab00)
---
hw/xwayland/xwayland-glamor-eglstream.c | 131 +++++++++++-------------
1 file changed, 60 insertions(+), 71 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 77b24a4b4..32f9a326f 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -93,6 +93,7 @@ struct xwl_pixmap {
/* add any new <= 4-byte member here to avoid holes on 64-bit */
struct xwl_screen *xwl_screen;
struct wl_buffer *buffer;
+ struct xwl_eglstream_pending_stream *pending_stream;
/* XWL_PIXMAP_EGLSTREAM. */
EGLStreamKHR stream;
@@ -103,7 +104,6 @@ struct xwl_pixmap {
};
static DevPrivateKeyRec xwl_eglstream_private_key;
-static DevPrivateKeyRec xwl_eglstream_window_private_key;
static inline struct xwl_eglstream_private *
xwl_eglstream_get(struct xwl_screen *xwl_screen)
@@ -112,21 +112,6 @@ xwl_eglstream_get(struct xwl_screen *xwl_screen)
&xwl_eglstream_private_key);
}
-static inline struct xwl_eglstream_pending_stream *
-xwl_eglstream_window_get_pending(WindowPtr window)
-{
- return dixLookupPrivate(&window->devPrivates,
- &xwl_eglstream_window_private_key);
-}
-
-static inline void
-xwl_eglstream_window_set_pending(WindowPtr window,
- struct xwl_eglstream_pending_stream *stream)
-{
- dixSetPrivate(&window->devPrivates,
- &xwl_eglstream_window_private_key, stream);
-}
-
static GLint
xwl_eglstream_compile_glsl_prog(GLenum type, const char *source)
{
@@ -323,7 +308,6 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
{
if (pending->cb)
wl_callback_destroy(pending->cb);
- xwl_eglstream_window_set_pending(pending->window, NULL);
xorg_list_del(&pending->link);
free(pending);
}
@@ -331,16 +315,9 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
static void
xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
{
- struct xwl_eglstream_private *xwl_eglstream =
- xwl_eglstream_get(xwl_pixmap->xwl_screen);
- struct xwl_eglstream_pending_stream *pending;
-
- xorg_list_for_each_entry(pending,
- &xwl_eglstream->pending_streams, link) {
- if (pending->xwl_pixmap == xwl_pixmap) {
- xwl_glamor_eglstream_destroy_pending_stream(pending);
- break;
- }
+ if (xwl_pixmap->pending_stream) {
+ xwl_glamor_eglstream_destroy_pending_stream(xwl_pixmap->pending_stream);
+ xwl_pixmap->pending_stream = NULL;
}
}
@@ -363,23 +340,41 @@ xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
return xwl_pixmap_get(pixmap)->buffer;
}
+static void
+xwl_eglstream_maybe_set_pending_stream_invalid(PixmapPtr pixmap)
+{
+ struct xwl_pixmap *xwl_pixmap;
+ struct xwl_eglstream_pending_stream *pending;
+
+ xwl_pixmap = xwl_pixmap_get(pixmap);
+ if (!xwl_pixmap)
+ return;
+
+ pending = xwl_pixmap->pending_stream;
+ if (!pending)
+ return;
+
+ pending->is_valid = FALSE;
+}
+
static void
xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
{
- struct xwl_screen *xwl_screen = xwl_screen_get(window->drawable.pScreen);
+ ScreenPtr screen = window->drawable.pScreen;
+ struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
- struct xwl_eglstream_pending_stream *pending;
+ PixmapPtr old_pixmap;
- pending = xwl_eglstream_window_get_pending(window);
- if (pending) {
- /* The pixmap for this window has changed before the compositor
- * finished attaching the consumer for the window's pixmap's original
- * eglstream. A producer can no longer be attached, so the stream's
- * useless
- */
- pending->is_valid = FALSE;
- }
+ /* The pixmap for this window has changed.
+ * If that occurs while there is a stream pending, i.e. before the
+ * compositor has finished attaching the consumer for the window's
+ * pixmap's original eglstream, then a producer could no longer be
+ * attached, so the stream would be useless.
+ */
+ old_pixmap = (*screen->GetWindowPixmap) (window);
+ if (old_pixmap)
+ xwl_eglstream_maybe_set_pending_stream_invalid(old_pixmap);
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
(*xwl_screen->screen->SetWindowPixmap)(window, pixmap);
@@ -489,16 +484,18 @@ xwl_eglstream_print_error(EGLDisplay egl_display,
* - Receive pixmap B's stream callback, fall over and fail because the
* window's surface now incorrectly has pixmap A's stream attached to it.
*
- * We work around this problem by keeping a queue of pending streams, and
- * only allowing one queue entry to exist for each window. In the scenario
- * listed above, this should happen:
+ * We work around this problem by keeping a pending stream associated with
+ * the xwl_pixmap, which itself is associated with the window pixmap.
+ * In the scenario listed above, this should happen:
*
* - Begin processing X events...
- * - A window is resized, causing us to add an eglstream (known as eglstream
- * A) waiting for its consumer to finish attachment to be added to the
- * queue.
+ * - A window is resized, a new window pixmap is created causing us to
+ * add an eglstream (known as eglstream A) waiting for its consumer
+ * to finish attachment.
* - Resize on same window happens. We invalidate the previously pending
- * stream and add another one to the pending queue (known as eglstream B).
+ * stream on the old window pixmap.
+ * A new window pixmap is attached to the window and another pending
+ * stream is created for that new pixmap (known as eglstream B).
* - Begin processing Wayland events...
* - Receive invalidated callback from compositor for eglstream A, destroy
* stream.
@@ -515,6 +512,7 @@ xwl_eglstream_consumer_ready_callback(void *data,
xwl_eglstream_get(xwl_screen);
struct xwl_pixmap *xwl_pixmap;
struct xwl_eglstream_pending_stream *pending;
+ PixmapPtr pixmap;
Bool found = FALSE;
xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
@@ -528,6 +526,9 @@ xwl_eglstream_consumer_ready_callback(void *data,
wl_callback_destroy(callback);
pending->cb = NULL;
+ xwl_pixmap = pending->xwl_pixmap;
+ pixmap = pending->pixmap;
+
if (!pending->is_valid) {
xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
goto out;
@@ -535,12 +536,11 @@ xwl_eglstream_consumer_ready_callback(void *data,
xwl_glamor_egl_make_current(xwl_screen);
- xwl_pixmap = pending->xwl_pixmap;
xwl_pixmap->surface = eglCreateStreamProducerSurfaceKHR(
xwl_screen->egl_display, xwl_eglstream->config,
xwl_pixmap->stream, (int[]) {
- EGL_WIDTH, pending->pixmap->drawable.width,
- EGL_HEIGHT, pending->pixmap->drawable.height,
+ EGL_WIDTH, pixmap->drawable.width,
+ EGL_HEIGHT, pixmap->drawable.height,
EGL_NONE
});
@@ -555,14 +555,14 @@ xwl_eglstream_consumer_ready_callback(void *data,
pending->window->drawable.id, pending->pixmap);
out:
- xwl_glamor_eglstream_destroy_pending_stream(pending);
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
}
static const struct wl_callback_listener consumer_ready_listener = {
xwl_eglstream_consumer_ready_callback
};
-static void
+static struct xwl_eglstream_pending_stream *
xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
WindowPtr window, PixmapPtr pixmap)
{
@@ -570,14 +570,8 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
xwl_eglstream_get(xwl_screen);
struct xwl_eglstream_pending_stream *pending_stream;
-#ifdef DEBUG
- if (!xwl_eglstream_window_get_pending(window))
- DebugF("eglstream: win %d begins new eglstream for pixmap %p\n",
- window->drawable.id, pixmap);
- else
- DebugF("eglstream: win %d interrupts and replaces pending eglstream for pixmap %p\n",
- window->drawable.id, pixmap);
-#endif
+ DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
+ window->drawable.id, pixmap);
pending_stream = malloc(sizeof(*pending_stream));
pending_stream->window = window;
@@ -586,11 +580,12 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
pending_stream->is_valid = TRUE;
xorg_list_init(&pending_stream->link);
xorg_list_add(&pending_stream->link, &xwl_eglstream->pending_streams);
- xwl_eglstream_window_set_pending(window, pending_stream);
pending_stream->cb = wl_display_sync(xwl_screen->display);
wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
xwl_screen);
+
+ return pending_stream;
}
static void
@@ -663,7 +658,8 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
wl_eglstream_controller_attach_eglstream_consumer(
xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer);
- xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
+ xwl_pixmap->pending_stream =
+ xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
fail:
if (stream_fd >= 0)
@@ -674,22 +670,19 @@ static Bool
xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
- struct xwl_eglstream_pending_stream *pending =
- xwl_eglstream_window_get_pending(xwl_window->window);
PixmapPtr pixmap =
(*xwl_screen->screen->GetWindowPixmap)(xwl_window->window);
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
if (xwl_pixmap) {
+ struct xwl_eglstream_pending_stream *pending = xwl_pixmap->pending_stream;
+
if (pending) {
/* Wait for the compositor to finish connecting the consumer for
* this eglstream */
- if (pending->is_valid)
- return FALSE;
+ assert(pending->is_valid);
- /* The pixmap for this window was changed before the compositor
- * finished connecting the eglstream for the window's previous
- * pixmap. Begin creating a new eglstream. */
+ return FALSE;
} else {
return TRUE;
}
@@ -1190,10 +1183,6 @@ xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen)
xwl_eglstream->SetWindowPixmap = screen->SetWindowPixmap;
screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
- if (!dixRegisterPrivateKey(&xwl_eglstream_window_private_key,
- PRIVATE_WINDOW, 0))
- return FALSE;
-
return TRUE;
}
--
2.31.1

View File

@ -0,0 +1,73 @@
From f76dd86f5bbdccb3655ac58365e4604d03de65f5 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Wed, 14 Apr 2021 17:31:08 +0200
Subject: [PATCH xserver 14/27] xwayland/eglstream: Keep a reference to the
pixmap
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit affc47452 - "xwayland: Drop the separate refcount for the
xwl_pixmap" removed the separate reference counter for the xwl_pixmap
which holds the EGLStream.
While that works fine for the common case, if the window's pixmap is
changed before the stream is ready, the older pixmap will be destroyed
and the xwl_pixmap along with it, even if the compositor is still using
the stream.
The code that was removed with commit affc47452 was taking care of that
by increasing the separate reference counter for the xwl_pixmap, but it
no longer the case.
As a result, we may end up with the EGL stream in the wrong state when
trying to use it, which will cascade down into all sort of issues.
To avoid the problem, increase the reference count on the pixmap when it
is marked as invalid in EGLStream's SetWindowPixmap().
This way, the xwl_pixmap and the EGLStream are kept until released by
the compositor, even when the pixmap changes before stream is ready.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Fixes: affc47452 xwayland: Drop the separate refcount for the xwl_pixmap
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit e19bf86c17ef9c802fea24410cc6b1f51a19ce7f)
---
hw/xwayland/xwayland-glamor-eglstream.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 32f9a326f..807bfcb1d 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -355,6 +355,13 @@ xwl_eglstream_maybe_set_pending_stream_invalid(PixmapPtr pixmap)
return;
pending->is_valid = FALSE;
+
+ /* The compositor may still be using the stream, so we can't destroy
+ * it yet. We'll only have a guarantee that the stream is safe to
+ * destroy once we receive the pending wl_display_sync() for this
+ * stream
+ */
+ pending->pixmap->refcnt++;
}
static void
@@ -530,8 +537,9 @@ xwl_eglstream_consumer_ready_callback(void *data,
pixmap = pending->pixmap;
if (!pending->is_valid) {
- xwl_eglstream_destroy_pixmap_stream(pending->xwl_pixmap);
- goto out;
+ xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
+ dixDestroyPixmap(pixmap, 0);
+ return;
}
xwl_glamor_egl_make_current(xwl_screen);
--
2.31.1

View File

@ -0,0 +1,146 @@
From a68e939342aed0ea11c737d166e506442e048e90 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 27 Apr 2021 14:17:19 +0200
Subject: [PATCH xserver 15/27] xwayland/eglstream: Drop the list of pending
streams
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Now that the pending stream is associated with the xwl_pixmap for
EGLStream and the xwl_pixmap itself is associated to the pixmap, we have
a reliable way to get to those data from any pending stream.
As a result, the list of pending streams that we keep in the EGLStream
global structure becomes useless.
So we can drop the pending stream's xwl_pixmap and also the list of
pending streams altogether, and save us a walk though that list for each
callback.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit bee2ebb29f0999862ab39af26c673c00af40b082)
---
hw/xwayland/xwayland-glamor-eglstream.c | 41 ++++++-------------------
1 file changed, 9 insertions(+), 32 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 807bfcb1d..399a691d3 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -55,12 +55,9 @@ struct xwl_eglstream_pending_stream {
PixmapPtr pixmap;
WindowPtr window;
- struct xwl_pixmap *xwl_pixmap;
struct wl_callback *cb;
Bool is_valid;
-
- struct xorg_list link;
};
struct xwl_eglstream_private {
@@ -73,8 +70,6 @@ struct xwl_eglstream_private {
SetWindowPixmapProcPtr SetWindowPixmap;
- struct xorg_list pending_streams;
-
Bool have_egl_damage;
GLint blit_prog;
@@ -308,7 +303,6 @@ xwl_glamor_eglstream_destroy_pending_stream(struct xwl_eglstream_pending_stream
{
if (pending->cb)
wl_callback_destroy(pending->cb);
- xorg_list_del(&pending->link);
free(pending);
}
@@ -514,28 +508,16 @@ xwl_eglstream_consumer_ready_callback(void *data,
struct wl_callback *callback,
uint32_t time)
{
- struct xwl_screen *xwl_screen = data;
+ struct xwl_eglstream_pending_stream *pending = data;
+ PixmapPtr pixmap = pending->pixmap;
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+ struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
struct xwl_eglstream_private *xwl_eglstream =
xwl_eglstream_get(xwl_screen);
- struct xwl_pixmap *xwl_pixmap;
- struct xwl_eglstream_pending_stream *pending;
- PixmapPtr pixmap;
- Bool found = FALSE;
-
- xorg_list_for_each_entry(pending, &xwl_eglstream->pending_streams, link) {
- if (pending->cb == callback) {
- found = TRUE;
- break;
- }
- }
- assert(found);
wl_callback_destroy(callback);
pending->cb = NULL;
- xwl_pixmap = pending->xwl_pixmap;
- pixmap = pending->pixmap;
-
if (!pending->is_valid) {
xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
dixDestroyPixmap(pixmap, 0);
@@ -571,11 +553,10 @@ static const struct wl_callback_listener consumer_ready_listener = {
};
static struct xwl_eglstream_pending_stream *
-xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
- WindowPtr window, PixmapPtr pixmap)
+xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
{
- struct xwl_eglstream_private *xwl_eglstream =
- xwl_eglstream_get(xwl_screen);
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+ struct xwl_screen *xwl_screen = xwl_pixmap->xwl_screen;
struct xwl_eglstream_pending_stream *pending_stream;
DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
@@ -584,14 +565,11 @@ xwl_eglstream_queue_pending_stream(struct xwl_screen *xwl_screen,
pending_stream = malloc(sizeof(*pending_stream));
pending_stream->window = window;
pending_stream->pixmap = pixmap;
- pending_stream->xwl_pixmap = xwl_pixmap_get(pixmap);
pending_stream->is_valid = TRUE;
- xorg_list_init(&pending_stream->link);
- xorg_list_add(&pending_stream->link, &xwl_eglstream->pending_streams);
pending_stream->cb = wl_display_sync(xwl_screen->display);
wl_callback_add_listener(pending_stream->cb, &consumer_ready_listener,
- xwl_screen);
+ pending_stream);
return pending_stream;
}
@@ -667,7 +645,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
xwl_eglstream->controller, xwl_window->surface, xwl_pixmap->buffer);
xwl_pixmap->pending_stream =
- xwl_eglstream_queue_pending_stream(xwl_screen, window, pixmap);
+ xwl_eglstream_queue_pending_stream(window, pixmap);
fail:
if (stream_fd >= 0)
@@ -1249,7 +1227,6 @@ xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
&xwl_eglstream_private_key, xwl_eglstream);
xwl_eglstream->egl_device = egl_device;
- xorg_list_init(&xwl_eglstream->pending_streams);
xwl_screen->eglstream_backend.init_egl = xwl_glamor_eglstream_init_egl;
xwl_screen->eglstream_backend.init_wl_registry = xwl_glamor_eglstream_init_wl_registry;
--
2.31.1

View File

@ -0,0 +1,49 @@
From 9601f2cc5c94b9db4c7f8da404dae53b9609c995 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 19 Apr 2021 18:11:19 +0200
Subject: [PATCH xserver 16/27] xwayland/eglstream: Do not commit without
surface
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The EGL surface for the xwl_pixmap is created once the stream is ready
and valid.
If the pixmap's EGL surface fails, for whatever reason, the xwl_pixmap
will be unusable and will end up as an invalid wl_buffer.
Make sure we do not allow commits in that case and recreate the
xwl_pixmap/stream.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 098e0f52c088c6eb52c7e54c5a11cefabd480908)
---
hw/xwayland/xwayland-glamor-eglstream.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 399a691d3..ce066cd9e 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -670,7 +670,14 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
return FALSE;
} else {
- return TRUE;
+ if (xwl_pixmap->surface != EGL_NO_SURFACE)
+ return TRUE;
+
+ /* The pending stream got removed, we have a xwl_pixmap and
+ * yet we do not have a surface.
+ * So something went wrong with the surface creation, retry.
+ */
+ xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
}
}
--
2.31.1

View File

@ -0,0 +1,47 @@
From 39df6934d5a9a132c2e87456e35094b7e81a238e Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 19 Apr 2021 14:52:38 +0200
Subject: [PATCH xserver 17/27] xwayland/eglstream: Fix calloc/malloc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use calloc() instead of malloc() like the rest of the code.
Also fix the arguments of calloc() calls to match the definition which
is calloc(size_t nmemb, size_t size).
This is a cleanup patch, no functional change.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit a45799971083c47082d085d3732a5b12692cf75b)
---
hw/xwayland/xwayland-glamor-eglstream.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index ce066cd9e..3a3caa976 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -562,7 +562,7 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
DebugF("eglstream: win %d queues new pending stream for pixmap %p\n",
window->drawable.id, pixmap);
- pending_stream = malloc(sizeof(*pending_stream));
+ pending_stream = calloc(1, sizeof(*pending_stream));
pending_stream->window = window;
pending_stream->pixmap = pixmap;
pending_stream->is_valid = TRUE;
@@ -596,7 +596,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
struct wl_array stream_attribs;
int stream_fd = -1;
- xwl_pixmap = calloc(sizeof(*xwl_pixmap), 1);
+ xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
if (!xwl_pixmap)
FatalError("Not enough memory to create pixmap\n");
xwl_pixmap_set_private(pixmap, xwl_pixmap);
--
2.31.1

View File

@ -0,0 +1,56 @@
From a964ccdadf351d90482df00c272dee3634f7a8ee Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 30 Apr 2021 09:02:29 +0200
Subject: [PATCH xserver 18/27] xwayland/eglstream: Check eglSwapBuffers()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
EGLstream's post_damage() would unconditionally return success
regardless of the actual status of the eglSwapBuffers().
Yet, if eglSwapBuffers() fails, we should not post the corresponding
damage as they wouldn't match the actual content of the buffer.
Use the eglSwapBuffers() return value as the return value for
post_damage() and do not take a refrence on the pixmap if it fails.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit b583395cd38ad101c7541bd8b0e91143ced44703)
---
hw/xwayland/xwayland-glamor-eglstream.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 3a3caa976..6721acfe8 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -750,14 +750,20 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (xwl_eglstream->have_egl_damage)
- eglSwapBuffersWithDamageKHR(xwl_screen->egl_display,
- xwl_pixmap->surface, egl_damage, 1);
+ status = eglSwapBuffersWithDamageKHR(xwl_screen->egl_display,
+ xwl_pixmap->surface,
+ egl_damage, 1);
else
- eglSwapBuffers(xwl_screen->egl_display, xwl_pixmap->surface);
+ status = eglSwapBuffers(xwl_screen->egl_display,
+ xwl_pixmap->surface);
+
+ if (!status) {
+ ErrorF("eglstream: buffer swap failed, not posting damage\n");
+ goto out;
+ }
/* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++;
- status = TRUE;
out:
/* Restore previous state */
--
2.31.1

View File

@ -0,0 +1,89 @@
From 7b06e468b37164eeaa18fc32cba801de0eee4eb1 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Tue, 4 May 2021 10:56:38 +0200
Subject: [PATCH xserver 19/27] xwayland/eglstream: Do not always increment
pixmap refcnt on commit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently, the EGLstream backend would increment the pixmap refcount for
each commit, and decrease that refcount on the wl_buffer release
callback.
But that's relying on the compositor sending us a release callback for
each commit, otherwise the pixmap refcount will keep increasing and the
pixmap will be leaked.
So instead, increment the refcount on the pixmap only when we have not
received a release notification for the wl_buffer, to avoid increasing
the pixmap refcount more than once without a corresponding release
event.
This way, if the pixmap is still in use when released on the X11 side,
the EGL stream will be kept until the compositor releases it.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit d85bfa6ab7495281516f3a4b05dc1ff0b2c4bf91)
---
hw/xwayland/xwayland-glamor-eglstream.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 6721acfe8..64f4e31f5 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -89,6 +89,7 @@ struct xwl_pixmap {
struct xwl_screen *xwl_screen;
struct wl_buffer *buffer;
struct xwl_eglstream_pending_stream *pending_stream;
+ Bool wait_for_buffer_release;
/* XWL_PIXMAP_EGLSTREAM. */
EGLStreamKHR stream;
@@ -577,8 +578,16 @@ xwl_eglstream_queue_pending_stream(WindowPtr window, PixmapPtr pixmap)
static void
xwl_eglstream_buffer_release_callback(void *data)
{
- /* drop the reference we took in post_damage, freeing if necessary */
- dixDestroyPixmap(data, 0);
+ PixmapPtr pixmap = data;
+ struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
+
+ assert(xwl_pixmap);
+
+ if (xwl_pixmap->wait_for_buffer_release) {
+ xwl_pixmap->wait_for_buffer_release = FALSE;
+ /* drop the reference we took in the ready callback, freeing if necessary */
+ dixDestroyPixmap(pixmap, 0);
+ }
}
static const struct wl_buffer_listener xwl_eglstream_buffer_release_listener = {
@@ -606,6 +615,7 @@ xwl_eglstream_create_pixmap_and_stream(struct xwl_screen *xwl_screen,
xwl_glamor_egl_make_current(xwl_screen);
+ xwl_pixmap->wait_for_buffer_release = FALSE;
xwl_pixmap->xwl_screen = xwl_screen;
xwl_pixmap->surface = EGL_NO_SURFACE;
xwl_pixmap->stream = eglCreateStreamKHR(xwl_screen->egl_display, NULL);
@@ -762,8 +772,11 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
goto out;
}
- /* hang onto the pixmap until the compositor has released it */
- pixmap->refcnt++;
+ if (!xwl_pixmap->wait_for_buffer_release) {
+ /* hang onto the pixmap until the compositor has released it */
+ pixmap->refcnt++;
+ xwl_pixmap->wait_for_buffer_release = TRUE;
+ }
out:
/* Restore previous state */
--
2.31.1

View File

@ -0,0 +1,51 @@
From 9519ebe96344ec64e8f18eae2420df101c446a1a Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Fri, 30 Apr 2021 16:23:10 +0200
Subject: [PATCH xserver 20/27] xwayland/eglstream: Set ALU to GXCopy for
blitting
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The EGLstream backend's post damage function uses a shader and
glDrawArrays() to copy the data from the glamor's pixmap texture prior
to do the eglSwapBuffers().
However, glDrawArrays() can be affected by the GL state, and therefore
not reliably produce the expected copy, causing the content of the
buffer to be corrupted.
Make sure to set the ALU to GXCopy prior to call glDrawArrays() to get
the expected result.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 012350e3db47fef0404346f55968032e62004fcf)
---
hw/xwayland/xwayland-glamor-eglstream.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 64f4e31f5..2094d293a 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -33,6 +33,7 @@
#define EGL_NO_X11
#include <glamor_egl.h>
#include <glamor.h>
+#include <glamor_priv.h>
#include <glamor_transform.h>
#include <glamor_transfer.h>
@@ -727,6 +728,8 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
* won't actually draw to it
*/
xwl_glamor_egl_make_current(xwl_screen);
+ glamor_set_alu(xwl_screen->screen, GXcopy);
+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (eglGetCurrentSurface(EGL_READ) != xwl_pixmap->surface ||
--
2.31.1

View File

@ -0,0 +1,43 @@
From 64deb9471c7d9cad4c2ec1de1fba6a35c9af8e68 Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Fri, 14 May 2021 08:26:49 -0400
Subject: [PATCH xserver 21/27] xwayland/eglstream: allow commits to dma-buf
backed pixmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As of commit 098e0f52 xwl_glamor_eglstream_allow_commits will not allow commits
if the xwl_pixmap does not have an EGLSurface. This is valid for pixmaps backed
by an EGLStream, however pixmaps backed by a dma-buf for OpenGL or Vulkan
rendering will never have an EGLSurface. Unlike EGLStream backed pixmaps,
though, glamor will render directly to the buffer that Xwayland passes to the
compositor. Hence, they don't require the intermediate copy in
xwl_glamor_eglstream_post_damage that EGLStream backed pixmaps do, so there is
no need for an EGLSurface.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 3d33d885fcd1215a74c1819278cf6f9557c9860b)
---
hw/xwayland/xwayland-glamor-eglstream.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2094d293a..2d0827709 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -681,7 +681,8 @@ xwl_glamor_eglstream_allow_commits(struct xwl_window *xwl_window)
return FALSE;
} else {
- if (xwl_pixmap->surface != EGL_NO_SURFACE)
+ if (xwl_pixmap->surface != EGL_NO_SURFACE ||
+ xwl_pixmap->type == XWL_PIXMAP_DMA_BUF)
return TRUE;
/* The pending stream got removed, we have a xwl_pixmap and
--
2.31.1

View File

@ -0,0 +1,76 @@
From 29cba30948cda34e744314343109964ff9ed515c Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Tue, 11 May 2021 17:00:21 -0400
Subject: [PATCH xserver 22/27] xwayland/eglstream: flush stream after
eglSwapBuffers
When eglSwapBuffers inserts a new frame into a window's stream, there may be a
delay before the state of the consumer end of the stream is updated to reflect
this. If the subsequent wl_surface_attach, wl_surface_damage, wl_surface_commit
calls are received by the compositor before then, it will (typically) re-use
the previous frame acquired from the stream instead of the latest one.
This can leave the window displaying out-of-date contents, which might never be
updated thereafter.
To fix this, after calling eglSwapBuffers, xwl_glamor_eglstream_post_damage
should call eglStreamFlushNV. This call will block until it can be guaranteed
that the state of the consumer end of the stream has been updated to reflect
that a new frame is available.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1171
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
(cherry picked from commit 7515c23a416825f0db51f9b445279b12d5918ebf)
---
hw/xwayland/xwayland-glamor-eglstream.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 2d0827709..c583a1390 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -72,6 +72,7 @@ struct xwl_eglstream_private {
SetWindowPixmapProcPtr SetWindowPixmap;
Bool have_egl_damage;
+ Bool have_egl_stream_flush;
GLint blit_prog;
GLuint blit_vao;
@@ -776,6 +777,13 @@ xwl_glamor_eglstream_post_damage(struct xwl_window *xwl_window,
goto out;
}
+#ifdef EGL_NV_stream_flush
+ if (xwl_eglstream->have_egl_stream_flush)
+ /* block until stream state is updated on the compositor's side */
+ eglStreamFlushNV(xwl_screen->egl_display,
+ xwl_pixmap->stream);
+#endif
+
if (!xwl_pixmap->wait_for_buffer_release) {
/* hang onto the pixmap until the compositor has released it */
pixmap->refcnt++;
@@ -1173,6 +1181,18 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
ErrorF("Driver lacks EGL_KHR_swap_buffers_with_damage, performance "
"will be affected\n");
+#ifdef EGL_NV_stream_flush
+ xwl_eglstream->have_egl_stream_flush =
+ epoxy_has_egl_extension(xwl_screen->egl_display,
+ "EGL_NV_stream_flush");
+#else
+ xwl_eglstream->have_egl_stream_flush = FALSE;
+#endif /* EGL_NV_stream_flush */
+
+ if (!xwl_eglstream->have_egl_stream_flush)
+ ErrorF("EGL_NV_stream_flush not available, "
+ "this may cause visible corruption.\n");
+
xwl_eglstream_init_shaders(xwl_screen);
if (epoxy_has_gl_extension("GL_OES_EGL_image") &&
--
2.31.1

View File

@ -0,0 +1,57 @@
From 4c01758cbe7db02d84ac0cba0c626e855bf927d6 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 20 May 2021 12:11:42 +0200
Subject: [PATCH xserver 23/27] xwayland: Add preferred GLVND vendor to
xwl_screen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If Xwayland's EGLstream backend supports hardware acceleration with the
NVIDIA closed-source driver, the GLX library also needs to be one
shipped by NVIDIA, that's what GLVND is for.
Add a new member to the xwl_screen that the backend can optionally set
to the preferred GLVND vendor to use.
If not set, "mesa" is assumed.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 24fc8aea1e4bbaba780f1a316fba797a0198f603)
---
hw/xwayland/xwayland-glx.c | 3 +++
hw/xwayland/xwayland-screen.h | 3 +++
2 files changed, 6 insertions(+)
diff --git a/hw/xwayland/xwayland-glx.c b/hw/xwayland/xwayland-glx.c
index 7e2a87fc1..eba8946ab 100644
--- a/hw/xwayland/xwayland-glx.c
+++ b/hw/xwayland/xwayland-glx.c
@@ -378,6 +378,9 @@ egl_screen_probe(ScreenPtr pScreen)
return NULL;
}
+ if (!screen->base.glvnd && xwl_screen->glvnd_vendor)
+ screen->base.glvnd = strdup(xwl_screen->glvnd_vendor);
+
if (!screen->base.glvnd)
screen->base.glvnd = strdup("mesa");
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index 5fe4712bd..b965dddd7 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -107,6 +107,9 @@ struct xwl_screen {
struct glamor_context *glamor_ctx;
Atom allow_commits_prop;
+
+ /* The preferred GLVND vendor. If NULL, "mesa" is assumed. */
+ const char *glvnd_vendor;
};
/* Apps which use randr/vidmode to change the mode when going fullscreen,
--
2.31.1

View File

@ -0,0 +1,42 @@
From 430eb872784c04e825126e0d7454f3a5bbefff70 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Mon, 17 May 2021 18:20:57 +0200
Subject: [PATCH xserver 24/27] xwayland/eglstream: Use "nvidia" for GLVND
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the EGLStream backend is able to use hardware acceleration with the
NVIDIA closed source driver, we should use the "nvidia" GLX
implementation instead of the one from Mesa to take advantage of the
NVIDIA hardware accelerated rendering.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit fae58e9b03696a3890f9c876306c68ffa6f9ff30)
---
hw/xwayland/xwayland-glamor-eglstream.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index c583a1390..5e89849ff 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -1195,9 +1195,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");
+ if (epoxy_has_gl_extension("GL_OES_EGL_image")) {
+ if (dri3_screen_init(xwl_screen->screen, &xwl_dri3_info))
+ xwl_screen->glvnd_vendor = "nvidia";
+ else
+ ErrorF("DRI3 initialization failed. Performance will be affected.\n");
}
return TRUE;
--
2.31.1

View File

@ -0,0 +1,35 @@
From 0cb42b7de629e74afed9b19d47672cebfe08f12e Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 20 May 2021 16:46:33 +0200
Subject: [PATCH xserver 25/27] xwayland/eglstream: Log when GL_OES_EGL_image
is missing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
That will dramatically affect performance, might as well log when we
cannot use GL_OES_EGL_image with the NVIDIA closed-source driver.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
(cherry picked from commit 34a58d7714025bc1043bf5282358406eb10e4b8e)
---
hw/xwayland/xwayland-glamor-eglstream.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/xwayland/xwayland-glamor-eglstream.c b/hw/xwayland/xwayland-glamor-eglstream.c
index 5e89849ff..0affc954c 100644
--- a/hw/xwayland/xwayland-glamor-eglstream.c
+++ b/hw/xwayland/xwayland-glamor-eglstream.c
@@ -1200,6 +1200,8 @@ xwl_glamor_eglstream_init_egl(struct xwl_screen *xwl_screen)
xwl_screen->glvnd_vendor = "nvidia";
else
ErrorF("DRI3 initialization failed. Performance will be affected.\n");
+ } else {
+ ErrorF("Driver lacks GL_OES_EGL_image, performance will be affected.\n");
}
return TRUE;
--
2.31.1

View File

@ -0,0 +1,60 @@
From a604a0a26791e9f352aad27232127d729bca4334 Mon Sep 17 00:00:00 2001
From: Erik Kurzinger <ekurzinger@nvidia.com>
Date: Thu, 10 Dec 2020 14:24:32 -0800
Subject: [PATCH xserver 26/27] glx: don't create implicit GLXWindow if one
already exists
If a GLXMakeCurrent request specifies an X window as its drawable,
__glXGetDrawable will implicitly create a GLXWindow for it. However,
the client may have already explicitly created a GLXWindow for that X
window. If that happens, two __glXDrawableRes resources will be added
to the window.
If the explicitly-created GLXWindow is later destroyed by the client,
DrawableGone will call FreeResourceByType on the X window, but this
will actually free the resource for the implicitly-created GLXWindow,
since that one would be at the head of the list.
Then if the X window is destroyed after that, the resource for the
explicitly-created GLXWindow will be freed. But that GLXWindow was
already destroyed above. This crashes the server when it tries to call
the destroyed GLXWindow's destructor. It also means the
implicitly-created GLXWindow would have been leaked since the
FreeResourceByType call mentioned above skips calling the destructor.
To fix this, if __glXGetDrawable is given an X window, it should check
if there is already a GLXWindow associated with it, and only create an
implicit one if there is not.
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit b7a85e44da91d1663d5b4eabac06327c92a80f91)
---
glx/glxcmds.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 37576b6ef..1b9ad6d14 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -487,8 +487,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
__GLXscreen *pGlxScreen;
int rc;
- if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
- DixWriteAccess, &pGlxDraw, &rc)) {
+ rc = dixLookupResourceByType((void **)&pGlxDraw, drawId,
+ __glXDrawableRes, client, DixWriteAccess);
+ if (rc == Success &&
+ /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable.
+ * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is
+ * an X window, but the client has already created a GLXWindow
+ * associated with it, so we don't want to create another one. */
+ (pGlxDraw->drawId == drawId ||
+ pGlxDraw->type == GLX_DRAWABLE_WINDOW)) {
if (glxc != NULL &&
glxc->config != NULL &&
glxc->config != pGlxDraw->config) {
--
2.31.1

View File

@ -0,0 +1,45 @@
From 1607ac6870f7cf67c30b96529ea5ca389c771a3d Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 3 Jun 2021 17:51:01 +0200
Subject: [PATCH xserver 27/27] glx: Set ContextTag for all contexts
Currently, xorgGlxMakeCurrent() would set the context tag only for
indirect GLX contexts.
However, several other places expect to find a context for the tag or
they would raise a GLXBadContextTag error, such as WaitGL() or WaitX().
Set the context tag for direct contexts as well, to avoid raising an
error and possibly killing the client and set currentClient.
Thanks to Erik Kurzinger <ekurzinger@nvidia.com> for spotting the issue.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit c468d34c7208c9041f9c077b54a00ae9cccad6a3)
(cherry picked from commit aad61e8e03311eb8bae4f7db59e65634733eadc2)
---
glx/glxcmds.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 1b9ad6d14..8b2170306 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -662,10 +662,11 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
glxc->readPriv = NULL;
return __glXError(GLXBadContext);
}
+ }
+ glxServer.setContextTagPrivate(client, newContextTag, glxc);
+ if (glxc)
glxc->currentClient = client;
- glxServer.setContextTagPrivate(client, newContextTag, glxc);
- }
if (prevglxc) {
prevglxc->currentClient = NULL;
--
2.31.1

View File

@ -0,0 +1,188 @@
%global commit 280aac5a0ee09c45b17ec4be0681397f7c34c12e
%global shortcommit %(c=%{commit}; echo ${c:0:7})
#global gitdate 20210201
%global pkgname %{?gitdate:xserver}%{!?gitdate:xwayland}
%global default_font_path "catalogue:/etc/X11/fontpath.d,built-ins"
Summary: Xwayland
Name: xorg-x11-server-Xwayland
Version: 21.1.1
Release: 6%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
URL: http://www.x.org
%if 0%{?gitdate}
Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{pkgname}-%{shortcommit}.tar.gz
%else
Source0: https://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.xz
%endif
Patch1: 0001-xwayland-Move-dmabuf-interface-to-common-glamor-code.patch
Patch2: 0002-xwayland-move-formats-and-modifiers-functions-to-com.patch
Patch3: 0003-xwayland-Add-check_flip-glamor-backend-function.patch
Patch4: 0004-xwayland-implement-pixmap_from_buffers-for-the-eglst.patch
Patch5: 0005-xwayland-eglstream-fix-X11-rendering-to-flipping-GL-.patch
Patch6: 0006-xwayland-eglstream-Check-buffer-creation.patch
Patch7: 0007-xwayland-Check-buffer-prior-to-attaching-it.patch
Patch8: 0008-glamor-Dump-backtrace-on-GL-error.patch
Patch9: 0009-xwayland-glamor-Add-return-status-to-post_damage.patch
Patch10: 0010-xwayland-eglstream-Check-framebuffer-status.patch
Patch11: 0011-xwayland-eglstream-Small-refactoring.patch
Patch12: 0012-xwayland-eglstream-Add-more-error-checking.patch
Patch13: 0013-xwayland-eglstream-Dissociate-pending-stream-from-wi.patch
Patch14: 0014-xwayland-eglstream-Keep-a-reference-to-the-pixmap.patch
Patch15: 0015-xwayland-eglstream-Drop-the-list-of-pending-streams.patch
Patch16: 0016-xwayland-eglstream-Do-not-commit-without-surface.patch
Patch17: 0017-xwayland-eglstream-Fix-calloc-malloc.patch
Patch18: 0018-xwayland-eglstream-Check-eglSwapBuffers.patch
Patch19: 0019-xwayland-eglstream-Do-not-always-increment-pixmap-re.patch
Patch20: 0020-xwayland-eglstream-Set-ALU-to-GXCopy-for-blitting.patch
Patch21: 0021-xwayland-eglstream-allow-commits-to-dma-buf-backed-p.patch
Patch22: 0022-xwayland-eglstream-flush-stream-after-eglSwapBuffers.patch
Patch23: 0023-xwayland-Add-preferred-GLVND-vendor-to-xwl_screen.patch
Patch24: 0024-xwayland-eglstream-Use-nvidia-for-GLVND.patch
Patch25: 0025-xwayland-eglstream-Log-when-GL_OES_EGL_image-is-miss.patch
Patch26: 0026-glx-don-t-create-implicit-GLXWindow-if-one-already-e.patch
Patch27: 0027-glx-Set-ContextTag-for-all-contexts.patch
# https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/704
Patch28: 0001-xwayland-eglstream-Keep-pending-stream-if-the-pixmap.patch
Patch29: 0002-xwayland-eglstream-Remove-stream-validity.patch
License: MIT
Requires: xorg-x11-server-common
Requires: libEGL
Requires: libepoxy >= 1.5.5
BuildRequires: gcc
BuildRequires: git-core
BuildRequires: meson
BuildRequires: wayland-devel
BuildRequires: pkgconfig(wayland-client) >= 1.3.0
BuildRequires: pkgconfig(wayland-protocols)
BuildRequires: pkgconfig(wayland-eglstream-protocols)
BuildRequires: pkgconfig(dmx)
BuildRequires: pkgconfig(epoxy) >= 1.5.5
BuildRequires: pkgconfig(fontenc)
BuildRequires: pkgconfig(libdrm) >= 2.4.0
BuildRequires: pkgconfig(libssl)
BuildRequires: pkgconfig(libtirpc)
BuildRequires: pkgconfig(pixman-1)
BuildRequires: pkgconfig(x11)
BuildRequires: pkgconfig(xau)
BuildRequires: pkgconfig(xdmcp)
BuildRequires: pkgconfig(xext)
BuildRequires: pkgconfig(xfixes)
BuildRequires: pkgconfig(xfont2)
BuildRequires: pkgconfig(xi)
BuildRequires: pkgconfig(xinerama)
BuildRequires: pkgconfig(xkbfile)
BuildRequires: pkgconfig(xmu)
BuildRequires: pkgconfig(xorg-macros) >= 1.17
BuildRequires: pkgconfig(xpm)
BuildRequires: pkgconfig(xrender)
BuildRequires: pkgconfig(xres)
BuildRequires: pkgconfig(xshmfence) >= 1.1
BuildRequires: pkgconfig(xtrans) >= 1.3.2
BuildRequires: pkgconfig(xtst)
BuildRequires: pkgconfig(xv)
BuildRequires: xorg-x11-proto-devel >= 7.7-10
BuildRequires: mesa-libGL-devel >= 9.2
BuildRequires: mesa-libEGL-devel
BuildRequires: mesa-libgbm-devel
BuildRequires: audit-libs-devel
BuildRequires: libselinux-devel >= 2.0.86-1
# libunwind is Exclusive for the following arches
%ifarch aarch64 %{arm} hppa ia64 mips ppc ppc64 %{ix86} x86_64
%if !0%{?rhel}
BuildRequires: libunwind-devel
%endif
%endif
BuildRequires: pkgconfig(xcb-aux)
BuildRequires: pkgconfig(xcb-image)
BuildRequires: pkgconfig(xcb-icccm)
BuildRequires: pkgconfig(xcb-keysyms)
BuildRequires: pkgconfig(xcb-renderutil)
%description
Xwayland is an X server for running X clients under Wayland.
%package devel
Summary: Development package
Requires: pkgconfig
%description devel
The development package provides the developmental files which are
necessary for developing Wayland compositors using Xwayland.
%prep
%autosetup -S git_am -n %{pkgname}-%{?gitdate:%{commit}}%{!?gitdate:%{version}}
%build
%meson \
-Dxwayland_eglstream=true \
-Ddefault_font_path=%{default_font_path} \
-Dbuilder_string="Build ID: %{name} %{version}-%{release}" \
-Dxkb_output_dir=%{_localstatedir}/lib/xkb \
-Dxcsecurity=true \
-Dglamor=true \
-Ddri3=true
%meson_build
%install
%meson_install
# Remove unwanted files/dirs
rm $RPM_BUILD_ROOT%{_mandir}/man1/Xserver.1*
rm -Rf $RPM_BUILD_ROOT%{_libdir}/xorg
rm -Rf $RPM_BUILD_ROOT%{_includedir}/xorg
rm -Rf $RPM_BUILD_ROOT%{_datadir}/aclocal
rm -Rf $RPM_BUILD_ROOT%{_localstatedir}/lib/xkb
%files
%{_bindir}/Xwayland
%{_mandir}/man1/Xwayland.1*
%files devel
%{_libdir}/pkgconfig/xwayland.pc
%changelog
* Mon Aug 9 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-6
- Backport the latest fixes from Xwayland for EGLstream (rhbz#1977741)
* Tue Jun 29 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-5
- Require libepoxy >= 1.5.5 (rhbz#1976132)
* Mon Jun 21 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-4
- Fix a use-after-free in the previous changes for GLX
* Mon Jun 14 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-3
- Backport fixes for GLX and EGLstream (#1961981)
* Thu Jun 03 2021 Tomas Pelka <tpelka@redhat.com> - 21.1.1-2
- bump release and rebuild to correctly trigger gating
* Wed Apr 14 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-1
- xwayland 21.1.1 (CVE-2021-3472 / ZDI-CAN-1259)
* Thu Mar 18 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.0-1
- xwayland 21.1.0
* Thu Mar 4 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.0.99.902-1
- xwayland 21.0.99.902
- Remove xdmcp, udev, udev_kms build options
- Stop overriding the vendor name, same as xorg-x11-server
* Thu Feb 18 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.0.99.901-1
- xwayland 21.0.99.901
* Mon Feb 1 2021 Olivier Fourdan <ofourdan@redhat.com> - 1.20.99.1-0.1.20210201git5429791
- Initial import (#1912335).