aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alc.cpp
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/alc.cpp
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/alc.cpp')
-rw-r--r--Alc/alc.cpp37
1 files changed, 24 insertions, 13 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