summaryrefslogtreecommitdiff
path: root/src/egl/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main')
-rw-r--r--src/egl/main/eglapi.c13
-rw-r--r--src/egl/main/egldevice.c16
-rw-r--r--src/egl/main/egldevice.h3
-rw-r--r--src/egl/main/egldisplay.c67
-rw-r--r--src/egl/main/egldisplay.h7
-rw-r--r--src/egl/main/eglglobals.c1
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,