From 210e150601d9b458d446483f5f16e1e67cc6e3ba Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 12 May 2016 19:05:06 -0700 Subject: [PATCH] Avoid updating the effect state object if it's not changed --- Alc/ALc.c | 24 ++++++++++++------------ Alc/ALu.c | 15 +++++++-------- OpenAL32/Include/alAuxEffectSlot.h | 4 +++- OpenAL32/alAuxEffectSlot.c | 34 +++++++++++++++++++++------------- 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index b3d7eb38..47aa0f04 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2066,7 +2066,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); } context = ATOMIC_LOAD(&device->ContextList); @@ -2078,17 +2078,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) for(pos = 0;pos < context->EffectSlotMap.size;pos++) { ALeffectslot *slot = context->EffectSlotMap.array[pos].value; + ALeffectState *state = slot->Params.EffectState; - slot->Params.EffectState->OutBuffer = device->Dry.Buffer; - slot->Params.EffectState->OutChannels = device->Dry.NumChannels; - if(V(slot->Params.EffectState,deviceUpdate)(device) == AL_FALSE) + state->OutBuffer = device->Dry.Buffer; + state->OutChannels = device->Dry.NumChannels; + if(V(state,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -3487,16 +3488,15 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->DefaultSlot = NULL; ERR("Failed to initialize the default effect slot\n"); } - else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) - { - DeinitEffectSlot(device->DefaultSlot); - device->DefaultSlot = NULL; - ERR("Failed to initialize the default effect\n"); - } else { aluInitEffectPanning(device->DefaultSlot); - UpdateEffectSlotProps(device->DefaultSlot); + if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) + { + DeinitEffectSlot(device->DefaultSlot); + device->DefaultSlot = NULL; + ERR("Failed to initialize the default effect\n"); + } } } diff --git a/Alc/ALu.c b/Alc/ALu.c index 3b873aa5..a555b834 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -342,14 +342,6 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); slot->Params.EffectType = ATOMIC_LOAD(&props->Type, almemory_order_relaxed); memcpy(&slot->Params.EffectProps, &props->Props, sizeof(props->Props)); - /* If the existing state object is different from the one being set, - * exchange it so it remains in the freelist and isn't leaked. - */ - if(slot->Params.EffectState == ATOMIC_LOAD(&props->State, almemory_order_relaxed)) - slot->Params.EffectState = NULL; - slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, - &props->State, slot->Params.EffectState, almemory_order_relaxed - ); if(IsReverbEffect(slot->Params.EffectType)) { slot->Params.RoomRolloff = slot->Params.EffectProps.Reverb.RoomRolloffFactor; @@ -362,6 +354,13 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; } + /* If the state object is changed, exchange it with the current one so it + * remains in the freelist and isn't leaked. + */ + if(ATOMIC_LOAD(&props->UpdateState, almemory_order_relaxed)) + slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, + &props->State, slot->Params.EffectState, almemory_order_relaxed + ); V(slot->Params.EffectState,update)(device, slot); diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 7f670a95..85827746 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -79,6 +79,8 @@ struct ALeffectslotProps { ATOMIC(ALenum) Type; ALeffectProps Props; + /* Flag indicates if State should be updated. */ + ATOMIC(ALboolean) UpdateState; ATOMIC(ALeffectState*) State; ATOMIC(struct ALeffectslotProps*) next; @@ -139,7 +141,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); -void UpdateEffectSlotProps(ALeffectslot *slot); +void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 1407e1b1..368a0fb1 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -195,12 +195,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, AL_FALSE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); done: WriteUnlock(&context->PropLock); @@ -256,7 +256,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); done: WriteUnlock(&context->PropLock); @@ -482,18 +482,24 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); - EffectSlot->Effect.State = State; - } + if(!effect) + { + EffectSlot->Effect.Type = AL_EFFECT_NULL; + memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); + } + else + { + EffectSlot->Effect.Type = effect->type; + memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + } - if(!effect) - { - EffectSlot->Effect.Type = AL_EFFECT_NULL; - memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); + EffectSlot->Effect.State = State; + UpdateEffectSlotProps(EffectSlot, AL_TRUE); } - else + else if(effect) { - EffectSlot->Effect.Type = effect->type; memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + UpdateEffectSlotProps(EffectSlot, AL_FALSE); } return AL_NO_ERROR; @@ -559,7 +565,7 @@ void DeinitEffectSlot(ALeffectslot *slot) DELETE_OBJ(slot->Params.EffectState); } -void UpdateEffectSlotProps(ALeffectslot *slot) +void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate) { struct ALeffectslotProps *props; ALeffectState *oldstate; @@ -587,8 +593,10 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, - almemory_order_relaxed); + ATOMIC_STORE(&props->UpdateState, withstate, almemory_order_relaxed); + oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, + withstate ? slot->Effect.State : NULL, almemory_order_relaxed + ); /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, -- 2.11.4.GIT