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