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
#EXTRA_LIB_PATH ?=
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)
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

View File

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

View File

@ -321,7 +321,8 @@ eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError;
t->LastError = EGL_SUCCESS;
if (!_eglIsCurrentThreadDummy())
t->LastError = EGL_SUCCESS;
return e;
}
@ -546,6 +547,9 @@ eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
switch (api) {
#ifdef EGL_VERSION_1_4
case EGL_OPENGL_API:
@ -603,15 +607,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;
}

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!
*/
@ -219,6 +208,9 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_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) {

View File

@ -47,10 +47,6 @@ 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);

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
* the object itself.

View File

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

View File

@ -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);
}
}

View File

@ -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"
/**
@ -33,9 +23,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 +39,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 */

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
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{

View File

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