diff options
Diffstat (limited to 'src/egl/main')
-rw-r--r-- | src/egl/main/eglapi.c | 13 | ||||
-rw-r--r-- | src/egl/main/egldevice.c | 16 | ||||
-rw-r--r-- | src/egl/main/egldevice.h | 3 | ||||
-rw-r--r-- | src/egl/main/egldisplay.c | 67 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 7 | ||||
-rw-r--r-- | src/egl/main/eglglobals.c | 1 |
6 files changed, 100 insertions, 7 deletions
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 05c529ba0a7..ed160e65b20 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -406,6 +406,9 @@ _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display, disp = _eglGetSurfacelessDisplay(native_display, attrib_list); break; #endif + case EGL_PLATFORM_DEVICE_EXT: + disp = _eglGetDeviceDisplay(native_display, attrib_list); + break; default: RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL); } @@ -923,8 +926,8 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config, if (native_window == NULL) RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); -#ifdef HAVE_SURFACELESS_PLATFORM - if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) { + if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS || + disp->Platform == _EGL_PLATFORM_DEVICE)) { /* From the EGL_MESA_platform_surfaceless spec (v1): * * eglCreatePlatformWindowSurface fails when called with a <display> @@ -939,7 +942,6 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config, */ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } -#endif _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); @@ -1050,8 +1052,8 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, _EGLSurface *surf; EGLSurface ret; -#if HAVE_SURFACELESS_PLATFORM - if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) { + if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS || + disp->Platform == _EGL_PLATFORM_DEVICE)) { /* From the EGL_MESA_platform_surfaceless spec (v1): * * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface @@ -1064,7 +1066,6 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config, */ RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); } -#endif _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c index 82af1f47fed..76b8960fa5b 100644 --- a/src/egl/main/egldevice.c +++ b/src/egl/main/egldevice.c @@ -202,6 +202,22 @@ _eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext) }; } +/* Ideally we'll have an extension which passes the render node, + * instead of the card one + magic. + * + * Then we can move this in _eglQueryDeviceStringEXT below. Until then + * keep it separate. + */ +const char * +_eglGetDRMDeviceRenderNode(_EGLDevice *dev) +{ +#ifdef HAVE_LIBDRM + return dev->device->nodes[DRM_NODE_RENDER]; +#else + return NULL; +#endif +} + EGLBoolean _eglQueryDeviceAttribEXT(_EGLDevice *dev, EGLint attribute, EGLAttrib *value) diff --git a/src/egl/main/egldevice.h b/src/egl/main/egldevice.h index 883f96f8e30..83a47d5eacc 100644 --- a/src/egl/main/egldevice.h +++ b/src/egl/main/egldevice.h @@ -68,6 +68,9 @@ typedef enum _egl_device_extension _EGLDeviceExtension; EGLBoolean _eglDeviceSupports(_EGLDevice *dev, _EGLDeviceExtension ext); +const char * +_eglGetDRMDeviceRenderNode(_EGLDevice *dev); + EGLBoolean _eglQueryDeviceAttribEXT(_EGLDevice *dev, EGLint attribute, EGLAttrib *value); diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 422b473844e..91655b73454 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -35,12 +35,14 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include <fcntl.h> #include "c11/threads.h" #include "util/u_atomic.h" #include "eglcontext.h" #include "eglcurrent.h" #include "eglsurface.h" +#include "egldevice.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" @@ -202,6 +204,13 @@ _eglFiniDisplay(void) } } + + /* The fcntl() code in _eglGetDeviceDisplay() ensures that valid fd >= 3, + * and invalid one is 0. + */ + if (disp->Options.fd) + close(disp->Options.fd); + free(disp->Options.Attribs); free(disp); } @@ -557,3 +566,61 @@ _eglGetSurfacelessDisplay(void *native_display, attrib_list); } #endif /* HAVE_SURFACELESS_PLATFORM */ + + +_EGLDisplay* +_eglGetDeviceDisplay(void *native_display, + const EGLAttrib *attrib_list) +{ + _EGLDevice *dev; + _EGLDisplay *display; + int fd = -1; + + dev = _eglLookupDevice(native_display); + if (!dev) { + _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay"); + return NULL; + } + + if (attrib_list) { + for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) { + EGLAttrib attrib = attrib_list[i]; + EGLAttrib value = attrib_list[i + 1]; + + /* EGL_EXT_platform_device does not recognize any attributes, + * EGL_EXT_device_drm adds the optional EGL_DRM_MASTER_FD_EXT. + */ + + if (!_eglDeviceSupports(dev, _EGL_DEVICE_DRM) || + attrib != EGL_DRM_MASTER_FD_EXT) { + _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay"); + return NULL; + } + + fd = (int) value; + } + } + + display = _eglFindDisplay(_EGL_PLATFORM_DEVICE, native_display, attrib_list); + if (!display) { + _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay"); + return NULL; + } + + /* If the fd is explicitly provided and we did not dup() it yet, do so. + * The spec mandates that we do so, since we'll need it past the + * eglGetPlatformDispay call. + * + * The new fd is guaranteed to be 3 or greater. + */ + if (fd != -1 && display->Options.fd == 0) { + display->Options.fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); + if (display->Options.fd == -1) { + /* Do not (really) need to teardown the display */ + _eglError(EGL_BAD_ALLOC, "eglGetPlatformDisplay"); + return NULL; + } + } + + return display; +} diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 369ab31187f..f73ff99fbee 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -50,6 +50,7 @@ enum _egl_platform_type { _EGL_PLATFORM_ANDROID, _EGL_PLATFORM_HAIKU, _EGL_PLATFORM_SURFACELESS, + _EGL_PLATFORM_DEVICE, _EGL_NUM_PLATFORMS, _EGL_INVALID_PLATFORM = -1 @@ -149,7 +150,6 @@ struct _egl_extensions EGLBoolean WL_create_wayland_buffer_from_image; }; - struct _egl_display { /* used to link displays */ @@ -168,6 +168,7 @@ struct _egl_display struct { EGLBoolean ForceSoftware; /**< Use software path only */ EGLAttrib *Attribs; /**< Platform-specific options */ + int fd; /**< plaform device specific, local fd */ } Options; /* these fields are set by the driver during init */ @@ -314,6 +315,10 @@ _eglGetSurfacelessDisplay(void *native_display, const EGLAttrib *attrib_list); #endif +_EGLDisplay* +_eglGetDeviceDisplay(void *native_display, + const EGLAttrib *attrib_list); + #ifdef __cplusplus } #endif diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 2fc64bc52c3..0d7270333ec 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -85,6 +85,7 @@ struct _egl_global _eglGlobal = #ifdef HAVE_SURFACELESS_PLATFORM " EGL_MESA_platform_surfaceless" #endif + " EGL_EXT_platform_device" "", .ClientExtensionString = NULL, |