summaryrefslogtreecommitdiff
path: root/src/egl/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main')
-rw-r--r--src/egl/main/Makefile5
-rw-r--r--src/egl/main/eglapi.c34
-rw-r--r--src/egl/main/eglcompiler.h31
-rw-r--r--src/egl/main/eglcontext.c136
-rw-r--r--src/egl/main/eglcontext.h29
-rw-r--r--src/egl/main/eglcurrent.c283
-rw-r--r--src/egl/main/eglcurrent.h92
-rw-r--r--src/egl/main/egldisplay.c253
-rw-r--r--src/egl/main/egldisplay.h79
-rw-r--r--src/egl/main/egldriver.c4
-rw-r--r--src/egl/main/eglglobals.c113
-rw-r--r--src/egl/main/eglglobals.h32
-rw-r--r--src/egl/main/eglscreen.c15
-rw-r--r--src/egl/main/eglsurface.c121
-rw-r--r--src/egl/main/eglsurface.h32
-rw-r--r--src/egl/main/egltypedefs.h1
16 files changed, 849 insertions, 411 deletions
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 8cfa25ca16..e1ff8794b3 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -7,9 +7,11 @@ include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
HEADERS = \
+ eglcompiler.h \
eglconfig.h \
eglconfigutil.h \
eglcontext.h \
+ eglcurrent.h \
egldefines.h \
egldisplay.h \
egldriver.h \
@@ -28,6 +30,7 @@ SOURCES = \
eglconfig.c \
eglconfigutil.c \
eglcontext.c \
+ eglcurrent.c \
egldisplay.c \
egldriver.c \
eglglobals.c \
@@ -66,7 +69,7 @@ $(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*
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 9df938e188..f0a6f7f935 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -51,7 +51,12 @@ eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
_eglInitGlobals();
- dpy = _eglNewDisplay(nativeDisplay);
+ dpy = _eglFindDisplay(nativeDisplay);
+ if (!dpy) {
+ dpy = _eglNewDisplay(nativeDisplay);
+ if (dpy)
+ _eglLinkDisplay(dpy);
+ }
return _eglGetDisplayHandle(dpy);
}
@@ -321,7 +326,8 @@ eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError;
- t->LastError = EGL_SUCCESS;
+ if (!_eglIsCurrentThreadDummy())
+ t->LastError = EGL_SUCCESS;
return e;
}
@@ -546,11 +552,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 +570,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 +597,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);
}
@@ -603,15 +615,19 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLBoolean
eglReleaseThread(void)
{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLDisplay dpy = eglGetCurrentDisplay();
+ EGLDisplay dpy;
+
+ if (_eglIsCurrentThreadDummy())
+ return EGL_TRUE;
+
+ 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);
}
- _eglDeleteThreadData(t);
+ _eglDestroyCurrentThread();
return EGL_TRUE;
}
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
new file mode 100644
index 0000000000..0b19afedfd
--- /dev/null
+++ b/src/egl/main/eglcompiler.h
@@ -0,0 +1,31 @@
+#ifndef EGLCOMPILER_INCLUDED
+#define EGLCOMPILER_INCLUDED
+
+
+/**
+ * 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/eglcontext.c b/src/egl/main/eglcontext.c
index 461679db09..9ab4286d3a 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,7 +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;
@@ -49,7 +46,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,66 +56,6 @@ _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
@@ -128,18 +64,24 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* example code */
_EGLContext *context;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateContext");
+ return EGL_NO_CONTEXT;
+ }
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
return EGL_NO_CONTEXT;
- if (!_eglInitContext(drv, dpy, context, config, attrib_list)) {
+ if (!_eglInitContext(drv, context, conf, attrib_list)) {
free(context);
return EGL_NO_CONTEXT;
}
- _eglSaveContext(context);
- return (EGLContext) context;
+ return _eglLinkContext(context, _eglLookupDisplay(dpy));
#endif
return EGL_NO_CONTEXT;
}
@@ -153,12 +95,9 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
- if (context->IsBound) {
- context->DeletePending = EGL_TRUE;
- }
- else {
+ _eglUnlinkContext(context);
+ if (!context->IsBound)
free(context);
- }
return EGL_TRUE;
}
else {
@@ -203,7 +142,7 @@ _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
@@ -214,10 +153,13 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_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) {
@@ -233,6 +175,32 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
+
+#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 {
+ apiIndex = t->CurrentAPIIndex;
+ }
+
+ oldContext = t->CurrentContexts[apiIndex];
+ if (oldContext) {
+ oldDrawSurface = oldContext->DrawSurface;
+ oldReadSurface = oldContext->ReadSurface;
}
/*
@@ -240,7 +208,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
*/
if (oldDrawSurface != NULL) {
oldDrawSurface->IsBound = EGL_FALSE;
- if (oldDrawSurface->DeletePending) {
+ if (!_eglIsSurfaceLinked(oldDrawSurface)) {
/* make sure we don't try to rebind a deleted surface */
if (draw == oldDrawSurface || draw == oldReadSurface) {
draw = NULL;
@@ -251,7 +219,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
}
if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
oldReadSurface->IsBound = EGL_FALSE;
- if (oldReadSurface->DeletePending) {
+ if (!_eglIsSurfaceLinked(oldReadSurface)) {
/* make sure we don't try to rebind a deleted surface */
if (read == oldDrawSurface || read == oldReadSurface) {
read = NULL;
@@ -262,7 +230,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
}
if (oldContext != NULL) {
oldContext->IsBound = EGL_FALSE;
- if (oldContext->DeletePending) {
+ if (!_eglIsContextLinked(oldContext)) {
/* make sure we don't try to rebind a deleted context */
if (ctx == oldContext) {
ctx = NULL;
@@ -283,9 +251,11 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
ctx->IsBound = EGL_TRUE;
draw->IsBound = EGL_TRUE;
read->IsBound = EGL_TRUE;
+ t->CurrentContexts[apiIndex] = ctx;
+ }
+ else {
+ t->CurrentContexts[apiIndex] = NULL;
}
-
- t->CurrentContext = ctx;
return EGL_TRUE;
}
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 34fee9c637..2fb28d38b9 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -11,7 +11,9 @@
*/
struct _egl_context
{
- _EGLDisplay *Display; /* who do I belong to? */
+ /* Managed by EGLDisplay for linking */
+ _EGLDisplay *Display;
+ _EGLContext *Next;
_EGLConfig *Config;
@@ -19,7 +21,6 @@ struct _egl_context
_EGLSurface *ReadSurface;
EGLBoolean IsBound;
- EGLBoolean DeletePending;
EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
@@ -27,28 +28,8 @@ 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);
-
-
-extern _EGLContext *
-_eglLookupContext(EGLContext ctx);
-
-
-extern _EGLContext *
-_eglGetCurrentContext(void);
+_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
+ _EGLConfig *config, const EGLint *attrib_list);
extern EGLContext
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
new file mode 100644
index 0000000000..96152db19f
--- /dev/null
+++ b/src/egl/main/eglcurrent.c
@@ -0,0 +1,283 @@
+#include <stdlib.h>
+#include <string.h>
+#include "eglcurrent.h"
+#include "eglcontext.h"
+#include "egllog.h"
+
+
+/* a fallback thread info to guarantee that every thread always has one */
+static _EGLThreadInfo dummy_thread;
+
+
+#ifdef GLX_USE_TLS
+static __thread const _EGLThreadInfo *_egl_TSD;
+ __attribute__ ((tls_model("initial-exec")));
+
+static INLINE EGLBoolean _eglInitTSD(void) { return EGL_TRUE; }
+static INLINE void _eglFiniTSD(void) { }
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t) { _egl_TSD = t; }
+
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
+{
+ return (_EGLThreadInfo *) _egl_TSD;
+}
+
+#elif PTHREADS
+#include <pthread.h>
+
+static pthread_key_t _egl_TSD;
+
+static INLINE EGLBoolean _eglInitTSD(void)
+{
+ return (pthread_key_create(&_egl_TSD, NULL) == 0);
+}
+
+static INLINE void _eglFiniTSD(void)
+{
+ pthread_key_delete(_egl_TSD);
+}
+
+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);
+}
+
+#else /* PTHREADS */
+static const _EGLThreadInfo *_egl_TSD;
+
+static INLINE EGLBoolean _eglInitTSD(void) { return EGL_TRUE; }
+static INLINE void _eglFiniTSD(void) { }
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t) { _egl_TSD = t; }
+
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
+{
+ return (_EGLThreadInfo *) _egl_TSD;
+}
+#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);
+}
+
+
+/**
+ * Initialize "current thread" management.
+ */
+EGLBoolean
+_eglInitCurrent(void)
+{
+ _eglInitThreadInfo(&dummy_thread);
+ return _eglInitTSD();
+}
+
+
+/**
+ * Finish "current thread" management.
+ */
+void
+_eglFiniCurrent(void)
+{
+ /* TODO trace and release all threads... */
+ _eglFiniTSD();
+}
+
+
+/**
+ * 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 = _eglGetTSD();
+ if (!t) {
+ t = _eglCreateThreadInfo();
+ _eglSetTSD(t);
+ }
+
+ return t;
+}
+
+
+/**
+ * Destroy the calling thread's thread info.
+ */
+void
+_eglDestroyCurrentThread(void)
+{
+ _EGLThreadInfo *t = _eglGetTSD();
+ 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 = _eglGetTSD();
+ 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..f9fdf7bd0f
--- /dev/null
+++ b/src/egl/main/eglcurrent.h
@@ -0,0 +1,92 @@
+#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;
+};
+
+
+extern EGLBoolean
+_eglInitCurrent(void);
+
+
+extern void
+_eglFiniCurrent(void);
+
+
+/**
+ * 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..89de609d0b 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
+#include "eglsurface.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
@@ -25,11 +26,6 @@ _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;
@@ -46,8 +42,37 @@ _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
+_eglLinkDisplay(_EGLDisplay *dpy)
+{
+ EGLuint key;
+ key = _eglHashGenKey(_eglGlobal.Displays);
+ assert(key);
+ /* "link" the display to the hash table */
+ _eglHashInsert(_eglGlobal.Displays, key, dpy);
+ dpy->Handle = (EGLDisplay) key;
+
+ return dpy->Handle;
+}
+
+
+/**
+ * Unlink a linked display from itself.
+ * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
+ */
+void
+_eglUnlinkDisplay(_EGLDisplay *dpy)
+{
+ _eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle);
+ dpy->Handle = EGL_NO_DISPLAY;
+}
+
+
+/**
+ * Return the handle of a linked display, or EGL_NO_DISPLAY.
*/
EGLDisplay
_eglGetDisplayHandle(_EGLDisplay *display)
@@ -60,40 +85,70 @@ _eglGetDisplayHandle(_EGLDisplay *display)
/**
- * Return the _EGLDisplay object that corresponds to the given public/
- * opaque display handle.
- * This is the inverse of _eglGetDisplayHandle().
+ * Lookup a handle to find the linked display.
+ * Return NULL if the handle has no corresponding linked display.
*/
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
EGLuint key = (EGLuint) dpy;
- if (!_eglGlobal.Displays)
- return NULL;
return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
}
-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);
+ EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays);
+
+ /* Walk the hash table. Should switch to list if it is a problem. */
+ while (key) {
+ _EGLDisplay *dpy = (_EGLDisplay *)
+ _eglHashLookup(_eglGlobal.Displays, key);
+ assert(dpy);
+
+ if (dpy->NativeDisplay == nativeDisplay)
+ return dpy;
+ key = _eglHashNextEntry(_eglGlobal.Displays, key);
+ }
+
+ return NULL;
}
-_EGLDisplay *
-_eglGetCurrentDisplay(void)
+/**
+ * Destroy the contexts and surfaces that are linked to the display.
+ */
+void
+_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy)
{
- _EGLContext *ctx = _eglGetCurrentContext();
- if (ctx)
- return ctx->Display;
- else
- return NULL;
+ _EGLDisplay *display;
+ _EGLContext *contexts;
+ _EGLSurface *surfaces;
+
+ display = _eglLookupDisplay(dpy);
+ if (!display)
+ return;
+ contexts = display->ContextList;
+ surfaces = display->SurfaceList;
+
+ while (contexts) {
+ EGLContext handle = _eglGetContextHandle(contexts);
+ contexts = contexts->Next;
+ drv->API.DestroyContext(drv, dpy, handle);
+ }
+ assert(!display->ContextList);
+
+ while (surfaces) {
+ EGLSurface handle = _eglGetSurfaceHandle(surfaces);
+ surfaces = surfaces->Next;
+ drv->API.DestroySurface(drv, dpy, handle);
+ }
+ assert(!display->SurfaceList);
}
@@ -119,3 +174,147 @@ _eglCleanupDisplay(_EGLDisplay *disp)
/* 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;
+}
+
+
+/**
+ * Return the handle of a linked context, or EGL_NO_CONTEXT.
+ */
+EGLContext
+_eglGetContextHandle(_EGLContext *ctx)
+{
+ return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT;
+}
+
+
+/**
+ * Lookup a handle to find the linked context.
+ * Return NULL if the handle has no corresponding linked context.
+ */
+_EGLContext *
+_eglLookupContext(EGLContext ctx)
+{
+ _EGLContext *context = (_EGLContext *) ctx;
+ return (context && context->Display) ? context : 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)
+{
+ EGLuint key;
+
+ surf->Display = dpy;
+ surf->Next = dpy->SurfaceList;
+ dpy->SurfaceList = surf;
+
+ key = _eglHashGenKey(_eglGlobal.Surfaces);
+ assert(key);
+ _eglHashInsert(_eglGlobal.Surfaces, key, surf);
+
+ surf->Handle = (EGLSurface) key;
+ return surf->Handle;
+}
+
+
+/**
+ * Unlink a linked surface from its display.
+ * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
+ */
+void
+_eglUnlinkSurface(_EGLSurface *surf)
+{
+ _EGLSurface *prev;
+
+ _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
+ surf->Handle = EGL_NO_SURFACE;
+
+ 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;
+}
+
+
+/**
+ * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ */
+EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surface)
+{
+ if (surface)
+ return surface->Handle;
+ else
+ return EGL_NO_SURFACE;
+}
+
+
+/**
+ * Lookup a handle to find the linked surface.
+ * Return NULL if the handle has no corresponding linked surface.
+ */
+_EGLSurface *
+_eglLookupSurface(EGLSurface surf)
+{
+ _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
+ (EGLuint) surf);
+ return c;
+}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index ff623ee1c6..372ed3cd79 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -23,6 +23,9 @@ struct _egl_display
EGLint NumConfigs;
_EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */
+ /* lists of linked contexts and surface */
+ _EGLContext *ContextList;
+ _EGLSurface *SurfaceList;
#ifdef _EGL_PLATFORM_X
Display *Xdpy;
#endif
@@ -33,7 +36,15 @@ extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
-EGLDisplay
+extern EGLDisplay
+_eglLinkDisplay(_EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkDisplay(_EGLDisplay *dpy);
+
+
+extern EGLDisplay
_eglGetDisplayHandle(_EGLDisplay *display);
@@ -41,21 +52,77 @@ extern _EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy);
-extern void
-_eglSaveDisplay(_EGLDisplay *dpy);
+/**
+ * Return true if the display is linked.
+ */
+static INLINE EGLBoolean
+_eglIsDisplayLinked(_EGLDisplay *dpy)
+{
+ return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
+}
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 EGLContext
+_eglGetContextHandle(_EGLContext *ctx);
+extern _EGLContext *
+_eglLookupContext(EGLContext ctx);
+
+
+/**
+ * Return true if the context is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsContextLinked(_EGLContext *ctx)
+{
+ return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+}
+
+extern EGLSurface
+_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkSurface(_EGLSurface *surf);
+
+
+extern EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *);
+
+
+extern _EGLSurface *
+_eglLookupSurface(EGLSurface surf);
+
+
+/**
+ * Return true if the surface is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsSurfaceLinked(_EGLSurface *surf)
+{
+ return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE);
+}
+
#endif /* EGLDISPLAY_INCLUDED */
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 43b1f51903..f2a864cd8a 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -284,9 +284,7 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
_eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
- /*
- * XXX check for currently bound context/surfaces and delete them?
- */
+ _eglReleaseDisplayResources(drv, dpy);
b = drv->API.Terminate(drv, dpy);
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index b770e55dbd..55de394ef5 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,6 +1,6 @@
-#include <stdio.h>
#include <stdlib.h>
#include "eglglobals.h"
+#include "egllog.h"
struct _egl_global _eglGlobal =
{
@@ -22,8 +22,8 @@ _eglInitGlobals(void)
_eglGlobal.ClientAPIsMask = 0x0;
- /* XXX temporary */
- _eglGlobal.ThreadInfo = _eglNewThreadInfo();
+ if (!_eglInitCurrent())
+ _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
}
}
@@ -34,113 +34,8 @@ _eglInitGlobals(void)
void
_eglDestroyGlobals(void)
{
+ _eglFiniCurrent();
/* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays);
_eglDeleteHashTable(_eglGlobal.Surfaces);
}
-
-
-/**
- * Allocate and init a new _EGLThreadInfo object.
- */
-_EGLThreadInfo *
-_eglNewThreadInfo(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;
-}
-
-
-/**
- * Delete/free a _EGLThreadInfo object.
- */
-void
-_eglDeleteThreadData(_EGLThreadInfo *t)
-{
- free(t);
-}
-
-
-
-/**
- * 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;
-}
-
-
-/**
- * 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;
-
- 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);
- }
-}
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index 14d8ea487a..a9443cfbdd 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -3,17 +3,7 @@
#include "egltypedefs.h"
#include "eglhash.h"
-
-
-/**
- * Per-thread info
- */
-struct _egl_thread_info
-{
- EGLint LastError;
- _EGLContext *CurrentContext;
- EGLenum CurrentAPI;
-};
+#include "eglcurrent.h"
/**
@@ -23,6 +13,7 @@ struct _egl_global
{
EGLBoolean Initialized;
+ /* these are private to egldisplay.c */
_EGLHashtable *Displays;
_EGLHashtable *Surfaces;
@@ -33,9 +24,6 @@ struct _egl_global
char ClientAPIs[1000]; /**< updated by eglQueryString */
- /* XXX temporary - should be thread-specific data (TSD) */
- _EGLThreadInfo *ThreadInfo;
-
EGLint NumDrivers;
_EGLDriver *Drivers[10];
};
@@ -52,20 +40,4 @@ 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);
-
-
#endif /* EGLGLOBALS_INCLUDED */
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 9c9a8377bf..b6bde65e8b 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -128,20 +128,25 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateScreenSurfaceMESA");
+ return EGL_NO_SURFACE;
+ }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
- 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;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 6905acac50..9821e63628 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
#include "egldriver.h"
@@ -20,12 +21,10 @@
* \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 renderBuffer = EGL_BACK_BUFFER;
@@ -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,72 +209,6 @@ _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)
{
@@ -385,19 +317,24 @@ _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateWindowSurface");
+ return EGL_NO_SURFACE;
+ }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
- 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;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@@ -412,19 +349,24 @@ _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
+ return EGL_NO_SURFACE;
+ }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
- 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;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@@ -439,19 +381,24 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
- 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;
}
- _eglSaveSurface(surf);
-
- return surf->Handle;
+ return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@@ -465,13 +412,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
_EGLSurface *surf = _eglLookupSurface(surface);
if (surf) {
- _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
- if (surf->IsBound) {
- surf->DeletePending = EGL_TRUE;
- }
- else {
+ _eglUnlinkSurface(surf);
+ if (!surf->IsBound)
free(surf);
- }
return EGL_TRUE;
}
else {
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 50f965b5cb..f9413eb9d7 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -10,12 +10,15 @@
*/
struct _egl_surface
{
- EGLSurface Handle; /* The public/opaque handle which names this object */
+ /* Managed by EGLDisplay for linking */
+ _EGLDisplay *Display;
+ _EGLSurface *Next;
+ EGLSurface Handle;
+
_EGLConfig *Config;
/* May need reference counting here */
EGLBoolean IsBound;
- EGLBoolean DeletePending;
EGLBoolean BoundToTexture;
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
@@ -39,29 +42,8 @@ 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
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 9fbc55352c..0a770dec0c 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;