xserver: Branch 'xwayland-21.1' - 27 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 23 10:44:08 UTC 2021
glamor/glamor.c | 1
glx/glxcmds.c | 16
hw/xwayland/xwayland-cursor.c | 11
hw/xwayland/xwayland-glamor-eglstream.c | 600 +++++++++++++++++++++++++-------
hw/xwayland/xwayland-glamor-gbm.c | 186 ---------
hw/xwayland/xwayland-glamor.c | 216 ++++++++++-
hw/xwayland/xwayland-glamor.h | 24 -
hw/xwayland/xwayland-glx.c | 3
hw/xwayland/xwayland-present.c | 12
hw/xwayland/xwayland-screen.h | 4
hw/xwayland/xwayland-window.c | 13
11 files changed, 746 insertions(+), 340 deletions(-)
New commits:
commit 763f4fb27849923e7e70f217b1467ef98df1d526
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Thu Jun 3 17:51:01 2021 +0200
glx: Set ContextTag for all contexts
Currently, xorgGlxMakeCurrent() would set the context tag only for
indirect GLX contexts.
However, several other places expect to find a context for the tag or
they would raise a GLXBadContextTag error, such as WaitGL() or WaitX().
Set the context tag for direct contexts as well, to avoid raising an
error and possibly killing the client and set currentClient.
Thanks to Erik Kurzinger <ekurzinger at nvidia.com> for spotting the issue.
Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
(cherry picked from commit c468d34c7208c9041f9c077b54a00ae9cccad6a3)
(cherry picked from commit aad61e8e03311eb8bae4f7db59e65634733eadc2)
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 1b9ad6d14..8b2170306 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -662,10 +662,11 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
glxc->readPriv = NULL;
return __glXError(GLXBadContext);
}
+ }
+ glxServer.setContextTagPrivate(client, newContextTag, glxc);
+ if (glxc)
glxc->currentClient = client;
- glxServer.setContextTagPrivate(client, newContextTag, glxc);
- }
if (prevglxc) {
prevglxc->currentClient = NULL;
commit e754b473d1ed35a8d39e0c199efefb65364acbe1
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Thu Dec 10 14:24:32 2020 -0800
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 at nvidia.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
(cherry picked from commit b7a85e44da91d1663d5b4eabac06327c92a80f91)
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) {
commit 831426afd1832c6a671cac5d29bda15736dce68e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Thu May 20 16:46:33 2021 +0200
xwayland/eglstream: Log when GL_OES_EGL_image is missing
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 34a58d7714025bc1043bf5282358406eb10e4b8e)
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;
commit 2e1bb50644ce2553451da74506f8f26cb7222a8f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Mon May 17 18:20:57 2021 +0200
xwayland/eglstream: Use "nvidia" for GLVND
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit fae58e9b03696a3890f9c876306c68ffa6f9ff30)
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;
commit 8744ab1b417018888d2d1192a09aae16d06fc20c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Thu May 20 12:11:42 2021 +0200
xwayland: Add preferred GLVND vendor to xwl_screen
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 24fc8aea1e4bbaba780f1a316fba797a0198f603)
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,
commit f4720f1c42cb9fec3edfa8e871f8557b038e2aad
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Tue May 11 17:00:21 2021 -0400
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 at nvidia.com>
(cherry picked from commit 7515c23a416825f0db51f9b445279b12d5918ebf)
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") &&
commit b2963fccc186b384af22891a7f73892c93a7ba39
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Fri May 14 08:26:49 2021 -0400
xwayland/eglstream: allow commits to dma-buf backed pixmaps
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 at nvidia.com>
Acked-by: Olivier Fourdan <ofourdan at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 3d33d885fcd1215a74c1819278cf6f9557c9860b)
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
commit bdb4712da34c743fae3d971590761d6fe3859e3c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Fri Apr 30 16:23:10 2021 +0200
xwayland/eglstream: Set ALU to GXCopy for blitting
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 at redhat.com>
Suggested-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 012350e3db47fef0404346f55968032e62004fcf)
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 ||
commit 96febe8ba46d7a177f9d26ec69dfbcfd72b0ceae
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Tue May 4 10:56:38 2021 +0200
xwayland/eglstream: Do not always increment pixmap refcnt on commit
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 at redhat.com>
Suggested-by: Michel Dänzer <mdaenzer at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit d85bfa6ab7495281516f3a4b05dc1ff0b2c4bf91)
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 */
commit 7d839b3ed342e89948481e2cc796ef575d412cb5
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Fri Apr 30 09:02:29 2021 +0200
xwayland/eglstream: Check eglSwapBuffers()
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit b583395cd38ad101c7541bd8b0e91143ced44703)
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 */
commit 8b8a9bf6c7dd6b606ed22878ee7decefe507ba01
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Mon Apr 19 14:52:38 2021 +0200
xwayland/eglstream: Fix calloc/malloc
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit a45799971083c47082d085d3732a5b12692cf75b)
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);
commit 15e550cc9a5a7fff7f97d74e22cf96bcb0fbf568
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Mon Apr 19 18:11:19 2021 +0200
xwayland/eglstream: Do not commit without surface
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 098e0f52c088c6eb52c7e54c5a11cefabd480908)
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);
}
}
commit 01319a9006d32286b73bdff0417bd7da47d2724d
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Tue Apr 27 14:17:19 2021 +0200
xwayland/eglstream: Drop the list of pending streams
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 at redhat.com>
Suggested-by: Michel Dänzer <mdaenzer at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit bee2ebb29f0999862ab39af26c673c00af40b082)
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;
commit 77617490fc9182896e12cc7668f1957178e27eb2
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Wed Apr 14 17:31:08 2021 +0200
xwayland/eglstream: Keep a reference to the pixmap
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at 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)
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);
commit b05b19df014bccfc28650ae1ce150b9bb25bcfdd
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Fri Apr 16 10:38:23 2021 +0200
xwayland/eglstream: Dissociate pending stream from window
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit cb61ecc7291cfbed2f76d4437cd7450b8e4dab00)
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;
}
commit 1cce4bfd684116a8af936ca2ca1756482ed246cb
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Thu Apr 1 08:46:52 2021 +0200
xwayland/eglstream: Add more error checking
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit cc596bcfb273eeab82ac3d59867668af8bad2abf)
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 =
commit 526cb24826d576c016048fe6e3143efa6d50a176
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Thu Apr 15 10:59:36 2021 +0200
xwayland/eglstream: Small refactoring
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 at redhat.com>
Acked-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 823f3254fabd16e5e721da57cd260beac9b8f8bd)
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;
}
commit 72790f7446996a354d08de6db7a8b35a2d793e68
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Wed Mar 31 09:49:35 2021 +0200
xwayland/eglstream: Check framebuffer status
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 85244d2a2081d61a2e4a06e847041f638de01e3f)
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
commit 46dc7e8ee355a97fb422f2dcc6f12bbaeb4a1c0c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Wed Mar 31 13:57:45 2021 +0200
xwayland/glamor: Add return status to post_damage
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 at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 252cbad316f43edc08aa5c844789398a58ba270c)
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);
commit 673676e759427fd30799e45c12600268c240fc39
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Tue Mar 30 08:48:25 2021 +0200
glamor: Dump backtrace on GL error
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 at redhat.com>
Reviewed-by: Martin Peres <martin.peres at mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 3b265c59a6456f6e4abfb9e1694237bc56f1776a)
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();
}
/**
commit 740f00d44f5b2b6eed22474b1067903c82f1aa8c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Mon Mar 29 15:01:15 2021 +0200
xwayland: Check buffer prior to attaching it
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 at redhat.com>
Reviewed-by: Martin Peres <martin.peres at mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 25d2f4948f0abd39e099b8ac69b7cb1dab38a10a)
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);
commit 8499fc0671666399a906f976fe6c57c5759a1e9e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Mon Mar 29 14:22:56 2021 +0200
xwayland/eglstream: Check buffer creation
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 at redhat.com>
Reviewed-by: Martin Peres <martin.peres at mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
(cherry picked from commit 4f0889e98306d30a37aba0fadb1fd3790c13205a)
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
commit d60acf6f0b403b8f0f026c3ffcdae0c9b57a60bd
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Tue Apr 27 07:23:44 2021 -0400
xwayland-eglstream: fix X11 rendering to flipping GL / VK window
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 at nvidia.com>
Acked-by: Olivier Fourdan <ofourdan at redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
(cherry picked from commit 4f6fbd5009ae533cf0b3bbe382502254f9276a01)
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
commit 3d10978cb635db46facacf9667d2090e3f90b28c
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Thu Dec 3 14:57:51 2020 -0800
xwayland: implement pixmap_from_buffers for the eglstream backend
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 at redhat.com>
Acked-by: Olivier Fourdan <ofourdan at redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>
(cherry picked from commit 38e875904b039ec1889e7c81eb1d577a4f69b26d)
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))
commit f44b22b0c6178736124bd7f6991c04049639f792
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Wed Mar 3 11:56:41 2021 +0100
xwayland: Add check_flip() glamor backend function
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 at redhat.com>
Acked-by: Olivier Fourdan <ofourdan at redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>
(cherry picked from commit bc99dd2127f12f1aae55971c09a2792eeaa98444)
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 */
commit 15d3756814755fa9af59166705d957d9d0e4fbb2
Author: Erik Kurzinger <ekurzinger at nvidia.com>
Date: Fri Feb 12 12:09:27 2021 -0800
xwayland: move formats and modifiers functions to common glamor code
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 at redhat.com>
Acked-by: Olivier Fourdan <ofourdan at redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger at nvidia.com>
(cherry picked from commit 400d4d0fdd55192f394e1a8273dfb2423c895ec0)
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 */
commit 1f65893873cf65e96c90d6001b7bce82f5a55ccc
Author: Olivier Fourdan <ofourdan at redhat.com>
Date: Wed Mar 3 09:55:12 2021 +0100
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 at redhat.com>
(cherry picked from commit ae225417c0a0828ffb24e11eb4b968c34692e25a)
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;
More information about the xorg-commit
mailing list