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
|
# 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
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue