[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