aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-02-20 22:00:26 -0800
committerChris Robinson <[email protected]>2019-02-20 22:00:26 -0800
commit3966665ca34ff4641df54b046a181f3a3d4991f6 (patch)
tree8fdcddecad69d64dd424b2b62892cc4c1c2bd359 /Alc
parentc43381d811f436187b99c51951365c33fc735dc5 (diff)
Store effect slots in groups of 64
Now that their wet buffers are allocated dynamically, the ALeffectslot object itself is rather small.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/alc.cpp37
-rw-r--r--Alc/alcontext.h22
2 files changed, 41 insertions, 18 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 55104f9e..99247753 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2081,18 +2081,26 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
std::unique_lock<std::mutex> proplock{context->PropLock};
std::unique_lock<std::mutex> slotlock{context->EffectSlotLock};
- for(auto &slot : context->EffectSlotList)
+ for(auto &sublist : context->EffectSlotList)
{
- if(!slot) continue;
- aluInitEffectPanning(slot.get());
+ uint64_t usemask = ~sublist.FreeMask;
+ while(usemask)
+ {
+ ALsizei idx = CTZ64(usemask);
+ ALeffectslot *slot = sublist.EffectSlots + idx;
- EffectState *state{slot->Effect.State};
- state->mOutBuffer = device->Dry.Buffer;
- state->mOutChannels = device->Dry.NumChannels;
- if(state->deviceUpdate(device) == AL_FALSE)
- update_failed = AL_TRUE;
- else
- UpdateEffectSlotProps(slot.get(), context);
+ usemask &= ~(1_u64 << idx);
+
+ aluInitEffectPanning(slot);
+
+ EffectState *state{slot->Effect.State};
+ state->mOutBuffer = device->Dry.Buffer;
+ state->mOutChannels = device->Dry.NumChannels;
+ if(state->deviceUpdate(device) == AL_FALSE)
+ update_failed = AL_TRUE;
+ else
+ UpdateEffectSlotProps(slot, context);
+ }
}
slotlock.unlock();
@@ -2415,12 +2423,14 @@ ALCcontext::~ALCcontext()
delete ActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed);
DefaultSlot = nullptr;
- count = std::count_if(EffectSlotList.cbegin(), EffectSlotList.cend(),
- [](const ALeffectslotPtr &slot) noexcept -> bool { return slot != nullptr; }
+ count = std::accumulate(EffectSlotList.cbegin(), EffectSlotList.cend(), size_t{0u},
+ [](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
+ { return cur + POPCNT64(~sublist.FreeMask); }
);
if(count > 0)
WARN(SZFMT " AuxiliaryEffectSlot%s not deleted\n", count, (count==1)?"":"s");
EffectSlotList.clear();
+ NumEffectSlots = 0;
count = 0;
ALvoiceProps *vprops{FreeVoiceProps.exchange(nullptr, std::memory_order_acquire)};
@@ -3440,7 +3450,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
if(DefaultEffect.type != AL_EFFECT_NULL && dev->Type == Playback)
{
- ALContext->DefaultSlot = al::make_unique<ALeffectslot>();
+ void *ptr{al_calloc(16, sizeof(ALeffectslot))};
+ ALContext->DefaultSlot = std::unique_ptr<ALeffectslot>{new (ptr) ALeffectslot{}};
if(InitEffectSlot(ALContext->DefaultSlot.get()) == AL_NO_ERROR)
aluInitEffectPanning(ALContext->DefaultSlot.get());
else
diff --git a/Alc/alcontext.h b/Alc/alcontext.h
index bdf5f2fe..2c4ad1d3 100644
--- a/Alc/alcontext.h
+++ b/Alc/alcontext.h
@@ -56,10 +56,21 @@ struct SourceSubList {
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Sources, rhs.Sources); return *this; }
};
-/* Effect slots are rather large, and apps aren't likely to have more than one
- * or two (let alone 64), so hold them individually.
- */
-using ALeffectslotPtr = std::unique_ptr<ALeffectslot>;
+struct EffectSlotSubList {
+ uint64_t FreeMask{~0_u64};
+ ALeffectslot *EffectSlots{nullptr}; /* 64 */
+
+ EffectSlotSubList() noexcept = default;
+ EffectSlotSubList(const EffectSlotSubList&) = delete;
+ EffectSlotSubList(EffectSlotSubList&& rhs) noexcept
+ : FreeMask{rhs.FreeMask}, EffectSlots{rhs.EffectSlots}
+ { rhs.FreeMask = ~0_u64; rhs.EffectSlots = nullptr; }
+ ~EffectSlotSubList();
+
+ EffectSlotSubList& operator=(const EffectSlotSubList&) = delete;
+ EffectSlotSubList& operator=(EffectSlotSubList&& rhs) noexcept
+ { std::swap(FreeMask, rhs.FreeMask); std::swap(EffectSlots, rhs.EffectSlots); return *this; }
+};
struct ALCcontext {
RefCount ref{1u};
@@ -68,7 +79,8 @@ struct ALCcontext {
ALuint NumSources{0};
std::mutex SourceLock;
- al::vector<ALeffectslotPtr> EffectSlotList;
+ al::vector<EffectSlotSubList> EffectSlotList;
+ ALuint NumEffectSlots{0u};
std::mutex EffectSlotLock;
std::atomic<ALenum> LastError{AL_NO_ERROR};