aboutsummaryrefslogtreecommitdiffstats
path: root/alc/alu.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-01-14 10:38:24 -0800
committerChris Robinson <[email protected]>2020-01-14 10:39:41 -0800
commit5324bdb9080db1acdd45e84d191542501675a302 (patch)
tree97c94bdcd85f278f3b21ddd84c36d4cd9661afc4 /alc/alu.cpp
parent400c768e2fa5ea7ce72f2c4235f2363012153ac9 (diff)
Signal the event handler only once per update
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r--alc/alu.cpp74
1 files changed, 40 insertions, 34 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 25e36973..e5899794 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -484,7 +484,6 @@ bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
AsyncEvent *evt{new (evt_vec.first.buf) AsyncEvent{EventType_ReleaseEffectState}};
evt->u.mEffectState = oldstate;
ring->writeAdvance(1);
- context->mEventSem.post();
}
else
{
@@ -1638,48 +1637,55 @@ void ProcessContext(ALCcontext *ctx, const ALuint SamplesToDo)
std::for_each(voices.begin(), voices.end(), mix_voice);
/* Process effects. */
- if(auxslots.empty()) return;
- auto slots = auxslots.data();
- auto slots_end = slots + auxslots.size();
-
- /* First sort the slots into scratch 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;
-
- *sorted_slots_end = *slots;
- ++sorted_slots_end;
- while(++slots != slots_end)
+ if(const size_t num_slots{auxslots.size()})
{
- auto in_chain = [](const ALeffectslot *slot1, const ALeffectslot *slot2) noexcept -> bool
- {
- while((slot1=slot1->Params.Target) != nullptr) {
- if(slot1 == slot2) return true;
- }
- return false;
- };
+ auto slots = auxslots.data();
+ auto slots_end = slots + num_slots;
- /* If this effect slot targets an effect slot already in the list (i.e.
- * slots outputs to something in sorted_slots), directly or indirectly,
- * insert it prior to that element.
+ /* First sort the slots into scratch storage, so that effects come
+ * before their effect target (or their targets' target).
*/
- auto checker = sorted_slots;
- do {
- if(in_chain(*slots, *checker)) break;
- } while(++checker != sorted_slots_end);
+ auto sorted_slots = const_cast<ALeffectslot**>(slots_end);
+ auto sorted_slots_end = sorted_slots;
- checker = std::move_backward(checker, sorted_slots_end, sorted_slots_end+1);
- *--checker = *slots;
+ *sorted_slots_end = *slots;
++sorted_slots_end;
- }
+ while(++slots != slots_end)
+ {
+ auto in_chain = [](const ALeffectslot *s1, const ALeffectslot *s2) noexcept -> bool
+ {
+ while((s1=s1->Params.Target) != nullptr) {
+ if(s1 == s2) return true;
+ }
+ return false;
+ };
+
+ /* If this effect slot targets an effect slot already in the list
+ * (i.e. slots outputs to something in sorted_slots), directly or
+ * indirectly, insert it prior to that element.
+ */
+ auto checker = sorted_slots;
+ do {
+ if(in_chain(*slots, *checker)) break;
+ } while(++checker != sorted_slots_end);
+
+ checker = std::move_backward(checker, sorted_slots_end, sorted_slots_end+1);
+ *--checker = *slots;
+ ++sorted_slots_end;
+ }
- std::for_each(sorted_slots, sorted_slots_end,
- [SamplesToDo](const ALeffectslot *slot) -> void
+ auto process_effect = [SamplesToDo](const ALeffectslot *slot) -> void
{
EffectState *state{slot->Params.mEffectState};
state->process(SamplesToDo, slot->Wet.Buffer, state->mOutTarget);
- });
+ };
+ std::for_each(sorted_slots, sorted_slots_end, process_effect);
+ }
+
+ /* Signal the event handler if there are any events to read. */
+ RingBuffer *ring{ctx->mAsyncEvents.get()};
+ if(ring->readSpace() > 0)
+ ctx->mEventSem.post();
}