Audio: Implement support for ALC_EXT_thread_local_context
This commit is contained in:
parent
3e1b61070c
commit
3fb1096d07
|
|
@ -27,6 +27,7 @@ namespace Nz
|
||||||
enum class OpenALExtension
|
enum class OpenALExtension
|
||||||
{
|
{
|
||||||
SourceLatency,
|
SourceLatency,
|
||||||
|
ThreadLocalContext,
|
||||||
|
|
||||||
Max = SourceLatency
|
Max = SourceLatency
|
||||||
};
|
};
|
||||||
|
|
@ -82,6 +83,8 @@ namespace Nz
|
||||||
OpenALDevice& operator=(const OpenALDevice&) = delete;
|
OpenALDevice& operator=(const OpenALDevice&) = delete;
|
||||||
OpenALDevice& operator=(OpenALDevice&&) = delete;
|
OpenALDevice& operator=(OpenALDevice&&) = delete;
|
||||||
|
|
||||||
|
static const OpenALDevice* GetCurrentDevice();
|
||||||
|
|
||||||
// We give each device its own set of function pointer, even though regular OpenAL extensions are always the same (for a set library).
|
// We give each device its own set of function pointer, even though regular OpenAL extensions are always the same (for a set library).
|
||||||
// This makes it easier to wrap them (for error handling), and extension pointers are device-local anyway.
|
// This makes it easier to wrap them (for error handling), and extension pointers are device-local anyway.
|
||||||
#define NAZARA_AUDIO_AL_ALC_FUNCTION(name) decltype(&::name) name;
|
#define NAZARA_AUDIO_AL_ALC_FUNCTION(name) decltype(&::name) name;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,18 @@
|
||||||
#define NAZARA_AUDIO_AL_EXT_END()
|
#define NAZARA_AUDIO_AL_EXT_END()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NAZARA_AUDIO_ALC_EXT_FUNCTION
|
||||||
|
#define NAZARA_AUDIO_ALC_EXT_FUNCTION(func) NAZARA_AUDIO_AL_EXT_FUNCTION(func)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NAZARA_AUDIO_ALC_EXT_BEGIN
|
||||||
|
#define NAZARA_AUDIO_ALC_EXT_BEGIN(ext) NAZARA_AUDIO_AL_EXT_BEGIN(ext)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NAZARA_AUDIO_ALC_EXT_END
|
||||||
|
#define NAZARA_AUDIO_ALC_EXT_END() NAZARA_AUDIO_AL_EXT_END()
|
||||||
|
#endif
|
||||||
|
|
||||||
NAZARA_AUDIO_AL_FUNCTION(alBuffer3f)
|
NAZARA_AUDIO_AL_FUNCTION(alBuffer3f)
|
||||||
NAZARA_AUDIO_AL_FUNCTION(alBuffer3i)
|
NAZARA_AUDIO_AL_FUNCTION(alBuffer3i)
|
||||||
NAZARA_AUDIO_AL_FUNCTION(alBufferData)
|
NAZARA_AUDIO_AL_FUNCTION(alBufferData)
|
||||||
|
|
@ -102,7 +114,7 @@ NAZARA_AUDIO_AL_FUNCTION(alSourceStopv)
|
||||||
NAZARA_AUDIO_AL_FUNCTION(alSourceUnqueueBuffers)
|
NAZARA_AUDIO_AL_FUNCTION(alSourceUnqueueBuffers)
|
||||||
NAZARA_AUDIO_AL_FUNCTION(alSpeedOfSound)
|
NAZARA_AUDIO_AL_FUNCTION(alSpeedOfSound)
|
||||||
|
|
||||||
#ifndef NAZARA_PLATFORM_WEB
|
#ifdef AL_SOFT_source_latency
|
||||||
NAZARA_AUDIO_AL_EXT_BEGIN(AL_SOFT_source_latency)
|
NAZARA_AUDIO_AL_EXT_BEGIN(AL_SOFT_source_latency)
|
||||||
NAZARA_AUDIO_AL_EXT_FUNCTION(alGetSource3dSOFT)
|
NAZARA_AUDIO_AL_EXT_FUNCTION(alGetSource3dSOFT)
|
||||||
NAZARA_AUDIO_AL_EXT_FUNCTION(alGetSource3i64SOFT)
|
NAZARA_AUDIO_AL_EXT_FUNCTION(alGetSource3i64SOFT)
|
||||||
|
|
@ -140,9 +152,19 @@ NAZARA_AUDIO_ALC_FUNCTION(alcOpenDevice)
|
||||||
NAZARA_AUDIO_ALC_FUNCTION(alcProcessContext)
|
NAZARA_AUDIO_ALC_FUNCTION(alcProcessContext)
|
||||||
NAZARA_AUDIO_ALC_FUNCTION(alcSuspendContext)
|
NAZARA_AUDIO_ALC_FUNCTION(alcSuspendContext)
|
||||||
|
|
||||||
|
#ifdef ALC_EXT_thread_local_context
|
||||||
|
NAZARA_AUDIO_ALC_EXT_BEGIN(ALC_EXT_thread_local_context)
|
||||||
|
NAZARA_AUDIO_ALC_EXT_FUNCTION(alcGetThreadContext)
|
||||||
|
NAZARA_AUDIO_ALC_EXT_FUNCTION(alcSetThreadContext)
|
||||||
|
NAZARA_AUDIO_ALC_EXT_END()
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef NAZARA_AUDIO_AL_FUNCTION
|
#undef NAZARA_AUDIO_AL_FUNCTION
|
||||||
#undef NAZARA_AUDIO_AL_ALC_FUNCTION
|
#undef NAZARA_AUDIO_AL_ALC_FUNCTION
|
||||||
#undef NAZARA_AUDIO_AL_EXT_FUNCTION
|
#undef NAZARA_AUDIO_AL_EXT_FUNCTION
|
||||||
#undef NAZARA_AUDIO_ALC_FUNCTION
|
|
||||||
#undef NAZARA_AUDIO_AL_EXT_BEGIN
|
#undef NAZARA_AUDIO_AL_EXT_BEGIN
|
||||||
#undef NAZARA_AUDIO_AL_EXT_END
|
#undef NAZARA_AUDIO_AL_EXT_END
|
||||||
|
#undef NAZARA_AUDIO_ALC_EXT_FUNCTION
|
||||||
|
#undef NAZARA_AUDIO_ALC_EXT_BEGIN
|
||||||
|
#undef NAZARA_AUDIO_ALC_EXT_END
|
||||||
|
#undef NAZARA_AUDIO_ALC_FUNCTION
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ namespace Nz
|
||||||
#include <Nazara/Audio/OpenALFunctions.hpp>
|
#include <Nazara/Audio/OpenALFunctions.hpp>
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local const OpenALDevice* s_currentALDevice;
|
// Regular OpenAL contexts are process-wide, but ALC_EXT_thread_local_context allows thread-local contexts
|
||||||
|
const OpenALDevice* s_currentGlobalALDevice;
|
||||||
|
thread_local const OpenALDevice* s_currentThreadALDevice;
|
||||||
|
|
||||||
template<typename FuncType, std::size_t FuncIndex, typename>
|
template<typename FuncType, std::size_t FuncIndex, typename>
|
||||||
struct ALWrapper;
|
struct ALWrapper;
|
||||||
|
|
@ -35,7 +37,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
return [](Args... args) -> Ret
|
return [](Args... args) -> Ret
|
||||||
{
|
{
|
||||||
const OpenALDevice* device = s_currentALDevice; //< pay TLS cost once
|
const OpenALDevice* device = OpenALDevice::GetCurrentDevice();
|
||||||
assert(device);
|
assert(device);
|
||||||
|
|
||||||
FuncType funcPtr = reinterpret_cast<FuncType>(device->GetFunctionByIndex(FuncIndex));
|
FuncType funcPtr = reinterpret_cast<FuncType>(device->GetFunctionByIndex(FuncIndex));
|
||||||
|
|
@ -121,7 +123,7 @@ namespace Nz
|
||||||
if (m_library.alcMakeContextCurrent(m_context) != AL_TRUE)
|
if (m_library.alcMakeContextCurrent(m_context) != AL_TRUE)
|
||||||
throw std::runtime_error("failed to activate OpenAL context");
|
throw std::runtime_error("failed to activate OpenAL context");
|
||||||
|
|
||||||
s_currentALDevice = this;
|
s_currentGlobalALDevice = this;
|
||||||
|
|
||||||
SymbolLoader loader(*this);
|
SymbolLoader loader(*this);
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
@ -131,6 +133,7 @@ namespace Nz
|
||||||
#define NAZARA_AUDIO_AL_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), false>(name, #name, library.name);
|
#define NAZARA_AUDIO_AL_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), false>(name, #name, library.name);
|
||||||
#define NAZARA_AUDIO_ALC_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), true>(name, #name, library.name);
|
#define NAZARA_AUDIO_ALC_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), true>(name, #name, library.name);
|
||||||
#define NAZARA_AUDIO_AL_EXT_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), false>(name, #name, nullptr);
|
#define NAZARA_AUDIO_AL_EXT_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), false>(name, #name, nullptr);
|
||||||
|
#define NAZARA_AUDIO_ALC_EXT_FUNCTION(name) loader.Load<decltype(&::name), UnderlyingCast(FunctionIndex:: name), true>(name, #name, nullptr);
|
||||||
#include <Nazara/Audio/OpenALFunctions.hpp>
|
#include <Nazara/Audio/OpenALFunctions.hpp>
|
||||||
|
|
||||||
m_renderer = reinterpret_cast<const char*>(alGetString(AL_RENDERER));
|
m_renderer = reinterpret_cast<const char*>(alGetString(AL_RENDERER));
|
||||||
|
|
@ -157,6 +160,9 @@ namespace Nz
|
||||||
if (library.alIsExtensionPresent("AL_SOFT_source_latency"))
|
if (library.alIsExtensionPresent("AL_SOFT_source_latency"))
|
||||||
m_extensionStatus[OpenALExtension::SourceLatency] = true;
|
m_extensionStatus[OpenALExtension::SourceLatency] = true;
|
||||||
|
|
||||||
|
if (library.alIsExtensionPresent("ALC_EXT_thread_local_context"))
|
||||||
|
m_extensionStatus[OpenALExtension::ThreadLocalContext] = true;
|
||||||
|
|
||||||
SetListenerDirection(Vector3f::Forward());
|
SetListenerDirection(Vector3f::Forward());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,20 +170,23 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||||
|
|
||||||
MakeContextCurrent();
|
// alcMakeContextCurrent resets the thread context
|
||||||
|
alcMakeContextCurrent(m_context);
|
||||||
alcDestroyContext(m_context);
|
alcDestroyContext(m_context);
|
||||||
alcCloseDevice(m_device);
|
alcCloseDevice(m_device);
|
||||||
|
|
||||||
if (s_currentALDevice == this)
|
if (s_currentThreadALDevice)
|
||||||
s_currentALDevice = nullptr;
|
s_currentThreadALDevice = nullptr;
|
||||||
|
|
||||||
|
if (s_currentGlobalALDevice == this)
|
||||||
|
s_currentGlobalALDevice = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenALDevice::ClearErrorFlag() const
|
bool OpenALDevice::ClearErrorFlag() const
|
||||||
{
|
{
|
||||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||||
|
|
||||||
assert(s_currentALDevice == this);
|
assert(GetCurrentDevice() == this);
|
||||||
alGetError();
|
alGetError();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -322,10 +331,27 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||||
|
|
||||||
if (s_currentALDevice != this)
|
if (alcSetThreadContext)
|
||||||
{
|
{
|
||||||
m_library.alcMakeContextCurrent(m_context);
|
if (s_currentThreadALDevice != this)
|
||||||
s_currentALDevice = this;
|
{
|
||||||
|
alcSetThreadContext(m_context);
|
||||||
|
s_currentThreadALDevice = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (s_currentGlobalALDevice != this)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
From EXT_thread_local_context:
|
||||||
|
alcMakeContextCurrent changes the current process-wide context and set the current thread-local context to NULL.
|
||||||
|
This has the side effect of changing the current thread-local context, so that the new current process-wide context will be used.
|
||||||
|
*/
|
||||||
|
alcMakeContextCurrent(m_context);
|
||||||
|
s_currentGlobalALDevice = this;
|
||||||
|
s_currentThreadALDevice = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,7 +384,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||||
|
|
||||||
assert(s_currentALDevice == this);
|
assert(GetCurrentDevice() == this);
|
||||||
|
|
||||||
bool hasAnyError = false;
|
bool hasAnyError = false;
|
||||||
if (ALuint lastError = alGetError(); lastError != AL_NO_ERROR)
|
if (ALuint lastError = alGetError(); lastError != AL_NO_ERROR)
|
||||||
|
|
@ -485,4 +511,13 @@ namespace Nz
|
||||||
|
|
||||||
alSpeedOfSound(speed);
|
alSpeedOfSound(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OpenALDevice* OpenALDevice::GetCurrentDevice()
|
||||||
|
{
|
||||||
|
const OpenALDevice* device = s_currentThreadALDevice;
|
||||||
|
if (device)
|
||||||
|
return device;
|
||||||
|
|
||||||
|
return s_currentGlobalALDevice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue