Chris Robinson : openal32: Wrap and track OpenAL contexts.

Alexandre Julliard julliard at winehq.org
Wed Sep 9 09:58:49 CDT 2009


Module: wine
Branch: master
Commit: fbafa5d8f5137bec9e5468f3d7ac405ba3220c67
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fbafa5d8f5137bec9e5468f3d7ac405ba3220c67

Author: Chris Robinson <chris.kcat at gmail.com>
Date:   Tue Aug 25 18:55:53 2009 -0700

openal32: Wrap and track OpenAL contexts.

---

 dlls/openal32/openal.c |  115 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/dlls/openal32/openal.c b/dlls/openal32/openal.c
index 840498d..6e48375 100644
--- a/dlls/openal32/openal.c
+++ b/dlls/openal32/openal.c
@@ -36,6 +36,11 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(openal32);
 
+typedef struct wine_ALCcontext {
+    ALCcontext *ctx;
+
+    struct wine_ALCcontext *next;
+} wine_ALCcontext;
 
 struct FuncList {
     const char *name;
@@ -45,6 +50,18 @@ struct FuncList {
 static const struct FuncList ALCFuncs[];
 static const struct FuncList ALFuncs[];
 
+static wine_ALCcontext *CtxList;
+static wine_ALCcontext *CurrentCtx;
+
+CRITICAL_SECTION openal_cs;
+static CRITICAL_SECTION_DEBUG openal_cs_debug =
+{
+    0, 0, &openal_cs,
+    {&openal_cs_debug.ProcessLocksList,
+    &openal_cs_debug.ProcessLocksList},
+    0, 0, {(DWORD_PTR)(__FILE__ ": openal_cs")}
+};
+CRITICAL_SECTION openal_cs = {&openal_cs_debug, -1, 0, 0, 0, 0};
 
 /***********************************************************************
  *           OpenAL initialisation routine
@@ -56,12 +73,30 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hinst);
         break;
+    case DLL_PROCESS_DETACH:
+        while(CtxList)
+        {
+            wine_ALCcontext *next = CtxList->next;
+            HeapFree(GetProcessHeap(), 0, CtxList);
+            CtxList = next;
+        }
     }
 
     return TRUE;
 }
 
 
+/* Validates the given context */
+static wine_ALCcontext *ValidateCtx(ALCcontext *ctx)
+{
+    wine_ALCcontext *cur = CtxList;
+
+    while(cur != NULL && cur->ctx != ctx)
+        cur = cur->next;
+    return cur;
+}
+
+
 /***********************************************************************
  *           OpenAL thunk routines
  */
@@ -69,12 +104,55 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 /* OpenAL ALC 1.0 functions */
 ALCcontext* CDECL wine_alcCreateContext(ALCdevice *device, const ALCint* attrlist)
 {
-    return alcCreateContext(device, attrlist);
+    wine_ALCcontext *ctx;
+
+    ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wine_ALCcontext));
+    if(!ctx)
+    {
+        ERR("Out of memory!\n");
+        return NULL;
+    }
+
+    ctx->ctx = alcCreateContext(device, attrlist);
+    if(!ctx->ctx)
+    {
+        HeapFree(GetProcessHeap(), 0, ctx);
+        WARN("Failed to create new context\n");
+        return NULL;
+    }
+    TRACE("Created new context %p\n", ctx->ctx);
+
+    EnterCriticalSection(&openal_cs);
+    ctx->next = CtxList;
+    CtxList = ctx;
+    LeaveCriticalSection(&openal_cs);
+
+    return ctx->ctx;
 }
 
 ALCboolean CDECL wine_alcMakeContextCurrent(ALCcontext *context)
 {
-    return alcMakeContextCurrent(context);
+    wine_ALCcontext *ctx = NULL;
+
+    EnterCriticalSection(&openal_cs);
+    if(context && !(ctx=ValidateCtx(context)))
+    {
+        FIXME("Could not find context %p in context list\n", context);
+        LeaveCriticalSection(&openal_cs);
+        return ALC_FALSE;
+    }
+
+    if(alcMakeContextCurrent(ctx ? ctx->ctx : NULL) == ALC_FALSE)
+    {
+        WARN("Failed to make context %p current\n", ctx->ctx);
+        LeaveCriticalSection(&openal_cs);
+        return ALC_FALSE;
+    }
+
+    CurrentCtx = ctx;
+    LeaveCriticalSection(&openal_cs);
+
+    return ALC_TRUE;
 }
 
 ALvoid CDECL wine_alcProcessContext(ALCcontext *context)
@@ -89,12 +167,43 @@ ALvoid CDECL wine_alcSuspendContext(ALCcontext *context)
 
 ALvoid CDECL wine_alcDestroyContext(ALCcontext *context)
 {
+    wine_ALCcontext **list, *ctx;
+
+    EnterCriticalSection(&openal_cs);
+
+    list = &CtxList;
+    while(*list && (*list)->ctx != context)
+        list = &(*list)->next;
+
+    if(!(*list))
+    {
+        FIXME("Could not find context %p in context list\n", context);
+        LeaveCriticalSection(&openal_cs);
+        return;
+    }
+
+    ctx = *list;
+    *list = (*list)->next;
+
+    if(ctx == CurrentCtx)
+        CurrentCtx = NULL;
+
+    LeaveCriticalSection(&openal_cs);
+
+    HeapFree(GetProcessHeap(), 0, ctx);
     alcDestroyContext(context);
 }
 
 ALCcontext* CDECL wine_alcGetCurrentContext(ALCvoid)
 {
-    return alcGetCurrentContext();
+    ALCcontext *ret = NULL;
+
+    EnterCriticalSection(&openal_cs);
+    if(CurrentCtx)
+        ret = CurrentCtx->ctx;
+    LeaveCriticalSection(&openal_cs);
+
+    return ret;
 }
 
 ALCdevice* CDECL wine_alcGetContextsDevice(ALCcontext *context)




More information about the wine-cvs mailing list