diff options
author | Chris Robinson <[email protected]> | 2009-09-12 16:45:46 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2009-09-12 16:45:46 -0700 |
commit | 59ed9338d88fc76c54c68c79af6b2f2999eac6df (patch) | |
tree | 93dc952f832d9db0d8e6db6556efdde57df2ebdf | |
parent | b444dea63b007b52a5eb5c2861c1e7091f31fe9d (diff) |
Add support for the in-progress ALC_EXT_thread_local_context extension
-rw-r--r-- | Alc/ALc.c | 84 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 15 | ||||
-rw-r--r-- | include/AL/alext.h | 6 |
3 files changed, 97 insertions, 8 deletions
@@ -111,6 +111,10 @@ static ALCfunction alcFunctions[] = { { "alcCaptureStart", (ALvoid *) alcCaptureStart }, { "alcCaptureStop", (ALvoid *) alcCaptureStop }, { "alcCaptureSamples", (ALvoid *) alcCaptureSamples }, + + { "alcMakeCurrent", (ALvoid *) alcMakeCurrent }, + { "alcGetThreadContext", (ALvoid *) alcGetThreadContext }, + { NULL, (ALvoid *) NULL } }; @@ -175,7 +179,7 @@ static ALCchar *alcDefaultAllDeviceSpecifier; static ALCchar *alcCaptureDefaultDeviceSpecifier; -static ALCchar alcExtensionList[] = "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_disconnect ALC_EXT_EFX"; +static ALCchar alcExtensionList[] = "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_disconnect ALC_EXT_EFX ALC_EXTX_thread_local_context"; static ALCint alcMajorVersion = 1; static ALCint alcMinorVersion = 1; @@ -197,6 +201,9 @@ static CRITICAL_SECTION g_csMutex; static ALCcontext *g_pContextList = NULL; static ALCuint g_ulContextCount = 0; +// Thread-local current context +static tls_type LocalContext; + // Context Error static ALCenum g_eLastContextError = ALC_NO_ERROR; @@ -229,6 +236,8 @@ BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) for(i = 0;BackendList[i].Deinit;i++) BackendList[i].Deinit(); + tls_delete(LocalContext); + FreeALConfig(); ALTHUNK_EXIT(); DeleteCriticalSection(&g_csMutex); @@ -252,6 +261,8 @@ static void my_deinit() for(i = 0;BackendList[i].Deinit;i++) BackendList[i].Deinit(); + tls_delete(LocalContext); + FreeALConfig(); ALTHUNK_EXIT(); DeleteCriticalSection(&g_csMutex); @@ -305,6 +316,8 @@ static void InitAL(void) ALTHUNK_INIT(); ReadALConfig(); + tls_create(&LocalContext); + devs = GetConfigValue(NULL, "drivers", ""); if(devs[0]) { @@ -509,10 +522,18 @@ ALCcontext *GetContextSuspended(void) SuspendContext(NULL); - pContext = g_pContextList; - while(pContext && !pContext->InUse) - pContext = pContext->next; - + pContext = tls_get(LocalContext); + if(pContext && !IsContext(pContext)) + { + tls_set(LocalContext, NULL); + pContext = NULL; + } + if(!pContext) + { + pContext = g_pContextList; + while(pContext && !pContext->InUse) + pContext = pContext->next; + } if(pContext) SuspendContext(pContext); @@ -1307,15 +1328,33 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context) */ ALCAPI ALCcontext * ALCAPIENTRY alcGetCurrentContext(ALCvoid) { + ALCcontext *pContext; + + if((pContext=GetContextSuspended()) != NULL) + ProcessContext(pContext); + + return pContext; +} + +/* + alcGetThreadContext + + Returns the currently active thread-local Context +*/ +ALCcontext * ALCAPIENTRY alcGetThreadContext(void) +{ ALCcontext *pContext = NULL; InitAL(); SuspendContext(NULL); - pContext = g_pContextList; - while ((pContext) && (!pContext->InUse)) - pContext = pContext->next; + pContext = tls_get(LocalContext); + if(pContext && !IsContext(pContext)) + { + tls_set(LocalContext, NULL); + pContext = NULL; + } ProcessContext(NULL); @@ -1374,6 +1413,8 @@ ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context) ALContext->InUse=AL_TRUE; ProcessContext(ALContext); } + + tls_set(LocalContext, NULL); } else { @@ -1386,6 +1427,33 @@ ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context) return bReturn; } +/* + alcMakeCurrent + + Makes the given Context the active Context for the current thread +*/ +ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context) +{ + ALboolean bReturn = AL_TRUE; + + InitAL(); + + SuspendContext(NULL); + + // context must be a valid Context or NULL + if(context == NULL || IsContext(context)) + tls_set(LocalContext, context); + else + { + SetALCError(ALC_INVALID_CONTEXT); + bReturn = AL_FALSE; + } + + ProcessContext(NULL); + + return bReturn; +} + static ALenum GetFormatFromString(const char *str) { diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index eba91d14..55b59b97 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -20,6 +20,12 @@ #endif #include <windows.h> +typedef DWORD tls_type; +#define tls_create(x) (*(x) = TlsAlloc()) +#define tls_delete(x) TlsFree((x)) +#define tls_get(x) TlsGetValue((x)) +#define tls_set(x, a) TlsSetValue((x), (a)) + #else #include <assert.h> @@ -33,6 +39,12 @@ #define IsBadWritePtr(a,b) (0) +typedef pthread_key_t tls_type; +#define tls_create(x) pthread_key_create((x), NULL) +#define tls_delete(x) pthread_key_delete((x)) +#define tls_get(x) pthread_getspecific((x)) +#define tls_set(x, a) pthread_setspecific((x), (a)) + typedef pthread_mutex_t CRITICAL_SECTION; static inline void EnterCriticalSection(CRITICAL_SECTION *cs) { @@ -314,6 +326,9 @@ const char *GetConfigValue(const char *blockName, const char *keyName, const cha int GetConfigValueInt(const char *blockName, const char *keyName, int def); float GetConfigValueFloat(const char *blockName, const char *keyName, float def); +ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context); +ALCcontext* ALCAPIENTRY alcGetThreadContext(void); + #ifdef __cplusplus } #endif diff --git a/include/AL/alext.h b/include/AL/alext.h index 221e9c63..cc42e20b 100644 --- a/include/AL/alext.h +++ b/include/AL/alext.h @@ -144,6 +144,12 @@ typedef ALvoid (AL_APIENTRY*PFNALUNMAPDATABUFFEREXTPROC)(ALuint uiBuffer); #define ALC_CONNECTED 0x313 #endif +#ifndef ALC_EXT_thread_local_context +#define ALC_EXT_thread_local_context 1 +typedef ALCboolean (ALCAPIENTRY*PFNALCMAKECURRENTPROC)(ALCcontext *context); +typedef ALCcontext* (ALCAPIENTRY*PFNALCGETTHREADCONTEXTPROC)(void); +#endif + #ifdef __cplusplus } #endif |