From 5c8e63290620d78763503f9ba4de28530ae1961e Mon Sep 17 00:00:00 2001 From: Kyle Brenneman Date: Fri, 4 Mar 2016 13:01:34 -0700 Subject: GLdispatch: Rename the API state structures. Rename __GLdispatchAPIState to __GLdispatchThreadState, to make it clearer that the structure contains thread-specific data. Updated some out-of-date comments. --- src/GLX/libglx.c | 196 ++++++++++++++++++++--------------------- src/GLX/libglxcurrent.h | 40 +++++---- src/GLdispatch/GLdispatch.c | 66 +++++++------- src/GLdispatch/GLdispatch.h | 102 ++++++++++++--------- src/GLdispatch/export_list.sym | 2 +- 5 files changed, 211 insertions(+), 195 deletions(-) diff --git a/src/GLX/libglx.c b/src/GLX/libglx.c index 3c19831..df3f4d2 100644 --- a/src/GLX/libglx.c +++ b/src/GLX/libglx.c @@ -89,14 +89,14 @@ static __GLXcontextInfo *glxContextHash = NULL; static glvnd_mutex_t glxContextHashLock; /** - * A list of current __GLXAPIState structures. This is used so that we can + * A list of current __GLXThreadState structures. This is used so that we can * clean up at process termination or after a fork. */ -static struct glvnd_list currentAPIStateList; -static glvnd_mutex_t currentAPIStateListMutex = GLVND_MUTEX_INITIALIZER; +static struct glvnd_list currentThreadStateList; +static glvnd_mutex_t currentThreadStateListMutex = GLVND_MUTEX_INITIALIZER; -static __GLXAPIState *CreateAPIState(__GLXvendorInfo *vendor); -static void DestroyAPIState(__GLXAPIState *apiState); +static __GLXThreadState *CreateThreadState(__GLXvendorInfo *vendor); +static void DestroyThreadState(__GLXThreadState *threadState); /*! * Updates the current context. @@ -477,13 +477,13 @@ PUBLIC GLXContext glXGetCurrentContext(void) { __glXThreadInitialize(); - __GLXAPIState *apiState = __glXGetCurrentAPIState(); - if (apiState != NULL) { - // The current thread has an API state pointer if and only if it has a + __GLXThreadState *threadState = __glXGetCurrentThreadState(); + if (threadState != NULL) { + // The current thread has a thread state pointer if and only if it has a // current context, and the currentContext pointer is assigned before - // the apiState pointer is put into TLS, so it will never be NULL. - assert(apiState->currentContext != NULL); - return apiState->currentContext->context; + // the threadState pointer is put into TLS, so it will never be NULL. + assert(threadState->currentContext != NULL); + return threadState->currentContext->context; } else { return NULL; } @@ -494,9 +494,9 @@ PUBLIC GLXDrawable glXGetCurrentDrawable(void) { __glXThreadInitialize(); - __GLXAPIState *apiState = __glXGetCurrentAPIState(); - if (apiState != NULL) { - return apiState->currentDraw; + __GLXThreadState *threadState = __glXGetCurrentThreadState(); + if (threadState != NULL) { + return threadState->currentDraw; } else { return None; } @@ -506,9 +506,9 @@ PUBLIC GLXDrawable glXGetCurrentReadDrawable(void) { __glXThreadInitialize(); - __GLXAPIState *apiState = __glXGetCurrentAPIState(); - if (apiState != NULL) { - return apiState->currentRead; + __GLXThreadState *threadState = __glXGetCurrentThreadState(); + if (threadState != NULL) { + return threadState->currentRead; } else { return None; } @@ -518,9 +518,9 @@ PUBLIC Display *glXGetCurrentDisplay(void) { __glXThreadInitialize(); - __GLXAPIState *apiState = __glXGetCurrentAPIState(); - if (apiState != NULL) { - return apiState->currentDisplay; + __GLXThreadState *threadState = __glXGetCurrentThreadState(); + if (threadState != NULL) { + return threadState->currentDisplay; } else { return NULL; } @@ -530,10 +530,10 @@ __GLXvendorInfo *__glXGetCurrentDynDispatch(void) { __glXThreadInitialize(); - __GLXAPIState *apiState = __glXGetCurrentAPIState(); + __GLXThreadState *threadState = __glXGetCurrentThreadState(); - if (apiState != NULL) { - return apiState->currentVendor; + if (threadState != NULL) { + return threadState->currentVendor; } else { return NULL; } @@ -551,70 +551,70 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext context) void DisplayClosed(Display *dpy) { - __GLXAPIState *apiState; + __GLXThreadState *threadState; __glXFreeDisplay(dpy); - apiState = __glXGetCurrentAPIState(); - if (apiState != NULL && apiState->currentDisplay == dpy) { + threadState = __glXGetCurrentThreadState(); + if (threadState != NULL && threadState->currentDisplay == dpy) { // Clear out the current context, but don't call into the vendor // library or do anything that might require a valid display. __glDispatchLoseCurrent(); __glvndPthreadFuncs.mutex_lock(&glxContextHashLock); - UpdateCurrentContext(NULL, apiState->currentContext); + UpdateCurrentContext(NULL, threadState->currentContext); __glvndPthreadFuncs.mutex_unlock(&glxContextHashLock); - DestroyAPIState(apiState); + DestroyThreadState(threadState); } - __glvndPthreadFuncs.mutex_lock(¤tAPIStateListMutex); - glvnd_list_for_each_entry(apiState, ¤tAPIStateList, entry) { + __glvndPthreadFuncs.mutex_lock(¤tThreadStateListMutex); + glvnd_list_for_each_entry(threadState, ¤tThreadStateList, entry) { /* - * Stub out any references to this display in any other API states. + * Stub out any references to this display in any other thread states. */ - if (apiState->currentDisplay == dpy) { - apiState->currentDisplay = NULL; + if (threadState->currentDisplay == dpy) { + threadState->currentDisplay = NULL; } } - __glvndPthreadFuncs.mutex_unlock(¤tAPIStateListMutex); + __glvndPthreadFuncs.mutex_unlock(¤tThreadStateListMutex); } -static void ThreadDestroyed(__GLdispatchAPIState *apiState) +static void ThreadDestroyed(__GLdispatchThreadState *threadState) { - __GLXAPIState *glxState = (__GLXAPIState *) apiState; + __GLXThreadState *glxState = (__GLXThreadState *) threadState; // Clear out the current context. __glvndPthreadFuncs.mutex_lock(&glxContextHashLock); UpdateCurrentContext(NULL, glxState->currentContext); __glvndPthreadFuncs.mutex_unlock(&glxContextHashLock); - // Free the API state struct. - DestroyAPIState(glxState); + // Free the thread state struct. + DestroyThreadState(glxState); } -static __GLXAPIState *CreateAPIState(__GLXvendorInfo *vendor) +static __GLXThreadState *CreateThreadState(__GLXvendorInfo *vendor) { - __GLXAPIState *apiState = calloc(1, sizeof(*apiState)); + __GLXThreadState *threadState = calloc(1, sizeof(*threadState)); - assert(apiState); + assert(threadState); - apiState->glas.tag = GLDISPATCH_API_GLX; - apiState->glas.threadDestroyedCallback = ThreadDestroyed; - apiState->currentVendor = vendor; + threadState->glas.tag = GLDISPATCH_API_GLX; + threadState->glas.threadDestroyedCallback = ThreadDestroyed; + threadState->currentVendor = vendor; - __glvndPthreadFuncs.mutex_lock(¤tAPIStateListMutex); - glvnd_list_add(&apiState->entry, ¤tAPIStateList); - __glvndPthreadFuncs.mutex_unlock(¤tAPIStateListMutex); + __glvndPthreadFuncs.mutex_lock(¤tThreadStateListMutex); + glvnd_list_add(&threadState->entry, ¤tThreadStateList); + __glvndPthreadFuncs.mutex_unlock(¤tThreadStateListMutex); - return apiState; + return threadState; } -static void DestroyAPIState(__GLXAPIState *apiState) +static void DestroyThreadState(__GLXThreadState *threadState) { - // Free the API state struct. - __glvndPthreadFuncs.mutex_lock(¤tAPIStateListMutex); - glvnd_list_del(&apiState->entry); - __glvndPthreadFuncs.mutex_unlock(¤tAPIStateListMutex); + // Free the thread state struct. + __glvndPthreadFuncs.mutex_lock(¤tThreadStateListMutex); + glvnd_list_del(&threadState->entry); + __glvndPthreadFuncs.mutex_unlock(¤tThreadStateListMutex); - free(apiState); + free(threadState); } /* @@ -753,14 +753,14 @@ static void NotifyXError(Display *dpy, unsigned char errorCode, static Bool InternalLoseCurrent(void) { - __GLXAPIState *apiState = __glXGetCurrentAPIState(); + __GLXThreadState *threadState = __glXGetCurrentThreadState(); Bool ret; - if (apiState == NULL) { + if (threadState == NULL) { return True; } - ret = apiState->currentVendor->staticDispatch.makeCurrent(apiState->currentDisplay, None, NULL); + ret = threadState->currentVendor->staticDispatch.makeCurrent(threadState->currentDisplay, None, NULL); if (!ret) { return False; } @@ -768,34 +768,34 @@ static Bool InternalLoseCurrent(void) __glDispatchLoseCurrent(); // Remove the context from the current context map. - UpdateCurrentContext(NULL, apiState->currentContext); - DestroyAPIState(apiState); + UpdateCurrentContext(NULL, threadState->currentContext); + DestroyThreadState(threadState); return True; } /** * Calls into the vendor library to set the current context, and then updates - * the API state fields to match. + * the thread state fields to match. * * This function does *not* call into libGLdispatch, so it can only switch * to another context with the same vendor. * * If this function succeeds, then it will update the current display, context, - * and drawables in \p apiState. + * and drawables in \p threadState. * - * If it fails, then it will leave \p apiState unmodified. It's up to the + * If it fails, then it will leave \p threadState unmodified. It's up to the * vendor library to ensure that the old context is still current in that case. */ static Bool InternalMakeCurrentVendor( Display *dpy, GLXDrawable draw, GLXDrawable read, __GLXcontextInfo *ctxInfo, char callerOpcode, - __GLXAPIState *apiState, + __GLXThreadState *threadState, __GLXvendorInfo *vendor) { Bool ret; - assert(apiState->currentVendor == vendor); + assert(threadState->currentVendor == vendor); if (callerOpcode == X_GLXMakeCurrent && draw == read) { ret = vendor->staticDispatch.makeCurrent(dpy, draw, ctxInfo->context); @@ -807,10 +807,10 @@ static Bool InternalMakeCurrentVendor( } if (ret) { - apiState->currentDisplay = dpy; - apiState->currentDraw = draw; - apiState->currentRead = read; - apiState->currentContext = ctxInfo; + threadState->currentDisplay = dpy; + threadState->currentDraw = draw; + threadState->currentRead = read; + threadState->currentContext = ctxInfo; } return ret; @@ -820,8 +820,8 @@ static Bool InternalMakeCurrentVendor( * Makes a context current. This function handles both the vendor library and * libGLdispatch. * - * There must not be a current API state in libGLdispatch when this function is - * called. + * There must not be a current thread state in libGLdispatch when this function + * is called. * * If this function fails, then it will release the context and dispatch state * before returning. @@ -831,21 +831,21 @@ static Bool InternalMakeCurrentDispatch( __GLXcontextInfo *ctxInfo, char callerOpcode, __GLXvendorInfo *vendor) { - __GLXAPIState *apiState; + __GLXThreadState *threadState; Bool ret; - assert(__glXGetCurrentAPIState() == NULL); + assert(__glXGetCurrentThreadState() == NULL); UpdateCurrentContext(ctxInfo, NULL); - apiState = CreateAPIState(vendor); - if (apiState == NULL) { + threadState = CreateThreadState(vendor); + if (threadState == NULL) { UpdateCurrentContext(NULL, ctxInfo); return False; } ret = __glDispatchMakeCurrent( - &apiState->glas, + &threadState->glas, vendor->glDispatch, vendor->vendorID, vendor->glxvc->patchCallbacks @@ -854,14 +854,14 @@ static Bool InternalMakeCurrentDispatch( if (ret) { // Call into the vendor library. ret = InternalMakeCurrentVendor(dpy, draw, read, ctxInfo, callerOpcode, - apiState, vendor); + threadState, vendor); if (!ret) { __glDispatchLoseCurrent(); } } if (!ret) { - DestroyAPIState(apiState); + DestroyThreadState(threadState); UpdateCurrentContext(NULL, ctxInfo); } @@ -875,7 +875,7 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext context, char callerOpcode) { - __GLXAPIState *apiState; + __GLXThreadState *threadState; __GLXvendorInfo *oldVendor, *newVendor; Display *oldDpy; GLXDrawable oldDraw, oldRead; @@ -884,14 +884,14 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw, Bool ret; __glXThreadInitialize(); - apiState = __glXGetCurrentAPIState(); + threadState = __glXGetCurrentThreadState(); - if (apiState != NULL) { - oldVendor = apiState->currentVendor; - oldDpy = apiState->currentDisplay; - oldDraw = apiState->currentDraw; - oldRead = apiState->currentRead; - oldCtxInfo = apiState->currentContext; + if (threadState != NULL) { + oldVendor = threadState->currentVendor; + oldDpy = threadState->currentDisplay; + oldDraw = threadState->currentDraw; + oldRead = threadState->currentRead; + oldCtxInfo = threadState->currentContext; assert(oldCtxInfo != NULL); @@ -903,7 +903,7 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw, } } else { // We might have a non-GLX context current... - __GLdispatchAPIState *glas = __glDispatchGetCurrentAPIState(); + __GLdispatchThreadState *glas = __glDispatchGetCurrentThreadState(); if (glas != NULL && glas->tag != GLDISPATCH_API_GLX) { NotifyXError(dpy, BadAccess, 0, callerOpcode, True, NULL); return False; @@ -965,7 +965,7 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw, } if (oldVendor == newVendor) { - assert(apiState != NULL); + assert(threadState != NULL); /* * We're switching between two contexts that use the same vendor. That @@ -974,7 +974,7 @@ static Bool CommonMakeCurrent(Display *dpy, GLXDrawable draw, * switch contexts, but don't call into libGLdispatch. */ ret = InternalMakeCurrentVendor(dpy, draw, read, newCtxInfo, callerOpcode, - apiState, newVendor); + threadState, newVendor); if (ret) { UpdateCurrentContext(newCtxInfo, oldCtxInfo); } @@ -1938,7 +1938,7 @@ void __glXThreadInitialize(void) static void __glXAPITeardown(Bool doReset) { - __GLXAPIState *apiState, *apiStateTemp; + __GLXThreadState *threadState, *threadStateTemp; __GLXcontextInfo *currContext, *currContextTemp; __glvndPthreadFuncs.mutex_lock(&glxContextHashLock); @@ -1949,9 +1949,9 @@ static void __glXAPITeardown(Bool doReset) assert(glxContextHash == NULL); __glvndPthreadFuncs.mutex_unlock(&glxContextHashLock); - glvnd_list_for_each_entry_safe(apiState, apiStateTemp, ¤tAPIStateList, entry) { - glvnd_list_del(&apiState->entry); - free(apiState); + glvnd_list_for_each_entry_safe(threadState, threadStateTemp, ¤tThreadStateList, entry) { + glvnd_list_del(&threadState->entry); + free(threadState); } if (doReset) { @@ -1960,7 +1960,7 @@ static void __glXAPITeardown(Bool doReset) * hash lock, and not throwing away cached addresses. */ __glvndPthreadFuncs.rwlock_init(&__glXProcAddressHash.lock, NULL); - __glvndPthreadFuncs.mutex_init(¤tAPIStateListMutex, NULL); + __glvndPthreadFuncs.mutex_init(¤tThreadStateListMutex, NULL); } else { LKDHASH_TEARDOWN(__GLXprocAddressHash, __glXProcAddressHash, CleanupProcAddressEntry, @@ -1997,7 +1997,7 @@ void _init(void) __glDispatchInit(); glvndSetupPthreads(); - glvnd_list_init(¤tAPIStateList); + glvnd_list_init(¤tThreadStateList); /* * glxContextHashLock must be a recursive mutex, because we'll have it @@ -2043,11 +2043,11 @@ void _fini(void) __glXThreadInitialize(); /* - * If libGLX owns the current API state, lose current + * If libGLX owns the current thread state, lose current * in GLdispatch before going further. */ - __GLdispatchAPIState *glas = - __glDispatchGetCurrentAPIState(); + __GLdispatchThreadState *glas = + __glDispatchGetCurrentThreadState(); if (glas && glas->tag == GLDISPATCH_API_GLX) { __glDispatchLoseCurrent(); @@ -2057,7 +2057,7 @@ void _fini(void) /* Unregister all XCloseDisplay() callbacks */ XGLVUnregisterCloseDisplayCallbacks(); - /* Tear down all GLX API state */ + /* Tear down all GLX thread state */ __glXAPITeardown(False); /* Tear down all mapping state */ diff --git a/src/GLX/libglxcurrent.h b/src/GLX/libglxcurrent.h index af6fe43..38ef23b 100644 --- a/src/GLX/libglxcurrent.h +++ b/src/GLX/libglxcurrent.h @@ -42,18 +42,18 @@ typedef struct __GLXcontextInfoRec __GLXcontextInfo; -/* +/*! * Define current API library state here. * - * A thread will have a __GLXAPIState struct if and only if it has a current + * A thread will have a __GLXThreadState struct if and only if it has a current * GLX context. If we don't have a current context, then there's nothing useful * to store in it. * - * The pointer to the current __GLXAPIState is stored in libGLdispatch, since - * it's also the current __GLdispatchAPIState struct. + * The pointer to the current __GLXThreadState is stored in libGLdispatch, since + * it's also the current __GLdispatchThreadState struct. */ -typedef struct __GLXAPIStateRec { - __GLdispatchAPIState glas; /* Must be the first entry! */ +typedef struct __GLXThreadStateRec { + __GLdispatchThreadState glas; /* Must be the first entry! */ __GLXvendorInfo *currentVendor; @@ -63,40 +63,42 @@ typedef struct __GLXAPIStateRec { __GLXcontextInfo *currentContext; struct glvnd_list entry; -} __GLXAPIState; +} __GLXThreadState; /*! - * This attempts to pull the current API state from TLS, and falls back to - * __glXGetAPIState() if that fails. + * Looks up the current thread state. + * + * If there isn't a current context, or if the current context was set by + * another library like EGL, then this will return \c NULL. */ -static inline __GLXAPIState *__glXGetCurrentAPIState(void) +static inline __GLXThreadState *__glXGetCurrentThreadState(void) { - __GLdispatchAPIState *glas = __glDispatchGetCurrentAPIState(); + __GLdispatchThreadState *glas = __glDispatchGetCurrentThreadState(); if (unlikely(!glas || (glas->tag != GLDISPATCH_API_GLX))) { return NULL; } else { - return (__GLXAPIState *)(glas); + return (__GLXThreadState *)(glas); } } /*! - * This gets the current GLX static dispatch table, which is stored in the API - * state. + * This gets the current GLX static dispatch table, which is stored in the + * thread state. */ static inline const __GLXdispatchTableStatic *__glXGetCurrentDispatch(void) { - __GLXAPIState *apiState = __glXGetCurrentAPIState(); - if (likely(apiState)) { - return &apiState->currentVendor->staticDispatch; + __GLXThreadState *threadState = __glXGetCurrentThreadState(); + if (likely(threadState)) { + return &threadState->currentVendor->staticDispatch; } else { return __glXDispatchNoopPtr; } } /*! - * This gets the current GLX dynamic dispatch table, which is stored in the API - * state. + * This gets the current GLX dynamic dispatch table, which is stored in the + * thread state. */ __GLXvendorInfo *__glXGetCurrentDynDispatch(void); diff --git a/src/GLdispatch/GLdispatch.c b/src/GLdispatch/GLdispatch.c index aecc3b4..9c22498 100644 --- a/src/GLdispatch/GLdispatch.c +++ b/src/GLdispatch/GLdispatch.c @@ -58,16 +58,16 @@ static int numCurrentContexts; /** * Private data for each API state. */ -typedef struct __GLdispatchAPIStatePrivateRec { +typedef struct __GLdispatchThreadStatePrivateRec { /// A pointer back to the API state. - __GLdispatchAPIState *apiState; + __GLdispatchThreadState *threadState; /// ID of the current vendor for this state int vendorID; /// The current (high-level) __GLdispatch table __GLdispatchTable *dispatch; -} __GLdispatchAPIStatePrivate; +} __GLdispatchThreadStatePrivate; typedef struct __GLdispatchProcEntryRec { char *procName; @@ -131,11 +131,11 @@ static GLint64 dispatchStubListGeneration; static int firstUnusedVendorID = 1; /** - * The key used to store the __GLdispatchAPIState for the current thread. + * The key used to store the __GLdispatchThreadState for the current thread. */ static glvnd_key_t threadContextKey; -static void SetCurrentAPIState(__GLdispatchAPIState *apiState); +static void SetCurrentThreadState(__GLdispatchThreadState *threadState); static void ThreadDestroyed(void *data); static int RegisterStubCallbacks(const __GLdispatchStubPatchCallbacks *callbacks); @@ -423,7 +423,7 @@ static inline int PatchingIsDisabledByEnvVar(void) static inline int ContextIsCurrentInAnyOtherThread(void) { - int thisThreadsContext = !!__glDispatchGetCurrentAPIState(); + int thisThreadsContext = !!__glDispatchGetCurrentThreadState(); int otherContexts; CheckDispatchLocked(); @@ -616,19 +616,19 @@ static int PatchEntrypoints( return 1; } -PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState, +PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchThreadState *threadState, __GLdispatchTable *dispatch, int vendorID, const __GLdispatchPatchCallbacks *patchCb) { - __GLdispatchAPIStatePrivate *priv; + __GLdispatchThreadStatePrivate *priv; - if (__glDispatchGetCurrentAPIState() != NULL) { + if (__glDispatchGetCurrentThreadState() != NULL) { assert(!"__glDispatchMakeCurrent called with a current API state\n"); return GL_FALSE; } - priv = (__GLdispatchAPIStatePrivate *) malloc(sizeof(__GLdispatchAPIStatePrivate)); + priv = (__GLdispatchThreadStatePrivate *) malloc(sizeof(__GLdispatchThreadStatePrivate)); if (priv == NULL) { return GL_FALSE; } @@ -670,61 +670,61 @@ PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState, */ priv->dispatch = dispatch; priv->vendorID = vendorID; - priv->apiState = apiState; - apiState->priv = priv; + priv->threadState = threadState; + threadState->priv = priv; /* * Set the current state in TLS. */ - SetCurrentAPIState(apiState); + SetCurrentThreadState(threadState); _glapi_set_current(dispatch->table); return GL_TRUE; } -static void LoseCurrentInternal(__GLdispatchAPIState *curApiState, +static void LoseCurrentInternal(__GLdispatchThreadState *curThreadState, GLboolean threadDestroyed) { LockDispatch(); // Try to restore the libglvnd default stubs, if possible. PatchEntrypoints(NULL, 0); - if (curApiState) { + if (curThreadState) { numCurrentContexts--; - if (curApiState->priv != NULL) { - if (curApiState->priv->dispatch != NULL) { - DispatchCurrentUnref(curApiState->priv->dispatch); + if (curThreadState->priv != NULL) { + if (curThreadState->priv->dispatch != NULL) { + DispatchCurrentUnref(curThreadState->priv->dispatch); } - free(curApiState->priv); - curApiState->priv = NULL; + free(curThreadState->priv); + curThreadState->priv = NULL; } } UnlockDispatch(); if (!threadDestroyed) { - SetCurrentAPIState(NULL); + SetCurrentThreadState(NULL); _glapi_set_current(NULL); } } PUBLIC void __glDispatchLoseCurrent(void) { - __GLdispatchAPIState *curApiState = __glDispatchGetCurrentAPIState(); - if (curApiState == NULL) { + __GLdispatchThreadState *curThreadState = __glDispatchGetCurrentThreadState(); + if (curThreadState == NULL) { return; } - LoseCurrentInternal(curApiState, GL_FALSE); + LoseCurrentInternal(curThreadState, GL_FALSE); } -__GLdispatchAPIState *__glDispatchGetCurrentAPIState(void) +__GLdispatchThreadState *__glDispatchGetCurrentThreadState(void) { - return (__GLdispatchAPIState *) __glvndPthreadFuncs.getspecific(threadContextKey); + return (__GLdispatchThreadState *) __glvndPthreadFuncs.getspecific(threadContextKey); } -void SetCurrentAPIState(__GLdispatchAPIState *apiState) +void SetCurrentThreadState(__GLdispatchThreadState *threadState) { - __glvndPthreadFuncs.setspecific(threadContextKey, apiState); + __glvndPthreadFuncs.setspecific(threadContextKey, threadState); } /* @@ -750,7 +750,7 @@ void __glDispatchReset(void) UnlockDispatch(); /* Clear GLAPI TLS entries. */ - SetCurrentAPIState(NULL); + SetCurrentThreadState(NULL); _glapi_set_current(NULL); } @@ -832,11 +832,11 @@ void __glDispatchCheckMultithreaded(void) void ThreadDestroyed(void *data) { if (data != NULL) { - __GLdispatchAPIState *apiState = (__GLdispatchAPIState *) data; - LoseCurrentInternal(apiState, GL_TRUE); + __GLdispatchThreadState *threadState = (__GLdispatchThreadState *) data; + LoseCurrentInternal(threadState, GL_TRUE); - if (apiState->threadDestroyedCallback != NULL) { - apiState->threadDestroyedCallback(apiState); + if (threadState->threadDestroyedCallback != NULL) { + threadState->threadDestroyedCallback(threadState); } } } diff --git a/src/GLdispatch/GLdispatch.h b/src/GLdispatch/GLdispatch.h index 5532403..5dd700a 100644 --- a/src/GLdispatch/GLdispatch.h +++ b/src/GLdispatch/GLdispatch.h @@ -35,24 +35,32 @@ #include "glvnd/GLdispatchABI.h" /*! - * The current version of the ABI between libGLdispatch and the window system - * libraries. + * \defgroup gldispatch core GL/GLES dispatch and TLS module * - * \see __glDispatchGetABIVersion + * libGLdispatch manages the dispatch table used to dispatch OpenGL and GLES + * functions to the appropriate vendor library for the current context. + * + * Window system libraries (libGLX.so and eventually libEGL.so) use + * libGLdispatch.so to set and keep track of the current rendering context. + * Their respective MakeCurrent calls (glXMakeCurrent and eglMakeCurrent) pass + * in a dispatch table for whatever vendor owns the current context. + * + * The entrypoint libraries (libOpenGL.so, libGL.so, libGLESv1_CM.so, and + * libGLESv2.so) all use the dispatch table stored in libGLdispatch.so. + * + * The dispatch table and dispatch stubs are based on Mesa's mapi/glapi + * library. */ -#define GLDISPATCH_ABI_VERSION 0 /*! - * \defgroup gldispatch core GL/GLES dispatch and TLS module + * The current version of the ABI between libGLdispatch and the window system + * libraries. * - * GLdispatch is a thin wrapper around Mesa's mapi/glapi dispatch table - * implementation which does some bookkeeping to simplify dispatch table - * management. API libraries use this library to retrieve dispatch stubs and fix - * up the dispatch table at make current time to point to the appropriate vendor - * library entrypoints. + * \see __glDispatchGetABIVersion */ +#define GLDISPATCH_ABI_VERSION 1 -/* Namespaces for API state */ +/* Namespaces for thread state */ enum { GLDISPATCH_API_GLX, GLDISPATCH_API_EGL @@ -68,51 +76,57 @@ typedef void (*__GLdispatchProc)(void); typedef void *(*__GLgetProcAddressCallback)(const char *procName, void *param); /** - * An opaque structure used for internal API state data. + * An opaque structure used for internal thread state data. */ -struct __GLdispatchAPIStatePrivateRec; +struct __GLdispatchThreadStatePrivateRec; /*! - * Generic API state structure. The window system binding API libraries subclass - * from this structure to track API-library specific current state (e.g. - * current drawables). There is one API state for each combination of (winsys - * library, thread that has had a context current). The winsys library is - * responsible for tracking, allocating, and freeing its API states. Though - * each thread owns an API state within the winsys library, only one API state - * may be "current" at a time (the API state of the winsys binding which has - * a context current). This is done to conserve TLS space. - */ -typedef struct __GLdispatchAPIStateRec { + * Generic thread state structure. The window system binding API libraries + * subclass from this structure to track API-library specific current state + * (e.g. current context and drawables). + * + * A thread has a thread state structure if and only if it has a current + * context. A thread can only have one thread state at a time, so there can't + * be both a current GLX context and a current EGL context at the same time. + * + * The winsys library is responsible for tracking, allocating, and freeing the + * thread state structures. + */ +typedef struct __GLdispatchThreadStateRec { /************************************************************************* * Winsys-managed variables: fixed for lifetime of state *************************************************************************/ /*! - * Namespace of the state: either API_GLX or API_EGL + * Specifies which window system library owns this state. It should be set + * to either \c GLDISPATCH_API_GLX or \c GLDISPATCH_API_EGL. + * + * This is used to make sure that a GLX context doesn't clobber a current + * EGL context or vice-versa. */ int tag; - /** + /*! * A callback that is called when a thread that has a current context * terminates. * * This is called after libGLdispatch handles its cleanup, so - * __glDispatchGetCurrentAPIState will return NULL. The API state is passed - * as a parameter instead. + * __glDispatchGetCurrentThreadState will return NULL. The thread state is + * passed as a parameter instead. * * The callback should not call __glDispatchMakeCurrent or * __glDispatchLoseCurrent. * - * \param apiState The API state passed to __glDispatchMakeCurrent. + * \param threadState The thread state passed to __glDispatchMakeCurrent. */ - void (*threadDestroyedCallback)(struct __GLdispatchAPIStateRec *apiState); + void (*threadDestroyedCallback)(struct __GLdispatchThreadStateRec *threadState); /************************************************************************* * GLdispatch-managed variables: Modified by MakeCurrent() *************************************************************************/ /*! - * Private data for this API state. + * Private data for this thread state. * * This structure is assigned in \c __glDispatchMakeCurrent, and freed in * \c __glDispatchLoseCurrent. @@ -120,8 +134,8 @@ typedef struct __GLdispatchAPIStateRec { * The value of this pointer, if any, is an internal detail of * libGLdispatch. The window system library should just ignore it. */ - struct __GLdispatchAPIStatePrivateRec *priv; -} __GLdispatchAPIState; + struct __GLdispatchThreadStatePrivateRec *priv; +} __GLdispatchThreadState; /*! * Gets the version number for the ABI between libGLdispatch and the @@ -187,12 +201,12 @@ PUBLIC __GLdispatchTable *__glDispatchCreateTable( PUBLIC void __glDispatchDestroyTable(__GLdispatchTable *dispatch); /*! - * This makes the given API state current, and assigns this API state - * the passed-in current dispatch table and vendor ID. + * This makes the given thread state current, and assigns this thread state the + * passed-in current dispatch table and vendor ID. * - * When this function is called, the current thread must not already have an - * API state. To switch between two API states, first release the old API state - * by calling \c __glDispatchLoseCurrent. + * When this function is called, the current thread must not already have a + * thread state. To switch between two thread states, first release the old + * thread state by calling \c __glDispatchLoseCurrent. * * If patchCb is not NULL, GLdispatch will attempt to overwrite its * entrypoints (and the entrypoints of any loaded interface libraries) @@ -203,14 +217,14 @@ PUBLIC void __glDispatchDestroyTable(__GLdispatchTable *dispatch); * This returns GL_FALSE if the make current operation failed, and GL_TRUE * if it succeeded. */ -PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState, +PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchThreadState *threadState, __GLdispatchTable *dispatch, int vendorID, const __GLdispatchPatchCallbacks *patchCb); /*! - * This makes the NOP dispatch table current and sets the current API state to - * NULL. + * This makes the NOP dispatch table current and sets the current thread state + * to NULL. * * A window system library should only call this if it created the current API * state. That is, if libGLX should not attempt to release an EGL context or @@ -219,11 +233,11 @@ PUBLIC GLboolean __glDispatchMakeCurrent(__GLdispatchAPIState *apiState, PUBLIC void __glDispatchLoseCurrent(void); /*! - * This gets the current (opaque) API state pointer. If the pointer is - * NULL, no context is current, otherwise the contents of the pointer depends on - * which client API owns the context (EGL or GLX). + * This gets the current thread state pointer. If the pointer is \c NULL, no + * context is current, otherwise the contents of the pointer depends on which + * client API owns the context (EGL or GLX). */ -PUBLIC __GLdispatchAPIState *__glDispatchGetCurrentAPIState(void); +PUBLIC __GLdispatchThreadState *__glDispatchGetCurrentThreadState(void); /** * Checks to see if multiple threads are being used. This should be called diff --git a/src/GLdispatch/export_list.sym b/src/GLdispatch/export_list.sym index 317b3af..41be6bf 100644 --- a/src/GLdispatch/export_list.sym +++ b/src/GLdispatch/export_list.sym @@ -6,7 +6,7 @@ __glDispatchCreateTable __glDispatchDestroyTable __glDispatchFini __glDispatchGetABIVersion -__glDispatchGetCurrentAPIState +__glDispatchGetCurrentThreadState __glDispatchGetProcAddress __glDispatchInit __glDispatchLoseCurrent -- cgit v1.2.3