You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
6.9 KiB
180 lines
6.9 KiB
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); |
|
|
|
|