[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