diff options
-rw-r--r-- | Alc/alc.cpp | 10 | ||||
-rw-r--r-- | Alc/alcontext.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 4 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.cpp | 38 |
4 files changed, 32 insertions, 22 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index ca13e911..cea1fb61 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2325,15 +2325,11 @@ static ALvoid InitContext(ALCcontext *Context) //Validate Context if(!Context->DefaultSlot) - auxslots = new ALeffectslotArray{}; + auxslots = ALeffectslot::CreatePtrArray(0); else { - /* Allocate twice as much space for effect slots so the mixer has a - * place to sort them. - */ - auxslots = new ALeffectslotArray{}; - auxslots->reserve(2); - auxslots->push_back(Context->DefaultSlot.get()); + auxslots = ALeffectslot::CreatePtrArray(1); + (*auxslots)[0] = Context->DefaultSlot.get(); } Context->ActiveAuxSlots.store(auxslots, std::memory_order_relaxed); diff --git a/Alc/alcontext.h b/Alc/alcontext.h index dc9ada55..472d06ae 100644 --- a/Alc/alcontext.h +++ b/Alc/alcontext.h @@ -107,7 +107,7 @@ struct ALCcontext { std::atomic<ALsizei> VoiceCount{0}; ALsizei MaxVoices{0}; - using ALeffectslotArray = al::vector<ALeffectslot*>; + using ALeffectslotArray = al::FlexArray<ALeffectslot*>; std::atomic<ALeffectslotArray*> ActiveAuxSlots{nullptr}; std::thread EventThread; 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()}; |