[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