aboutsummaryrefslogtreecommitdiffstats
path: root/al
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-08-11 02:10:26 -0700
committerChris Robinson <[email protected]>2023-08-11 02:10:26 -0700
commit09eff761b8c8a2da79b0083c86a304eb3643b396 (patch)
tree7408644f085ba7ccc6ca2f64d2f1959dbc4e1e08 /al
parent9296af5566afea4ba4cb78b374ef3ee0bf9bc04b (diff)
Add AL_EXT_debug functions to set/get object names
Diffstat (limited to 'al')
-rw-r--r--al/auxeffectslot.cpp13
-rw-r--r--al/auxeffectslot.h3
-rw-r--r--al/buffer.cpp15
-rw-r--r--al/buffer.h3
-rw-r--r--al/debug.cpp101
-rw-r--r--al/debug.h1
-rw-r--r--al/effect.cpp15
-rw-r--r--al/effect.h2
-rw-r--r--al/filter.cpp15
-rw-r--r--al/filter.h2
-rw-r--r--al/source.cpp14
-rw-r--r--al/source.h5
-rw-r--r--al/state.cpp5
13 files changed, 188 insertions, 6 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 6f82db71..09db0736 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -286,6 +286,8 @@ ALeffectslot *AllocEffectSlot(ALCcontext *context)
void FreeEffectSlot(ALCcontext *context, ALeffectslot *slot)
{
+ context->mEffectSlotNames.erase(slot->id);
+
const ALuint id{slot->id - 1};
const size_t lidx{id >> 6};
const ALuint slidx{id & 0x3f};
@@ -962,6 +964,17 @@ void ALeffectslot::updateProps(ALCcontext *context)
}
}
+void ALeffectslot::SetName(ALCcontext* context, ALuint id, std::string_view name)
+{
+ std::lock_guard<std::mutex> _{context->mEffectSlotLock};
+
+ auto slot = LookupEffectSlot(context, id);
+ if(!slot) UNLIKELY
+ return context->setError(AL_INVALID_NAME, "Invalid effect slot ID %u", id);
+
+ context->mEffectSlotNames.insert_or_assign(id, name);
+}
+
void UpdateAllEffectSlotProps(ALCcontext *context)
{
std::lock_guard<std::mutex> _{context->mEffectSlotLock};
diff --git a/al/auxeffectslot.h b/al/auxeffectslot.h
index 3e9a2a4e..9038647c 100644
--- a/al/auxeffectslot.h
+++ b/al/auxeffectslot.h
@@ -3,6 +3,7 @@
#include <atomic>
#include <cstddef>
+#include <string_view>
#include "AL/al.h"
#include "AL/alc.h"
@@ -76,6 +77,8 @@ struct ALeffectslot {
ALenum initEffect(ALenum effectType, const EffectProps &effectProps, ALCcontext *context);
void updateProps(ALCcontext *context);
+ static void SetName(ALCcontext *context, ALuint id, std::string_view name);
+
/* This can be new'd for the context's default effect slot. */
DEF_NEWDEL(ALeffectslot)
diff --git a/al/buffer.cpp b/al/buffer.cpp
index 58e8f375..e56aa13e 100644
--- a/al/buffer.cpp
+++ b/al/buffer.cpp
@@ -222,6 +222,8 @@ void FreeBuffer(ALCdevice *device, ALbuffer *buffer)
eax_x_ram_clear(*device, *buffer);
#endif // ALSOFT_EAX
+ device->mBufferNames.erase(buffer->id);
+
const ALuint id{buffer->id - 1};
const size_t lidx{id >> 6};
const ALuint slidx{id & 0x3f};
@@ -1440,6 +1442,19 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum /*format*/) no
}
+void ALbuffer::SetName(ALCcontext *context, ALuint id, std::string_view name)
+{
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard<std::mutex> _{device->BufferLock};
+
+ auto buffer = LookupBuffer(device, id);
+ if(!buffer) UNLIKELY
+ return context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", id);
+
+ device->mBufferNames.insert_or_assign(id, name);
+}
+
+
BufferSubList::~BufferSubList()
{
if(!Buffers)
diff --git a/al/buffer.h b/al/buffer.h
index 3df1fa4c..f936cf98 100644
--- a/al/buffer.h
+++ b/al/buffer.h
@@ -3,6 +3,7 @@
#include <atomic>
#include <cstddef>
+#include <string_view>
#include "AL/al.h"
@@ -47,6 +48,8 @@ struct ALbuffer : public BufferStorage {
/* Self ID */
ALuint id{0};
+ static void SetName(ALCcontext *context, ALuint id, std::string_view name);
+
DISABLE_ALLOC()
#ifdef ALSOFT_EAX
diff --git a/al/debug.cpp b/al/debug.cpp
index 2d8819f3..62e88914 100644
--- a/al/debug.cpp
+++ b/al/debug.cpp
@@ -17,9 +17,14 @@
#include "alc/context.h"
#include "alc/inprogext.h"
#include "alspan.h"
+#include "auxeffectslot.h"
+#include "buffer.h"
#include "core/logging.h"
#include "direct_defs.h"
+#include "effect.h"
+#include "filter.h"
#include "opthelpers.h"
+#include "source.h"
namespace {
@@ -242,13 +247,8 @@ FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertDirectEXT(ALCcontext *context,
if(!message) UNLIKELY
return context->setError(AL_INVALID_VALUE, "Null message pointer");
- if(length >= MaxDebugMessageLength) UNLIKELY
- return context->setError(AL_INVALID_VALUE, "Debug message too long (%d >= %d)", length,
- MaxDebugMessageLength);
-
auto msgview = (length < 0) ? std::string_view{message}
: std::string_view{message, static_cast<uint>(length)};
-
if(msgview.length() >= MaxDebugMessageLength) UNLIKELY
return context->setError(AL_INVALID_VALUE, "Debug message too long (%zu >= %d)",
msgview.length(), MaxDebugMessageLength);
@@ -472,3 +472,94 @@ FORCE_ALIGN ALuint AL_APIENTRY alGetDebugMessageLogDirectEXT(ALCcontext *context
return count;
}
+
+FORCE_ALIGN DECL_FUNCEXT4(void, alObjectLabel,EXT, ALenum, ALuint, ALsizei, const ALchar*)
+FORCE_ALIGN void AL_APIENTRY alObjectLabelDirectEXT(ALCcontext *context, ALenum identifier,
+ ALuint name, ALsizei length, const ALchar *label) noexcept
+{
+ if(!label && length != 0) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Null label pointer");
+
+ auto objname = (length < 0) ? std::string_view{label}
+ : std::string_view{label, static_cast<uint>(length)};
+ if(objname.length() >= MaxObjectLabelLength) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Object label length too long (%zu >= %d)",
+ objname.length(), MaxObjectLabelLength);
+
+ if(identifier == AL_SOURCE_EXT)
+ return ALsource::SetName(context, name, objname);
+ if(identifier == AL_BUFFER)
+ return ALbuffer::SetName(context, name, objname);
+ if(identifier == AL_FILTER_EXT)
+ return ALfilter::SetName(context, name, objname);
+ if(identifier == AL_EFFECT_EXT)
+ return ALeffect::SetName(context, name, objname);
+ if(identifier == AL_AUXILIARY_EFFECT_SLOT_EXT)
+ return ALeffectslot::SetName(context, name, objname);
+
+ return context->setError(AL_INVALID_ENUM, "Invalid name identifier 0x%04x", identifier);
+}
+
+FORCE_ALIGN DECL_FUNCEXT5(void, alGetObjectLabel,EXT, ALenum, ALuint, ALsizei, ALsizei*, ALchar*)
+FORCE_ALIGN void AL_APIENTRY alGetObjectLabelDirectEXT(ALCcontext *context, ALenum identifier,
+ ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) noexcept
+{
+ if(bufSize < 0) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Negative label bufSize");
+
+ if(!label && !length) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Null length and label");
+ if(label && bufSize == 0) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Zero label bufSize");
+
+ auto copy_name = [name,bufSize,length,label](std::unordered_map<ALuint,std::string> &names)
+ {
+ std::string_view objname;
+
+ auto iter = names.find(name);
+ if(iter != names.end())
+ objname = iter->second;
+
+ if(!label)
+ *length = static_cast<ALsizei>(objname.length());
+ else
+ {
+ const size_t tocopy{minz(objname.length(), static_cast<uint>(bufSize)-1)};
+ std::memcpy(label, objname.data(), tocopy);
+ label[tocopy] = '\0';
+ if(length)
+ *length = static_cast<ALsizei>(tocopy);
+ }
+ };
+
+ if(identifier == AL_SOURCE_EXT)
+ {
+ std::lock_guard _{context->mSourceLock};
+ copy_name(context->mSourceNames);
+ }
+ else if(identifier == AL_BUFFER)
+ {
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard _{device->BufferLock};
+ copy_name(device->mBufferNames);
+ }
+ else if(identifier == AL_FILTER_EXT)
+ {
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard _{device->FilterLock};
+ copy_name(device->mFilterNames);
+ }
+ else if(identifier == AL_EFFECT_EXT)
+ {
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard _{device->EffectLock};
+ copy_name(device->mEffectNames);
+ }
+ else if(identifier == AL_AUXILIARY_EFFECT_SLOT_EXT)
+ {
+ std::lock_guard _{context->mEffectSlotLock};
+ copy_name(context->mEffectSlotNames);
+ }
+ else
+ context->setError(AL_INVALID_ENUM, "Invalid name identifier 0x%04x", identifier);
+}
diff --git a/al/debug.h b/al/debug.h
index 0c53f0ae..2764bb7f 100644
--- a/al/debug.h
+++ b/al/debug.h
@@ -14,6 +14,7 @@ using uint = unsigned int;
inline constexpr uint8_t MaxDebugLoggedMessages{64};
inline constexpr uint16_t MaxDebugMessageLength{1024};
inline constexpr uint8_t MaxDebugGroupDepth{64};
+inline constexpr uint16_t MaxObjectLabelLength{1024};
inline constexpr uint DebugSourceBase{0};
diff --git a/al/effect.cpp b/al/effect.cpp
index 81cbb4c6..5c7f9627 100644
--- a/al/effect.cpp
+++ b/al/effect.cpp
@@ -207,6 +207,8 @@ ALeffect *AllocEffect(ALCdevice *device)
void FreeEffect(ALCdevice *device, ALeffect *effect)
{
+ device->mEffectNames.erase(effect->id);
+
const ALuint id{effect->id - 1};
const size_t lidx{id >> 6};
const ALuint slidx{id & 0x3f};
@@ -511,6 +513,19 @@ void InitEffect(ALeffect *effect)
InitEffectParams(effect, AL_EFFECT_NULL);
}
+void ALeffect::SetName(ALCcontext* context, ALuint id, std::string_view name)
+{
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard<std::mutex> _{device->EffectLock};
+
+ auto effect = LookupEffect(device, id);
+ if(!effect) UNLIKELY
+ return context->setError(AL_INVALID_NAME, "Invalid effect ID %u", id);
+
+ device->mEffectNames.insert_or_assign(id, name);
+}
+
+
EffectSubList::~EffectSubList()
{
if(!Effects)
diff --git a/al/effect.h b/al/effect.h
index a1d43313..3d05e692 100644
--- a/al/effect.h
+++ b/al/effect.h
@@ -50,6 +50,8 @@ struct ALeffect {
/* Self ID */
ALuint id{0u};
+ static void SetName(ALCcontext *context, ALuint id, std::string_view name);
+
DISABLE_ALLOC()
};
diff --git a/al/filter.cpp b/al/filter.cpp
index 9ad57b54..e6520e6a 100644
--- a/al/filter.cpp
+++ b/al/filter.cpp
@@ -163,6 +163,8 @@ ALfilter *AllocFilter(ALCdevice *device)
void FreeFilter(ALCdevice *device, ALfilter *filter)
{
+ device->mFilterNames.erase(filter->id);
+
const ALuint id{filter->id - 1};
const size_t lidx{id >> 6};
const ALuint slidx{id & 0x3f};
@@ -671,6 +673,19 @@ FORCE_ALIGN void AL_APIENTRY alGetFilterfvDirect(ALCcontext *context, ALuint fil
}
+void ALfilter::SetName(ALCcontext *context, ALuint id, std::string_view name)
+{
+ ALCdevice *device{context->mALDevice.get()};
+ std::lock_guard<std::mutex> _{device->FilterLock};
+
+ auto filter = LookupFilter(device, id);
+ if(!filter) UNLIKELY
+ return context->setError(AL_INVALID_NAME, "Invalid filter ID %u", id);
+
+ device->mFilterNames.insert_or_assign(id, name);
+}
+
+
FilterSubList::~FilterSubList()
{
if(!Filters)
diff --git a/al/filter.h b/al/filter.h
index 2ed483cc..24ebc203 100644
--- a/al/filter.h
+++ b/al/filter.h
@@ -48,6 +48,8 @@ struct ALfilter {
/* Self ID */
ALuint id{0};
+ static void SetName(ALCcontext *context, ALuint id, std::string_view name);
+
DISABLE_ALLOC()
};
diff --git a/al/source.cpp b/al/source.cpp
index 70182ec8..6bcb7318 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -764,6 +764,8 @@ ALsource *AllocSource(ALCcontext *context)
void FreeSource(ALCcontext *context, ALsource *source)
{
+ context->mSourceNames.erase(source->id);
+
const ALuint id{source->id - 1};
const size_t lidx{id >> 6};
const ALuint slidx{id & 0x3f};
@@ -3614,6 +3616,18 @@ void UpdateAllSourceProps(ALCcontext *context)
}
}
+void ALsource::SetName(ALCcontext *context, ALuint id, std::string_view name)
+{
+ std::lock_guard<std::mutex> _{context->mSourceLock};
+
+ auto source = LookupSource(context, id);
+ if(!source) UNLIKELY
+ return context->setError(AL_INVALID_NAME, "Invalid source ID %u", id);
+
+ context->mSourceNames.insert_or_assign(id, name);
+}
+
+
SourceSubList::~SourceSubList()
{
if(!Sources)
diff --git a/al/source.h b/al/source.h
index ac97c8a7..2bdeb2a3 100644
--- a/al/source.h
+++ b/al/source.h
@@ -4,9 +4,10 @@
#include <array>
#include <atomic>
#include <cstddef>
+#include <deque>
#include <iterator>
#include <limits>
-#include <deque>
+#include <string_view>
#include "AL/al.h"
#include "AL/alc.h"
@@ -157,6 +158,8 @@ struct ALsource {
ALsource(const ALsource&) = delete;
ALsource& operator=(const ALsource&) = delete;
+ static void SetName(ALCcontext *context, ALuint id, std::string_view name);
+
DISABLE_ALLOC()
#ifdef ALSOFT_EAX
diff --git a/al/state.cpp b/al/state.cpp
index 5b0772c7..1c41d63c 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -152,6 +152,7 @@ enum PropertyValue : ALenum {
MaxDebugMessageLength = AL_MAX_DEBUG_MESSAGE_LENGTH_EXT,
MaxDebugLoggedMessages = AL_MAX_DEBUG_LOGGED_MESSAGES_EXT,
MaxDebugGroupDepth = AL_MAX_DEBUG_GROUP_STACK_DEPTH_EXT,
+ MaxLabelLength = AL_MAX_LABEL_LENGTH_EXT,
ContextFlags = AL_CONTEXT_FLAGS_EXT,
#ifdef ALSOFT_EAX
EaxRamSize = AL_EAX_RAM_SIZE,
@@ -245,6 +246,10 @@ void GetValue(ALCcontext *context, ALenum pname, T *values)
*values = cast_value(MaxDebugGroupDepth);
return;
+ case AL_MAX_LABEL_LENGTH_EXT:
+ *values = cast_value(MaxObjectLabelLength);
+ return;
+
case AL_CONTEXT_FLAGS_EXT:
*values = cast_value(context->mContextFlags.to_ulong());
return;