[PATCH] xaudio2: Always set current OpenAL context before making AL calls

Andrew Eikum aeikum at codeweavers.com
Thu Jun 30 14:07:24 CDT 2016


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---

Should fix bug 40833.

 dlls/xaudio2_7/xaudio_dll.c | 58 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 51 insertions(+), 7 deletions(-)

diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
index e83bc22..7605559 100644
--- a/dlls/xaudio2_7/xaudio_dll.c
+++ b/dlls/xaudio2_7/xaudio_dll.c
@@ -34,8 +34,29 @@
 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
+static CRITICAL_SECTION al_lock;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+    0, 0, &al_lock,
+    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": al_lock") }
+};
+static CRITICAL_SECTION al_lock = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static void context_lock(ALCcontext *ctx)
+{
+    EnterCriticalSection(&al_lock);
+    alcMakeContextCurrent(ctx);
+}
+
+static void context_unlock(void)
+{
+    LeaveCriticalSection(&al_lock);
+}
+
 static ALCdevice *(ALC_APIENTRY *palcLoopbackOpenDeviceSOFT)(const ALCchar*);
 static void (ALC_APIENTRY *palcRenderSamplesSOFT)(ALCdevice*, ALCvoid*, ALCsizei);
+static ALCboolean (ALC_APIENTRY *palcSetThreadContext)(ALCcontext*);
 
 static HINSTANCE instance;
 
@@ -96,7 +117,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
 
         if(!alcIsExtensionPresent(NULL, "ALC_SOFT_loopback") ||
                 !(palcLoopbackOpenDeviceSOFT = alcGetProcAddress(NULL, "alcLoopbackOpenDeviceSOFT")) ||
-                !(palcRenderSamplesSOFT = alcGetProcAddress(NULL, "alcRenderSamplesSOFT"))){
+                !(palcRenderSamplesSOFT = alcGetProcAddress(NULL, "alcRenderSamplesSOFT")) ||
+                !(palcSetThreadContext = alcGetProcAddress(NULL, "alcSetThreadContext"))){
             ERR("XAudio2 requires the ALC_SOFT_loopback extension (OpenAL-Soft >= 1.14)\n");
             return FALSE;
         }
@@ -313,8 +335,12 @@ static HRESULT WINAPI XA2SRC_SetVolume(IXAudio2SourceVoice *iface, float Volume,
 
     al_gain = Volume;
 
+    context_lock(This->xa2->al_ctx);
+
     alSourcef(This->al_src, AL_GAIN, al_gain);
 
+    context_unlock();
+
     return S_OK;
 }
 
@@ -366,10 +392,13 @@ static void WINAPI XA2SRC_DestroyVoice(IXAudio2SourceVoice *iface)
 
     TRACE("%p\n", This);
 
+    context_lock(This->xa2->al_ctx);
+
     EnterCriticalSection(&This->lock);
 
     if(!This->in_use){
         LeaveCriticalSection(&This->lock);
+        context_unlock();
         return;
     }
 
@@ -405,6 +434,8 @@ static void WINAPI XA2SRC_DestroyVoice(IXAudio2SourceVoice *iface)
     This->cur_buf = 0;
 
     LeaveCriticalSection(&This->lock);
+
+    context_unlock();
 }
 
 static HRESULT WINAPI XA2SRC_Start(IXAudio2SourceVoice *iface, UINT32 Flags,
@@ -728,8 +759,12 @@ static HRESULT WINAPI XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice *iface,
     else
         r = Ratio;
 
+    context_lock(This->xa2->al_ctx);
+
     alSourcef(This->al_src, AL_PITCH, r);
 
+    context_unlock();
+
     return S_OK;
 }
 
@@ -740,8 +775,12 @@ static void WINAPI XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice *iface, float *p
 
     TRACE("%p, %p\n", This, pRatio);
 
+    context_lock(This->xa2->al_ctx);
+
     alGetSourcef(This->al_src, AL_PITCH, &ratio);
 
+    context_unlock();
+
     *pRatio = ratio;
 }
 
@@ -1377,6 +1416,8 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
 
     dump_fmt(pSourceFormat);
 
+    context_lock(This->al_ctx);
+
     EnterCriticalSection(&This->lock);
 
     LIST_FOR_EACH_ENTRY(src, &This->source_voices, XA2SourceImpl, entry){
@@ -1390,6 +1431,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
         src = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*src));
         if(!src){
             LeaveCriticalSection(&This->lock);
+            context_unlock();
             return E_OUTOFMEMORY;
         }
 
@@ -1424,6 +1466,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
     if(!src->al_fmt){
         src->in_use = FALSE;
         LeaveCriticalSection(&src->lock);
+        context_unlock();
         WARN("OpenAL can't convert this format!\n");
         return AUDCLNT_E_UNSUPPORTED_FORMAT;
     }
@@ -1437,6 +1480,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
         HeapFree(GetProcessHeap(), 0, src->fmt);
         src->in_use = FALSE;
         LeaveCriticalSection(&src->lock);
+        context_unlock();
         return hr;
     }
 
@@ -1448,6 +1492,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
         HeapFree(GetProcessHeap(), 0, src->fmt);
         src->in_use = FALSE;
         LeaveCriticalSection(&src->lock);
+        context_unlock();
         return E_OUTOFMEMORY;
     }
 
@@ -1457,6 +1502,8 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
 
     LeaveCriticalSection(&src->lock);
 
+    context_unlock();
+
 #if XAUDIO2_VER == 0
     *ppSourceVoice = (IXAudio2SourceVoice*)&src->IXAudio20SourceVoice_iface;
 #elif XAUDIO2_VER <= 3
@@ -1752,12 +1799,6 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
         goto exit;
     }
 
-    if(alcMakeContextCurrent(This->al_ctx) == ALC_FALSE){
-        WARN("alcMakeContextCurrent failed\n");
-        hr = COMPAT_E_DEVICE_INVALIDATED;
-        goto exit;
-    }
-
     hr = IAudioClient_Start(This->aclient);
     if (FAILED(hr))
     {
@@ -2402,6 +2443,9 @@ static void do_engine_tick(IXAudio2Impl *This)
 static DWORD WINAPI engine_threadproc(void *arg)
 {
     IXAudio2Impl *This = arg;
+
+    palcSetThreadContext(This->al_ctx);
+
     while(1){
         WaitForSingleObject(This->mmevt, INFINITE);
 
-- 
2.9.0




More information about the wine-patches mailing list