diff options
author | Chris Robinson <[email protected]> | 2023-04-30 17:46:18 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-04-30 17:46:18 -0700 |
commit | 22077687cf4b9fdfd29d78debc2daf044deee81d (patch) | |
tree | fc9aab402ea9e33f7cec2e1ef1dfa98203665578 /al | |
parent | f2a0df87916de7b9fa8b65a52814c9a09fc6bee9 (diff) |
Implement debug log storage
Diffstat (limited to 'al')
-rw-r--r-- | al/debug.cpp | 93 | ||||
-rw-r--r-- | al/debug.h | 9 | ||||
-rw-r--r-- | al/state.cpp | 61 |
3 files changed, 162 insertions, 1 deletions
diff --git a/al/debug.cpp b/al/debug.cpp index 2694d7b4..ab81f5a8 100644 --- a/al/debug.cpp +++ b/al/debug.cpp @@ -71,6 +71,46 @@ constexpr al::optional<DebugSeverity> GetDebugSeverity(ALenum severity) noexcept } // namespace +ALenum GetDebugSourceEnum(DebugSource source) +{ + switch(source) + { + case DebugSource::API: return AL_DEBUG_SOURCE_API_SOFT; + case DebugSource::System: return AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT; + case DebugSource::ThirdParty: return AL_DEBUG_SOURCE_THIRD_PARTY_SOFT; + case DebugSource::Application: return AL_DEBUG_SOURCE_APPLICATION_SOFT; + case DebugSource::Other: return AL_DEBUG_SOURCE_OTHER_SOFT; + } + throw std::runtime_error{"Unexpected debug source value "+std::to_string(al::to_underlying(source))}; +} + +ALenum GetDebugTypeEnum(DebugType type) +{ + switch(type) + { + case DebugType::Error: return AL_DEBUG_TYPE_ERROR_SOFT; + case DebugType::DeprecatedBehavior: return AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT; + case DebugType::UndefinedBehavior: return AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT; + case DebugType::Portability: return AL_DEBUG_TYPE_PORTABILITY_SOFT; + case DebugType::Performance: return AL_DEBUG_TYPE_PERFORMANCE_SOFT; + case DebugType::Marker: return AL_DEBUG_TYPE_MARKER_SOFT; + case DebugType::Other: return AL_DEBUG_TYPE_OTHER_SOFT; + } + throw std::runtime_error{"Unexpected debug type value "+std::to_string(al::to_underlying(type))}; +} + +ALenum GetDebugSeverityEnum(DebugSeverity severity) +{ + switch(severity) + { + case DebugSeverity::High: return AL_DEBUG_SEVERITY_HIGH_SOFT; + case DebugSeverity::Medium: return AL_DEBUG_SEVERITY_MEDIUM_SOFT; + case DebugSeverity::Low: return AL_DEBUG_SEVERITY_LOW_SOFT; + case DebugSeverity::Notification: return AL_DEBUG_SEVERITY_NOTIFICATION_SOFT; + } + throw std::runtime_error{"Unexpected debug severity value "+std::to_string(al::to_underlying(severity))}; +} + FORCE_ALIGN void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept { @@ -91,6 +131,18 @@ FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type if(!message) return context->setError(AL_INVALID_VALUE, "Null message pointer"); + if(length < 0) + { + size_t newlen{std::strlen(message)}; + if(newlen > MaxDebugMessageLength) UNLIKELY + return context->setError(AL_INVALID_VALUE, "Debug message too long (%zu > %d)", newlen, + MaxDebugMessageLength); + length = static_cast<ALsizei>(newlen); + } + else if(length > MaxDebugMessageLength) UNLIKELY + return context->setError(AL_INVALID_VALUE, "Debug message too long (%d > %d)", length, + MaxDebugMessageLength); + auto dsource = GetDebugSource(source); if(!dsource) return context->setError(AL_INVALID_ENUM, "Invalid debug source 0x%04x", source); @@ -189,3 +241,44 @@ FORCE_ALIGN void AL_APIENTRY alDebugMessageControlSOFT(ALenum source, ALenum typ std::for_each(srcIndices.cbegin(), srcIndices.cend(), [apply_type](const uint idx){ apply_type(1<<idx); }); } + + +FORCE_ALIGN ALuint AL_APIENTRY alGetDebugMessageLogSOFT(ALuint count, ALsizei logBufSize, + ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, + ALchar *logBuf) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return 0; + + if(logBufSize < 0) + { + context->setError(AL_INVALID_VALUE, "Negative debug log buffer size"); + return 0; + } + + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + ALsizei logBufWritten{0}; + for(ALuint i{0};i < count;++i) + { + if(context->mDebugLog.empty()) + return i; + + auto &entry = context->mDebugLog.front(); + const size_t tocopy{entry.mMessage.size() + 1}; + const size_t avail{static_cast<ALuint>(logBufSize - logBufWritten)}; + if(avail < tocopy) + return i; + + if(sources) sources[i] = GetDebugSourceEnum(entry.mSource); + if(types) types[i] = GetDebugTypeEnum(entry.mType); + if(ids) ids[i] = entry.mId; + if(severities) severities[i] = GetDebugSeverityEnum(entry.mSeverity); + if(lengths) lengths[i] = static_cast<ALsizei>(tocopy); + if(logBuf) std::copy_n(entry.mMessage.data(), tocopy, logBuf+logBufWritten); + + logBufWritten += static_cast<ALsizei>(tocopy); + context->mDebugLog.pop_front(); + } + + return count; +} @@ -1,4 +1,13 @@ #ifndef AL_DEBUG_H #define AL_DEBUG_H +#include <stdint.h> + + +/* Somewhat arbitrary. Avoid letting it get out of control if the app enables + * logging but never reads it. + */ +constexpr uint8_t MaxDebugLoggedMessages{64}; +constexpr uint16_t MaxDebugMessageLength{1024}; + #endif /* AL_DEBUG_H */ diff --git a/al/state.cpp b/al/state.cpp index 7b7377f7..1e1a0085 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -33,6 +33,7 @@ #include "AL/alc.h" #include "AL/alext.h" +#include "al/debug.h" #include "alc/alu.h" #include "alc/context.h" #include "alc/inprogext.h" @@ -259,6 +260,10 @@ START_API_FUNC case AL_DISTANCE_MODEL: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: return alGetInteger(pname) != 0; } @@ -299,6 +304,10 @@ START_API_FUNC case AL_DISTANCE_MODEL: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: return alGetInteger(pname); } @@ -325,8 +334,11 @@ START_API_FUNC case AL_DISTANCE_MODEL: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: return static_cast<ALfloat>(alGetInteger(pname)); - break; case AL_DEFERRED_UPDATES_SOFT: return alGetBoolean(pname) ? 1.0f : 0.0f; @@ -401,6 +413,29 @@ START_API_FUNC value = al::to_underlying(ResamplerDefault); break; + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + { + std::lock_guard<std::mutex> __{context->mDebugCbLock}; + value = static_cast<ALint>(context->mDebugLog.size()); + break; + } + + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + { + std::lock_guard<std::mutex> __{context->mDebugCbLock}; + value = context->mDebugLog.empty() ? 0 + : static_cast<ALint>(context->mDebugLog.front().mMessage.size()+1); + break; + } + + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + value = MaxDebugMessageLength; + break; + + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: + value = MaxDebugLoggedMessages; + break; + #ifdef ALSOFT_EAX #define EAX_ERROR "[alGetInteger] EAX not enabled." @@ -452,6 +487,10 @@ START_API_FUNC case AL_DISTANCE_MODEL: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: return alGetInteger(pname); } @@ -519,6 +558,10 @@ START_API_FUNC case AL_GAIN_LIMIT_SOFT: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: values[0] = alGetBoolean(pname); return; } @@ -552,6 +595,10 @@ START_API_FUNC case AL_GAIN_LIMIT_SOFT: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: values[0] = alGetDouble(pname); return; } @@ -585,6 +632,10 @@ START_API_FUNC case AL_GAIN_LIMIT_SOFT: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: values[0] = alGetFloat(pname); return; } @@ -618,6 +669,10 @@ START_API_FUNC case AL_GAIN_LIMIT_SOFT: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: values[0] = alGetInteger(pname); return; } @@ -651,6 +706,10 @@ START_API_FUNC case AL_GAIN_LIMIT_SOFT: case AL_NUM_RESAMPLERS_SOFT: case AL_DEFAULT_RESAMPLER_SOFT: + case AL_DEBUG_LOGGED_MESSAGES_SOFT: + case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT: + case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT: values[0] = alGetInteger64SOFT(pname); return; } |