aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-09-12 16:45:46 -0700
committerChris Robinson <[email protected]>2009-09-12 16:45:46 -0700
commit59ed9338d88fc76c54c68c79af6b2f2999eac6df (patch)
tree93dc952f832d9db0d8e6db6556efdde57df2ebdf
parentb444dea63b007b52a5eb5c2861c1e7091f31fe9d (diff)
Add support for the in-progress ALC_EXT_thread_local_context extension
-rw-r--r--Alc/ALc.c84
-rw-r--r--OpenAL32/Include/alMain.h15
-rw-r--r--include/AL/alext.h6
3 files changed, 97 insertions, 8 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index c4ec9fc7..16272ecc 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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