Avoid updating the effect state object if it's not changed
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
+21
-13
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user