summaryrefslogtreecommitdiff
path: root/src/egl/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main')
-rw-r--r--src/egl/main/Makefile15
-rw-r--r--src/egl/main/eglapi.c695
-rw-r--r--src/egl/main/eglapi.h74
-rw-r--r--src/egl/main/eglcompiler.h64
-rw-r--r--src/egl/main/eglconfig.c20
-rw-r--r--src/egl/main/eglconfig.h8
-rw-r--r--src/egl/main/eglconfigutil.c2
-rw-r--r--src/egl/main/eglcontext.c254
-rw-r--r--src/egl/main/eglcontext.h54
-rw-r--r--src/egl/main/eglcurrent.c342
-rw-r--r--src/egl/main/eglcurrent.h84
-rw-r--r--src/egl/main/egldisplay.c350
-rw-r--r--src/egl/main/egldisplay.h247
-rw-r--r--src/egl/main/egldriver.c343
-rw-r--r--src/egl/main/egldriver.h46
-rw-r--r--src/egl/main/eglglobals.c160
-rw-r--r--src/egl/main/eglglobals.h51
-rw-r--r--src/egl/main/eglhash.c347
-rw-r--r--src/egl/main/eglhash.h39
-rw-r--r--src/egl/main/eglmisc.c60
-rw-r--r--src/egl/main/eglmisc.h6
-rw-r--r--src/egl/main/eglmode.c37
-rw-r--r--src/egl/main/eglmode.h10
-rw-r--r--src/egl/main/eglmutex.h52
-rw-r--r--src/egl/main/eglscreen.c108
-rw-r--r--src/egl/main/eglscreen.h24
-rw-r--r--src/egl/main/eglsurface.c206
-rw-r--r--src/egl/main/eglsurface.h82
-rw-r--r--src/egl/main/egltypedefs.h3
-rw-r--r--src/egl/main/eglx.c100
-rw-r--r--src/egl/main/eglx.h12
31 files changed, 2171 insertions, 1724 deletions
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index fab8f16089..c951b070f1 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -7,38 +7,38 @@ include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES)
HEADERS = \
+ eglcompiler.h \
eglconfig.h \
eglconfigutil.h \
eglcontext.h \
+ eglcurrent.h \
egldefines.h \
egldisplay.h \
egldriver.h \
eglglobals.h \
egllog.h \
- eglhash.h \
eglmisc.h \
eglmode.h \
+ eglmutex.h \
eglscreen.h \
eglstring.h \
- eglsurface.h \
- eglx.h
+ eglsurface.h
SOURCES = \
eglapi.c \
eglconfig.c \
eglconfigutil.c \
eglcontext.c \
+ eglcurrent.c \
egldisplay.c \
egldriver.c \
eglglobals.c \
egllog.c \
- eglhash.c \
eglmisc.c \
eglmode.c \
eglscreen.c \
eglstring.c \
- eglsurface.c \
- eglx.c
+ eglsurface.c
OBJECTS = $(SOURCES:.c=.o)
@@ -66,11 +66,12 @@ $(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS)
install: default
$(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR)
clean:
-rm -f *.o *.so*
-rm -f core.*
+ -rm -f depend depend.bak
depend: $(SOURCES) $(HEADERS)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 9df938e188..29617b7aff 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -29,7 +29,6 @@
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -39,7 +38,9 @@
#include "eglglobals.h"
#include "egldriver.h"
#include "eglsurface.h"
-
+#include "eglconfig.h"
+#include "eglscreen.h"
+#include "eglmode.h"
/**
@@ -50,8 +51,12 @@ EGLDisplay EGLAPIENTRY
eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
- _eglInitGlobals();
- dpy = _eglNewDisplay(nativeDisplay);
+ dpy = _eglFindDisplay(nativeDisplay);
+ if (!dpy) {
+ dpy = _eglNewDisplay(nativeDisplay);
+ if (dpy)
+ _eglLinkDisplay(dpy);
+ }
return _eglGetDisplayHandle(dpy);
}
@@ -63,232 +68,484 @@ eglGetDisplay(NativeDisplayType nativeDisplay)
EGLBoolean EGLAPIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLDriver *drv;
EGLint major_int, minor_int;
- if (dpy) {
- EGLBoolean retVal;
- _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
- if (!dpyPriv) {
- return EGL_FALSE;
- }
- dpyPriv->Driver = _eglOpenDriver(dpyPriv,
- dpyPriv->DriverName,
- dpyPriv->DriverArgs);
- if (!dpyPriv->Driver) {
- return EGL_FALSE;
- }
- /* Initialize the particular driver now */
- retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
- &major_int, &minor_int);
-
- dpyPriv->Driver->APImajor = major_int;
- dpyPriv->Driver->APIminor = minor_int;
- snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
- "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name);
-
- /* Update applications version of major and minor if not NULL */
- if((major != NULL) && (minor != NULL))
- {
- *major = major_int;
- *minor = minor_int;
+ if (!disp)
+ return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+ drv = disp->Driver;
+ if (!drv) {
+ drv = _eglOpenDriver(disp);
+ if (!drv)
+ return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
+
+ /* Initialize the particular display now */
+ if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) {
+ _eglCloseDriver(drv, disp);
+ return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
}
- return retVal;
+ disp->APImajor = major_int;
+ disp->APIminor = minor_int;
+ snprintf(disp->Version, sizeof(disp->Version),
+ "%d.%d (%s)", major_int, minor_int, drv->Name);
+
+ /* update the global notion of supported APIs */
+ _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
+
+ disp->Driver = drv;
+ } else {
+ major_int = disp->APImajor;
+ minor_int = disp->APIminor;
+ }
+
+ /* Update applications version of major and minor if not NULL */
+ if ((major != NULL) && (minor != NULL)) {
+ *major = major_int;
+ *minor = minor_int;
}
- return EGL_FALSE;
+
+ return EGL_TRUE;
}
EGLBoolean EGLAPIENTRY
eglTerminate(EGLDisplay dpy)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return _eglCloseDriver(drv, dpy);
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLDriver *drv;
+
+ if (!disp)
+ return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+ drv = disp->Driver;
+ if (drv) {
+ drv->API.Terminate(drv, disp);
+ _eglCloseDriver(drv, disp);
+ disp->Driver = NULL;
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * A bunch of check functions and declare macros to simply error checking.
+ */
+static INLINE _EGLDriver *
+_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
+{
+ if (!disp) {
+ _eglError(EGL_BAD_DISPLAY, msg);
+ return NULL;
+ }
+ if (!disp->Driver) {
+ _eglError(EGL_NOT_INITIALIZED, msg);
+ return NULL;
+ }
+ return disp->Driver;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!surf) {
+ _eglError(EGL_BAD_SURFACE, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!context) {
+ _eglError(EGL_BAD_CONTEXT, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, msg);
+ return NULL;
+ }
+ return drv;
}
+#define _EGL_DECLARE_DD(dpy) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckDisplay(disp, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLSurface *surf = _eglLookupSurface((surface), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckSurface(disp, surf, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLContext *context = _eglLookupContext((ctx), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckContext(disp, context, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#ifdef EGL_MESA_screen_surface
+
+
+static INLINE _EGLDriver *
+_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!scrn) {
+ _eglError(EGL_BAD_SCREEN_MESA, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!m) {
+ _eglError(EGL_BAD_MODE_MESA, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLScreen *scrn = _eglLookupScreen((screen), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLMode *m = _eglLookupMode((mode), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckMode(disp, m, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#endif /* EGL_MESA_screen_surface */
+
+
const char * EGLAPIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.QueryString(drv, dpy, name);
- else
- return NULL;
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.QueryString(drv, disp, name);
}
EGLBoolean EGLAPIENTRY
-eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- /* XXX check drv for null in remaining functions */
- return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
}
EGLBoolean EGLAPIENTRY
-eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
+ config_size, num_config);
}
EGLBoolean EGLAPIENTRY
-eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
}
EGLContext EGLAPIENTRY
-eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
-{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
+eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLContext *share = _eglLookupContext(share_list, disp);
+ _EGLDriver *drv;
+ _EGLContext *context;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_CONTEXT;
+ if (!share && share_list != EGL_NO_CONTEXT) {
+ _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+ return EGL_NO_CONTEXT;
+ }
+
+ context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
+ if (context)
+ return _eglLinkContext(context, disp);
+ else
+ return EGL_NO_CONTEXT;
}
EGLBoolean EGLAPIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.DestroyContext(drv, dpy, ctx);
+ _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+ _eglUnlinkContext(context);
+ return drv->API.DestroyContext(drv, disp, context);
}
EGLBoolean EGLAPIENTRY
-eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
+ EGLContext ctx)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLContext *context = _eglLookupContext(ctx, disp);
+ _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
+ _EGLSurface *read_surf = _eglLookupSurface(read, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckDisplay(disp, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+ if (!context && ctx != EGL_NO_CONTEXT)
+ return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+ if ((!draw_surf && draw != EGL_NO_SURFACE) ||
+ (!read_surf && read != EGL_NO_SURFACE))
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+
+ return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
}
EGLBoolean EGLAPIENTRY
-eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
+ _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+ return drv->API.QueryContext(drv, disp, context, attribute, value);
}
EGLSurface EGLAPIENTRY
-eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window, const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLSurface EGLAPIENTRY
-eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ NativePixmapType pixmap, const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLSurface EGLAPIENTRY
-eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean EGLAPIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.DestroySurface(drv, dpy, surface);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ _eglUnlinkSurface(surf);
+ return drv->API.DestroySurface(drv, disp, surf);
}
-
EGLBoolean EGLAPIENTRY
-eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.QuerySurface(drv, disp, surf, attribute, value);
}
-
EGLBoolean EGLAPIENTRY
-eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
}
EGLBoolean EGLAPIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.BindTexImage(drv, dpy, surface, buffer);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.BindTexImage(drv, disp, surf, buffer);
}
EGLBoolean EGLAPIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
}
EGLBoolean EGLAPIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SwapInterval(drv, dpy, interval);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.SwapInterval(drv, disp, interval);
}
EGLBoolean EGLAPIENTRY
-eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SwapBuffers(drv, dpy, draw);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.SwapBuffers(drv, disp, surf);
}
EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CopyBuffers(drv, dpy, surface, target);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.CopyBuffers(drv, disp, surf, target);
}
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitGL(drv, dpy);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitGL(drv, disp);
}
EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitNative(drv, dpy, engine);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitNative(drv, disp, engine);
}
@@ -321,7 +578,8 @@ eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError;
- t->LastError = EGL_SUCCESS;
+ if (!_eglIsCurrentThreadDummy())
+ t->LastError = EGL_SUCCESS;
return e;
}
@@ -415,111 +673,168 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
+ modes, modes_size, num_modes);
}
EGLBoolean EGLAPIENTRY
-eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
+eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
+ EGLint mode_size, EGLint *num_mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
}
EGLBoolean EGLAPIENTRY
-eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
+eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+ return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
}
EGLBoolean EGLAPIENTRY
-eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
-{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
- else
+eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
+ EGLint mask)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLContext *source_context = _eglLookupContext(source, disp);
+ _EGLContext *dest_context = _eglLookupContext(dest, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckContext(disp, source_context, __FUNCTION__);
+ if (!drv || !dest_context) {
+ if (drv)
+ _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
return EGL_FALSE;
+ }
+
+ return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
+ mask);
}
EGLBoolean
-eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
+eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
+ EGLint max_screens, EGLint *num_screens)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.GetScreensMESA(drv, disp, screens,
+ max_screens, num_screens);
}
EGLSurface
-eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean
-eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
+eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
+ EGLSurface surface, EGLModeMESA mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGLMode *m = _eglLookupMode(mode, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+ if (!surf && surface != EGL_NO_SURFACE)
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+ if (!m && mode != EGL_NO_MODE_MESA)
+ return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
+
+ return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
}
EGLBoolean
eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
}
EGLBoolean
-eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
+eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
}
EGLBoolean
-eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
+eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
+ EGLSurface *surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
+ surf = NULL;
+ if (surface)
+ *surface = _eglGetSurfaceHandle(surf);
+ return (surf != NULL);
}
EGLBoolean
eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLDriver *drv;
+ _EGLMode *m;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
+ m = NULL;
+ if (mode)
+ *mode = m->Handle;
+
+ return (m != NULL);
}
const char *
eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryModeStringMESA(drv, dpy, mode);
+ _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+ return drv->API.QueryModeStringMESA(drv, disp, m);
}
@@ -546,11 +861,17 @@ eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
+ if (_eglIsCurrentThreadDummy())
+ return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
+
+ if (!_eglIsApiValid(api))
+ return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+
switch (api) {
#ifdef EGL_VERSION_1_4
case EGL_OPENGL_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
- t->CurrentAPI = api;
+ t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
@@ -558,14 +879,14 @@ eglBindAPI(EGLenum api)
#endif
case EGL_OPENGL_ES_API:
if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
- t->CurrentAPI = api;
+ t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
case EGL_OPENVG_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
- t->CurrentAPI = api;
+ t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
@@ -585,7 +906,7 @@ eglQueryAPI(void)
{
/* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
_EGLThreadInfo *t = _eglGetCurrentThread();
- return t->CurrentAPI;
+ return _eglConvertApiFromIndex(t->CurrentAPIIndex);
}
@@ -594,24 +915,38 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLClientBuffer buffer, EGLConfig config,
const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
- config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
+ conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean
eglReleaseThread(void)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- /* unbind context */
- (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ /* unbind current context */
+ if (!_eglIsCurrentThreadDummy()) {
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+ if (disp) {
+ drv = disp->Driver;
+ (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+ }
}
- _eglDeleteThreadData(t);
+
+ _eglDestroyCurrentThread();
return EGL_TRUE;
}
@@ -619,13 +954,17 @@ eglReleaseThread(void)
EGLBoolean
eglWaitClient(void)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitClient(drv, dpy);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitClient(drv, disp);
}
+
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index f6163a0c7a..6081e58892 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -12,61 +12,61 @@ typedef void (*_EGLProc)();
*/
/* driver funcs */
-typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
-typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
+typedef EGLBoolean (*Initialize_t)(_EGLDriver *, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (*Terminate_t)(_EGLDriver *, _EGLDisplay *dpy);
/* config funcs */
-typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLint attribute, EGLint *value);
/* context funcs */
-typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
-typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
+typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
+typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
/* surface funcs */
-typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
-typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
-typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
-typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
+typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value);
+typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
+typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
+typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target);
/* misc funcs */
-typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
-typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
+typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
typedef _EGLProc (*GetProcAddress_t)(const char *procname);
#ifdef EGL_MESA_screen_surface
-typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
-typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef EGLSurface (*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
-typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
+typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask);
+typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
+typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y);
+typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface);
+typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode);
+typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode);
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
-typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLSurface (*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
new file mode 100644
index 0000000000..6b639b75c6
--- /dev/null
+++ b/src/egl/main/eglcompiler.h
@@ -0,0 +1,64 @@
+#ifndef EGLCOMPILER_INCLUDED
+#define EGLCOMPILER_INCLUDED
+
+
+/**
+ * Get standard integer types
+ */
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+# include <stdint.h>
+#elif defined(_MSC_VER)
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+# ifndef __eglplatform_h_
+ typedef __int32 int32_t;
+# endif
+ typedef unsigned __int32 uint32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
+# if defined(_WIN64)
+ typedef __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+# else
+ typedef __int32 intptr_t;
+ typedef unsigned __int32 uintptr_t;
+# endif
+
+# define INT64_C(__val) __val##i64
+# define UINT64_C(__val) __val##ui64
+#else
+/* hope the best instead of adding a bunch of ifdef's */
+# include <stdint.h>
+#endif
+
+
+/**
+ * Function inlining
+ */
+#if defined(__GNUC__)
+# define INLINE __inline__
+#elif defined(__MSC__)
+# define INLINE __inline
+#elif defined(_MSC_VER)
+# define INLINE __inline
+#elif defined(__ICL)
+# define INLINE __inline
+#elif defined(__INTEL_COMPILER)
+# define INLINE inline
+#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
+# define INLINE __inline
+#elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
+# define INLINE inline
+# define __inline inline
+# define __inline__ inline
+#elif (__STDC_VERSION__ >= 199901L) /* C99 */
+# define INLINE inline
+#else
+# define INLINE
+#endif
+
+
+#endif /* EGLCOMPILER_INCLUDED */
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index f2f32585c7..d47b99eed4 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -34,7 +34,7 @@ void
_eglInitConfig(_EGLConfig *config, EGLint id)
{
memset(config, 0, sizeof(*config));
- config->Handle = (EGLConfig) id;
+ config->Handle = (EGLConfig) _eglUIntToPointer((unsigned int) id);
_eglSetConfigAttrib(config, EGL_CONFIG_ID, id);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
@@ -71,10 +71,9 @@ _eglGetConfigHandle(_EGLConfig *config)
* This is the inverse of _eglGetConfigHandle().
*/
_EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+_eglLookupConfig(EGLConfig config, _EGLDisplay *disp)
{
EGLint i;
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
for (i = 0; i < disp->NumConfigs; i++) {
if (disp->Configs[i]->Handle == config) {
return disp->Configs[i];
@@ -319,10 +318,9 @@ _eglCompareConfigs(const void *a, const void *b)
* Typical fallback routine for eglChooseConfig
*/
EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint *num_configs)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLConfig **configList, criteria;
EGLint i, count;
@@ -367,10 +365,9 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
* Fallback for eglGetConfigAttrib.
*/
EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
EGLint attribute, EGLint *value)
{
- const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
const EGLint k = attribute - FIRST_ATTRIB;
if (k >= 0 && k < MAX_ATTRIBS) {
*value = conf->Attrib[k];
@@ -387,16 +384,9 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Fallback for eglGetConfigs.
*/
EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
EGLint config_size, EGLint *num_config)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
- if (!drv->Initialized) {
- _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
- return EGL_FALSE;
- }
-
if (configs) {
EGLint i;
*num_config = MIN2(disp->NumConfigs, config_size);
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index db1c4c10e0..36ed96ae95 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -34,7 +34,7 @@ _eglGetConfigHandle(_EGLConfig *config);
extern _EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
+_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy);
extern _EGLConfig *
@@ -46,15 +46,15 @@ _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern void
diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c
index 138dc729e7..c9d00e7982 100644
--- a/src/egl/main/eglconfigutil.c
+++ b/src/egl/main/eglconfigutil.c
@@ -156,6 +156,7 @@ _eglFillInConfigs(_EGLConfig * configs,
{0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
};
+#if 0
static const uint32_t masks_table_bgr[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -177,6 +178,7 @@ _eglFillInConfigs(_EGLConfig * configs,
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
};
+#endif
static const uint8_t bytes_per_pixel[8] = {
0, 0, 0, 2, 2, 4, 0, 4
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 461679db09..b094f49bfc 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -14,11 +14,9 @@
* in the attrib_list.
*/
EGLBoolean
-_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
- EGLConfig config, const EGLint *attrib_list)
+_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
+ _EGLConfig *conf, const EGLint *attrib_list)
{
- _EGLConfig *conf;
- _EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint i;
const EGLenum api = eglQueryAPI();
@@ -27,12 +25,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
return EGL_FALSE;
}
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "_eglInitContext");
- return EGL_FALSE;
- }
-
memset(ctx, 0, sizeof(_EGLContext));
ctx->ClientVersion = 1; /* the default, per EGL spec */
@@ -49,7 +41,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
}
}
- ctx->Display = display;
ctx->Config = conf;
ctx->DrawSurface = EGL_NO_SURFACE;
ctx->ReadSurface = EGL_NO_SURFACE;
@@ -60,88 +51,27 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
/**
- * Save a new _EGLContext into the hash table.
- */
-void
-_eglSaveContext(_EGLContext *ctx)
-{
- /* no-op.
- * Public EGLContext handle and private _EGLContext are the same.
- */
-}
-
-
-/**
- * Remove the given _EGLContext object from the hash table.
- */
-void
-_eglRemoveContext(_EGLContext *ctx)
-{
- /* no-op.
- * Public EGLContext handle and private _EGLContext are the same.
- */
-}
-
-
-/**
- * Return the public handle for the given private context ptr.
- * This is the inverse of _eglLookupContext().
- */
-EGLContext
-_eglGetContextHandle(_EGLContext *ctx)
-{
- /* just a cast! */
- return (EGLContext) ctx;
-}
-
-
-/**
- * Return the _EGLContext object that corresponds to the given
- * EGLContext handle.
- * This is the inverse of _eglGetContextHandle().
- */
-_EGLContext *
-_eglLookupContext(EGLContext ctx)
-{
- /* just a cast since EGLContext is just a void ptr */
- return (_EGLContext *) ctx;
-}
-
-
-/**
- * Return the currently bound _EGLContext object, or NULL.
- */
-_EGLContext *
-_eglGetCurrentContext(void)
-{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- return t->CurrentContext;
-}
-
-
-/**
* Just a placeholder/demo function. Real driver will never use this!
*/
-EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- EGLContext share_list, const EGLint *attrib_list)
+_EGLContext *
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
{
#if 0 /* example code */
_EGLContext *context;
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
- return EGL_NO_CONTEXT;
+ return NULL;
- if (!_eglInitContext(drv, dpy, context, config, attrib_list)) {
+ if (!_eglInitContext(drv, context, conf, attrib_list)) {
free(context);
- return EGL_NO_CONTEXT;
+ return NULL;
}
- _eglSaveContext(context);
- return (EGLContext) context;
+ return context;
#endif
- return EGL_NO_CONTEXT;
+ return NULL;
}
@@ -149,39 +79,21 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
- _EGLContext *context = _eglLookupContext(ctx);
- if (context) {
- if (context->IsBound) {
- context->DeletePending = EGL_TRUE;
- }
- else {
- free(context);
- }
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
- return EGL_TRUE;
- }
+ if (!_eglIsContextBound(ctx))
+ free(ctx);
+ return EGL_TRUE;
}
EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
EGLint attribute, EGLint *value)
{
- _EGLContext *c = _eglLookupContext(ctx);
-
(void) drv;
(void) dpy;
- if (!c) {
- _eglError(EGL_BAD_CONTEXT, "eglQueryContext");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
@@ -203,90 +115,100 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
/**
* Drivers will typically call this to do the error checking and
- * update the various IsBound and DeletePending flags.
+ * update the various flags.
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
- EGLSurface r, EGLContext context)
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw,
+ _EGLSurface *read, _EGLContext *ctx)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
- _EGLContext *ctx = _eglLookupContext(context);
- _EGLSurface *draw = _eglLookupSurface(d);
- _EGLSurface *read = _eglLookupSurface(r);
+ _EGLContext *oldContext = NULL;
+ _EGLSurface *oldDrawSurface = NULL;
+ _EGLSurface *oldReadSurface = NULL;
+ EGLint apiIndex;
- _EGLContext *oldContext = _eglGetCurrentContext();
- _EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
- _EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);
+ if (_eglIsCurrentThreadDummy())
+ return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
- /* error checking */
if (ctx) {
- if (draw == NULL || read == NULL) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
- if (draw->Config != ctx->Config) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
- if (read->Config != ctx->Config) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
+ /* error checking */
+ if (ctx->Binding && ctx->Binding != t)
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ if (draw == NULL || read == NULL)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ if (draw->Config != ctx->Config || read->Config != ctx->Config)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ if ((draw->Binding && draw->Binding->Binding != t) ||
+ (read->Binding && read->Binding->Binding != t))
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+
+#ifdef EGL_VERSION_1_4
+ /* OpenGL and OpenGL ES are conflicting */
+ switch (ctx->ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)])
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ break;
+ case EGL_OPENGL_API:
+ if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)])
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ break;
+ default:
+ break;
}
+#endif
+ apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
+ }
+ else {
+ if (draw != NULL || read != NULL)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ apiIndex = t->CurrentAPIIndex;
}
- /*
- * check if the old context or surfaces need to be deleted
- */
- if (oldDrawSurface != NULL) {
- oldDrawSurface->IsBound = EGL_FALSE;
- if (oldDrawSurface->DeletePending) {
- /* make sure we don't try to rebind a deleted surface */
- if (draw == oldDrawSurface || draw == oldReadSurface) {
- draw = NULL;
- }
- /* really delete surface now */
- drv->API.DestroySurface(drv, dpy, oldDrawSurface->Handle);
+ oldContext = t->CurrentContexts[apiIndex];
+ if (oldContext) {
+ oldDrawSurface = oldContext->DrawSurface;
+ oldReadSurface = oldContext->ReadSurface;
+ assert(oldDrawSurface);
+ assert(oldReadSurface);
+
+ /* break old bindings */
+ t->CurrentContexts[apiIndex] = NULL;
+ oldContext->Binding = NULL;
+ oldContext->DrawSurface = NULL;
+ oldContext->ReadSurface = NULL;
+ oldDrawSurface->Binding = NULL;
+ oldReadSurface->Binding = NULL;
+
+ /*
+ * check if the old context or surfaces need to be deleted
+ */
+ if (!_eglIsSurfaceLinked(oldDrawSurface)) {
+ assert(draw != oldDrawSurface && read != oldDrawSurface);
+ drv->API.DestroySurface(drv, dpy, oldDrawSurface);
}
- }
- if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
- oldReadSurface->IsBound = EGL_FALSE;
- if (oldReadSurface->DeletePending) {
- /* make sure we don't try to rebind a deleted surface */
- if (read == oldDrawSurface || read == oldReadSurface) {
- read = NULL;
- }
- /* really delete surface now */
- drv->API.DestroySurface(drv, dpy, oldReadSurface->Handle);
+ if (oldReadSurface != oldDrawSurface &&
+ !_eglIsSurfaceLinked(oldReadSurface)) {
+ assert(draw != oldReadSurface && read != oldReadSurface);
+ drv->API.DestroySurface(drv, dpy, oldReadSurface);
}
- }
- if (oldContext != NULL) {
- oldContext->IsBound = EGL_FALSE;
- if (oldContext->DeletePending) {
- /* make sure we don't try to rebind a deleted context */
- if (ctx == oldContext) {
- ctx = NULL;
- }
- /* really delete context now */
- drv->API.DestroyContext(drv, dpy, _eglGetContextHandle(oldContext));
+ if (!_eglIsContextLinked(oldContext)) {
+ assert(ctx != oldContext);
+ drv->API.DestroyContext(drv, dpy, oldContext);
}
}
+ /* build new bindings */
if (ctx) {
- /* check read/draw again, in case we deleted them above */
- if (draw == NULL || read == NULL) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
+ t->CurrentContexts[apiIndex] = ctx;
+ ctx->Binding = t;
ctx->DrawSurface = draw;
ctx->ReadSurface = read;
- ctx->IsBound = EGL_TRUE;
- draw->IsBound = EGL_TRUE;
- read->IsBound = EGL_TRUE;
+ draw->Binding = ctx;
+ read->Binding = ctx;
}
- t->CurrentContext = ctx;
-
return EGL_TRUE;
}
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 34fee9c637..647f24488f 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -11,15 +11,16 @@
*/
struct _egl_context
{
- _EGLDisplay *Display; /* who do I belong to? */
-
- _EGLConfig *Config;
+ /* Managed by EGLDisplay for linking */
+ _EGLDisplay *Display;
+ _EGLContext *Next;
+ /* The bound status of the context */
+ _EGLThreadInfo *Binding;
_EGLSurface *DrawSurface;
_EGLSurface *ReadSurface;
- EGLBoolean IsBound;
- EGLBoolean DeletePending;
+ _EGLConfig *Config;
EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
@@ -27,47 +28,38 @@ struct _egl_context
extern EGLBoolean
-_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
- EGLConfig config, const EGLint *attrib_list);
-
-
-extern void
-_eglSaveContext(_EGLContext *ctx);
-
-
-extern void
-_eglRemoveContext(_EGLContext *ctx);
-
-
-extern EGLContext
-_eglGetContextHandle(_EGLContext *ctx);
+_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
+ _EGLConfig *config, const EGLint *attrib_list);
extern _EGLContext *
-_eglLookupContext(EGLContext ctx);
-
-
-extern _EGLContext *
-_eglGetCurrentContext(void);
-
-
-extern EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
extern EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
extern EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
extern EGLBoolean
_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+
+/**
+ * Return true if the context is bound to a thread.
+ */
+static INLINE EGLBoolean
+_eglIsContextBound(_EGLContext *ctx)
+{
+ return (ctx->Binding != NULL);
+}
+
+
#endif /* EGLCONTEXT_INCLUDED */
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
new file mode 100644
index 0000000000..4431f964f6
--- /dev/null
+++ b/src/egl/main/eglcurrent.c
@@ -0,0 +1,342 @@
+#include <stdlib.h>
+#include <string.h>
+#include "eglcurrent.h"
+#include "eglcontext.h"
+#include "egllog.h"
+#include "eglmutex.h"
+#include "eglglobals.h"
+
+
+/* This should be kept in sync with _eglInitThreadInfo() */
+#define _EGL_THREAD_INFO_INITIALIZER \
+ { EGL_SUCCESS, { NULL }, 1 }
+
+/* a fallback thread info to guarantee that every thread always has one */
+static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
+
+
+#ifdef GLX_USE_TLS
+static __thread const _EGLThreadInfo *_egl_TSD;
+ __attribute__ ((tls_model("initial-exec")));
+
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+{
+ _egl_TSD = t;
+}
+
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
+{
+ return (_EGLThreadInfo *) _egl_TSD;
+}
+
+static INLINE void _eglFiniTSD(void)
+{
+}
+
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
+{
+ /* TODO destroy TSD */
+ (void) dtor;
+ (void) _eglFiniTSD;
+ return EGL_TRUE;
+}
+
+#elif PTHREADS
+#include <pthread.h>
+
+static _EGL_DECLARE_MUTEX(_egl_TSDMutex);
+static EGLBoolean _egl_TSDInitialized;
+static pthread_key_t _egl_TSD;
+static void (*_egl_FreeTSD)(_EGLThreadInfo *);
+
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+{
+ pthread_setspecific(_egl_TSD, (const void *) t);
+}
+
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
+{
+ return (_EGLThreadInfo *) pthread_getspecific(_egl_TSD);
+}
+
+static INLINE void _eglFiniTSD(void)
+{
+ _eglLockMutex(&_egl_TSDMutex);
+ if (_egl_TSDInitialized) {
+ _EGLThreadInfo *t = _eglGetTSD();
+
+ _egl_TSDInitialized = EGL_FALSE;
+ if (t && _egl_FreeTSD)
+ _egl_FreeTSD((void *) t);
+ pthread_key_delete(_egl_TSD);
+ }
+ _eglUnlockMutex(&_egl_TSDMutex);
+}
+
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
+{
+ if (!_egl_TSDInitialized) {
+ _eglLockMutex(&_egl_TSDMutex);
+
+ /* check again after acquiring lock */
+ if (!_egl_TSDInitialized) {
+ if (pthread_key_create(&_egl_TSD, (void (*)(void *)) dtor) != 0) {
+ _eglUnlockMutex(&_egl_TSDMutex);
+ return EGL_FALSE;
+ }
+ _egl_FreeTSD = dtor;
+ _eglAddAtExitCall(_eglFiniTSD);
+ _egl_TSDInitialized = EGL_TRUE;
+ }
+
+ _eglUnlockMutex(&_egl_TSDMutex);
+ }
+
+ return EGL_TRUE;
+}
+
+#else /* PTHREADS */
+static const _EGLThreadInfo *_egl_TSD;
+static void (*_egl_FreeTSD)(_EGLThreadInfo *);
+
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+{
+ _egl_TSD = t;
+}
+
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
+{
+ return (_EGLThreadInfo *) _egl_TSD;
+}
+
+static INLINE void _eglFiniTSD(void)
+{
+ if (_egl_FreeTSD && _egl_TSD)
+ _egl_FreeTSD((_EGLThreadInfo *) _egl_TSD);
+}
+
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
+{
+ if (!_egl_FreeTSD && dtor) {
+ _egl_FreeTSD = dtor;
+ _eglAddAtExitCall(_eglFiniTSD);
+ }
+ return EGL_TRUE;
+}
+
+#endif /* !PTHREADS */
+
+
+static void
+_eglInitThreadInfo(_EGLThreadInfo *t)
+{
+ memset(t, 0, sizeof(*t));
+ t->LastError = EGL_SUCCESS;
+ /* default, per EGL spec */
+ t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
+}
+
+
+/**
+ * Allocate and init a new _EGLThreadInfo object.
+ */
+static _EGLThreadInfo *
+_eglCreateThreadInfo(void)
+{
+ _EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo));
+ if (t)
+ _eglInitThreadInfo(t);
+ else
+ t = &dummy_thread;
+ return t;
+}
+
+
+/**
+ * Delete/free a _EGLThreadInfo object.
+ */
+static void
+_eglDestroyThreadInfo(_EGLThreadInfo *t)
+{
+ if (t != &dummy_thread)
+ free(t);
+}
+
+
+/**
+ * Make sure TSD is initialized and return current value.
+ */
+static INLINE _EGLThreadInfo *
+_eglCheckedGetTSD(void)
+{
+ if (_eglInitTSD(&_eglDestroyThreadInfo) != EGL_TRUE) {
+ _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
+ return NULL;
+ }
+
+ return _eglGetTSD();
+}
+
+
+/**
+ * Return the calling thread's thread info.
+ * If the calling thread nevers calls this function before, or if its thread
+ * info was destroyed, a new one is created. This function never returns NULL.
+ * In the case allocation fails, a dummy one is returned. See also
+ * _eglIsCurrentThreadDummy.
+ */
+_EGLThreadInfo *
+_eglGetCurrentThread(void)
+{
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
+ if (!t) {
+ t = _eglCreateThreadInfo();
+ _eglSetTSD(t);
+ }
+
+ return t;
+}
+
+
+/**
+ * Destroy the calling thread's thread info.
+ */
+void
+_eglDestroyCurrentThread(void)
+{
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
+ if (t) {
+ _eglDestroyThreadInfo(t);
+ _eglSetTSD(NULL);
+ }
+}
+
+
+/**
+ * Return true if the calling thread's thread info is dummy.
+ * A dummy thread info is shared by all threads and should not be modified.
+ * Functions like eglBindAPI or eglMakeCurrent should check for dummy-ness
+ * before updating the thread info.
+ */
+EGLBoolean
+_eglIsCurrentThreadDummy(void)
+{
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
+ return (!t || t == &dummy_thread);
+}
+
+
+/**
+ * Return the currently bound context, or NULL.
+ */
+_EGLContext *
+_eglGetCurrentContext(void)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ return t->CurrentContexts[t->CurrentAPIIndex];
+}
+
+
+/**
+ * Return the display of the currently bound context, or NULL.
+ */
+_EGLDisplay *
+_eglGetCurrentDisplay(void)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex];
+ if (ctx)
+ return ctx->Display;
+ else
+ return NULL;
+}
+
+
+/**
+ * Return the read or write surface of the currently bound context, or NULL.
+ */
+_EGLSurface *
+_eglGetCurrentSurface(EGLint readdraw)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex];
+ if (ctx) {
+ switch (readdraw) {
+ case EGL_DRAW:
+ return ctx->DrawSurface;
+ case EGL_READ:
+ return ctx->ReadSurface;
+ default:
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+
+/**
+ * Record EGL error code.
+ */
+EGLBoolean
+_eglError(EGLint errCode, const char *msg)
+{
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ const char *s;
+
+ if (t == &dummy_thread)
+ return EGL_FALSE;
+
+ if (t->LastError == EGL_SUCCESS) {
+ t->LastError = errCode;
+
+ switch (errCode) {
+ case EGL_BAD_ACCESS:
+ s = "EGL_BAD_ACCESS";
+ break;
+ case EGL_BAD_ALLOC:
+ s = "EGL_BAD_ALLOC";
+ break;
+ case EGL_BAD_ATTRIBUTE:
+ s = "EGL_BAD_ATTRIBUTE";
+ break;
+ case EGL_BAD_CONFIG:
+ s = "EGL_BAD_CONFIG";
+ break;
+ case EGL_BAD_CONTEXT:
+ s = "EGL_BAD_CONTEXT";
+ break;
+ case EGL_BAD_CURRENT_SURFACE:
+ s = "EGL_BAD_CURRENT_SURFACE";
+ break;
+ case EGL_BAD_DISPLAY:
+ s = "EGL_BAD_DISPLAY";
+ break;
+ case EGL_BAD_MATCH:
+ s = "EGL_BAD_MATCH";
+ break;
+ case EGL_BAD_NATIVE_PIXMAP:
+ s = "EGL_BAD_NATIVE_PIXMAP";
+ break;
+ case EGL_BAD_NATIVE_WINDOW:
+ s = "EGL_BAD_NATIVE_WINDOW";
+ break;
+ case EGL_BAD_PARAMETER:
+ s = "EGL_BAD_PARAMETER";
+ break;
+ case EGL_BAD_SURFACE:
+ s = "EGL_BAD_SURFACE";
+ break;
+ case EGL_BAD_SCREEN_MESA:
+ s = "EGL_BAD_SCREEN_MESA";
+ break;
+ case EGL_BAD_MODE_MESA:
+ s = "EGL_BAD_MODE_MESA";
+ break;
+ default:
+ s = "other";
+ }
+ _eglLog(_EGL_DEBUG, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
+ }
+
+ return EGL_FALSE;
+}
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
new file mode 100644
index 0000000000..8eb241029e
--- /dev/null
+++ b/src/egl/main/eglcurrent.h
@@ -0,0 +1,84 @@
+#ifndef EGLCURRENT_INCLUDED
+#define EGLCURRENT_INCLUDED
+
+#include "egltypedefs.h"
+
+
+#define _EGL_API_NUM_INDICES \
+ (EGL_OPENGL_API - EGL_OPENGL_ES_API + 2) /* idx 0 is for EGL_NONE */
+
+
+/**
+ * Per-thread info
+ */
+struct _egl_thread_info
+{
+ EGLint LastError;
+ _EGLContext *CurrentContexts[_EGL_API_NUM_INDICES];
+ /* use index for fast access to current context */
+ EGLint CurrentAPIIndex;
+};
+
+
+/**
+ * Return true if a client API enum can be converted to an index.
+ */
+static INLINE EGLBoolean
+_eglIsApiValid(EGLenum api)
+{
+ return ((api >= EGL_OPENGL_ES_API && api <= EGL_OPENGL_API) ||
+ api == EGL_NONE);
+}
+
+
+/**
+ * Convert a client API enum to an index, for use by thread info.
+ * The client API enum is assumed to be valid.
+ */
+static INLINE EGLint
+_eglConvertApiToIndex(EGLenum api)
+{
+ return (api != EGL_NONE) ? api - EGL_OPENGL_ES_API + 1 : 0;
+}
+
+
+/**
+ * Convert an index, used by thread info, to a client API enum.
+ * The index is assumed to be valid.
+ */
+static INLINE EGLenum
+_eglConvertApiFromIndex(EGLint idx)
+{
+ return (idx) ? EGL_OPENGL_ES_API + idx - 1 : EGL_NONE;
+}
+
+
+extern _EGLThreadInfo *
+_eglGetCurrentThread(void);
+
+
+extern void
+_eglDestroyCurrentThread(void);
+
+
+extern EGLBoolean
+_eglIsCurrentThreadDummy(void);
+
+
+extern _EGLContext *
+_eglGetCurrentContext(void);
+
+
+extern _EGLDisplay *
+_eglGetCurrentDisplay(void);
+
+
+extern _EGLSurface *
+_eglGetCurrentSurface(EGLint readdraw);
+
+
+extern EGLBoolean
+_eglError(EGLint errCode, const char *msg);
+
+
+#endif /* EGLCURRENT_INCLUDED */
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 47a2323eaf..896d60dbe1 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -1,4 +1,3 @@
-
/**
* Functions related to EGLDisplay.
*/
@@ -7,11 +6,67 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
+#include "eglsurface.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "eglstring.h"
+#include "eglmutex.h"
+#include "egllog.h"
+
+
+/**
+ * Finish display management.
+ */
+void
+_eglFiniDisplay(void)
+{
+ _EGLDisplay *dpyList, *dpy;
+
+ /* atexit function is called with global mutex locked */
+ dpyList = _eglGlobal.DisplayList;
+ while (dpyList) {
+ /* pop list head */
+ dpy = dpyList;
+ dpyList = dpyList->Next;
+
+ if (dpy->ContextList || dpy->SurfaceList)
+ _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy);
+
+ free(dpy);
+ }
+ _eglGlobal.DisplayList = NULL;
+}
+
+
+/**
+ * If the first character is '!' we interpret it as specific driver name
+ * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as
+ * arguments.
+ *
+ * The caller may free() the returned driver name.
+ */
+char *
+_eglSplitDisplayString(const char *dpyString, const char **args)
+{
+ char *drv, *p;
+
+ if (!dpyString || dpyString[0] != '!')
+ return NULL;
+ drv = _eglstrdup(dpyString + 1);
+ if (!drv)
+ return NULL;
+
+ p = strchr(dpyString, ':');
+ if (p) {
+ drv[p - dpyString] = '\0';
+ p++;
+ }
+ if (args)
+ *args = p;
+
+ return drv;
+}
/**
@@ -25,17 +80,9 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
if (dpy) {
- EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
-
- dpy->Handle = (EGLDisplay) key;
- _eglHashInsert(_eglGlobal.Displays, key, dpy);
-
dpy->NativeDisplay = nativeDisplay;
-#if defined(_EGL_PLATFORM_X)
- dpy->Xdpy = (Display *) nativeDisplay;
-#endif
- dpy->DriverName = _eglChooseDriver(dpy);
+ dpy->DriverName = _eglPreloadDriver(dpy);
if (!dpy->DriverName) {
free(dpy);
return NULL;
@@ -46,54 +93,107 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
/**
- * Return the public handle for an internal _EGLDisplay.
- * This is the inverse of _eglLookupDisplay().
+ * Link a display to itself and return the handle of the link.
+ * The handle can be passed to client directly.
*/
EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display)
+_eglLinkDisplay(_EGLDisplay *dpy)
{
- if (display)
- return display->Handle;
- else
- return EGL_NO_DISPLAY;
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ dpy->Next = _eglGlobal.DisplayList;
+ _eglGlobal.DisplayList = dpy;
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
+
+ return (EGLDisplay) dpy;
}
-
+
/**
- * Return the _EGLDisplay object that corresponds to the given public/
- * opaque display handle.
- * This is the inverse of _eglGetDisplayHandle().
+ * Unlink a linked display from itself.
+ * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
*/
-_EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy)
+void
+_eglUnlinkDisplay(_EGLDisplay *dpy)
{
- EGLuint key = (EGLuint) dpy;
- if (!_eglGlobal.Displays)
- return NULL;
- return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
+ _EGLDisplay *prev;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ prev = _eglGlobal.DisplayList;
+ if (prev != dpy) {
+ while (prev) {
+ if (prev->Next == dpy)
+ break;
+ prev = prev->Next;
+ }
+ assert(prev);
+ prev->Next = dpy->Next;
+ }
+ else {
+ _eglGlobal.DisplayList = dpy->Next;
+ }
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
}
-void
-_eglSaveDisplay(_EGLDisplay *dpy)
+/**
+ * Find the display corresponding to the specified native display id in all
+ * linked displays.
+ */
+_EGLDisplay *
+_eglFindDisplay(NativeDisplayType nativeDisplay)
{
- EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
- assert(dpy);
- assert(!dpy->Handle);
- dpy->Handle = (EGLDisplay) key;
- assert(dpy->Handle);
- _eglHashInsert(_eglGlobal.Displays, key, dpy);
+ _EGLDisplay *dpy;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ dpy = _eglGlobal.DisplayList;
+ while (dpy) {
+ if (dpy->NativeDisplay == nativeDisplay) {
+ _eglUnlockMutex(_eglGlobal.Mutex);
+ return dpy;
+ }
+ dpy = dpy->Next;
+ }
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
+
+ return NULL;
}
-_EGLDisplay *
-_eglGetCurrentDisplay(void)
+/**
+ * Destroy the contexts and surfaces that are linked to the display.
+ */
+void
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
{
- _EGLContext *ctx = _eglGetCurrentContext();
- if (ctx)
- return ctx->Display;
- else
- return NULL;
+ _EGLContext *contexts;
+ _EGLSurface *surfaces;
+
+ contexts = display->ContextList;
+ surfaces = display->SurfaceList;
+
+ while (contexts) {
+ _EGLContext *ctx = contexts;
+ contexts = contexts->Next;
+
+ _eglUnlinkContext(ctx);
+ drv->API.DestroyContext(drv, display, ctx);
+ }
+ assert(!display->ContextList);
+
+ while (surfaces) {
+ _EGLSurface *surf = surfaces;
+ surfaces = surfaces->Next;
+
+ _eglUnlinkSurface(surf);
+ drv->API.DestroySurface(drv, display, surf);
+ }
+ assert(!display->SurfaceList);
}
@@ -106,16 +206,166 @@ _eglCleanupDisplay(_EGLDisplay *disp)
{
EGLint i;
- for (i = 0; i < disp->NumConfigs; i++) {
- free(disp->Configs[i]);
+ if (disp->Configs) {
+ for (i = 0; i < disp->NumConfigs; i++)
+ free(disp->Configs[i]);
+ free(disp->Configs);
+ disp->Configs = NULL;
+ disp->NumConfigs = 0;
}
- free(disp->Configs);
- disp->Configs = NULL;
/* XXX incomplete */
+}
- free((void *) disp->DriverName);
- disp->DriverName = NULL;
- /* driver deletes the _EGLDisplay object */
+/**
+ * Link a context to a display and return the handle of the link.
+ * The handle can be passed to client directly.
+ */
+EGLContext
+_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy)
+{
+ ctx->Display = dpy;
+ ctx->Next = dpy->ContextList;
+ dpy->ContextList = ctx;
+ return (EGLContext) ctx;
+}
+
+
+/**
+ * Unlink a linked context from its display.
+ * Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
+ */
+void
+_eglUnlinkContext(_EGLContext *ctx)
+{
+ _EGLContext *prev;
+
+ prev = ctx->Display->ContextList;
+ if (prev != ctx) {
+ while (prev) {
+ if (prev->Next == ctx)
+ break;
+ prev = prev->Next;
+ }
+ assert(prev);
+ prev->Next = ctx->Next;
+ }
+ else {
+ ctx->Display->ContextList = ctx->Next;
+ }
+
+ ctx->Next = NULL;
+ ctx->Display = NULL;
+}
+
+
+/**
+ * Link a surface to a display and return the handle of the link.
+ * The handle can be passed to client directly.
+ */
+EGLSurface
+_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
+{
+ surf->Display = dpy;
+ surf->Next = dpy->SurfaceList;
+ dpy->SurfaceList = surf;
+ return (EGLSurface) surf;
}
+
+
+/**
+ * Unlink a linked surface from its display.
+ * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
+ */
+void
+_eglUnlinkSurface(_EGLSurface *surf)
+{
+ _EGLSurface *prev;
+
+ prev = surf->Display->SurfaceList;
+ if (prev != surf) {
+ while (prev) {
+ if (prev->Next == surf)
+ break;
+ prev = prev->Next;
+ }
+ assert(prev);
+ prev->Next = surf->Next;
+ }
+ else {
+ prev = NULL;
+ surf->Display->SurfaceList = surf->Next;
+ }
+
+ surf->Next = NULL;
+ surf->Display = NULL;
+}
+
+
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a display.
+ */
+EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+ _EGLDisplay *cur;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+ cur = _eglGlobal.DisplayList;
+ while (cur) {
+ if (cur == (_EGLDisplay *) dpy)
+ break;
+ cur = cur->Next;
+ }
+ _eglUnlockMutex(_eglGlobal.Mutex);
+ return (cur != NULL);
+}
+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a context.
+ */
+EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
+{
+ _EGLContext *cur = NULL;
+
+ if (dpy)
+ cur = dpy->ContextList;
+ while (cur) {
+ if (cur == (_EGLContext *) ctx) {
+ assert(cur->Display == dpy);
+ break;
+ }
+ cur = cur->Next;
+ }
+ return (cur != NULL);
+}
+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a surface.
+ */
+EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
+{
+ _EGLSurface *cur = NULL;
+
+ if (dpy)
+ cur = dpy->SurfaceList;
+ while (cur) {
+ if (cur == (_EGLSurface *) surf) {
+ assert(cur->Display == dpy);
+ break;
+ }
+ cur = cur->Next;
+ }
+ return (cur != NULL);
+}
+
+
+#endif /* !_EGL_SKIP_HANDLE_CHECK */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index ff623ee1c6..6575fdf198 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -1,21 +1,45 @@
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
-#ifdef _EGL_PLATFORM_X
-#include <X11/Xlib.h>
-#endif
-
#include "egltypedefs.h"
+#include "egldefines.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+
+
+/**
+ * Optional EGL extensions info.
+ */
+struct _egl_extensions
+{
+ EGLBoolean MESA_screen_surface;
+ EGLBoolean MESA_copy_context;
+
+ char String[_EGL_MAX_EXTENSIONS_LEN];
+};
struct _egl_display
{
+ /* used to link displays */
+ _EGLDisplay *Next;
+
EGLNativeDisplayType NativeDisplay;
- EGLDisplay Handle;
const char *DriverName;
- const char *DriverArgs;
_EGLDriver *Driver;
+ void *DriverData; /* private to driver */
+
+ int APImajor, APIminor; /**< as returned by eglInitialize() */
+ char Version[1000]; /**< initialized from APImajor/minor, DriverName */
+
+ /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
+ EGLint ClientAPIsMask;
+ char ClientAPIs[1000]; /**< updated by eglQueryString */
+
+ _EGLExtensions Extensions;
+
+ int LargestPbuffer;
EGLint NumScreens;
_EGLScreen **Screens; /* array [NumScreens] */
@@ -23,39 +47,226 @@ struct _egl_display
EGLint NumConfigs;
_EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */
-#ifdef _EGL_PLATFORM_X
- Display *Xdpy;
-#endif
+ /* lists of linked contexts and surface */
+ _EGLContext *ContextList;
+ _EGLSurface *SurfaceList;
};
-extern _EGLDisplay *
-_eglNewDisplay(NativeDisplayType displayName);
+extern void
+_eglFiniDisplay(void);
-EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display);
+extern char *
+_eglSplitDisplayString(const char *dpyString, const char **args);
extern _EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy);
+_eglNewDisplay(NativeDisplayType displayName);
+
+
+extern EGLDisplay
+_eglLinkDisplay(_EGLDisplay *dpy);
extern void
-_eglSaveDisplay(_EGLDisplay *dpy);
+_eglUnlinkDisplay(_EGLDisplay *dpy);
extern _EGLDisplay *
-_eglGetCurrentDisplay(void);
+_eglFindDisplay(NativeDisplayType nativeDisplay);
+
+
+extern void
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy);
extern void
_eglCleanupDisplay(_EGLDisplay *disp);
-extern EGLBoolean
-_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attrib, EGLint *value);
+extern EGLContext
+_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkContext(_EGLContext *ctx);
+
+
+extern EGLSurface
+_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkSurface(_EGLSurface *surf);
+
+
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
+extern EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy);
+
+
+extern EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy);
+
+
+extern EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy);
+
+
+#else /* !_EGL_SKIP_HANDLE_CHECK */
+
+/* Only do a quick check. This is NOT standard compliant. */
+
+static INLINE EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+ return ((_EGLDisplay *) dpy != NULL);
+}
+static INLINE EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
+{
+ _EGLContext *c = (_EGLContext *) ctx;
+ return (dpy && c && c->Display == dpy);
+}
+
+
+static INLINE EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
+{
+ _EGLSurface *s = (_EGLSurface *) surf;
+ return (dpy && s && s->Display == dpy);
+}
+
+
+#endif /* _EGL_SKIP_HANDLE_CHECK */
+
+
+/**
+ * Lookup a handle to find the linked display.
+ * Return NULL if the handle has no corresponding linked display.
+ */
+static INLINE _EGLDisplay *
+_eglLookupDisplay(EGLDisplay display)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) display;
+ if (!_eglCheckDisplayHandle(display))
+ dpy = NULL;
+ return dpy;
+}
+
+
+/**
+ * Return the handle of a linked display, or EGL_NO_DISPLAY.
+ */
+static INLINE EGLDisplay
+_eglGetDisplayHandle(_EGLDisplay *dpy)
+{
+ return (EGLDisplay) ((dpy) ? dpy : EGL_NO_DISPLAY);
+}
+
+
+/**
+ * Return true if the display is linked.
+ */
+static INLINE EGLBoolean
+_eglIsDisplayLinked(_EGLDisplay *dpy)
+{
+ return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
+}
+
+
+/**
+ * Lookup a handle to find the linked context.
+ * Return NULL if the handle has no corresponding linked context.
+ */
+static INLINE _EGLContext *
+_eglLookupContext(EGLContext context, _EGLDisplay *dpy)
+{
+ _EGLContext *ctx = (_EGLContext *) context;
+ if (!_eglCheckContextHandle(context, dpy))
+ ctx = NULL;
+ return ctx;
+}
+
+
+/**
+ * Return the handle of a linked context, or EGL_NO_CONTEXT.
+ */
+static INLINE EGLContext
+_eglGetContextHandle(_EGLContext *ctx)
+{
+ return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT);
+}
+
+
+/**
+ * Return true if the context is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsContextLinked(_EGLContext *ctx)
+{
+ return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+}
+
+
+/**
+ * Lookup a handle to find the linked surface.
+ * Return NULL if the handle has no corresponding linked surface.
+ */
+static INLINE _EGLSurface *
+_eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy)
+{
+ _EGLSurface *surf = (_EGLSurface *) surface;
+ if (!_eglCheckSurfaceHandle(surf, dpy))
+ surf = NULL;
+ return surf;
+}
+
+
+/**
+ * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ */
+static INLINE EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surf)
+{
+ return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE);
+}
+
+
+/**
+ * Return true if the surface is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsSurfaceLinked(_EGLSurface *surf)
+{
+ return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE);
+}
+
+
+/**
+ * Cast an unsigned int to a pointer.
+ */
+static INLINE void *
+_eglUIntToPointer(unsigned int v)
+{
+ return (void *) ((uintptr_t) v);
+}
+
+
+/**
+ * Cast a pointer to an unsigned int. The pointer must be one that is
+ * returned by _eglUIntToPointer.
+ */
+static INLINE unsigned int
+_eglPointerToUInt(const void *p)
+{
+ return (unsigned int) ((uintptr_t) p);
+}
+
#endif /* EGLDISPLAY_INCLUDED */
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 43b1f51903..87786e36bb 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -22,7 +22,6 @@
#if defined(_EGL_PLATFORM_X)
#include <dlfcn.h>
-#include "eglx.h"
#elif defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
#define WINDOWS_STATIC_LINK
@@ -38,7 +37,6 @@
/* XXX Need to decide how to do dynamic name lookup on Windows */
static const char *DefaultDriverName = "TBD";
#endif
- static const char *SysFS = NULL;
typedef HMODULE lib_handle;
static HMODULE
@@ -61,8 +59,7 @@
}
#elif defined(_EGL_PLATFORM_X)
- static const char *DefaultDriverName = ":0";
- static const char *SysFS = "/sys/class";
+ static const char *DefaultDriverName = "egl_softpipe";
typedef void * lib_handle;
@@ -80,142 +77,69 @@
#endif
-/**
- * Given a card number, use sysfs to determine the DRI driver name.
- */
-const char *
-_eglChooseDRMDriver(int card)
-{
-#if 0
- return _eglstrdup("libEGLdri");
-#else
- char path[2000], driverName[2000];
- FILE *f;
- int length;
-
- snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
-
- f = fopen(path, "r");
- if (!f)
- return NULL;
-
- fgets(driverName, sizeof(driverName), f);
- fclose(f);
-
- if ((length = strlen(driverName)) > 1) {
- /* remove the trailing newline from sysfs */
- driverName[length - 1] = '\0';
- strncat(driverName, "_dri", sizeof(driverName));
- return _eglstrdup(driverName);
- }
- else {
- return NULL;
- }
-#endif
-}
/**
- * XXX this function is totally subject change!!!
- *
- *
- * Determine/return the name of the driver to use for the given _EGLDisplay.
- *
- * Try to be clever and determine if nativeDisplay is an Xlib Display
- * ptr or a string (naming a driver or screen number, etc).
- *
- * If the first character is ':' we interpret it as a screen or card index
- * number (i.e. ":0" or ":1", etc)
- * Else if the first character is '!' we interpret it as specific driver name
- * (i.e. "!r200" or "!i830".
- *
- * Whatever follows ':' is copied and put into dpy->DriverArgs.
- *
- * The caller may free() the returned string.
+ * Choose a driver for a given display.
+ * The caller may free() the returned strings.
*/
-const char *
-_eglChooseDriver(_EGLDisplay *dpy)
+static char *
+_eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
{
- /* Under Windows, the NativeDisplay is an HDC handle, therefore */
- /* it can't be interpreted as a string or a pointer. */
-#if defined(_EGL_PLATFORM_WINDOWS)
- const char *displayString = NULL;
-#else
- const char *displayString = (const char *) dpy->NativeDisplay;
-#endif
- const char *driverName = NULL;
+ char *path = NULL;
+ const char *args = NULL;
+ const char *suffix = NULL;
+ const char *p;
- (void) DefaultDriverName;
+ path = getenv("EGL_DRIVER");
+ if (path)
+ path = _eglstrdup(path);
#if defined(_EGL_PLATFORM_X)
- /* First, if the EGL_DRIVER env var is set, use that */
- driverName = getenv("EGL_DRIVER");
- if (driverName)
- return _eglstrdup(driverName);
-#endif
-
-#if 0
- if (!displayString) {
- /* choose a default */
- displayString = DefaultDriverName;
+ if (!path && dpy->NativeDisplay) {
+ /* assume (wrongly!) that the native display is a display string */
+ path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
}
-#endif
- /* extract default DriverArgs = whatever follows ':' */
- if (displayString &&
- (displayString[0] == '!' ||
- displayString[0] == ':')) {
- const char *args = strchr(displayString, ':');
- if (args)
- dpy->DriverArgs = _eglstrdup(args + 1);
- }
-
- /* determine driver name now */
- if (displayString && displayString[0] == ':' &&
- (displayString[1] >= '0' && displayString[1] <= '9') &&
- !displayString[2]) {
- int card = atoi(displayString + 1);
- driverName = _eglChooseDRMDriver(card);
- }
- else if (displayString && displayString[0] == '!') {
- /* use user-specified driver name */
- driverName = _eglstrdup(displayString + 1);
- /* truncate driverName at ':' if present */
- {
- char *args = strchr(driverName, ':');
- if (args) {
- *args = 0;
- }
+ suffix = "so";
+#elif defined(_EGL_PLATFORM_WINDOWS)
+ suffix = "dll";
+#endif /* _EGL_PLATFORM_X */
+
+ if (!path)
+ path = _eglstrdup(DefaultDriverName);
+
+ /* append suffix if there isn't */
+ p = strrchr(path, '.');
+ if (!p && suffix) {
+ size_t len = strlen(path);
+ char *tmp = malloc(len + strlen(suffix) + 2);
+ if (tmp) {
+ memcpy(tmp, path, len);
+ tmp[len++] = '.';
+ tmp[len] = '\0';
+ strcat(tmp + len, suffix);
+
+ free(path);
+ path = tmp;
}
}
- else
- {
- /* NativeDisplay is not a string! */
-#if defined(_EGL_PLATFORM_X)
- driverName = _xeglChooseDriver(dpy);
-#else
- driverName = DefaultDriverName;
-#endif
- }
- return driverName;
+ if (argsRet)
+ *argsRet = (args) ? _eglstrdup(args) : NULL;
+
+ return path;
}
/**
- * Open/load the named driver and call its bootstrap function: _eglMain().
- * By the time this function is called, the dpy->DriverName should have
- * been determined.
- *
- * \return new _EGLDriver object.
+ * Open the named driver and find its bootstrap function: _eglMain().
*/
-_EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
+static _EGLMain_t
+_eglOpenLibrary(const char *driverPath, lib_handle *handle)
{
- _EGLDriver *drv;
_EGLMain_t mainFunc;
lib_handle lib;
- char driverFilename[1000];
- assert(driverName);
+ assert(driverPath);
#if defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
@@ -224,85 +148,190 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
mainFunc = (_EGLMain_t)_eglMain;
#else
/* XXX untested */
- sprintf(driverFilename, "%s.dll", driverName);
- _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
- lib = open_library(driverFilename);
+ _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+ lib = open_library(driverPath);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s",
- driverFilename);
+ driverPath);
return NULL;
}
mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
#endif
#elif defined(_EGL_PLATFORM_X)
- /* XXX also prepend a directory path??? */
- sprintf(driverFilename, "%s.so", driverName);
- _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
- lib = open_library(driverFilename);
+ _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+ lib = open_library(driverPath);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s (%s)",
- driverFilename, dlerror());
+ driverPath, dlerror());
+ if (!getenv("EGL_DRIVER"))
+ _eglLog(_EGL_WARNING,
+ "The driver can be overridden by setting EGL_DRIVER");
return NULL;
}
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
#endif
if (!mainFunc) {
- _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
- close_library(lib);
+ _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
+ if (lib)
+ close_library(lib);
return NULL;
}
- drv = mainFunc(dpy, args);
+ *handle = lib;
+ return mainFunc;
+}
+
+
+/**
+ * Load the named driver. The path and args passed will be
+ * owned by the driver and freed.
+ */
+static _EGLDriver *
+_eglLoadDriver(char *path, char *args)
+{
+ _EGLMain_t mainFunc;
+ lib_handle lib;
+ _EGLDriver *drv = NULL;
+
+ mainFunc = _eglOpenLibrary(path, &lib);
+ if (!mainFunc)
+ return NULL;
+
+ drv = mainFunc(args);
if (!drv) {
- close_library(lib);
+ if (lib)
+ close_library(lib);
return NULL;
}
- /* with a recurvise open you want the inner most handle */
- if (!drv->LibHandle) {
- drv->LibHandle = lib;
- }
- else {
- close_library(lib);
+ if (!drv->Name) {
+ _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
+ drv->Name = "UNNAMED";
}
- /* update the global notion of supported APIs */
- _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
-
- _eglSaveDriver(drv);
+ drv->Path = path;
+ drv->Args = args;
+ drv->LibHandle = lib;
return drv;
}
-EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
+/**
+ * Match a display to a preloaded driver.
+ */
+static _EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy)
{
- void *handle = drv->LibHandle;
- EGLBoolean b;
+ _EGLDriver *defaultDriver = NULL;
+ EGLint i;
- _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
- /*
- * XXX check for currently bound context/surfaces and delete them?
- */
+ /* display specifies a driver */
+ if (dpy->DriverName) {
+ if (strcmp(dpy->DriverName, drv->Name) == 0)
+ return drv;
+ }
+ else if (drv->Probe) {
+ if (drv->Probe(drv, dpy))
+ return drv;
+ }
+ else {
+ if (!defaultDriver)
+ defaultDriver = drv;
+ }
+ }
+
+ return defaultDriver;
+}
+
+
+/**
+ * Load a driver and save it.
+ */
+const char *
+_eglPreloadDriver(_EGLDisplay *dpy)
+{
+ char *path, *args;
+ _EGLDriver *drv;
+ EGLint i;
+
+ path = _eglChooseDriver(dpy, &args);
+ if (!path)
+ return NULL;
+
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ drv = _eglGlobal.Drivers[i];
+ if (strcmp(drv->Path, path) == 0) {
+ _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
+ drv->Name);
+ free(path);
+ if (args)
+ free(args);
+ return drv->Name;
+ }
+ }
+
+ drv = _eglLoadDriver(path, args);
+ if (!drv)
+ return NULL;
- b = drv->API.Terminate(drv, dpy);
+ _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+
+ return drv->Name;
+}
+
+
+/**
+ * Open a preloaded driver.
+ */
+_EGLDriver *
+_eglOpenDriver(_EGLDisplay *dpy)
+{
+ _EGLDriver *drv = _eglMatchDriver(dpy);
+ return drv;
+}
- close_library(handle);
- return b;
+/**
+ * Close a preloaded driver.
+ */
+EGLBoolean
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ return EGL_TRUE;
}
/**
- * Save the given driver pointer in the list of all known drivers.
+ * Unload preloaded drivers.
*/
void
-_eglSaveDriver(_EGLDriver *drv)
+_eglUnloadDrivers(void)
{
- _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
+ EGLint i;
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
+ lib_handle handle = drv->LibHandle;
+
+ if (drv->Path)
+ free((char *) drv->Path);
+ if (drv->Args)
+ free((char *) drv->Args);
+
+ /* destroy driver */
+ if (drv->Unload)
+ drv->Unload(drv);
+
+ if (handle)
+ close_library(handle);
+ _eglGlobal.Drivers[i] = NULL;
+ }
+
+ _eglGlobal.NumDrivers = 0;
}
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 4066c6ec1d..6c848eb35e 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -4,19 +4,6 @@
#include "egltypedefs.h"
#include "eglapi.h"
-#include "egldefines.h"
-
-
-/**
- * Optional EGL extensions info.
- */
-struct _egl_extensions
-{
- EGLBoolean MESA_screen_surface;
- EGLBoolean MESA_copy_context;
-
- char String[_EGL_MAX_EXTENSIONS_LEN];
-};
/**
@@ -24,46 +11,37 @@ struct _egl_extensions
*/
struct _egl_driver
{
- EGLBoolean Initialized; /**< set by driver after initialized */
-
void *LibHandle; /**< dlopen handle */
+ const char *Path; /**< path to this driver */
+ const char *Args; /**< args to load this driver */
const char *Name; /**< name of this driver */
-
- int APImajor, APIminor; /**< as returned by eglInitialize() */
- char Version[1000]; /**< initialized from APImajor/minor, Name */
-
- /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
- EGLint ClientAPIsMask;
+ /**< probe a display to see if it is supported */
+ EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
+ /**< called before dlclose to release this driver */
+ void (*Unload)(_EGLDriver *drv);
_EGLAPI API; /**< EGL API dispatch table */
-
- _EGLExtensions Extensions;
-
- int LargestPbuffer;
};
-extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
+extern _EGLDriver *_eglMain(const char *args);
extern const char *
-_eglChooseDRMDriver(int card);
-
-extern const char *
-_eglChooseDriver(_EGLDisplay *dpy);
+_eglPreloadDriver(_EGLDisplay *dpy);
extern _EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args);
+_eglOpenDriver(_EGLDisplay *dpy);
extern EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy);
-extern void
-_eglSaveDriver(_EGLDriver *drv);
+void
+_eglUnloadDrivers(void);
extern _EGLDriver *
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index b770e55dbd..3ae4c1ad3a 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,146 +1,56 @@
-#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#include "eglglobals.h"
+#include "egldriver.h"
+#include "egllog.h"
+#include "eglmutex.h"
-struct _egl_global _eglGlobal =
-{
- EGL_FALSE
-};
-
-/**
- * Init the fields in the _eglGlobal struct
- * May be safely called more than once.
- */
-void
-_eglInitGlobals(void)
-{
- if (!_eglGlobal.Initialized) {
- _eglGlobal.Displays = _eglNewHashTable();
- _eglGlobal.Surfaces = _eglNewHashTable();
- _eglGlobal.FreeScreenHandle = 1;
- _eglGlobal.Initialized = EGL_TRUE;
-
- _eglGlobal.ClientAPIsMask = 0x0;
- /* XXX temporary */
- _eglGlobal.ThreadInfo = _eglNewThreadInfo();
- }
-}
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-/**
- * Should call this via an atexit handler.
- */
-void
-_eglDestroyGlobals(void)
+static _EGL_DECLARE_MUTEX(_eglGlobalMutex);
+struct _egl_global _eglGlobal =
{
- /* XXX TODO walk over table entries, deleting each */
- _eglDeleteHashTable(_eglGlobal.Displays);
- _eglDeleteHashTable(_eglGlobal.Surfaces);
-}
+ &_eglGlobalMutex, /* Mutex */
+ NULL, /* DisplayList */
+ 1, /* FreeScreenHandle */
+ 0x0, /* ClientAPIsMask */
+ 0, /* NumDrivers */
+ { NULL }, /* Drivers */
+ 2, /* NumAtExitCalls */
+ { /* AtExitCalls */
+ _eglFiniDisplay,
+ _eglUnloadDrivers
+ },
+};
-/**
- * Allocate and init a new _EGLThreadInfo object.
- */
-_EGLThreadInfo *
-_eglNewThreadInfo(void)
+static void
+_eglAtExit(void)
{
- _EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo));
- if (t) {
- t->CurrentContext = EGL_NO_CONTEXT;
- t->LastError = EGL_SUCCESS;
- t->CurrentAPI = EGL_OPENGL_ES_API; /* default, per EGL spec */
- }
- return t;
+ EGLint i;
+ for (i = _eglGlobal.NumAtExitCalls - 1; i >= 0; i--)
+ _eglGlobal.AtExitCalls[i]();
}
-/**
- * Delete/free a _EGLThreadInfo object.
- */
void
-_eglDeleteThreadData(_EGLThreadInfo *t)
+_eglAddAtExitCall(void (*func)(void))
{
- free(t);
-}
-
-
+ if (func) {
+ static EGLBoolean registered = EGL_FALSE;
-/**
- * Return pointer to calling thread's _EGLThreadInfo object.
- * Create a new one if needed.
- * Should never return NULL.
- */
-_EGLThreadInfo *
-_eglGetCurrentThread(void)
-{
- _eglInitGlobals();
-
- /* XXX temporary */
- return _eglGlobal.ThreadInfo;
-}
+ _eglLockMutex(_eglGlobal.Mutex);
+ if (!registered) {
+ atexit(_eglAtExit);
+ registered = EGL_TRUE;
+ }
-/**
- * Record EGL error code.
- */
-void
-_eglError(EGLint errCode, const char *msg)
-{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- const char *s;
-
- if (t->LastError == EGL_SUCCESS) {
- t->LastError = errCode;
+ assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls));
+ _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func;
- switch (errCode) {
- case EGL_BAD_ACCESS:
- s = "EGL_BAD_ACCESS";
- break;
- case EGL_BAD_ALLOC:
- s = "EGL_BAD_ALLOC";
- break;
- case EGL_BAD_ATTRIBUTE:
- s = "EGL_BAD_ATTRIBUTE";
- break;
- case EGL_BAD_CONFIG:
- s = "EGL_BAD_CONFIG";
- break;
- case EGL_BAD_CONTEXT:
- s = "EGL_BAD_CONTEXT";
- break;
- case EGL_BAD_CURRENT_SURFACE:
- s = "EGL_BAD_CURRENT_SURFACE";
- break;
- case EGL_BAD_DISPLAY:
- s = "EGL_BAD_DISPLAY";
- break;
- case EGL_BAD_MATCH:
- s = "EGL_BAD_MATCH";
- break;
- case EGL_BAD_NATIVE_PIXMAP:
- s = "EGL_BAD_NATIVE_PIXMAP";
- break;
- case EGL_BAD_NATIVE_WINDOW:
- s = "EGL_BAD_NATIVE_WINDOW";
- break;
- case EGL_BAD_PARAMETER:
- s = "EGL_BAD_PARAMETER";
- break;
- case EGL_BAD_SURFACE:
- s = "EGL_BAD_SURFACE";
- break;
- case EGL_BAD_SCREEN_MESA:
- s = "EGL_BAD_SCREEN_MESA";
- break;
- case EGL_BAD_MODE_MESA:
- s = "EGL_BAD_MODE_MESA";
- break;
- default:
- s = "other";
- }
- /* XXX temporary */
- fprintf(stderr, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
+ _eglUnlockMutex(_eglGlobal.Mutex);
}
}
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index 14d8ea487a..58511076d4 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -2,18 +2,9 @@
#define EGLGLOBALS_INCLUDED
#include "egltypedefs.h"
-#include "eglhash.h"
-
-
-/**
- * Per-thread info
- */
-struct _egl_thread_info
-{
- EGLint LastError;
- _EGLContext *CurrentContext;
- EGLenum CurrentAPI;
-};
+#include "egldisplay.h"
+#include "eglcurrent.h"
+#include "eglmutex.h"
/**
@@ -21,23 +12,21 @@ struct _egl_thread_info
*/
struct _egl_global
{
- EGLBoolean Initialized;
+ _EGLMutex *Mutex;
- _EGLHashtable *Displays;
- _EGLHashtable *Surfaces;
+ /* the list of all displays */
+ _EGLDisplay *DisplayList;
EGLScreenMESA FreeScreenHandle;
/* bitmaks of supported APIs (supported by _some_ driver) */
EGLint ClientAPIsMask;
- char ClientAPIs[1000]; /**< updated by eglQueryString */
-
- /* XXX temporary - should be thread-specific data (TSD) */
- _EGLThreadInfo *ThreadInfo;
-
EGLint NumDrivers;
_EGLDriver *Drivers[10];
+
+ EGLint NumAtExitCalls;
+ void (*AtExitCalls[10])(void);
};
@@ -45,27 +34,7 @@ extern struct _egl_global _eglGlobal;
extern void
-_eglInitGlobals(void);
-
-
-extern void
-_eglDestroyGlobals(void);
-
-
-extern _EGLThreadInfo *
-_eglNewThreadInfo(void);
-
-
-extern void
-_eglDeleteThreadData(_EGLThreadInfo *t);
-
-
-extern _EGLThreadInfo *
-_eglGetCurrentThread(void);
-
-
-extern void
-_eglError(EGLint errCode, const char *msg);
+_eglAddAtExitCall(void (*func)(void));
#endif /* EGLGLOBALS_INCLUDED */
diff --git a/src/egl/main/eglhash.c b/src/egl/main/eglhash.c
deleted file mode 100644
index 8e3da2e906..0000000000
--- a/src/egl/main/eglhash.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/**
- * \file hash.c
- * Generic hash table.
- *
- * This code taken from Mesa and adapted.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "eglhash.h"
-
-
-#define TABLE_SIZE 1023 /**< Size of lookup table/array */
-
-#define HASH_FUNC(K) ((K) % TABLE_SIZE)
-
-
-/*
- * Unfinished mutex stuff
- */
-
-typedef int _EGLMutex;
-
-static void
-_eglInitMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglDestroyMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglLockMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglUnlockMutex(_EGLMutex m)
-{
-}
-
-
-
-typedef struct _egl_hashentry _EGLHashentry;
-
-struct _egl_hashentry
-{
- EGLuint Key; /**< the entry's key */
- void *Data; /**< the entry's data */
- _EGLHashentry *Next; /**< pointer to next entry */
-};
-
-
-struct _egl_hashtable
-{
- _EGLHashentry *Table[TABLE_SIZE]; /**< the lookup table */
- EGLuint MaxKey; /**< highest key inserted so far */
- _EGLMutex Mutex; /**< mutual exclusion lock */
-};
-
-
-/**
- * Create a new hash table.
- *
- * \return pointer to a new, empty hash table.
- */
-_EGLHashtable *
-_eglNewHashTable(void)
-{
- _EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable));
- if (table) {
- _eglInitMutex(table->Mutex);
- table->MaxKey = 1;
- }
- return table;
-}
-
-
-
-/**
- * Delete a hash table.
- * Frees each entry on the hash table and then the hash table structure itself.
- * Note that the caller should have already traversed the table and deleted
- * the objects in the table (i.e. We don't free the entries' data pointer).
- *
- * \param table the hash table to delete.
- */
-void
-_eglDeleteHashTable(_EGLHashtable *table)
-{
- EGLuint i;
- assert(table);
- for (i = 0; i < TABLE_SIZE; i++) {
- _EGLHashentry *entry = table->Table[i];
- while (entry) {
- _EGLHashentry *next = entry->Next;
- free(entry);
- entry = next;
- }
- }
- _eglDestroyMutex(table->Mutex);
- free(table);
-}
-
-
-
-/**
- * Lookup an entry in the hash table.
- *
- * \param table the hash table.
- * \param key the key.
- *
- * \return pointer to user's data or NULL if key not in table
- */
-void *
-_eglHashLookup(const _EGLHashtable *table, EGLuint key)
-{
- EGLuint pos;
- const _EGLHashentry *entry;
-
- assert(table);
-
- if (!key)
- return NULL;
-
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- return entry->Data;
- }
- entry = entry->Next;
- }
- return NULL;
-}
-
-
-
-/**
- * Insert a key/pointer pair into the hash table.
- * If an entry with this key already exists we'll replace the existing entry.
- *
- * \param table the hash table.
- * \param key the key (not zero).
- * \param data pointer to user data.
- */
-void
-_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data)
-{
- /* search for existing entry with this key */
- EGLuint pos;
- _EGLHashentry *entry;
-
- assert(table);
- assert(key);
-
- _eglLockMutex(table->Mutex);
-
- if (key > table->MaxKey)
- table->MaxKey = key;
-
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- /* replace entry's data */
- entry->Data = data;
- _eglUnlockMutex(table->Mutex);
- return;
- }
- entry = entry->Next;
- }
-
- /* alloc and insert new table entry */
- entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry));
- entry->Key = key;
- entry->Data = data;
- entry->Next = table->Table[pos];
- table->Table[pos] = entry;
-
- _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Remove an entry from the hash table.
- *
- * \param table the hash table.
- * \param key key of entry to remove.
- *
- * While holding the hash table's lock, searches the entry with the matching
- * key and unlinks it.
- */
-void
-_eglHashRemove(_EGLHashtable *table, EGLuint key)
-{
- EGLuint pos;
- _EGLHashentry *entry, *prev;
-
- assert(table);
- assert(key);
-
- _eglLockMutex(table->Mutex);
-
- pos = HASH_FUNC(key);
- prev = NULL;
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- /* found it! */
- if (prev) {
- prev->Next = entry->Next;
- }
- else {
- table->Table[pos] = entry->Next;
- }
- free(entry);
- _eglUnlockMutex(table->Mutex);
- return;
- }
- prev = entry;
- entry = entry->Next;
- }
-
- _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Get the key of the "first" entry in the hash table.
- *
- * This is used in the course of deleting all display lists when
- * a context is destroyed.
- *
- * \param table the hash table
- *
- * \return key for the "first" entry in the hash table.
- *
- * While holding the lock, walks through all table positions until finding
- * the first entry of the first non-empty one.
- */
-EGLuint
-_eglHashFirstEntry(_EGLHashtable *table)
-{
- EGLuint pos;
- assert(table);
- _eglLockMutex(table->Mutex);
- for (pos = 0; pos < TABLE_SIZE; pos++) {
- if (table->Table[pos]) {
- _eglUnlockMutex(table->Mutex);
- return table->Table[pos]->Key;
- }
- }
- _eglUnlockMutex(table->Mutex);
- return 0;
-}
-
-
-/**
- * Given a hash table key, return the next key. This is used to walk
- * over all entries in the table. Note that the keys returned during
- * walking won't be in any particular order.
- * \return next hash key or 0 if end of table.
- */
-EGLuint
-_eglHashNextEntry(const _EGLHashtable *table, EGLuint key)
-{
- const _EGLHashentry *entry;
- EGLuint pos;
-
- assert(table);
- assert(key);
-
- /* Find the entry with given key */
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- break;
- }
- entry = entry->Next;
- }
-
- if (!entry) {
- /* the key was not found, we can't find next entry */
- return 0;
- }
-
- if (entry->Next) {
- /* return next in linked list */
- return entry->Next->Key;
- }
- else {
- /* look for next non-empty table slot */
- pos++;
- while (pos < TABLE_SIZE) {
- if (table->Table[pos]) {
- return table->Table[pos]->Key;
- }
- pos++;
- }
- return 0;
- }
-}
-
-
-/**
- * Dump contents of hash table for debugging.
- *
- * \param table the hash table.
- */
-void
-_eglHashPrint(const _EGLHashtable *table)
-{
- EGLuint i;
- assert(table);
- for (i = 0; i < TABLE_SIZE; i++) {
- const _EGLHashentry *entry = table->Table[i];
- while (entry) {
- printf("%u %p\n", entry->Key, entry->Data);
- entry = entry->Next;
- }
- }
-}
-
-
-
-/**
- * Return a new, unused hash key.
- */
-EGLuint
-_eglHashGenKey(_EGLHashtable *table)
-{
- EGLuint k;
-
- _eglLockMutex(table->Mutex);
- k = table->MaxKey;
- table->MaxKey++;
- _eglUnlockMutex(table->Mutex);
- return k;
-}
-
diff --git a/src/egl/main/eglhash.h b/src/egl/main/eglhash.h
deleted file mode 100644
index 1d6db9598c..0000000000
--- a/src/egl/main/eglhash.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * \file eglhash.h
- * Generic hash table.
- */
-
-
-#ifndef EGLHASH_INCLUDED
-#define EGLHASH_INCLUDED
-
-
-/* XXX move this? */
-typedef unsigned int EGLuint;
-
-
-typedef struct _egl_hashtable _EGLHashtable;
-
-
-extern _EGLHashtable *_eglNewHashTable(void);
-
-extern void _eglDeleteHashTable(_EGLHashtable *table);
-
-extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data);
-
-extern void _eglHashRemove(_EGLHashtable *table, EGLuint key);
-
-extern EGLuint _eglHashFirstEntry(_EGLHashtable *table);
-
-extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashPrint(const _EGLHashtable *table);
-
-extern EGLuint _eglHashGenKey(_EGLHashtable *table);
-
-extern void _egltest_hash_functions(void);
-
-
-#endif /* EGLHASH_INCLUDED */
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index b5bdc3ea4b..b37213faf1 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -35,6 +35,7 @@
#include <string.h>
#include "eglglobals.h"
#include "eglmisc.h"
+#include "egldisplay.h"
/**
@@ -42,42 +43,47 @@
* the driver's Extensions string.
*/
static void
-_eglUpdateExtensionsString(_EGLDriver *drv)
+_eglUpdateExtensionsString(_EGLDisplay *dpy)
{
- drv->Extensions.String[0] = 0;
+ char *exts = dpy->Extensions.String;
- if (drv->Extensions.MESA_screen_surface)
- strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
- if (drv->Extensions.MESA_copy_context)
- strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
- assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN);
+ if (exts[0])
+ return;
+
+ if (dpy->Extensions.MESA_screen_surface)
+ strcat(exts, "EGL_MESA_screen_surface ");
+ if (dpy->Extensions.MESA_copy_context)
+ strcat(exts, "EGL_MESA_copy_context ");
+ assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
}
static void
-_eglUpdateAPIsString(_EGLDriver *drv)
+_eglUpdateAPIsString(_EGLDisplay *dpy)
{
- _eglGlobal.ClientAPIs[0] = 0;
+ char *apis = dpy->ClientAPIs;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL ");
+ if (apis[0] || !dpy->ClientAPIsMask)
+ return;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_BIT)
+ strcat(apis, "OpenGL ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT)
+ strcat(apis, "OpenGL_ES ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenVG ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT)
+ strcat(apis, "OpenGL_ES2 ");
- assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs));
-}
+ if (dpy->ClientAPIsMask & EGL_OPENVG_BIT)
+ strcat(apis, "OpenVG ");
+ assert(strlen(apis) < sizeof(dpy->ClientAPIs));
+}
const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
{
(void) drv;
(void) dpy;
@@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
case EGL_VENDOR:
return _EGL_VENDOR_STRING;
case EGL_VERSION:
- return drv->Version;
+ return dpy->Version;
case EGL_EXTENSIONS:
- _eglUpdateExtensionsString(drv);
- return drv->Extensions.String;
+ _eglUpdateExtensionsString(dpy);
+ return dpy->Extensions.String;
#ifdef EGL_VERSION_1_2
case EGL_CLIENT_APIS:
- _eglUpdateAPIsString(drv);
- return _eglGlobal.ClientAPIs;
+ _eglUpdateAPIsString(dpy);
+ return dpy->ClientAPIs;
#endif
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString");
@@ -102,7 +108,7 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy)
{
/* just a placeholder */
(void) drv;
@@ -112,7 +118,7 @@ _eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
/* just a placeholder */
(void) drv;
diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h
index 4e2a40ea99..a15c839be2 100644
--- a/src/egl/main/eglmisc.h
+++ b/src/egl/main/eglmisc.h
@@ -33,15 +33,15 @@
extern const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
extern EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy);
extern EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
#endif /* EGLMISC_INCLUDED */
diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
index 786432234b..0f3ba6e5c0 100644
--- a/src/egl/main/eglmode.c
+++ b/src/egl/main/eglmode.c
@@ -34,9 +34,8 @@ my_strdup(const char *s)
* or null if non-existant.
*/
_EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode)
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
{
- const _EGLDisplay *disp = _eglLookupDisplay(dpy);
EGLint scrnum;
/* loop over all screens on the display */
@@ -272,19 +271,13 @@ _eglCompareModes(const void *a, const void *b)
* Called via eglChooseModeMESA API function.
*/
EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
_EGLMode **modeList, min;
EGLint i, count;
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglChooseModeMESA");
- return EGL_FALSE;
- }
-
if (!_eglParseModeAttribs(&min, attrib_list)) {
/* error code will have been recorded */
return EGL_FALSE;
@@ -326,16 +319,9 @@ _eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Called via eglGetModesMESA() API function.
*/
EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglGetModesMESA");
- return EGL_FALSE;
- }
-
if (modes) {
EGLint i;
*num_modes = MIN2(scrn->NumModes, modes_size);
@@ -356,17 +342,11 @@ _eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Query an attribute of a mode.
*/
EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLModeMESA mode, EGLint attribute, EGLint *value)
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLMode *m, EGLint attribute, EGLint *value)
{
- _EGLMode *m = _eglLookupMode(dpy, mode);
EGLint v;
- if (!m) {
- _eglError(EGL_BAD_MODE_MESA, "eglGetModeAttribMESA");
- return EGL_FALSE;
- }
-
v = getModeAttrib(m, attribute);
if (v < 0) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
@@ -382,13 +362,8 @@ _eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
* This is the default function called by eglQueryModeStringMESA().
*/
const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode)
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
{
- _EGLMode *m = _eglLookupMode(dpy, mode);
- if (!m) {
- _eglError(EGL_BAD_MODE_MESA, "eglQueryModeStringMESA");
- return NULL;
- }
return m->Name;
}
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index 52d4875676..af7c2c56d3 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -26,7 +26,7 @@ struct _egl_mode
extern _EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode);
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
extern _EGLMode *
@@ -35,23 +35,23 @@ _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
extern EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode,
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m,
EGLint attribute, EGLint *value);
extern const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m);
#endif /* EGLMODE_INCLUDED */
diff --git a/src/egl/main/eglmutex.h b/src/egl/main/eglmutex.h
new file mode 100644
index 0000000000..29faba0f24
--- /dev/null
+++ b/src/egl/main/eglmutex.h
@@ -0,0 +1,52 @@
+#ifndef EGLMUTEX_INCLUDED
+#define EGLMUTEX_INCLUDED
+
+#include "eglcompiler.h"
+
+#ifdef PTHREADS
+#include <pthread.h>
+
+typedef pthread_mutex_t _EGLMutex;
+
+static INLINE void _eglInitMutex(_EGLMutex *m)
+{
+ pthread_mutex_init(m, NULL);
+}
+
+static INLINE void
+_eglDestroyMutex(_EGLMutex *m)
+{
+ pthread_mutex_destroy(m);
+}
+
+static INLINE void
+_eglLockMutex(_EGLMutex *m)
+{
+ pthread_mutex_lock(m);
+}
+
+static INLINE void
+_eglUnlockMutex(_EGLMutex *m)
+{
+ pthread_mutex_unlock(m);
+}
+
+#define _EGL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define _EGL_DECLARE_MUTEX(m) \
+ _EGLMutex m = _EGL_MUTEX_INITIALIZER
+
+#else
+
+typedef int _EGLMutex;
+static INLINE void _eglInitMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglDestroyMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglLockMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglUnlockMutex(_EGLMutex *m) { (void) m; }
+
+#define _EGL_MUTEX_INITIALIZER 0
+#define _EGL_DECLARE_MUTEX(m) \
+ _EGLMutex m = _EGL_MUTEX_INITIALIZER
+
+#endif
+
+#endif /* EGLMUTEX_INCLUDED */
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 9c9a8377bf..14a1e9f8fe 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -52,13 +52,9 @@ _eglInitScreen(_EGLScreen *screen)
* Given a public screen handle, return the internal _EGLScreen object.
*/
_EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen)
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
{
EGLint i;
- _EGLDisplay *display = _eglLookupDisplay(dpy);
-
- if (!display)
- return NULL;
for (i = 0; i < display->NumScreens; i++) {
if (display->Screens[i]->Handle == screen)
@@ -89,17 +85,11 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
EGLint max_screens, EGLint *num_screens)
{
- _EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint n;
- if (!display) {
- _eglError(EGL_BAD_DISPLAY, "eglGetScreensMESA");
- return EGL_FALSE;
- }
-
if (display->NumScreens > max_screens) {
n = max_screens;
}
@@ -122,8 +112,8 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
@@ -131,19 +121,17 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
- if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA,
- config, attrib_list)) {
+ if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA,
+ conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
@@ -155,28 +143,15 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* this with code that _really_ shows the surface.
*/
EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface surface,
- EGLModeMESA m)
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface *surf,
+ _EGLMode *mode)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- _EGLMode *mode = _eglLookupMode(dpy, m);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
- return EGL_FALSE;
- }
- if (!mode && (m != EGL_NO_MODE_MESA )) {
- _eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA");
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE) {
+ if (!surf) {
scrn->CurrentSurface = NULL;
}
else {
- _EGLSurface *surf = _eglLookupSurface(surface);
- if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
+ if (surf->Type != EGL_SCREEN_BIT_MESA) {
_eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
return EGL_FALSE;
}
@@ -201,18 +176,10 @@ _eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
* this with code that _really_ sets the mode.
*/
EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
- EGLModeMESA mode)
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+ _EGLMode *m)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
- return EGL_FALSE;
- }
-
- scrn->CurrentMode = _eglLookupMode(dpy, mode);
-
+ scrn->CurrentMode = m;
return EGL_TRUE;
}
@@ -221,15 +188,9 @@ _eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Set a screen's surface origin.
*/
EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLint x, EGLint y)
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, EGLint x, EGLint y)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
- return EGL_FALSE;
- }
-
scrn->OriginX = x;
scrn->OriginY = y;
@@ -241,14 +202,10 @@ _eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
* Query a screen's current surface.
*/
EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface *surface)
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface **surf)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (scrn->CurrentSurface)
- *surface = scrn->CurrentSurface->Handle;
- else
- *surface = EGL_NO_SURFACE;
+ *surf = scrn->CurrentSurface;
return EGL_TRUE;
}
@@ -257,29 +214,18 @@ _eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
* Query a screen's current mode.
*/
EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
- EGLModeMESA *mode)
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+ _EGLMode **m)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (scrn->CurrentMode)
- *mode = scrn->CurrentMode->Handle;
- else
- *mode = EGL_NO_MODE_MESA;
+ *m = scrn->CurrentMode;
return EGL_TRUE;
}
EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLint attribute, EGLint *value)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_SCREEN_POSITION_MESA:
value[0] = scrn->OriginX;
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 833439b410..8860a2aa7f 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -35,7 +35,7 @@ _eglInitScreen(_EGLScreen *screen);
extern _EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen);
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
extern void
@@ -43,40 +43,40 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
extern EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-extern EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
extern EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLSurface *surf, _EGLMode *m);
extern EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA mode);
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode *m);
extern EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y);
extern EGLBoolean
-_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value);
+_eglQueryDisplayMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface *surface);
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface **surface);
extern EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m);
extern EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value);
extern void
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 6905acac50..e7a1a8329e 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -6,11 +6,11 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
@@ -20,14 +20,13 @@
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
-_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
- _EGLSurface *surf, EGLint type, EGLConfig config,
- const EGLint *attrib_list)
+_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
+ _EGLConfig *conf, const EGLint *attrib_list)
{
const char *func;
- _EGLConfig *conf;
EGLint width = 0, height = 0, largest = 0;
- EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
+ EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE;
+ EGLint mipmapTex = EGL_FALSE;
EGLint renderBuffer = EGL_BACK_BUFFER;
#ifdef EGL_VERSION_1_2
EGLint colorspace = EGL_COLORSPACE_sRGB;
@@ -55,7 +54,6 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
return EGL_FALSE;
}
- conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
@@ -211,89 +209,16 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
}
-void
-_eglSaveSurface(_EGLSurface *surf)
-{
- EGLuint key = _eglHashGenKey(_eglGlobal.Surfaces);
- assert(surf);
- assert(!surf->Handle);
- surf->Handle = (EGLSurface) key;
- assert(surf->Handle);
- _eglHashInsert(_eglGlobal.Surfaces, key, surf);
-}
-
-
-void
-_eglRemoveSurface(_EGLSurface *surf)
-{
- _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
-}
-
-
-
-/**
- * Return the public handle for an internal _EGLSurface.
- * This is the inverse of _eglLookupSurface().
- */
-EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *surface)
-{
- if (surface)
- return surface->Handle;
- else
- return EGL_NO_SURFACE;
-}
-
-
-/**
- * Return the private _EGLSurface which corresponds to a public EGLSurface
- * handle.
- * This is the inverse of _eglGetSurfaceHandle().
- */
-_EGLSurface *
-_eglLookupSurface(EGLSurface surf)
-{
- _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
- (EGLuint) surf);
- return c;
-}
-
-
-_EGLSurface *
-_eglGetCurrentSurface(EGLint readdraw)
-{
- _EGLContext *ctx = _eglGetCurrentContext();
- if (ctx) {
- switch (readdraw) {
- case EGL_DRAW:
- return ctx->DrawSurface;
- case EGL_READ:
- return ctx->ReadSurface;
- default:
- return NULL;
- }
- }
- return NULL;
-}
-
-
EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- /* Basically just do error checking here. Drivers have to do the
- * actual buffer swap.
- */
- _EGLSurface *surface = _eglLookupSurface(draw);
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
- return EGL_FALSE;
- }
+ /* Drivers have to do the actual buffer swap. */
return EGL_TRUE;
}
EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
NativePixmapType target)
{
/* copy surface to native pixmap */
@@ -303,14 +228,9 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint *value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
- return EGL_FALSE;
- }
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
@@ -322,7 +242,7 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE;
case EGL_LARGEST_PBUFFER:
- *value = drv->LargestPbuffer;
+ *value = dpy->LargestPbuffer;
return EGL_TRUE;
case EGL_SURFACE_TYPE:
*value = surface->Type;
@@ -379,8 +299,8 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
@@ -388,26 +308,24 @@ _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
- if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) {
+ if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativePixmapType pixmap, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
@@ -415,26 +333,24 @@ _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
- if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) {
+ if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
@@ -442,18 +358,16 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
- if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) {
+ if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return NULL;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
@@ -461,23 +375,11 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- _EGLSurface *surf = _eglLookupSurface(surface);
- if (surf) {
- _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
- if (surf->IsBound) {
- surf->DeletePending = EGL_TRUE;
- }
- else {
- free(surf);
- }
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
- }
+ if (!_eglIsSurfaceBound(surf))
+ free(surf);
+ return EGL_TRUE;
}
@@ -485,16 +387,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
* Default fallback routine - drivers might override this.
*/
EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
-
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_MIPMAP_LEVEL:
surface->MipmapLevel = value;
@@ -508,15 +403,14 @@ _eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
{
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+ if (surface->Type != EGL_PBUFFER_BIT) {
_eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
@@ -538,15 +432,14 @@ _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
{
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+ if (surface->Type != EGL_PBUFFER_BIT) {
_eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
@@ -573,14 +466,11 @@ _eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval)
{
_EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
- if (surf == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
- return EGL_FALSE;
- }
- surf->SwapInterval = interval;
+ if (surf)
+ surf->SwapInterval = interval;
return EGL_TRUE;
}
@@ -590,17 +480,17 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+_EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum buftype, EGLClientBuffer buffer,
- EGLConfig config, const EGLint *attrib_list)
+ _EGLConfig *conf, const EGLint *attrib_list)
{
if (buftype != EGL_OPENVG_IMAGE) {
_eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
- return EGL_NO_SURFACE;
+ return NULL;
}
- return EGL_NO_SURFACE;
+ return NULL;
}
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 50f965b5cb..f6d44b5922 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -10,14 +10,16 @@
*/
struct _egl_surface
{
- EGLSurface Handle; /* The public/opaque handle which names this object */
- _EGLConfig *Config;
+ /* Managed by EGLDisplay for linking */
+ _EGLDisplay *Display;
+ _EGLSurface *Next;
- /* May need reference counting here */
- EGLBoolean IsBound;
- EGLBoolean DeletePending;
+ /* The bound status of the surface */
+ _EGLContext *Binding;
EGLBoolean BoundToTexture;
+ _EGLConfig *Config;
+
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
EGLint Width, Height;
EGLint TextureFormat, TextureTarget;
@@ -39,84 +41,74 @@ struct _egl_surface
extern EGLBoolean
-_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
- _EGLSurface *surf, EGLint type, EGLConfig config,
- const EGLint *attrib_list);
-
-
-extern void
-_eglSaveSurface(_EGLSurface *surf);
-
-
-extern void
-_eglRemoveSurface(_EGLSurface *surf);
-
-
-extern EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *surface);
-
-
-extern _EGLSurface *
-_eglLookupSurface(EGLSurface surf);
-
-
-extern _EGLSurface *
-_eglGetCurrentSurface(EGLint readdraw);
+_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
+ _EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
extern EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target);
extern EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value);
-extern EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
-extern EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
-extern EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
extern EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
extern EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
extern EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
extern EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
extern EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
#ifdef EGL_VERSION_1_2
-extern EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+extern _EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum buftype, EGLClientBuffer buffer,
- EGLConfig config, const EGLint *attrib_list);
+ _EGLConfig *conf, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
+/**
+ * Return true if the surface is bound to a thread.
+ * A surface bound to a texutre is not considered bound by
+ * this function.
+ */
+static INLINE EGLBoolean
+_eglIsSurfaceBound(_EGLSurface *surf)
+{
+ return (surf->Binding != NULL);
+}
+
#endif /* EGLSURFACE_INCLUDED */
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 9fbc55352c..4461440b9b 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -6,6 +6,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include "eglcompiler.h"
typedef struct _egl_api _EGLAPI;
@@ -28,7 +29,7 @@ typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo;
-typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args);
+typedef _EGLDriver *(*_EGLMain_t)(const char *args);
#endif /* EGLTYPEDEFS_INCLUDED */
diff --git a/src/egl/main/eglx.c b/src/egl/main/eglx.c
deleted file mode 100644
index 50acc3a24f..0000000000
--- a/src/egl/main/eglx.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * X-specific EGL code.
- *
- * Any glue code needed to make EGL work with X is placed in this file.
- */
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-
-#include "egldriver.h"
-#include "egllog.h"
-#include "eglstring.h"
-#include "eglx.h"
-
-
-static const char *DefaultGLXDriver = "egl_glx";
-static const char *DefaultSoftDriver = "egl_softpipe";
-
-
-/**
- * Given an X Display ptr (at dpy->Xdpy) try to determine the appropriate
- * device driver. Return its name.
- *
- * This boils down to whether to use the egl_glx.so driver which will
- * load a DRI driver or the egl_softpipe.so driver that'll do software
- * rendering on Xlib.
- */
-const char *
-_xeglChooseDriver(_EGLDisplay *dpy)
-{
-#ifdef _EGL_PLATFORM_X
- _XPrivDisplay xdpy;
- int screen;
- const char *driverName;
-
- assert(dpy);
-
- if (!dpy->Xdpy) {
- dpy->Xdpy = XOpenDisplay(NULL);
- if (!dpy->Xdpy) {
- /* can't open X display -> can't use X-based driver */
- return NULL;
- }
- }
- xdpy = (_XPrivDisplay) dpy->Xdpy;
-
- assert(dpy->Xdpy);
-
- screen = DefaultScreen(dpy->Xdpy);
-
- /* See if we can choose a DRI/DRM driver */
- driverName = _eglChooseDRMDriver(screen);
- if (driverName) {
- free((void *) driverName);
- driverName = _eglstrdup(DefaultGLXDriver);
- }
- else {
- driverName = _eglstrdup(DefaultSoftDriver);
- }
-
- _eglLog(_EGL_DEBUG, "_xeglChooseDriver: %s", driverName);
-
- return driverName;
-#else
- return NULL;
-#endif
-}
-
-
diff --git a/src/egl/main/eglx.h b/src/egl/main/eglx.h
deleted file mode 100644
index 4323d55838..0000000000
--- a/src/egl/main/eglx.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef EGLX_INCLUDED
-#define EGLX_INCLUDED
-
-
-#include "egldisplay.h"
-
-
-extern const char *
-_xeglChooseDriver(_EGLDisplay *dpy);
-
-
-#endif /* EGLX_INCLUDED */