aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-01-18 18:53:58 -0800
committerChris Robinson <[email protected]>2020-01-18 18:53:58 -0800
commit3904289af7d4693a04c02d8739118182de56df96 (patch)
tree6351ed0eb2f8931c003ea103ebcba9ce4b69cff2
parent8a9eef70afea462c552f69c7564aa58bb0d4f6a5 (diff)
Only sort active effect slots as needed
-rw-r--r--al/auxeffectslot.cpp4
-rw-r--r--alc/alc.cpp8
-rw-r--r--alc/alu.cpp24
3 files changed, 29 insertions, 7 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 3c312c66..efc75aac 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -114,11 +114,13 @@ void AddActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *conte
delete curarray;
curarray = nullptr;
}
+ std::uninitialized_fill_n(newarray->end(), newcount, nullptr);
curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
ALCdevice *device{context->mDevice.get()};
while((device->MixCount.load(std::memory_order_acquire)&1))
std::this_thread::yield();
+ al::destroy_n(curarray->end(), curarray->size());
delete curarray;
}
@@ -150,11 +152,13 @@ void RemoveActiveEffectSlots(const ALuint *slotids, size_t count, ALCcontext *co
delete curarray;
curarray = nullptr;
}
+ std::uninitialized_fill_n(newarray->end(), newsize, nullptr);
curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
ALCdevice *device{context->mDevice.get()};
while((device->MixCount.load(std::memory_order_acquire)&1))
std::this_thread::yield();
+ al::destroy_n(curarray->end(), curarray->size());
delete curarray;
}
diff --git a/alc/alc.cpp b/alc/alc.cpp
index b077e796..f716bf0b 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -2169,6 +2169,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
std::unique_lock<std::mutex> proplock{context->mPropLock};
std::unique_lock<std::mutex> slotlock{context->mEffectSlotLock};
+ if(ALeffectslotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)})
+ std::fill_n(curarray->end(), curarray->size(), nullptr);
for(auto &sublist : context->mEffectSlotList)
{
uint64_t usemask = ~sublist.FreeMask;
@@ -2461,7 +2463,11 @@ ALCcontext::~ALCcontext()
}
TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
- delete mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed);
+ if(ALeffectslotArray *curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)})
+ {
+ al::destroy_n(curarray->end(), curarray->size());
+ delete curarray;
+ }
mDefaultSlot = nullptr;
count = std::accumulate(mEffectSlotList.cbegin(), mEffectSlotList.cend(), size_t{0u},
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 02d5e66f..b337286b 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -437,11 +437,16 @@ bool CalcListenerParams(ALCcontext *Context)
return true;
}
-bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
+bool CalcEffectSlotParams(ALeffectslot *slot, ALeffectslot **sorted_slots, ALCcontext *context)
{
ALeffectslotProps *props{slot->Params.Update.exchange(nullptr, std::memory_order_acq_rel)};
if(!props) return false;
+ /* If the effect slot target changed, clear the first sorted entry to force
+ * a re-sort.
+ */
+ if(slot->Params.Target != props->Target)
+ *sorted_slots = nullptr;
slot->Params.Gain = props->Gain;
slot->Params.AuxSendAuto = props->AuxSendAuto;
slot->Params.Target = props->Target;
@@ -1599,9 +1604,9 @@ void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray &slots,
{
bool force{CalcContextParams(ctx)};
force |= CalcListenerParams(ctx);
- force = std::accumulate(slots.begin(), slots.end(), force,
- [ctx](const bool f, ALeffectslot *slot) -> bool
- { return CalcEffectSlotParams(slot, ctx) | f; });
+ auto sorted_slots = const_cast<ALeffectslot**>(slots.data() + slots.size());
+ for(ALeffectslot *slot : slots)
+ force |= CalcEffectSlotParams(slot, sorted_slots, ctx);
auto calc_params = [ctx,force](ALvoice &voice) -> void
{ CalcSourceParams(&voice, ctx, force); };
@@ -1642,11 +1647,17 @@ void ProcessContext(ALCcontext *ctx, const ALuint SamplesToDo)
auto slots = auxslots.data();
auto slots_end = slots + num_slots;
- /* First sort the slots into scratch storage, so that effects come
- * before their effect target (or their targets' target).
+ /* First sort the slots into extra storage, so that effects come before
+ * their effect target (or their targets' target).
*/
auto sorted_slots = const_cast<ALeffectslot**>(slots_end);
auto sorted_slots_end = sorted_slots;
+ if(*sorted_slots)
+ {
+ /* Skip sorting if it has already been done. */
+ sorted_slots_end += num_slots;
+ goto skip_sorting;
+ }
*sorted_slots_end = *slots;
++sorted_slots_end;
@@ -1674,6 +1685,7 @@ void ProcessContext(ALCcontext *ctx, const ALuint SamplesToDo)
++sorted_slots_end;
}
+ skip_sorting:
auto process_effect = [SamplesToDo](const ALeffectslot *slot) -> void
{
EffectState *state{slot->Params.mEffectState};