diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | al/debug.cpp | 186 | ||||
-rw-r--r-- | al/debug.h | 4 | ||||
-rw-r--r-- | alc/context.cpp | 166 |
4 files changed, 192 insertions, 166 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 55644b04..eec2d58f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -742,6 +742,8 @@ set(OPENAL_OBJS al/auxeffectslot.h al/buffer.cpp al/buffer.h + al/debug.cpp + al/debug.h al/effect.cpp al/effect.h al/effects/autowah.cpp diff --git a/al/debug.cpp b/al/debug.cpp new file mode 100644 index 00000000..975443c7 --- /dev/null +++ b/al/debug.cpp @@ -0,0 +1,186 @@ +#include "config.h" + +#include "debug.h" + +#include <algorithm> +#include <array> +#include <mutex> +#include <stddef.h> +#include <utility> + +#include "AL/al.h" + +#include "alc/context.h" +#include "alc/inprogext.h" +#include "alspan.h" +#include "opthelpers.h" +#include "threads.h" + + +namespace { + +template<typename T, T ...Vals> +constexpr auto make_array(std::integer_sequence<T, Vals...>) +{ return std::array<T,sizeof...(Vals)>{Vals...}; } + +template<typename T, size_t N, typename Indices = std::make_integer_sequence<T,N>> +constexpr auto make_array() +{ return make_array(Indices{}); } + +} // namespace + + +FORCE_ALIGN void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + context->mDebugCb = callback; + context->mDebugParam = userParam; +} + +FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type, ALuint id, + ALenum severity, ALsizei length, const ALchar *message) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + if(!message) + return context->setError(AL_INVALID_VALUE, "Null message pointer"); + + DebugSource dsource{}; + switch(source) + { + case AL_DEBUG_SOURCE_THIRD_PARTY_SOFT: dsource = DebugSource::ThirdParty; break; + case AL_DEBUG_SOURCE_APPLICATION_SOFT: dsource = DebugSource::Application; break; + case AL_DEBUG_SOURCE_API_SOFT: + case AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT: + case AL_DEBUG_SOURCE_OTHER_SOFT: + return context->setError(AL_INVALID_ENUM, "Debug source enum 0x%04x not allowed", source); + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug source enum 0x%04x", source); + } + + DebugType dtype{}; + switch(type) + { + case AL_DEBUG_TYPE_ERROR_SOFT: dtype = DebugType::Error; break; + case AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT: dtype = DebugType::DeprecatedBehavior; break; + case AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT: dtype = DebugType::UndefinedBehavior; break; + case AL_DEBUG_TYPE_PORTABILITY_SOFT: dtype = DebugType::Portability; break; + case AL_DEBUG_TYPE_PERFORMANCE_SOFT: dtype = DebugType::Performance; break; + case AL_DEBUG_TYPE_MARKER_SOFT: dtype = DebugType::Marker; break; + case AL_DEBUG_TYPE_OTHER_SOFT: dtype = DebugType::Other; break; + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug type 0x%04x", type); + } + + DebugSeverity dseverity{}; + switch(severity) + { + case AL_DEBUG_SEVERITY_HIGH_SOFT: dseverity = DebugSeverity::High; break; + case AL_DEBUG_SEVERITY_MEDIUM_SOFT: dseverity = DebugSeverity::Medium; break; + case AL_DEBUG_SEVERITY_LOW_SOFT: dseverity = DebugSeverity::Low; break; + case AL_DEBUG_SEVERITY_NOTIFICATION_SOFT: dseverity = DebugSeverity::Notification; break; + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug severity 0x%04x", severity); + } + + context->debugMessage(dsource, dtype, id, dseverity, length, message); +} + + +FORCE_ALIGN void AL_APIENTRY alDebugMessageControlSOFT(ALenum source, ALenum type, ALenum severity, + ALsizei count, const ALuint *ids, ALboolean enable) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + if(count > 0) + { + if(!ids) + return context->setError(AL_INVALID_VALUE, "IDs is null with non-0 count"); + if(source == AL_DONT_CARE_SOFT) + return context->setError(AL_INVALID_VALUE, + "Debug source cannot be AL_DONT_CARE_SOFT with IDs"); + if(type == AL_DONT_CARE_SOFT) + return context->setError(AL_INVALID_VALUE, + "Debug type cannot be AL_DONT_CARE_SOFT with IDs"); + if(severity != AL_DONT_CARE_SOFT) + return context->setError(AL_INVALID_VALUE, + "Debug severity must be AL_DONT_CARE_SOFT with IDs"); + + return context->setError(AL_INVALID_VALUE, "Debug ID filtering not supported"); + return; + } + + if(enable != AL_TRUE && enable != AL_FALSE) + return context->setError(AL_INVALID_VALUE, "Invalid debug enable %d", enable); + + static constexpr size_t ElemCount{DebugSourceCount + DebugTypeCount + DebugSeverityCount}; + static constexpr auto Values = make_array<uint,ElemCount>(); + + al::span<const uint> srcIndices{al::as_span(Values).subspan<DebugSourceBase,DebugSourceCount>()}; + switch(source) + { + case AL_DEBUG_SOURCE_API_SOFT: srcIndices = srcIndices.subspan(0, 1); break; + case AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT: srcIndices = srcIndices.subspan(1, 1); break; + case AL_DEBUG_SOURCE_THIRD_PARTY_SOFT: srcIndices = srcIndices.subspan(2, 1); break; + case AL_DEBUG_SOURCE_APPLICATION_SOFT: srcIndices = srcIndices.subspan(3, 1); break; + case AL_DEBUG_SOURCE_OTHER_SOFT: srcIndices = srcIndices.subspan(4, 1); break; + case AL_DONT_CARE_SOFT: break; + default: + return context->setError(AL_INVALID_VALUE, "Invalid debug source 0x%04x", source); + } + + al::span<const uint> typeIndices{al::as_span(Values).subspan<DebugTypeBase,DebugTypeCount>()}; + switch(type) + { + case AL_DEBUG_TYPE_ERROR_SOFT: typeIndices = typeIndices.subspan(0, 1); break; + case AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT: typeIndices = typeIndices.subspan(1, 1); break; + case AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT: typeIndices = typeIndices.subspan(2, 1); break; + case AL_DEBUG_TYPE_PORTABILITY_SOFT: typeIndices = typeIndices.subspan(3, 1); break; + case AL_DEBUG_TYPE_PERFORMANCE_SOFT: typeIndices = typeIndices.subspan(4, 1); break; + case AL_DEBUG_TYPE_MARKER_SOFT: typeIndices = typeIndices.subspan(5, 1); break; + case AL_DEBUG_TYPE_OTHER_SOFT: typeIndices = typeIndices.subspan(6, 1); break; + case AL_DONT_CARE_SOFT: break; + default: + return context->setError(AL_INVALID_VALUE, "Invalid debug type 0x%04x", type); + } + + al::span<const uint> svrIndices{al::as_span(Values).subspan<DebugSeverityBase,DebugSeverityCount>()}; + switch(severity) + { + case AL_DEBUG_SEVERITY_HIGH_SOFT: svrIndices = svrIndices.subspan(0, 1); break; + case AL_DEBUG_SEVERITY_MEDIUM_SOFT: svrIndices = svrIndices.subspan(1, 1); break; + case AL_DEBUG_SEVERITY_LOW_SOFT: svrIndices = svrIndices.subspan(2, 1); break; + case AL_DEBUG_SEVERITY_NOTIFICATION_SOFT: svrIndices = svrIndices.subspan(3, 1); break; + case AL_DONT_CARE_SOFT: break; + default: + return context->setError(AL_INVALID_VALUE, "Invalid debug severity 0x%04x", severity); + } + + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + auto apply_filter = [enable,&context](const uint filter) + { + auto iter = std::lower_bound(context->mDebugFilters.cbegin(), + context->mDebugFilters.cend(), filter); + if(enable && (iter == context->mDebugFilters.cend() || *iter != filter)) + context->mDebugFilters.insert(iter, filter); + else if(!enable && iter != context->mDebugFilters.cend() && *iter == filter) + context->mDebugFilters.erase(iter); + }; + auto apply_severity = [apply_filter,svrIndices](const uint filter) + { + std::for_each(svrIndices.cbegin(), svrIndices.cend(), + [apply_filter,filter](const uint idx){ apply_filter(filter | (1<<idx)); }); + }; + auto apply_type = [apply_severity,typeIndices](const uint filter) + { + std::for_each(typeIndices.cbegin(), typeIndices.cend(), + [apply_severity,filter](const uint idx){ apply_severity(filter | (1<<idx)); }); + }; + std::for_each(srcIndices.cbegin(), srcIndices.cend(), + [apply_type](const uint idx){ apply_type(1<<idx); }); +} diff --git a/al/debug.h b/al/debug.h new file mode 100644 index 00000000..a268f690 --- /dev/null +++ b/al/debug.h @@ -0,0 +1,4 @@ +#ifndef AL_DEBUG_H +#define AL_DEBUG_H + +#endif /* AL_DEBUG_H */ diff --git a/alc/context.cpp b/alc/context.cpp index 3f7b456d..5b476009 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -349,172 +349,6 @@ void ALCcontext::sendDebugMessage(DebugSource source, DebugType type, ALuint id, } } -FORCE_ALIGN void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - std::lock_guard<std::mutex> _{context->mDebugCbLock}; - context->mDebugCb = callback; - context->mDebugParam = userParam; -} - -FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type, ALuint id, - ALenum severity, ALsizei length, const ALchar *message) noexcept -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - if(!message) - return context->setError(AL_INVALID_VALUE, "Null message pointer"); - - DebugSource dsource{}; - switch(source) - { - case AL_DEBUG_SOURCE_THIRD_PARTY_SOFT: dsource = DebugSource::ThirdParty; break; - case AL_DEBUG_SOURCE_APPLICATION_SOFT: dsource = DebugSource::Application; break; - case AL_DEBUG_SOURCE_API_SOFT: - case AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT: - case AL_DEBUG_SOURCE_OTHER_SOFT: - return context->setError(AL_INVALID_ENUM, "Debug source enum 0x%04x not allowed", source); - default: - return context->setError(AL_INVALID_ENUM, "Invalid debug source enum 0x%04x", source); - } - - DebugType dtype{}; - switch(type) - { - case AL_DEBUG_TYPE_ERROR_SOFT: dtype = DebugType::Error; break; - case AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT: dtype = DebugType::DeprecatedBehavior; break; - case AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT: dtype = DebugType::UndefinedBehavior; break; - case AL_DEBUG_TYPE_PORTABILITY_SOFT: dtype = DebugType::Portability; break; - case AL_DEBUG_TYPE_PERFORMANCE_SOFT: dtype = DebugType::Performance; break; - case AL_DEBUG_TYPE_MARKER_SOFT: dtype = DebugType::Marker; break; - case AL_DEBUG_TYPE_OTHER_SOFT: dtype = DebugType::Other; break; - default: - return context->setError(AL_INVALID_ENUM, "Invalid debug type 0x%04x", type); - } - - DebugSeverity dseverity{}; - switch(severity) - { - case AL_DEBUG_SEVERITY_HIGH_SOFT: dseverity = DebugSeverity::High; break; - case AL_DEBUG_SEVERITY_MEDIUM_SOFT: dseverity = DebugSeverity::Medium; break; - case AL_DEBUG_SEVERITY_LOW_SOFT: dseverity = DebugSeverity::Low; break; - case AL_DEBUG_SEVERITY_NOTIFICATION_SOFT: dseverity = DebugSeverity::Notification; break; - default: - return context->setError(AL_INVALID_ENUM, "Invalid debug severity 0x%04x", severity); - } - - context->debugMessage(dsource, dtype, id, dseverity, length, message); -} - - -namespace { - -template<typename T, T ...Vals> -constexpr auto make_array(std::integer_sequence<T, Vals...>) -{ return std::array<T,sizeof...(Vals)>{Vals...}; } - -template<typename T, size_t N, typename Indices = std::make_integer_sequence<T,N>> -constexpr auto make_array() -{ return make_array(Indices{}); } - -} // namespace - -FORCE_ALIGN void AL_APIENTRY alDebugMessageControlSOFT(ALenum source, ALenum type, ALenum severity, - ALsizei count, const ALuint *ids, ALboolean enable) noexcept -{ - ContextRef context{GetContextRef()}; - if(!context) UNLIKELY return; - - if(count > 0) - { - if(!ids) - return context->setError(AL_INVALID_VALUE, "IDs is null with non-0 count"); - if(source == AL_DONT_CARE_SOFT) - return context->setError(AL_INVALID_VALUE, - "Debug source cannot be AL_DONT_CARE_SOFT with IDs"); - if(type == AL_DONT_CARE_SOFT) - return context->setError(AL_INVALID_VALUE, - "Debug type cannot be AL_DONT_CARE_SOFT with IDs"); - if(severity != AL_DONT_CARE_SOFT) - return context->setError(AL_INVALID_VALUE, - "Debug severity must be AL_DONT_CARE_SOFT with IDs"); - - return context->setError(AL_INVALID_VALUE, "Debug ID filtering not supported"); - return; - } - - if(enable != AL_TRUE && enable != AL_FALSE) - return context->setError(AL_INVALID_VALUE, "Invalid debug enable %d", enable); - - static constexpr size_t ElemCount{DebugSourceCount + DebugTypeCount + DebugSeverityCount}; - static constexpr auto Values = make_array<uint,ElemCount>(); - - al::span<const uint> srcIndices{al::as_span(Values).subspan<DebugSourceBase,DebugSourceCount>()}; - switch(source) - { - case AL_DEBUG_SOURCE_API_SOFT: srcIndices = srcIndices.subspan(0, 1); break; - case AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT: srcIndices = srcIndices.subspan(1, 1); break; - case AL_DEBUG_SOURCE_THIRD_PARTY_SOFT: srcIndices = srcIndices.subspan(2, 1); break; - case AL_DEBUG_SOURCE_APPLICATION_SOFT: srcIndices = srcIndices.subspan(3, 1); break; - case AL_DEBUG_SOURCE_OTHER_SOFT: srcIndices = srcIndices.subspan(4, 1); break; - case AL_DONT_CARE_SOFT: break; - default: - return context->setError(AL_INVALID_VALUE, "Invalid debug source 0x%04x", source); - } - - al::span<const uint> typeIndices{al::as_span(Values).subspan<DebugTypeBase,DebugTypeCount>()}; - switch(type) - { - case AL_DEBUG_TYPE_ERROR_SOFT: typeIndices = typeIndices.subspan(0, 1); break; - case AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT: typeIndices = typeIndices.subspan(1, 1); break; - case AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT: typeIndices = typeIndices.subspan(2, 1); break; - case AL_DEBUG_TYPE_PORTABILITY_SOFT: typeIndices = typeIndices.subspan(3, 1); break; - case AL_DEBUG_TYPE_PERFORMANCE_SOFT: typeIndices = typeIndices.subspan(4, 1); break; - case AL_DEBUG_TYPE_MARKER_SOFT: typeIndices = typeIndices.subspan(5, 1); break; - case AL_DEBUG_TYPE_OTHER_SOFT: typeIndices = typeIndices.subspan(6, 1); break; - case AL_DONT_CARE_SOFT: break; - default: - return context->setError(AL_INVALID_VALUE, "Invalid debug type 0x%04x", type); - } - - al::span<const uint> svrIndices{al::as_span(Values).subspan<DebugSeverityBase,DebugSeverityCount>()}; - switch(severity) - { - case AL_DEBUG_SEVERITY_HIGH_SOFT: svrIndices = svrIndices.subspan(0, 1); break; - case AL_DEBUG_SEVERITY_MEDIUM_SOFT: svrIndices = svrIndices.subspan(1, 1); break; - case AL_DEBUG_SEVERITY_LOW_SOFT: svrIndices = svrIndices.subspan(2, 1); break; - case AL_DEBUG_SEVERITY_NOTIFICATION_SOFT: svrIndices = svrIndices.subspan(3, 1); break; - case AL_DONT_CARE_SOFT: break; - default: - return context->setError(AL_INVALID_VALUE, "Invalid debug severity 0x%04x", severity); - } - - std::lock_guard<std::mutex> _{context->mDebugCbLock}; - auto apply_filter = [enable,&context](const uint filter) - { - auto iter = std::lower_bound(context->mDebugFilters.cbegin(), - context->mDebugFilters.cend(), filter); - if(enable && (iter == context->mDebugFilters.cend() || *iter != filter)) - context->mDebugFilters.insert(iter, filter); - else if(!enable && iter != context->mDebugFilters.cend() && *iter == filter) - context->mDebugFilters.erase(iter); - }; - auto apply_severity = [apply_filter,svrIndices](const uint filter) - { - std::for_each(svrIndices.cbegin(), svrIndices.cend(), - [apply_filter,filter](const uint idx){ apply_filter(filter | (1<<idx)); }); - }; - auto apply_type = [apply_severity,typeIndices](const uint filter) - { - std::for_each(typeIndices.cbegin(), typeIndices.cend(), - [apply_severity,filter](const uint idx){ apply_severity(filter | (1<<idx)); }); - }; - std::for_each(srcIndices.cbegin(), srcIndices.cend(), - [apply_type](const uint idx){ apply_type(1<<idx); }); -} #ifdef ALSOFT_EAX namespace { |