diff options
author | Chris Robinson <[email protected]> | 2019-02-20 22:00:26 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-02-20 22:00:26 -0800 |
commit | 3966665ca34ff4641df54b046a181f3a3d4991f6 (patch) | |
tree | 8fdcddecad69d64dd424b2b62892cc4c1c2bd359 /Alc/alc.cpp | |
parent | c43381d811f436187b99c51951365c33fc735dc5 (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.cpp | 37 |
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 |