aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-01-11 07:28:44 -0800
committerChris Robinson <[email protected]>2019-01-11 07:28:44 -0800
commit81e7222633fefd29890e8f1e18af86c4985604f4 (patch)
tree33271bf0aae1c7acfac1cadb5139e8f87a976fd6 /OpenAL32
parent8aedaea5fb92d9cfed0a3e1f959f903fca713ec3 (diff)
Use a flexible array for the active effect slots
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h4
-rw-r--r--OpenAL32/alAuxEffectSlot.cpp38
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()};