egl: Support per-thread info.

This commit introduces a "current" system to manage per-thread info.  It
uses TLS, if GLX_USE_TLS is defined, or pthread, if PTHREADS is defined.
If none of them are defined, it uses a dummy implementation that is just
like before.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
This commit is contained in:
Chia-I Wu 2009-07-17 11:41:02 -06:00 committed by Brian Paul
parent 8e92ec9fdd
commit 75da80b295
11 changed files with 23 additions and 196 deletions

View File

@ -105,7 +105,7 @@ GALLIUM_STATE_TRACKERS_DIRS = glx
# Library dependencies # Library dependencies
#EXTRA_LIB_PATH ?= #EXTRA_LIB_PATH ?=
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -ldl EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -ldl -lpthread
OSMESA_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) OSMESA_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
GLU_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm GLU_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm
GLUT_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -lX11 -lXmu -lXi -lm GLUT_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -lX11 -lXmu -lXi -lm

View File

@ -11,6 +11,7 @@ HEADERS = \
eglconfig.h \ eglconfig.h \
eglconfigutil.h \ eglconfigutil.h \
eglcontext.h \ eglcontext.h \
eglcurrent.h \
egldefines.h \ egldefines.h \
egldisplay.h \ egldisplay.h \
egldriver.h \ egldriver.h \
@ -29,6 +30,7 @@ SOURCES = \
eglconfig.c \ eglconfig.c \
eglconfigutil.c \ eglconfigutil.c \
eglcontext.c \ eglcontext.c \
eglcurrent.c \
egldisplay.c \ egldisplay.c \
egldriver.c \ egldriver.c \
eglglobals.c \ eglglobals.c \

View File

@ -321,7 +321,8 @@ eglGetError(void)
{ {
_EGLThreadInfo *t = _eglGetCurrentThread(); _EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError; EGLint e = t->LastError;
t->LastError = EGL_SUCCESS; if (!_eglIsCurrentThreadDummy())
t->LastError = EGL_SUCCESS;
return e; return e;
} }
@ -546,6 +547,9 @@ eglBindAPI(EGLenum api)
{ {
_EGLThreadInfo *t = _eglGetCurrentThread(); _EGLThreadInfo *t = _eglGetCurrentThread();
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
switch (api) { switch (api) {
#ifdef EGL_VERSION_1_4 #ifdef EGL_VERSION_1_4
case EGL_OPENGL_API: case EGL_OPENGL_API:
@ -603,15 +607,19 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLBoolean EGLBoolean
eglReleaseThread(void) eglReleaseThread(void)
{ {
_EGLThreadInfo *t = _eglGetCurrentThread(); EGLDisplay dpy;
EGLDisplay dpy = eglGetCurrentDisplay();
if (_eglIsCurrentThreadDummy())
return EGL_TRUE;
dpy = eglGetCurrentDisplay();
if (dpy) { if (dpy) {
_EGLDriver *drv = _eglLookupDriver(dpy); _EGLDriver *drv = _eglLookupDriver(dpy);
/* unbind context */ /* unbind context */
(void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE, (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT); EGL_NO_SURFACE, EGL_NO_CONTEXT);
} }
_eglDeleteThreadData(t); _eglDestroyCurrentThread();
return EGL_TRUE; return EGL_TRUE;
} }

View File

@ -108,17 +108,6 @@ _eglLookupContext(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! * Just a placeholder/demo function. Real driver will never use this!
*/ */
@ -219,6 +208,9 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW); _EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
_EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ); _EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
/* error checking */ /* error checking */
if (ctx) { if (ctx) {
if (draw == NULL || read == NULL) { if (draw == NULL || read == NULL) {

View File

@ -47,10 +47,6 @@ extern _EGLContext *
_eglLookupContext(EGLContext ctx); _eglLookupContext(EGLContext ctx);
extern _EGLContext *
_eglGetCurrentContext(void);
extern EGLContext extern EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);

View File

@ -86,17 +86,6 @@ _eglSaveDisplay(_EGLDisplay *dpy)
} }
_EGLDisplay *
_eglGetCurrentDisplay(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Display;
else
return NULL;
}
/** /**
* Free all the data hanging of an _EGLDisplay object, but not * Free all the data hanging of an _EGLDisplay object, but not
* the object itself. * the object itself.

View File

@ -45,10 +45,6 @@ extern void
_eglSaveDisplay(_EGLDisplay *dpy); _eglSaveDisplay(_EGLDisplay *dpy);
extern _EGLDisplay *
_eglGetCurrentDisplay(void);
extern void extern void
_eglCleanupDisplay(_EGLDisplay *disp); _eglCleanupDisplay(_EGLDisplay *disp);

View File

@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "eglglobals.h" #include "eglglobals.h"
#include "egllog.h"
struct _egl_global _eglGlobal = struct _egl_global _eglGlobal =
{ {
@ -22,8 +22,8 @@ _eglInitGlobals(void)
_eglGlobal.ClientAPIsMask = 0x0; _eglGlobal.ClientAPIsMask = 0x0;
/* XXX temporary */ if (!_eglInitCurrent())
_eglGlobal.ThreadInfo = _eglNewThreadInfo(); _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
} }
} }
@ -34,113 +34,8 @@ _eglInitGlobals(void)
void void
_eglDestroyGlobals(void) _eglDestroyGlobals(void)
{ {
_eglFiniCurrent();
/* XXX TODO walk over table entries, deleting each */ /* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays); _eglDeleteHashTable(_eglGlobal.Displays);
_eglDeleteHashTable(_eglGlobal.Surfaces); _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);
}
}

View File

@ -3,17 +3,7 @@
#include "egltypedefs.h" #include "egltypedefs.h"
#include "eglhash.h" #include "eglhash.h"
#include "eglcurrent.h"
/**
* Per-thread info
*/
struct _egl_thread_info
{
EGLint LastError;
_EGLContext *CurrentContext;
EGLenum CurrentAPI;
};
/** /**
@ -33,9 +23,6 @@ struct _egl_global
char ClientAPIs[1000]; /**< updated by eglQueryString */ char ClientAPIs[1000]; /**< updated by eglQueryString */
/* XXX temporary - should be thread-specific data (TSD) */
_EGLThreadInfo *ThreadInfo;
EGLint NumDrivers; EGLint NumDrivers;
_EGLDriver *Drivers[10]; _EGLDriver *Drivers[10];
}; };
@ -52,20 +39,4 @@ extern void
_eglDestroyGlobals(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 */ #endif /* EGLGLOBALS_INCLUDED */

View File

@ -259,24 +259,6 @@ _eglLookupSurface(EGLSurface surf)
} }
_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 EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{ {

View File

@ -60,10 +60,6 @@ extern _EGLSurface *
_eglLookupSurface(EGLSurface surf); _eglLookupSurface(EGLSurface surf);
extern _EGLSurface *
_eglGetCurrentSurface(EGLint readdraw);
extern EGLBoolean extern EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw); _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);