aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-04-30 17:46:18 -0700
committerChris Robinson <[email protected]>2023-04-30 17:46:18 -0700
commit22077687cf4b9fdfd29d78debc2daf044deee81d (patch)
treefc9aab402ea9e33f7cec2e1ef1dfa98203665578 /al
parentf2a0df87916de7b9fa8b65a52814c9a09fc6bee9 (diff)
Implement debug log storage
Diffstat (limited to 'al')
-rw-r--r--al/debug.cpp93
-rw-r--r--al/debug.h9
-rw-r--r--al/state.cpp61
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;
+}
diff --git a/al/debug.h b/al/debug.h
index a268f690..23b0ca1b 100644
--- a/al/debug.h
+++ b/al/debug.h
@@ -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;
}