diff options
Diffstat (limited to '582b2d345abaa0e313cf16c902e602084ea59551.patch')
-rw-r--r-- | 582b2d345abaa0e313cf16c902e602084ea59551.patch | 180 |
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); + |