Blame SOURCES/582b2d345abaa0e313cf16c902e602084ea59551.patch

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