egl: Support per-thread info.
authorChia-I Wu <olvaffe@gmail.com>
Fri, 17 Jul 2009 17:41:02 +0000 (11:41 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 17 Jul 2009 17:41:02 +0000 (11:41 -0600)
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>
configs/default
src/egl/main/Makefile
src/egl/main/eglapi.c
src/egl/main/eglcontext.c
src/egl/main/eglcontext.h
src/egl/main/egldisplay.c
src/egl/main/egldisplay.h
src/egl/main/eglglobals.c
src/egl/main/eglglobals.h
src/egl/main/eglsurface.c
src/egl/main/eglsurface.h

index a8996702d70eb931b55497c1710bfd268c8dab11..60638d739ddd3925428ae0195e7bb8e20ebfded5 100644 (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
index 4034b28e910419b79849fa172fe6282ec8a5fe3e..e1ff8794b3544d95b8f9536fdde7c981ab37e8bf 100644 (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 \
index 9df938e188729d2b8f06c62c0f450aa02a5b7c01..8f4a489b913f26e94ee3ac4a93c709c4d39f4344 100644 (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;
 }
 
index 461679db0906068c439e4ffde414afc56dc7444a..5e24b02a58de4392079b1ce7aa31d964c714225a 100644 (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) {
index 34fee9c6376197e61f0a9b413c06419b44750991..5c8403153b3f94489e2095932a9827fa11498820 100644 (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);
 
index 47a2323eafb3923e508fdb9527dcc64c3983d243..01f67f6e4702fceb321e530d58c48ae5c9a6bf10 100644 (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.
index ff623ee1c666474649034ae51197546a3b193ec0..69f0d130efc1a368cd7969ee6488a2ca1aa167a4 100644 (file)
@@ -45,10 +45,6 @@ extern void
 _eglSaveDisplay(_EGLDisplay *dpy);
 
 
-extern _EGLDisplay *
-_eglGetCurrentDisplay(void);
-
-
 extern void
 _eglCleanupDisplay(_EGLDisplay *disp);
 
index b770e55dbdf72d2eef6589d504a1c766c627dc84..55de394ef5fb616765f303ee1bff624fd0deb89d 100644 (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);
-   }
-}
index 14d8ea487af04467a83ba8d0b0f973642c434421..fbb55c23f00a9600cc50f2b24a9c1aa75924cbe7 100644 (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 */
index 6905acac50b020f5ce6cc9c1df85a4600bd40edb..964288aac8bd0a846992150fbb03a6f498f08c0e 100644 (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)
 {
index 50f965b5cb7bd557b6a0dca689d5542ffebd1aeb..3b54221bd32c569f9f1098843a31961c352e5145 100644 (file)
@@ -60,10 +60,6 @@ extern _EGLSurface *
 _eglLookupSurface(EGLSurface surf);
  
 
-extern _EGLSurface *
-_eglGetCurrentSurface(EGLint readdraw);
-
-
 extern EGLBoolean
 _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);