[Mesa-dev] [PATCH 1/4] egl: Add MESA_get_display infrastructure

Kristian Høgsberg krh at bitplanet.net
Thu May 27 18:41:44 PDT 2010


---
 docs/MESA_get_display.spec      |  109 +++++++++++++++++++++++++++++++++++++++
 include/EGL/eglext.h            |   15 +++++
 src/egl/drivers/dri2/egl_dri2.c |   23 ++++++---
 src/egl/drivers/glx/egl_glx.c   |    5 ++
 src/egl/main/eglapi.c           |   13 ++++-
 src/egl/main/egldisplay.c       |    8 ++-
 src/egl/main/egldisplay.h       |    4 +-
 7 files changed, 165 insertions(+), 12 deletions(-)
 create mode 100644 docs/MESA_get_display.spec

diff --git a/docs/MESA_get_display.spec b/docs/MESA_get_display.spec
new file mode 100644
index 0000000..979e2b2
--- /dev/null
+++ b/docs/MESA_get_display.spec
@@ -0,0 +1,109 @@
+Name
+
+    MESA_get_display
+
+Name Strings
+
+    EGL_MESA_get_display
+
+Contact
+
+    Kristian Høgsberg <krh at bitplanet.net>
+
+Status
+
+    Proposal
+
+Version
+
+    Version 1, May 27, 2010
+
+Number
+
+    EGL Extension #not assigned
+
+Dependencies
+
+    Reguires EGL 1.4 or later.  This extension is written against the
+    wording of the EGL 1.4 specification.
+
+Overview
+
+    The EGL platform mechanism was designed to support one type of display
+    per platform.  On Unix, the native display type is an X11 Display
+    pointer, on Windows, the native display type is a handle to a device
+    context (HDC).
+
+    A platform may provide different types of displays.  Under Linux, for
+    example, one might want to initialize an EGL display from an XCB
+    connection or a DRM file descriptor.  However, there is only one EGL
+    entry point for initializing the display and it takes an
+    EGLNativeDisplayType.  To support multiple displays on one platform, one
+    would need multiple EGL libraries.
+
+    This extensions introduces a new entry point that allows an application
+    to pass in different types of displays along with an integer to identify
+    the type of display.  This allows one EGL library to support multiple
+    display types and lets applications clearly identify which one they want
+    to use.
+
+IP Status
+
+    Open-source; freely implementable.
+
+Issues
+
+    1) Should we use official EGL tokens for the display types or just
+    sequential numbers?  Using tokens helps avoiding clashes, but
+    we'll need to allocate those.
+
+    2) We can't detect this as a regular EGL extension as we can't get
+    the extension string until we have an EGL display.  It should be
+    sufficient to just require applications to use eglGetProcAddress()
+    to find out whether or not the eglGetDisplayMESA() entry point is
+    available.  Should we advertise the extension in the EGL extension
+    string anyway?  It's not useful once you have an EGL display.
+
+New Procedures and Functions
+
+    void eglGetDisplayMESA(EGLint type, void *display);
+
+New Tokens
+
+    None.
+
+Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
+
+    Add to section 3.2 Initialization:
+
+    Alternatively, the function
+
+	 void eglGetDisplayMESA(EGLint type, void *display);
+
+    may be used to obtain an EGL display for an alternative type of native
+    display.  'type' identifies the type of native display and 'display'
+    provides the details of the native display.  This extension defines
+    three types of native display types: EGL_DISPLAY_TYPE_NATIVE_MESA,
+    EGL_DISPLAY_TYPE_DRM_MESA, and EGL_DISPLAY_TYPE_XCB_MESA.
+
+    When type is EGL_DISPLAY_TYPE_NATIVE_MESA, the value of 'display' will
+    be interpreted as an EGLNativeDisplayType.  In other words, this is
+    equivalent to calling eglGetDisplay with the value of 'display'.
+
+    When type is EGL_DISPLAY_TYPE_DRM_MESA, the value of 'display' will be
+    interpreted as an integer file descriptor cast to a void pointer.  The
+    file descriptor will be assumed to refer to a DRM device under Linux
+    (typically /dev/dri/card0 or such).
+
+    When type is EGL_DISPLAY_TYPE_XCB_MESA, the value of 'display' will
+    interpreted as an xcb_connection_t pointer as used by the XCB library.
+    The XCB library is a new client side library for the X11 window system.
+
+    If no display matching type and display is available, EGL_NO_DISPLAY is
+    returned; no error condition is raised in this case.
+
+Revision History
+
+    May 27, 2010
+        Initial draft (Kristian Høgsberg)
+
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index e9f5a49..664fe55 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -246,6 +246,21 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #endif /* EGL_NOK_texture_from_pixmap */
 
 
+#ifndef EGL_MESA_get_display
+#define EGL_MESA_get_display 1
+
+#define EGL_DISPLAY_TYPE_NATIVE_MESA	0
+#define EGL_DISPLAY_TYPE_DRM_MESA	1
+#define EGL_DISPLAY_TYPE_XCB_MESA	2
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplayMESA(EGLint type, void *display);
+#endif
+
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYMESA) (EGLint type, void *display);
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index eb9a651..4ca6f80 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -645,14 +645,23 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
 
    disp->DriverData = (void *) dri2_dpy;
-   if (disp->NativeDisplay == NULL) {
-      dri2_dpy->conn = xcb_connect(0, 0);
-      if (!dri2_dpy->conn) {
-	 _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
-	 goto cleanup_dpy;
+   switch (disp->DisplayType) {
+   case EGL_DISPLAY_TYPE_NATIVE_MESA:
+      if (disp->NativeDisplay == NULL) {
+	 dri2_dpy->conn = xcb_connect(0, 0);
+	 if (!dri2_dpy->conn) {
+	    _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
+	    goto cleanup_dpy;
+	 }
+      } else {
+	 dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
       }
-   } else {
-      dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
+      break;
+
+   default:
+      _eglLog(_EGL_WARNING,
+	      "DRI2: unknown display type: %d", disp->DisplayType);
+      goto cleanup_dpy;
    }
 
    if (dri2_dpy->conn == NULL)
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index e08ef5f..cd54c77 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -502,6 +502,11 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
    if (!GLX_dpy)
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
 
+   if (disp->DisplayType != EGL_DISPLAY_TYPE_NATIVE_MESA) {
+      _eglLog(_EGL_WARNING, "GLX: Unsupported display type");
+      return EGL_FALSE;
+   }
+
    GLX_dpy->dpy = (Display *) disp->NativeDisplay;
    if (!GLX_dpy->dpy) {
       GLX_dpy->dpy = XOpenDisplay(NULL);
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 1a533e0..d158714 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -248,7 +248,8 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
 EGLDisplay EGLAPIENTRY
 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
 {
-   _EGLDisplay *dpy = _eglFindDisplay(nativeDisplay);
+   _EGLDisplay *dpy =
+      _eglFindDisplay(EGL_DISPLAY_TYPE_NATIVE_MESA, (void *) nativeDisplay);
    return _eglGetDisplayHandle(dpy);
 }
 
@@ -811,6 +812,13 @@ eglGetError(void)
    return e;
 }
 
+EGLDisplay EGLAPIENTRY
+eglGetDisplayMESA(EGLint type, void *display)
+{
+   _EGLDisplay *dpy = _eglFindDisplay(type, display);
+
+   return _eglGetDisplayHandle(dpy);
+}
 
 __eglMustCastToProperFunctionPointerType EGLAPIENTRY
 eglGetProcAddress(const char *procname)
@@ -841,6 +849,9 @@ eglGetProcAddress(const char *procname)
 #ifdef EGL_NOK_swap_region
       { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
 #endif
+#ifdef EGL_MESA_get_display
+      { "eglGetDisplayMESA", (_EGLProc) eglGetDisplayMESA },
+#endif
       { NULL, NULL }
    };
    EGLint i;
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 5dc5fd9..bd2113b 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -49,7 +49,7 @@ _eglFiniDisplay(void)
  * new one.
  */
 _EGLDisplay *
-_eglFindDisplay(EGLNativeDisplayType nativeDisplay)
+_eglFindDisplay(EGLint type, void *nativeDisplay)
 {
    _EGLDisplay *dpy;
 
@@ -58,7 +58,7 @@ _eglFindDisplay(EGLNativeDisplayType nativeDisplay)
    /* search the display list first */
    dpy = _eglGlobal.DisplayList;
    while (dpy) {
-      if (dpy->NativeDisplay == nativeDisplay)
+      if (dpy->DisplayType == type && dpy->VoidDisplay == nativeDisplay)
          break;
       dpy = dpy->Next;
    }
@@ -68,7 +68,9 @@ _eglFindDisplay(EGLNativeDisplayType nativeDisplay)
       dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
       if (dpy) {
          _eglInitMutex(&dpy->Mutex);
-         dpy->NativeDisplay = nativeDisplay;
+         dpy->NativeDisplay = (EGLNativeDisplayType) nativeDisplay;
+	 dpy->VoidDisplay = nativeDisplay;
+	 dpy->DisplayType = type;
 
          /* add to the display list */ 
          dpy->Next = _eglGlobal.DisplayList;
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 42e305f..fdf2686 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -61,6 +61,8 @@ struct _egl_display
    _EGLMutex Mutex;
 
    EGLNativeDisplayType NativeDisplay;
+   EGLint DisplayType;
+   void *VoidDisplay;
 
    EGLBoolean Initialized; /**< True if the display is initialized */
    _EGLDriver *Driver;
@@ -92,7 +94,7 @@ _eglFiniDisplay(void);
 
 
 extern _EGLDisplay *
-_eglFindDisplay(EGLNativeDisplayType displayName);
+_eglFindDisplay(EGLint type, void *display);
 
 
 PUBLIC void
-- 
1.7.0.1



More information about the mesa-dev mailing list