summaryrefslogtreecommitdiff
path: root/582b2d345abaa0e313cf16c902e602084ea59551.patch
diff options
context:
space:
mode:
Diffstat (limited to '582b2d345abaa0e313cf16c902e602084ea59551.patch')
-rw-r--r--582b2d345abaa0e313cf16c902e602084ea59551.patch180
1 files changed, 180 insertions, 0 deletions
diff --git a/582b2d345abaa0e313cf16c902e602084ea59551.patch b/582b2d345abaa0e313cf16c902e602084ea59551.patch
new file mode 100644
index 0000000..e9fe29d
--- /dev/null
+++ b/582b2d345abaa0e313cf16c902e602084ea59551.patch
@@ -0,0 +1,180 @@
+From 582b2d345abaa0e313cf16c902e602084ea59551 Mon Sep 17 00:00:00 2001
+From: Erik Kurzinger <ekurzinger@nvidia.com>
+Date: Tue, 23 Nov 2021 14:15:14 -0500
+Subject: [PATCH] egl-wayland: retrieve DRM device name before acquiring API
+ lock
+
+wlEglBindDisplaysHook acquires the external API lock before calling
+wl_eglstream_display_bind, which in turn calls wl_drm_display_bind. That
+function calls back into EGL to query the DRM device associated with the
+given EGLDisplay.
+
+Normally this is not a problem since the EGLDisplay passed to
+eglBindWaylandDisplayWL will be an internal EGL_PLATFORM_DEVICE handle.
+However, some applications, notably anything WebKit-based, will instead
+pass in an external EGL_PLATFORM_WAYLAND handle. This means that the
+eglQueryDisplayAttrib call by wl_drm_display_bind will require EGL to
+call back into the egl-wayland library to look up the internal handle.
+This is done by wlEglGetInternalHandleExport, which will attempt to
+acquire the external API lock a second time, which will fail.
+
+To avoid this, add a new function to wayland-drm.c which will retrieve
+the DRM device name for the given EGLDisplay. wlEglBindDisplaysHook will
+call this *before* acquiring the external API lock, and then pass it to
+wl_drm_display_bind via wl_eglstream_display_bind so it can be saved in
+the wl_eglstream_display struct.
+---
+ include/wayland-drm.h | 7 ++++++-
+ include/wayland-eglstream-server.h | 3 ++-
+ src/wayland-drm.c | 33 +++++++++++++++---------------
+ src/wayland-egldisplay.c | 8 +++++---
+ src/wayland-eglstream-server.c | 5 +++--
+ 5 files changed, 32 insertions(+), 24 deletions(-)
+
+diff --git a/include/wayland-drm.h b/include/wayland-drm.h
+index be363c6..84d0f11 100644
+--- a/include/wayland-drm.h
++++ b/include/wayland-drm.h
+@@ -23,9 +23,14 @@
+ #ifndef WAYLAND_DRM_H
+ #define WAYLAND_DRM_H
+
++extern const char *
++wl_drm_get_dev_name(const WlEglPlatformData *data,
++ EGLDisplay dpy);
++
+ extern EGLBoolean
+ wl_drm_display_bind(struct wl_display *display,
+- struct wl_eglstream_display *wlStreamDpy);
++ struct wl_eglstream_display *wlStreamDpy,
++ const char *dev_name);
+ extern void
+ wl_drm_display_unbind(struct wl_eglstream_display *wlStreamDpy);
+
+diff --git a/include/wayland-eglstream-server.h b/include/wayland-eglstream-server.h
+index 76e772c..0f7d477 100644
+--- a/include/wayland-eglstream-server.h
++++ b/include/wayland-eglstream-server.h
+@@ -49,7 +49,8 @@ EGLBoolean
+ wl_eglstream_display_bind(WlEglPlatformData *data,
+ struct wl_display *wlDisplay,
+ EGLDisplay eglDisplay,
+- const char *exts);
++ const char *exts,
++ const char *dev_name);
+
+ /*
+ * wl_eglstream_display_unbind()
+diff --git a/src/wayland-drm.c b/src/wayland-drm.c
+index aa6de23..a08d82f 100644
+--- a/src/wayland-drm.c
++++ b/src/wayland-drm.c
+@@ -152,37 +152,36 @@ bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+ wl_resource_post_event(resource, WL_DRM_CAPABILITIES, 0);
+ }
+
+-EGLBoolean
+-wl_drm_display_bind(struct wl_display *display,
+- struct wl_eglstream_display *wlStreamDpy)
++const char *
++wl_drm_get_dev_name(const WlEglPlatformData *data,
++ EGLDisplay dpy)
+ {
+- EGLDisplay dpy = wlStreamDpy->eglDisplay;
+ EGLDeviceEXT egl_dev;
+ const char *dev_exts;
+- const char *dev_name;
+
+- if (!wlStreamDpy->data->egl.queryDisplayAttrib(dpy,
+- EGL_DEVICE_EXT,
+- (EGLAttribKHR*)&egl_dev)) {
+- return EGL_FALSE;
++ if (!data->egl.queryDisplayAttrib(dpy, EGL_DEVICE_EXT,
++ (EGLAttribKHR*)&egl_dev)) {
++ return NULL;
+ }
+
+-
+- dev_exts = wlStreamDpy->data->egl.queryDeviceString(egl_dev,
+- EGL_EXTENSIONS);
++ dev_exts = data->egl.queryDeviceString(egl_dev, EGL_EXTENSIONS);
+
+ if (!dev_exts) {
+- return EGL_FALSE;
++ return NULL;
+ }
+
+ if (!wlEglFindExtension("EGL_EXT_device_drm_render_node", dev_exts)) {
+- return EGL_FALSE;
++ return NULL;
+ }
+
+- dev_name =
+- wlStreamDpy->data->egl.queryDeviceString(egl_dev,
+- EGL_DRM_RENDER_NODE_FILE_EXT);
++ return data->egl.queryDeviceString(egl_dev, EGL_DRM_RENDER_NODE_FILE_EXT);
++}
+
++EGLBoolean
++wl_drm_display_bind(struct wl_display *display,
++ struct wl_eglstream_display *wlStreamDpy,
++ const char *dev_name)
++{
+ if (!dev_name) {
+ return EGL_FALSE;
+ }
+diff --git a/src/wayland-egldisplay.c b/src/wayland-egldisplay.c
+index 8b7394a..d285bf7 100644
+--- a/src/wayland-egldisplay.c
++++ b/src/wayland-egldisplay.c
+@@ -30,6 +30,7 @@
+ #include "wayland-eglhandle.h"
+ #include "wayland-eglutils.h"
+ #include "wayland-drm-client-protocol.h"
++#include "wayland-drm.h"
+ #include <string.h>
+ #include <stdlib.h>
+ #include <assert.h>
+@@ -70,15 +71,16 @@ EGLBoolean wlEglIsValidNativeDisplayExport(void *data, void *nativeDpy)
+
+ EGLBoolean wlEglBindDisplaysHook(void *data, EGLDisplay dpy, void *nativeDpy)
+ {
+- /* Retrieve extension string before taking external API lock */
+- const char *exts = ((WlEglPlatformData *)data)->egl.queryString(dpy, EGL_EXTENSIONS);
++ /* Retrieve extension string and device name before taking external API lock */
++ const char *exts = ((WlEglPlatformData *)data)->egl.queryString(dpy, EGL_EXTENSIONS),
++ *dev_name = wl_drm_get_dev_name(data, dpy);
+ EGLBoolean res = EGL_FALSE;
+
+ wlExternalApiLock();
+
+ res = wl_eglstream_display_bind((WlEglPlatformData *)data,
+ (struct wl_display *)nativeDpy,
+- dpy, exts);
++ dpy, exts, dev_name);
+
+ wlExternalApiUnlock();
+
+diff --git a/src/wayland-eglstream-server.c b/src/wayland-eglstream-server.c
+index b1baa08..1dfd7ce 100644
+--- a/src/wayland-eglstream-server.c
++++ b/src/wayland-eglstream-server.c
+@@ -289,7 +289,8 @@ EGLBoolean
+ wl_eglstream_display_bind(WlEglPlatformData *data,
+ struct wl_display *wlDisplay,
+ EGLDisplay eglDisplay,
+- const char *exts)
++ const char *exts,
++ const char *dev_name)
+ {
+ struct wl_eglstream_display *wlStreamDpy = NULL;
+ char *env = NULL;
+@@ -355,7 +356,7 @@ wl_eglstream_display_bind(WlEglPlatformData *data,
+ wl_eglstream_display_global_bind);
+
+ /* Failure is not fatal */
+- wl_drm_display_bind(wlDisplay, wlStreamDpy);
++ wl_drm_display_bind(wlDisplay, wlStreamDpy, dev_name);
+
+ wl_list_insert(&wlStreamDpyList, &wlStreamDpy->link);
+