Backport fixes for GLX and EGLstream
Resolves: rhbz#1969486
This commit is contained in:
parent
5645c5fa27
commit
a618d2e780
257
0001-xwayland-Move-dmabuf-interface-to-common-glamor-code.patch
Normal file
257
0001-xwayland-Move-dmabuf-interface-to-common-glamor-code.patch
Normal 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
|
||||
|
330
0002-xwayland-move-formats-and-modifiers-functions-to-com.patch
Normal file
330
0002-xwayland-move-formats-and-modifiers-functions-to-com.patch
Normal 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
|
||||
|
112
0003-xwayland-Add-check_flip-glamor-backend-function.patch
Normal file
112
0003-xwayland-Add-check_flip-glamor-backend-function.patch
Normal 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
|
||||
|
425
0004-xwayland-implement-pixmap_from_buffers-for-the-eglst.patch
Normal file
425
0004-xwayland-implement-pixmap_from_buffers-for-the-eglst.patch
Normal 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
|
||||
|
@ -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
|
||||
|
53
0006-xwayland-eglstream-Check-buffer-creation.patch
Normal file
53
0006-xwayland-eglstream-Check-buffer-creation.patch
Normal 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
|
||||
|
88
0007-xwayland-Check-buffer-prior-to-attaching-it.patch
Normal file
88
0007-xwayland-Check-buffer-prior-to-attaching-it.patch
Normal 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
|
||||
|
38
0008-glamor-Dump-backtrace-on-GL-error.patch
Normal file
38
0008-glamor-Dump-backtrace-on-GL-error.patch
Normal 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
|
||||
|
125
0009-xwayland-glamor-Add-return-status-to-post_damage.patch
Normal file
125
0009-xwayland-glamor-Add-return-status-to-post_damage.patch
Normal 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
|
||||
|
74
0010-xwayland-eglstream-Check-framebuffer-status.patch
Normal file
74
0010-xwayland-eglstream-Check-framebuffer-status.patch
Normal 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
|
||||
|
138
0011-xwayland-eglstream-Small-refactoring.patch
Normal file
138
0011-xwayland-eglstream-Small-refactoring.patch
Normal 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
|
||||
|
150
0012-xwayland-eglstream-Add-more-error-checking.patch
Normal file
150
0012-xwayland-eglstream-Add-more-error-checking.patch
Normal 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
|
||||
|
323
0013-xwayland-eglstream-Dissociate-pending-stream-from-wi.patch
Normal file
323
0013-xwayland-eglstream-Dissociate-pending-stream-from-wi.patch
Normal 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
|
||||
|
73
0014-xwayland-eglstream-Keep-a-reference-to-the-pixmap.patch
Normal file
73
0014-xwayland-eglstream-Keep-a-reference-to-the-pixmap.patch
Normal 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
|
||||
|
146
0015-xwayland-eglstream-Drop-the-list-of-pending-streams.patch
Normal file
146
0015-xwayland-eglstream-Drop-the-list-of-pending-streams.patch
Normal 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
|
||||
|
49
0016-xwayland-eglstream-Do-not-commit-without-surface.patch
Normal file
49
0016-xwayland-eglstream-Do-not-commit-without-surface.patch
Normal 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
|
||||
|
47
0017-xwayland-eglstream-Fix-calloc-malloc.patch
Normal file
47
0017-xwayland-eglstream-Fix-calloc-malloc.patch
Normal 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
|
||||
|
56
0018-xwayland-eglstream-Check-eglSwapBuffers.patch
Normal file
56
0018-xwayland-eglstream-Check-eglSwapBuffers.patch
Normal 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
|
||||
|
@ -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
|
||||
|
51
0020-xwayland-eglstream-Set-ALU-to-GXCopy-for-blitting.patch
Normal file
51
0020-xwayland-eglstream-Set-ALU-to-GXCopy-for-blitting.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
57
0023-xwayland-Add-preferred-GLVND-vendor-to-xwl_screen.patch
Normal file
57
0023-xwayland-Add-preferred-GLVND-vendor-to-xwl_screen.patch
Normal 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
|
||||
|
42
0024-xwayland-eglstream-Use-nvidia-for-GLVND.patch
Normal file
42
0024-xwayland-eglstream-Use-nvidia-for-GLVND.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
42
0027-glx-Set-ContextTag-for-all-contexts.patch
Normal file
42
0027-glx-Set-ContextTag-for-all-contexts.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 604ac8f46a85a5c68b00751baa699d770f754e1c 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.
|
||||
|
||||
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)
|
||||
---
|
||||
glx/glxcmds.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
||||
index 1b9ad6d14..bd62e913c 100644
|
||||
--- a/glx/glxcmds.c
|
||||
+++ b/glx/glxcmds.c
|
||||
@@ -664,9 +664,10 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
|
||||
}
|
||||
|
||||
glxc->currentClient = client;
|
||||
- glxServer.setContextTagPrivate(client, newContextTag, glxc);
|
||||
}
|
||||
|
||||
+ glxServer.setContextTagPrivate(client, newContextTag, glxc);
|
||||
+
|
||||
if (prevglxc) {
|
||||
prevglxc->currentClient = NULL;
|
||||
if (!prevglxc->idExists) {
|
||||
--
|
||||
2.31.1
|
||||
|
@ -9,7 +9,7 @@
|
||||
Summary: Xwayland
|
||||
Name: xorg-x11-server-Xwayland
|
||||
Version: 21.1.1
|
||||
Release: 1%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
|
||||
Release: 2%{?gitdate:.%{gitdate}git%{shortcommit}}%{?dist}
|
||||
|
||||
URL: http://www.x.org
|
||||
%if 0%{?gitdate}
|
||||
@ -17,6 +17,35 @@ Source0: https://gitlab.freedesktop.org/xorg/%{pkgname}/-/archive/%{commit}/%{
|
||||
%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
|
||||
|
||||
License: MIT
|
||||
|
||||
Requires: xorg-x11-server-common
|
||||
@ -122,6 +151,9 @@ rm -Rf $RPM_BUILD_ROOT%{_localstatedir}/lib/xkb
|
||||
%{_libdir}/pkgconfig/xwayland.pc
|
||||
|
||||
%changelog
|
||||
* Thu Jun 17 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-2
|
||||
- Backport fixes for GLX and EGLstream (#1969486)
|
||||
|
||||
* Thu Jun 17 2021 Olivier Fourdan <ofourdan@redhat.com> - 21.1.1-1
|
||||
- xwayland 21.1.1 (#1952897)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user