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:
Adam Jackson
2017-08-02 15:55:08 -04:00
committed by Marge Bot
parent 41e664f825
commit c237539d62
3 changed files with 141 additions and 27 deletions

View File

@@ -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";

View File

@@ -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

View File

@@ -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"