aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-04-29 19:18:06 -0700
committerChris Robinson <[email protected]>2023-04-29 19:18:06 -0700
commita35211e2c1dc53e47c4a300366d22a27fb046a8c (patch)
treea0313f8d37a2193f1cdf07d37f8be4ba53ece8a1 /alc
parent234174c62123c5d2f57d649722b5ca53b0de9d2d (diff)
Start a debug API extension
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp4
-rw-r--r--alc/context.cpp78
-rw-r--r--alc/context.h41
-rw-r--r--alc/inprogext.h31
4 files changed, 153 insertions, 1 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index af8ff55d..0ed0ae58 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -459,6 +459,8 @@ const struct {
DECL(alBufferSubDataSOFT),
DECL(alBufferDataStatic),
+
+ DECL(alDebugMessageCallbackSOFT),
#ifdef ALSOFT_EAX
}, eaxFunctions[] = {
DECL(EAXGet),
@@ -915,6 +917,8 @@ constexpr struct {
DECL(AL_FORMAT_UHJ4CHN_MULAW_SOFT),
DECL(AL_FORMAT_UHJ4CHN_ALAW_SOFT),
+ DECL(AL_DEBUG_OUTPUT_SOFT),
+
DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT),
#ifdef ALSOFT_EAX
diff --git a/alc/context.cpp b/alc/context.cpp
index 008c2bf4..e2a2e2d2 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -113,7 +113,7 @@ void ALCcontext::setThreadContext(ALCcontext *context) noexcept
#endif
ALCcontext::ALCcontext(al::intrusive_ptr<ALCdevice> device)
- : ContextBase{device.get()}, mALDevice{std::move(device)}
+ : ContextBase{device.get()}, mALDevice{std::move(device)}
{
}
@@ -295,6 +295,82 @@ void ALCcontext::applyAllUpdates()
mHoldUpdates.store(false, std::memory_order_release);
}
+void ALCcontext::sendDebugMessage(DebugSource source, DebugType type, ALuint id,
+ DebugSeverity severity, ALsizei length, const char *message)
+{
+ std::lock_guard<std::mutex> _{mDebugCbLock};
+ if(!mDebugEnabled.load())
+ return;
+
+ if(mDebugCb)
+ mDebugCb(al::to_underlying(source), al::to_underlying(type), id,
+ al::to_underlying(severity), length, message, mDebugParam);
+ else
+ {
+ /* TODO: Store in a log. */
+ }
+}
+
+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);
+}
+
#ifdef ALSOFT_EAX
namespace {
diff --git a/alc/context.h b/alc/context.h
index e8efdbf1..697ecfe9 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -34,6 +34,30 @@ struct ALsource;
using uint = unsigned int;
+enum class DebugSource : ALenum {
+ API = AL_DEBUG_SOURCE_API_SOFT,
+ System = AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT,
+ ThirdParty = AL_DEBUG_SOURCE_THIRD_PARTY_SOFT,
+ Application = AL_DEBUG_SOURCE_APPLICATION_SOFT,
+ Other = AL_DEBUG_SOURCE_OTHER_SOFT,
+};
+enum class DebugType : ALenum {
+ Error = AL_DEBUG_TYPE_ERROR_SOFT,
+ DeprecatedBehavior = AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT,
+ UndefinedBehavior = AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT,
+ Portability = AL_DEBUG_TYPE_PORTABILITY_SOFT,
+ Performance = AL_DEBUG_TYPE_PERFORMANCE_SOFT,
+ Marker = AL_DEBUG_TYPE_MARKER_SOFT,
+ Other = AL_DEBUG_TYPE_OTHER_SOFT,
+};
+enum class DebugSeverity : ALenum {
+ High = AL_DEBUG_SEVERITY_HIGH_SOFT,
+ Medium = AL_DEBUG_SEVERITY_MEDIUM_SOFT,
+ Low = AL_DEBUG_SEVERITY_LOW_SOFT,
+ Notification = AL_DEBUG_SEVERITY_NOTIFICATION_SOFT,
+};
+
+
struct SourceSubList {
uint64_t FreeMask{~0_u64};
ALsource *Sources{nullptr}; /* 64 */
@@ -76,6 +100,8 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase {
std::atomic<ALenum> mLastError{AL_NO_ERROR};
+ std::atomic<bool> mDebugEnabled{false};
+
DistanceModel mDistanceModel{DistanceModel::Default};
bool mSourceDistanceModel{false};
@@ -88,6 +114,10 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase {
ALEVENTPROCSOFT mEventCb{};
void *mEventParam{nullptr};
+ std::mutex mDebugCbLock;
+ ALDEBUGPROCSOFT mDebugCb{};
+ void *mDebugParam{nullptr};
+
ALlistener mListener{};
al::vector<SourceSubList> mSourceList;
@@ -149,6 +179,17 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase {
#endif
void setError(ALenum errorCode, const char *msg, ...);
+ void sendDebugMessage(DebugSource source, DebugType type, ALuint id, DebugSeverity severity,
+ ALsizei length, const char *message);
+
+ void debugMessage(DebugSource source, DebugType type, ALuint id, DebugSeverity severity,
+ ALsizei length, const char *message)
+ {
+ if(!mDebugEnabled.load(std::memory_order_relaxed)) LIKELY
+ return;
+ sendDebugMessage(source, type, id, severity, length, message);
+ }
+
/* Process-wide current context */
static std::atomic<bool> sGlobalContextLock;
static std::atomic<ALCcontext*> sGlobalContext;
diff --git a/alc/inprogext.h b/alc/inprogext.h
index ccb9a4be..53dc9f0c 100644
--- a/alc/inprogext.h
+++ b/alc/inprogext.h
@@ -54,6 +54,37 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopvSOFT(ALsizei n, const ALuint *
#define AL_STOP_SOURCES_ON_DISCONNECT_SOFT 0x19AB
#endif
+#ifndef AL_SOFT_debug
+#define AL_SOFT_debug
+#define AL_DEBUG_OUTPUT_SOFT 0x19B2
+#define AL_DEBUG_CALLBACK_FUNCTION_SOFT 0x19B3
+#define AL_DEBUG_CALLBACK_USER_PARAM_SOFT 0x19B4
+#define AL_DEBUG_SOURCE_API_SOFT 0x19B5
+#define AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT 0x19B6
+#define AL_DEBUG_SOURCE_THIRD_PARTY_SOFT 0x19B7
+#define AL_DEBUG_SOURCE_APPLICATION_SOFT 0x19B8
+#define AL_DEBUG_SOURCE_OTHER_SOFT 0x19B9
+#define AL_DEBUG_TYPE_ERROR_SOFT 0x19BA
+#define AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT 0x19BB
+#define AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT 0x19BC
+#define AL_DEBUG_TYPE_PORTABILITY_SOFT 0x19BD
+#define AL_DEBUG_TYPE_PERFORMANCE_SOFT 0x19BE
+#define AL_DEBUG_TYPE_MARKER_SOFT 0x19BF
+#define AL_DEBUG_TYPE_OTHER_SOFT 0x19C0
+#define AL_DEBUG_SEVERITY_HIGH_SOFT 0x19C1
+#define AL_DEBUG_SEVERITY_MEDIUM_SOFT 0x19C2
+#define AL_DEBUG_SEVERITY_LOW_SOFT 0x19C3
+#define AL_DEBUG_SEVERITY_NOTIFICATION_SOFT 0x19C4
+
+typedef void (AL_APIENTRY*ALDEBUGPROCSOFT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message, void *userParam);
+typedef void (AL_APIENTRY*LPALDEBUGMESSAGECALLBACKSOFT)(ALDEBUGPROCSOFT callback, void *userParam);
+typedef void (AL_APIENTRY*LPALDEBUGMESSAGEINSERTSOFT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message);
+#ifdef AL_ALEXT_PROTOTYPES
+void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept;
+void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) noexcept;
+#endif
+#endif
+
/* Non-standard export. Not part of any extension. */
AL_API const ALchar* AL_APIENTRY alsoft_get_version(void);