diff options
author | CoprDistGit <infra@openeuler.org> | 2024-08-05 01:51:44 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-08-05 01:51:44 +0000 |
commit | 8e833e975d46c1347c5d0096d6efe3863cfbb771 (patch) | |
tree | f138da1f6668689f4034d769dfc2e5eaea6ebf5c /d4937adc5cd04ac7df98fc5616e40319fb52fdee.patch | |
parent | eb85001113e7452f2fe7866ef31b47a231dd1ddc (diff) |
automatic import of egl-waylandopeneuler24.03_LTS
Diffstat (limited to 'd4937adc5cd04ac7df98fc5616e40319fb52fdee.patch')
-rw-r--r-- | d4937adc5cd04ac7df98fc5616e40319fb52fdee.patch | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/d4937adc5cd04ac7df98fc5616e40319fb52fdee.patch b/d4937adc5cd04ac7df98fc5616e40319fb52fdee.patch new file mode 100644 index 0000000..48845f9 --- /dev/null +++ b/d4937adc5cd04ac7df98fc5616e40319fb52fdee.patch @@ -0,0 +1,268 @@ +From d4937adc5cd04ac7df98fc5616e40319fb52fdee Mon Sep 17 00:00:00 2001 +From: Austin Shafer <ashafer@nvidia.com> +Date: Wed, 27 Oct 2021 06:37:07 -0400 +Subject: [PATCH] wayland: Fail eglGetDisplay if wl_drm is not available + +This patch does two things: +- checks if wl_drm is in use on the server, and uses it to get the name + of the drm device the compositor is driving. +- Find an EGLDevice that matches the path returned by wl_drm. + +If wl_drm and the needed extensions are not present, or if a matching +EGLDevice is not found, then we fail. Right now we only support +running on the same GPU as the compositor, so any of these being +missing means that is not the case. +--- + src/wayland-egldisplay.c | 153 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 138 insertions(+), 15 deletions(-) + +diff --git a/src/wayland-egldisplay.c b/src/wayland-egldisplay.c +index a0370a5..8b7394a 100644 +--- a/src/wayland-egldisplay.c ++++ b/src/wayland-egldisplay.c +@@ -29,13 +29,19 @@ + #include "wayland-eglsurface.h" + #include "wayland-eglhandle.h" + #include "wayland-eglutils.h" ++#include "wayland-drm-client-protocol.h" + #include <string.h> + #include <stdlib.h> + #include <assert.h> ++#include <unistd.h> ++#include <fcntl.h> + + typedef struct WlServerProtocolsRec { + EGLBoolean hasEglStream; + EGLBoolean hasDmaBuf; ++ EGLBoolean hasDrm; ++ struct wl_drm *wldrm; ++ char *drm_name; + } WlServerProtocols; + + /* TODO: Make global display lists hang off platform data */ +@@ -241,6 +247,40 @@ static const struct wl_registry_listener registry_listener = { + registry_handle_global_remove + }; + ++static void wl_drm_device(void *data, struct wl_drm *wl_drm, const char *name) ++{ ++ WlServerProtocols *protocols = (WlServerProtocols *)data; ++ (void) wl_drm; ++ ++ protocols->drm_name = strdup(name); ++} ++ ++static void wl_drm_authenticated(void *data, struct wl_drm *wl_drm) ++{ ++ (void) data; ++ (void) wl_drm; ++} ++static void wl_drm_format(void *data, struct wl_drm *wl_drm, uint32_t format) ++{ ++ (void) data; ++ (void) wl_drm; ++ (void) format; ++} ++static void wl_drm_capabilities(void *data, struct wl_drm *wl_drm, uint32_t value) ++{ ++ (void) data; ++ (void) wl_drm; ++ (void) value; ++} ++ ++static const struct wl_drm_listener drmListener = { ++ .device = wl_drm_device, ++ .authenticated = wl_drm_authenticated, ++ .format = wl_drm_format, ++ .capabilities = wl_drm_capabilities, ++}; ++ ++ + static void + registry_handle_global_check_protocols( + void *data, +@@ -262,6 +302,12 @@ registry_handle_global_check_protocols( + (version >= 3)) { + protocols->hasDmaBuf = EGL_TRUE; + } ++ ++ if ((strcmp(interface, "wl_drm") == 0) && (version >= 2)) { ++ protocols->hasDrm = EGL_TRUE; ++ protocols->wldrm = wl_registry_bind(registry, name, &wl_drm_interface, 2); ++ wl_drm_add_listener(protocols->wldrm, &drmListener, protocols); ++ } + } + + static void +@@ -389,8 +435,8 @@ EGLBoolean wlEglTerminateHook(EGLDisplay dpy) + return res; + } + +-static void checkServerProtocols(struct wl_display *nativeDpy, +- WlServerProtocols *protocols) ++static void getServerProtocolsInfo(struct wl_display *nativeDpy, ++ WlServerProtocols *protocols) + { + struct wl_display *wrapper = NULL; + struct wl_registry *wlRegistry = NULL; +@@ -418,6 +464,11 @@ static void checkServerProtocols(struct wl_display *nativeDpy, + protocols); + if (ret == 0) { + wl_display_roundtrip_queue(nativeDpy, queue); ++ if (protocols->hasDrm) { ++ wl_display_roundtrip_queue(nativeDpy, queue); ++ /* destroy our wl_drm object */ ++ wl_drm_destroy(protocols->wldrm); ++ } + } + + if (queue) { +@@ -438,9 +489,13 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data, + WlServerProtocols protocols; + EGLint numDevices = 0; + int i = 0; ++ EGLDeviceEXT *eglDeviceList = NULL; + EGLDeviceEXT eglDevice = NULL; ++ EGLDeviceEXT tmpDev = NULL; + EGLint err = EGL_SUCCESS; + EGLBoolean useInitRefCount = EGL_FALSE; ++ const char *dev_exts; ++ const char *dev_name; + + if (platform != EGL_PLATFORM_WAYLAND_EXT) { + wlEglSetError(data, EGL_BAD_PARAMETER); +@@ -480,7 +535,6 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data, + + display = calloc(1, sizeof(*display)); + if (!display) { +- wlExternalApiUnlock(); + err = EGL_BAD_ALLOC; + goto fail; + } +@@ -498,7 +552,6 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data, + if (!display->nativeDpy) { + display->nativeDpy = wl_display_connect(NULL); + if (!display->nativeDpy) { +- wlExternalApiUnlock(); + err = EGL_BAD_ALLOC; + goto fail; + } +@@ -508,26 +561,85 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data, + } + + memset(&protocols, 0, sizeof(protocols)); +- checkServerProtocols(display->nativeDpy, &protocols); ++ /* ++ * This is where we check the supported protocols on the compositor, ++ * and bind to wl_drm to get the device name. ++ * protocols.drm_name will be allocated here if using wl_drm ++ */ ++ getServerProtocolsInfo(display->nativeDpy, &protocols); + +- if (!protocols.hasEglStream && !protocols.hasDmaBuf) { +- wlExternalApiUnlock(); +- goto fail; ++ if (!protocols.hasDrm || (!protocols.hasEglStream && !protocols.hasDmaBuf)) { ++ goto fail_cleanup_protocols; + } + +- if (!pData->egl.queryDevices(1, &eglDevice, &numDevices) || numDevices == 0) { +- wlExternalApiUnlock(); +- goto fail; ++ /* Get the number of devices available */ ++ if (!pData->egl.queryDevices(-1, NULL, &numDevices) || numDevices == 0) { ++ goto fail_cleanup_protocols; ++ } ++ ++ eglDeviceList = calloc(numDevices, sizeof(*eglDeviceList)); ++ if (!eglDeviceList) { ++ goto fail_cleanup_protocols; ++ } ++ ++ /* ++ * Now we need to find an EGLDevice. If wl_drm is in use we will try to find one that ++ * matches the device the compositor is using. We know that device is an nvidia device ++ * since we just checked that above. ++ */ ++ if (!pData->egl.queryDevices(numDevices, eglDeviceList, &numDevices) || numDevices == 0) { ++ goto fail_cleanup_devices; + } ++ ++ if (protocols.drm_name) { ++ for (int i = 0; i < numDevices; i++) { ++ tmpDev = eglDeviceList[i]; ++ ++ /* ++ * To check against the wl_drm name, we need to check if we can use ++ * the drm extension ++ */ ++ dev_exts = display->data->egl.queryDeviceString(tmpDev, ++ EGL_EXTENSIONS); ++ if (dev_exts) { ++ if (wlEglFindExtension("EGL_EXT_device_drm_render_node", dev_exts)) { ++ dev_name = ++ display->data->egl.queryDeviceString(tmpDev, ++ EGL_DRM_RENDER_NODE_FILE_EXT); ++ ++ if (dev_name) { ++ /* ++ * At this point we have gotten the name from wl_drm, gotten ++ * the drm node from the EGLDevice. If they match, then ++ * this is the final device to use, since it is the compositor's ++ * device. ++ */ ++ if (strcmp(dev_name, protocols.drm_name) == 0) { ++ eglDevice = eglDeviceList[0]; ++ break; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ /* ++ * Right now we are pretty much limited to running on the same GPU as the ++ * compositor. If we couldn't find an EGLDevice that has EGL_EXT_device_drm_render_node ++ * and the same DRM device path, then fail. ++ */ ++ if (!eglDevice) { ++ goto fail_cleanup_devices; ++ } ++ + display->devDpy = wlGetInternalDisplay(pData, eglDevice); + if (display->devDpy == NULL) { +- wlExternalApiUnlock(); +- goto fail; ++ goto fail_cleanup_devices; + } + + if (!wlEglInitializeMutex(&display->mutex)) { +- wlExternalApiUnlock(); +- goto fail; ++ goto fail_cleanup_devices; + } + display->refCount = 1; + WL_LIST_INIT(&display->wlEglSurfaceList); +@@ -537,10 +649,21 @@ EGLDisplay wlEglGetPlatformDisplayExport(void *data, + // in wlEglDisplayList. + wl_list_insert(&wlEglDisplayList, &display->link); + ++ free(eglDeviceList); ++ if (protocols.drm_name) { ++ free(protocols.drm_name); ++ } + wlExternalApiUnlock(); + return display; + ++fail_cleanup_devices: ++ free(eglDeviceList); ++fail_cleanup_protocols: ++ if (protocols.drm_name) { ++ free(protocols.drm_name); ++ } + fail: ++ wlExternalApiUnlock(); + + if (display->ownNativeDpy) { + wl_display_disconnect(display->nativeDpy); |