[Mesa-dev] [PATCH 25/25] egl/main: Enable Linux platform extensions
Chad Versace
chad.versace at linux.intel.com
Sun Feb 9 13:38:01 PST 2014
Enable EGL_EXT_platform_base and the Linux platform extensions layered
atop it: EGL_EXT_platform_x11, EGL_EXT_platform_wayland,
and EGL_MESA_platform_gbm.
Tested with Piglit's EGL_EXT_platform_base tests under an X11 session.
To enable running the Wayland and GBM tests, windowed Weston was running
and the kernel had render nodes enabled.
Also tested by running weston-smoke in stand-alone Weston.
Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
---
src/egl/main/eglapi.c | 132 ++++++++++++++++++++++++++++++++++++++--------
src/egl/main/egldisplay.c | 72 +++++++++++++++++++++++++
src/egl/main/egldisplay.h | 20 +++++++
src/egl/main/eglglobals.c | 10 +++-
src/egl/main/eglglobals.h | 4 ++
5 files changed, 215 insertions(+), 23 deletions(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 8a64f8a..d40fe1b 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -308,6 +308,36 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
return _eglGetDisplayHandle(dpy);
}
+EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *dpy;
+
+ switch (platform) {
+#ifdef HAVE_X11_PLATFORM
+ case EGL_PLATFORM_X11_EXT:
+ dpy = _eglGetX11Display((Display*) native_display, attrib_list);
+ break;
+#endif
+#ifdef HAVE_DRM_PLATFORM
+ case EGL_PLATFORM_GBM_MESA:
+ dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
+ attrib_list);
+ break;
+#endif
+#ifdef HAVE_WAYLAND_PLATFORM
+ case EGL_PLATFORM_WAYLAND_EXT:
+ dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
+ attrib_list);
+ break;
+#endif
+ default:
+ RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
+ }
+
+ return _eglGetDisplayHandle(dpy);
+}
/**
* This is typically the second EGL function that an application calls.
@@ -530,25 +560,17 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
}
-EGLSurface EGLAPIENTRY
-eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
- EGLNativeWindowType window, const EGLint *attrib_list)
+static EGLSurface
+_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
+ void *native_window, const EGLint *attrib_list)
{
- _EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLConfig *conf = _eglLookupConfig(config, disp);
_EGLDriver *drv;
_EGLSurface *surf;
EGLSurface ret;
- void *native_window_ptr;
-
- STATIC_ASSERT(sizeof(void*) == sizeof(window));
- native_window_ptr = (void*) window;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
- if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
- RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
-
- surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window_ptr,
+ surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -557,24 +579,52 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLSurface EGLAPIENTRY
-eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
- EGLNativePixmapType pixmap, const EGLint *attrib_list)
+eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType window, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ STATIC_ASSERT(sizeof(void*) == sizeof(window));
+ return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
+ attrib_list);
+}
+
+
+EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+#ifdef HAVE_X11_PLATFORM
+ if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
+ /* The `native_window` parameter for the X11 platform differs between
+ * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
+ * eglCreateWindowSurface(), the type of `native_window` is an Xlib
+ * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
+ * `Window*`. Convert `Window*` to `Window` because that's what
+ * dri2_x11_create_window_surface() expects.
+ */
+ native_window = (void*) (* (Window*) native_window);
+ }
+#endif
+
+ return _eglCreateWindowSurfaceCommon(disp, config, native_window,
+ attrib_list);
+}
+
+
+static EGLSurface
+_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
+ void *native_pixmap, const EGLint *attrib_list)
+{
_EGLConfig *conf = _eglLookupConfig(config, disp);
_EGLDriver *drv;
_EGLSurface *surf;
EGLSurface ret;
- void *native_pixmap_ptr;
-
- STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
- native_pixmap_ptr = (void*) pixmap;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
- if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
- RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
-
- surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap_ptr,
+ surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
attrib_list);
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -583,6 +633,41 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLSurface EGLAPIENTRY
+eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
+ return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
+ attrib_list);
+}
+
+EGLSurface EGLAPIENTRY
+eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
+ void *native_pixmap,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+#ifdef HAVE_X11_PLATFORM
+ /* The `native_pixmap` parameter for the X11 platform differs between
+ * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
+ * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
+ * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
+ * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
+ * dri2_x11_create_pixmap_surface() expects.
+ */
+ if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
+ native_pixmap = (void*) (* (Pixmap*) native_pixmap);
+ }
+#endif
+
+ return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
+ attrib_list);
+}
+
+
+EGLSurface EGLAPIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
@@ -1001,6 +1086,9 @@ eglGetProcAddress(const char *procname)
#ifdef EGL_EXT_swap_buffers_with_damage
{ "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
#endif
+ { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
+ { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
+ { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
{ NULL, NULL }
};
EGLint i;
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index e5d126e..718523a 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
+#include "eglcurrent.h"
#include "eglsurface.h"
#include "egldisplay.h"
#include "egldriver.h"
@@ -454,3 +455,74 @@ _eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
/* We always unlink before destroy. The driver still owns a reference */
assert(res->RefCount);
}
+
+#ifdef HAVE_X11_PLATFORM
+static EGLBoolean
+_eglParseX11DisplayAttribList(const EGLint *attrib_list)
+{
+ int i;
+
+ if (attrib_list == NULL) {
+ return EGL_TRUE;
+ }
+
+ for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
+ EGLint attrib = attrib_list[i];
+ EGLint value = attrib_list[i + 1];
+
+ /* EGL_EXT_platform_x11 recognizes exactly one attribute,
+ * EGL_PLATFORM_X11_SCREEN_EXT, which is optional.
+ *
+ * Mesa supports connecting to only the default screen, so we reject
+ * screen != 0.
+ */
+ if (attrib != EGL_PLATFORM_X11_SCREEN_EXT || value != 0) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return EGL_FALSE;
+ }
+ }
+
+ return EGL_TRUE;
+}
+
+_EGLDisplay*
+_eglGetX11Display(Display *native_display,
+ const EGLint *attrib_list)
+{
+ if (!_eglParseX11DisplayAttribList(attrib_list)) {
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_X11, native_display);
+}
+#endif /* HAVE_X11_PLATFORM */
+
+#ifdef HAVE_DRM_PLATFORM
+_EGLDisplay*
+_eglGetGbmDisplay(struct gbm_device *native_display,
+ const EGLint *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;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display);
+}
+#endif /* HAVE_DRM_PLATFORM */
+
+#ifdef HAVE_WAYLAND_PLATFORM
+_EGLDisplay*
+_eglGetWaylandDisplay(struct wl_display *native_display,
+ const EGLint *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;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display);
+}
+#endif /* HAVE_WAYLAND_PLATFORM */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index ef3524c..d5722ba 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -241,5 +241,25 @@ _eglIsResourceLinked(_EGLResource *res)
return res->IsLinked;
}
+#ifdef HAVE_X11_PLATFORM
+_EGLDisplay*
+_eglGetX11Display(Display *native_display, const EGLint *attrib_list);
+#endif
+
+#ifdef HAVE_DRM_PLATFORM
+struct gbm_device;
+
+_EGLDisplay*
+_eglGetGbmDisplay(struct gbm_device *native_display,
+ const EGLint *attrib_list);
+#endif
+
+#ifdef HAVE_WAYLAND_PLATFORM
+struct wl_display;
+
+_EGLDisplay*
+_eglGetWaylandDisplay(struct wl_display *native_display,
+ const EGLint *attrib_list);
+#endif
#endif /* EGLDISPLAY_INCLUDED */
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index 956fa91..cf669cf 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -51,11 +51,19 @@ struct _egl_global _eglGlobal =
/* ClientExtensions */
{
- true /* EGL_EXT_client_extensions */
+ true, /* EGL_EXT_client_extensions */
+ true, /* EGL_EXT_platform_base */
+ true, /* EGL_EXT_platform_x11 */
+ true, /* EGL_EXT_platform_wayland */
+ true /* EGL_MESA_platform_gbm */
},
/* ClientExtensionsString */
"EGL_EXT_client_extensions"
+ " EGL_EXT_platform_base"
+ " EGL_EXT_platform_x11"
+ " EGL_EXT_platform_wayland"
+ " EGL_MESA_platform_gbm"
};
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index 5ec6769..9046ea2 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -52,6 +52,10 @@ struct _egl_global
struct _egl_client_extensions {
bool EXT_client_extensions;
+ bool EXT_platform_base;
+ bool EXT_platform_x11;
+ bool EXT_platform_wayland;
+ bool MESA_platform_gbm;
} ClientExtensions;
const char *ClientExtensionString;
--
1.8.5.3
More information about the mesa-dev
mailing list