diff options
author | Chris Robinson <[email protected]> | 2016-08-25 06:17:36 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-08-25 06:17:36 -0700 |
commit | a16739f7651afb7653387b1e79b2985058d76e90 (patch) | |
tree | 0e0071564da36bb70293f36541a295682e13868f | |
parent | 4e4e597fa54cc3498ae28bea9c2684e1fee05389 (diff) |
Properly defer effect slot changes
Note that this now also causes all playing sources to update when an effect
slot is updated. This is a bit wasteful, as it should only need to re-update
sources that are using the effect slot (and only when a relevant property is
changed), but it's good enough. Especially with deferring since all playing
sources are going to get updated on the process call anyway.
-rw-r--r-- | Alc/ALc.c | 1 | ||||
-rw-r--r-- | Alc/ALu.c | 8 | ||||
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 3 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 39 |
4 files changed, 37 insertions, 14 deletions
@@ -1611,6 +1611,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) althrd_yield(); UpdateListenerProps(context); + UpdateAllEffectSlotProps(context); LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); @@ -295,14 +295,14 @@ static ALboolean CalcListenerParams(ALCcontext *Context) return AL_TRUE; } -static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) +static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { struct ALeffectslotProps *first; struct ALeffectslotProps *props; ALeffectState *state; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); - if(!props) return; + if(!props) return AL_FALSE; slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); @@ -339,6 +339,8 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); + + return AL_TRUE; } @@ -1339,7 +1341,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) ALboolean force = CalcListenerParams(ctx); while(slot) { - CalcEffectSlotParams(slot, ctx->Device); + force |= CalcEffectSlotParams(slot, ctx->Device); slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 363d2467..70fcac5c 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -88,6 +88,8 @@ struct ALeffectslotProps { typedef struct ALeffectslot { + ALboolean NeedsUpdate; + ALfloat Gain; ALboolean AuxSendAuto; @@ -152,6 +154,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); void UpdateEffectSlotProps(ALeffectslot *slot); +void UpdateAllEffectSlotProps(ALCcontext *context); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 85be5c6d..fb8c27f4 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -56,6 +56,13 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) static void ALeffectState_IncRef(ALeffectState *state); static void ALeffectState_DecRef(ALeffectState *state); +#define DO_UPDATEPROPS() do { \ + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ + UpdateEffectSlotProps(slot); \ + else \ + slot->NeedsUpdate = AL_TRUE; \ +} while(0) + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { @@ -212,14 +219,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; - UpdateEffectSlotProps(slot); - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + DO_UPDATEPROPS(); done: UnlockEffectSlotsRead(context); @@ -279,7 +284,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); + DO_UPDATEPROPS(); done: UnlockEffectSlotsRead(context); @@ -517,13 +522,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALeffectState_DecRef(EffectSlot->Effect.State); EffectSlot->Effect.State = State; - UpdateEffectSlotProps(EffectSlot); } else if(effect) - { EffectSlot->Effect.Props = effect->Props; - UpdateEffectSlotProps(EffectSlot); - } /* Remove state references from old effect slot property updates. */ props = ATOMIC_LOAD(&EffectSlot->FreeList); @@ -531,7 +532,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e { State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); if(State) ALeffectState_DecRef(State); - ATOMIC_LOAD(&props->next, almemory_order_relaxed); + props = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } return AL_NO_ERROR; @@ -577,6 +578,7 @@ ALenum InitEffectSlot(ALeffectslot *slot) if(!(slot->Effect.State=V0(factory,create)())) return AL_OUT_OF_MEMORY; + slot->NeedsUpdate = AL_FALSE; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; InitRef(&slot->ref, 0); @@ -661,8 +663,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - if(slot->Effect.State) - ALeffectState_IncRef(slot->Effect.State); + ALeffectState_IncRef(slot->Effect.State); oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, almemory_order_relaxed); @@ -685,6 +686,22 @@ void UpdateEffectSlotProps(ALeffectslot *slot) ALeffectState_DecRef(oldstate); } +void UpdateAllEffectSlotProps(ALCcontext *context) +{ + ALeffectslot *slot; + + LockEffectSlotsRead(context); + slot = ATOMIC_LOAD(&context->ActiveAuxSlotList); + while(slot) + { + if(slot->NeedsUpdate) + UpdateEffectSlotProps(slot); + slot->NeedsUpdate = AL_FALSE; + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } + UnlockEffectSlotsRead(context); +} + ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; |