From 3966665ca34ff4641df54b046a181f3a3d4991f6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 20 Feb 2019 22:00:26 -0800 Subject: Store effect slots in groups of 64 Now that their wet buffers are allocated dynamically, the ALeffectslot object itself is rather small. --- Alc/alc.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'Alc/alc.cpp') 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 proplock{context->PropLock}; std::unique_lock 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(); + void *ptr{al_calloc(16, sizeof(ALeffectslot))}; + ALContext->DefaultSlot = std::unique_ptr{new (ptr) ALeffectslot{}}; if(InitEffectSlot(ALContext->DefaultSlot.get()) == AL_NO_ERROR) aluInitEffectPanning(ALContext->DefaultSlot.get()); else -- cgit v1.2.3