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 | |
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')
-rw-r--r-- | Alc/alc.cpp | 37 | ||||
-rw-r--r-- | Alc/alcontext.h | 22 |
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}; |