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:
parent
8e92ec9fdd
commit
75da80b295
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -321,6 +321,7 @@ eglGetError(void)
|
|||
{
|
||||
_EGLThreadInfo *t = _eglGetCurrentThread();
|
||||
EGLint e = t->LastError;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -45,10 +45,6 @@ extern void
|
|||
_eglSaveDisplay(_EGLDisplay *dpy);
|
||||
|
||||
|
||||
extern _EGLDisplay *
|
||||
_eglGetCurrentDisplay(void);
|
||||
|
||||
|
||||
extern void
|
||||
_eglCleanupDisplay(_EGLDisplay *disp);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -60,10 +60,6 @@ extern _EGLSurface *
|
|||
_eglLookupSurface(EGLSurface surf);
|
||||
|
||||
|
||||
extern _EGLSurface *
|
||||
_eglGetCurrentSurface(EGLint readdraw);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
|
||||
|
||||
|
|
Loading…
Reference in New Issue