egl: Implement EGL_EXT_explicit_device
Implement support for EGL_EXT_explicit_device[1]. [1] https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_explicit_device.txt Signed-off-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Robert Foss <rfoss@redhat.com> Reviewed-by: Eric Engestrom <eric@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23873>
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#include "util/os_file.h"
|
||||
|
||||
#include "egl_dri2.h"
|
||||
#include "egldevice.h"
|
||||
#include "loader.h"
|
||||
|
||||
static struct gbm_bo *
|
||||
@@ -579,10 +580,28 @@ dri2_initialize_drm(_EGLDisplay *disp)
|
||||
|
||||
gbm = disp->PlatformDisplay;
|
||||
if (gbm == NULL) {
|
||||
char buf[64];
|
||||
int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
|
||||
if (n != -1 && n < sizeof(buf))
|
||||
dri2_dpy->fd_render_gpu = loader_open_device(buf);
|
||||
if (disp->Device) {
|
||||
drmDevicePtr drm = _eglDeviceDrm(disp->Device);
|
||||
|
||||
if (!_eglDeviceSupports(disp->Device, _EGL_DEVICE_DRM)) {
|
||||
err = "DRI2: Device isn't of _EGL_DEVICE_DRM type";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(drm->available_nodes & (1 << DRM_NODE_PRIMARY))) {
|
||||
err = "DRI2: Device does not have DRM_NODE_PRIMARY node";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dri2_dpy->fd_render_gpu =
|
||||
loader_open_device(drm->nodes[DRM_NODE_PRIMARY]);
|
||||
} else {
|
||||
char buf[64];
|
||||
int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
|
||||
if (n != -1 && n < sizeof(buf))
|
||||
dri2_dpy->fd_render_gpu = loader_open_device(buf);
|
||||
}
|
||||
|
||||
gbm = gbm_create_device(dri2_dpy->fd_render_gpu);
|
||||
if (gbm == NULL) {
|
||||
err = "DRI2: failed to create gbm device";
|
||||
|
@@ -474,18 +474,45 @@ _eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
|
||||
_EGLDisplay *
|
||||
_eglGetX11Display(Display *native_display, const EGLAttrib *attrib_list)
|
||||
{
|
||||
/* EGL_EXT_platform_x11 recognizes exactly one attribute,
|
||||
* EGL_PLATFORM_X11_SCREEN_EXT, which is optional.
|
||||
_EGLDisplay *dpy;
|
||||
_EGLDevice *dev = NULL;
|
||||
|
||||
/* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
|
||||
* which is optional.
|
||||
*/
|
||||
if (attrib_list != NULL) {
|
||||
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
|
||||
if (attrib_list[i] != EGL_PLATFORM_X11_SCREEN_EXT) {
|
||||
EGLAttrib attrib = attrib_list[i];
|
||||
EGLAttrib value = attrib_list[i + 1];
|
||||
|
||||
switch (attrib) {
|
||||
case EGL_DEVICE_EXT:
|
||||
dev = _eglLookupDevice((void *)value);
|
||||
if (!dev) {
|
||||
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
/* EGL_EXT_platform_x11 adds EGL_PLATFORM_X11_SCREEN_EXT,
|
||||
* which is optional.
|
||||
*/
|
||||
case EGL_PLATFORM_X11_SCREEN_EXT:
|
||||
break;
|
||||
|
||||
default:
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _eglFindDisplay(_EGL_PLATFORM_X11, native_display, attrib_list);
|
||||
|
||||
dpy = _eglFindDisplay(_EGL_PLATFORM_X11, native_display, attrib_list);
|
||||
if (dpy && dev) {
|
||||
dpy->Device = dev;
|
||||
}
|
||||
|
||||
return dpy;
|
||||
}
|
||||
#endif /* HAVE_X11_PLATFORM */
|
||||
|
||||
@@ -494,19 +521,42 @@ _EGLDisplay *
|
||||
_eglGetXcbDisplay(xcb_connection_t *native_display,
|
||||
const EGLAttrib *attrib_list)
|
||||
{
|
||||
_EGLDisplay *dpy;
|
||||
_EGLDevice *dev = NULL;
|
||||
|
||||
/* EGL_EXT_platform_xcb recognizes exactly one attribute,
|
||||
* EGL_PLATFORM_XCB_SCREEN_EXT, which is optional.
|
||||
*/
|
||||
if (attrib_list != NULL) {
|
||||
for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
|
||||
if (attrib_list[i] != EGL_PLATFORM_XCB_SCREEN_EXT) {
|
||||
EGLAttrib attrib = attrib_list[i];
|
||||
EGLAttrib value = attrib_list[i + 1];
|
||||
|
||||
switch (attrib) {
|
||||
case EGL_DEVICE_EXT:
|
||||
dev = _eglLookupDevice((void *)value);
|
||||
if (!dev) {
|
||||
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_XCB_SCREEN_EXT:
|
||||
break;
|
||||
|
||||
default:
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _eglFindDisplay(_EGL_PLATFORM_XCB, native_display, attrib_list);
|
||||
dpy = _eglFindDisplay(_EGL_PLATFORM_XCB, native_display, attrib_list);
|
||||
if (dpy && dev) {
|
||||
dpy->Device = dev;
|
||||
}
|
||||
|
||||
return dpy;
|
||||
}
|
||||
#endif /* HAVE_XCB_PLATFORM */
|
||||
|
||||
@@ -515,13 +565,28 @@ _EGLDisplay *
|
||||
_eglGetGbmDisplay(struct gbm_device *native_display,
|
||||
const EGLAttrib *attrib_list)
|
||||
{
|
||||
/* EGL_MESA_platform_gbm recognizes no attributes. */
|
||||
if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
_EGLDisplay *dpy;
|
||||
_EGLDevice *dev = NULL;
|
||||
|
||||
/* This platform recognizes only EXT_explicit_device */
|
||||
if (attrib_list) {
|
||||
if (attrib_list[0] != EGL_DEVICE_EXT) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
dev = _eglLookupDevice((void *)attrib_list[1]);
|
||||
if (!dev) {
|
||||
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display, attrib_list);
|
||||
dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, native_display, attrib_list);
|
||||
if (dpy) {
|
||||
dpy->Device = dev;
|
||||
}
|
||||
|
||||
return dpy;
|
||||
}
|
||||
#endif /* HAVE_DRM_PLATFORM */
|
||||
|
||||
@@ -530,33 +595,62 @@ _EGLDisplay *
|
||||
_eglGetWaylandDisplay(struct wl_display *native_display,
|
||||
const EGLAttrib *attrib_list)
|
||||
{
|
||||
/* EGL_EXT_platform_wayland recognizes no attributes. */
|
||||
if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
_EGLDisplay *dpy;
|
||||
_EGLDevice *dev = NULL;
|
||||
|
||||
/* This platform recognizes only EXT_explicit_device */
|
||||
if (attrib_list) {
|
||||
if (attrib_list[0] != EGL_DEVICE_EXT) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
dev = _eglLookupDevice((void *)attrib_list[1]);
|
||||
if (!dev) {
|
||||
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display, attrib_list);
|
||||
dpy = _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display, attrib_list);
|
||||
if (dpy) {
|
||||
dpy->Device = dev;
|
||||
}
|
||||
|
||||
return dpy;
|
||||
}
|
||||
#endif /* HAVE_WAYLAND_PLATFORM */
|
||||
|
||||
_EGLDisplay *
|
||||
_eglGetSurfacelessDisplay(void *native_display, const EGLAttrib *attrib_list)
|
||||
{
|
||||
/* This platform has no native display. */
|
||||
_EGLDisplay *dpy;
|
||||
|
||||
/* Any native display must be an EGLDeviceEXT we know about */
|
||||
if (native_display != NULL) {
|
||||
_eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This platform recognizes no display attributes. */
|
||||
if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
/* This platform recognizes only EXT_explicit_device */
|
||||
if (attrib_list) {
|
||||
if (attrib_list[0] != EGL_DEVICE_EXT) {
|
||||
_eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
if ((native_display && native_display != (void *)attrib_list[1]) ||
|
||||
(native_display != _eglLookupDevice(native_display))) {
|
||||
_eglError(EGL_BAD_DEVICE_EXT, "eglGetPlatformDisplay");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display,
|
||||
attrib_list);
|
||||
dpy =
|
||||
_eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display, attrib_list);
|
||||
if (dpy) {
|
||||
dpy->Device = native_display;
|
||||
}
|
||||
|
||||
return dpy;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ANDROID_PLATFORM
|
||||
|
@@ -83,6 +83,7 @@ struct _egl_global _eglGlobal = {
|
||||
|
||||
#if !DETECT_OS_WINDOWS
|
||||
"EGL_EXT_platform_device"
|
||||
" EGL_EXT_explicit_device"
|
||||
#endif
|
||||
#ifdef HAVE_WAYLAND_PLATFORM
|
||||
" EGL_EXT_platform_wayland"
|
||||
|
Reference in New Issue
Block a user