diff options
author | Chris Robinson <[email protected]> | 2019-01-11 07:28:44 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-01-11 07:28:44 -0800 |
commit | 81e7222633fefd29890e8f1e18af86c4985604f4 (patch) | |
tree | 33271bf0aae1c7acfac1cadb5139e8f87a976fd6 /OpenAL32 | |
parent | 8aedaea5fb92d9cfed0a3e1f959f903fca713ec3 (diff) |
Use a flexible array for the active effect slots
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 4 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.cpp | 38 |
2 files changed, 28 insertions, 14 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index cf4cd5d0..e761280a 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -44,7 +44,7 @@ struct EffectStateFactory { #define MAX_EFFECT_CHANNELS (4) -using ALeffectslotArray = al::vector<ALeffectslot*>; +using ALeffectslotArray = al::FlexArray<ALeffectslot*>; struct ALeffectslotProps { @@ -118,6 +118,8 @@ struct ALeffectslot { ALeffectslot& operator=(const ALeffectslot&) = delete; ~ALeffectslot(); + static ALeffectslotArray *CreatePtrArray(size_t count) noexcept; + DEF_NEWDEL(ALeffectslot) }; diff --git a/OpenAL32/alAuxEffectSlot.cpp b/OpenAL32/alAuxEffectSlot.cpp index dd50dae9..47fff9d1 100644 --- a/OpenAL32/alAuxEffectSlot.cpp +++ b/OpenAL32/alAuxEffectSlot.cpp @@ -71,12 +71,9 @@ void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *cont size_t newcount{curarray->size() + count}; /* Insert the new effect slots into the head of the array, followed by the - * existing ones. Allocate twice as much space for effect slots so the - * mixer has a place to sort them. + * existing ones. */ - auto newarray = new ALeffectslotArray{}; - newarray->reserve(newcount * 2); - newarray->resize(newcount); + ALeffectslotArray *newarray = ALeffectslot::CreatePtrArray(newcount); auto slotiter = std::transform(slotids, slotids+count, newarray->begin(), [context](ALuint id) noexcept -> ALeffectslot* { return LookupEffectSlot(context, id); } @@ -99,9 +96,7 @@ void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *cont if(UNLIKELY(newcount < newarray->size())) { curarray = newarray; - newarray = new ALeffectslotArray{}; - newarray->reserve(newcount * 2); - newarray->resize(newcount); + newarray = ALeffectslot::CreatePtrArray(newcount); std::copy_n(curarray->begin(), newcount, newarray->begin()); delete curarray; curarray = nullptr; @@ -122,9 +117,7 @@ void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *c /* Don't shrink the allocated array size since we don't know how many (if * any) of the effect slots to remove are in the array. */ - auto newarray = new ALeffectslotArray{}; - newarray->reserve(curarray->size() * 2); - newarray->resize(curarray->size()); + ALeffectslotArray *newarray = ALeffectslot::CreatePtrArray(curarray->size()); /* Copy each element in curarray to newarray whose ID is not in slotids. */ const ALuint *slotids_end{slotids + count}; @@ -132,9 +125,18 @@ void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *c [slotids, slotids_end](const ALeffectslot *slot) -> bool { return std::find(slotids, slotids_end, slot->id) == slotids_end; } ); - newarray->resize(std::distance(newarray->begin(), slotiter)); - /* TODO: Could reallocate newarray now that we know it's needed size. */ + /* Reallocate with the new size. */ + auto newsize = static_cast<size_t>(std::distance(newarray->begin(), slotiter)); + if(LIKELY(newsize != newarray->size())) + { + curarray = newarray; + newarray = ALeffectslot::CreatePtrArray(newsize); + std::copy_n(curarray->begin(), newsize, newarray->begin()); + + delete curarray; + curarray = nullptr; + } curarray = context->ActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel); ALCdevice *device{context->Device}; @@ -183,6 +185,16 @@ inline EffectStateFactory *getFactoryByType(ALenum type) } // namespace +ALeffectslotArray *ALeffectslot::CreatePtrArray(size_t count) noexcept +{ + /* Allocate space for twice as many pointers, so the mixer has scratch + * space to store a sorted list during mixing. + */ + void *ptr{al_calloc(DEF_ALIGN, ALeffectslotArray::CalcSizeof(count*2))}; + return new (ptr) ALeffectslotArray{count}; +} + + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ContextRef context{GetContextRef()}; |