aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-05-15 01:19:05 -0700
committerChris Robinson <[email protected]>2016-05-15 01:19:05 -0700
commit576c1116a65bd66effce6d92d1aa7e21d1dee83a (patch)
tree5b7137d90d74e005c9a042ed2c1eef8b4858d7b8
parentb3338d25f6d4fd02935ac83d0d3f227b145307d1 (diff)
Avoid using a flag to specify if the effect state needs to be updated
This fixes a potential missed state change if an update with a new state got replaced with one that doesn't.
-rw-r--r--Alc/ALc.c4
-rw-r--r--Alc/ALu.c12
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h4
-rw-r--r--OpenAL32/alAuxEffectSlot.c19
4 files changed, 20 insertions, 19 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index e5c18d8c..dfbb6c63 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2052,7 +2052,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
RestoreFPUMode(&oldMode);
return ALC_INVALID_DEVICE;
}
- UpdateEffectSlotProps(slot, AL_FALSE);
+ UpdateEffectSlotProps(slot);
}
context = ATOMIC_LOAD(&device->ContextList);
@@ -2077,7 +2077,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
return ALC_INVALID_DEVICE;
}
- UpdateEffectSlotProps(slot, AL_FALSE);
+ UpdateEffectSlotProps(slot);
}
UnlockUIntMapRead(&context->EffectSlotMap);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 2fffdcd9..329d01eb 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -336,6 +336,7 @@ static void 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;
@@ -355,13 +356,16 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
slot->Params.DecayTime = 0.0f;
slot->Params.AirAbsorptionGainHF = 1.0f;
}
+ state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed);
+
/* 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
- );
+ if(state != slot->Params.EffectState)
+ {
+ ATOMIC_STORE(&props->State, slot->Params.EffectState, almemory_order_relaxed);
+ slot->Params.EffectState = state;
+ }
V(slot->Params.EffectState,update)(device, slot, &props->Props);
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index 28c0b46f..85d730f8 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -79,8 +79,6 @@ struct ALeffectslotProps {
ATOMIC(ALenum) Type;
ALeffectProps Props;
- /* Flag indicates if State should be updated. */
- ATOMIC(ALboolean) UpdateState;
ATOMIC(ALeffectState*) State;
ATOMIC(struct ALeffectslotProps*) next;
@@ -140,7 +138,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id)
ALenum InitEffectSlot(ALeffectslot *slot);
void DeinitEffectSlot(ALeffectslot *slot);
-void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate);
+void UpdateEffectSlotProps(ALeffectslot *slot);
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 6d1423db..0dd6a53f 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -201,7 +201,7 @@ 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);
+ UpdateEffectSlotProps(slot);
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
UpdateAllSourceProps(context);
break;
@@ -264,7 +264,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateEffectSlotProps(slot, AL_FALSE);
+ UpdateEffectSlotProps(slot);
done:
WriteUnlock(&context->PropLock);
@@ -502,12 +502,12 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
}
EffectSlot->Effect.State = State;
- UpdateEffectSlotProps(EffectSlot, AL_TRUE);
+ UpdateEffectSlotProps(EffectSlot);
}
else if(effect)
{
memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props));
- UpdateEffectSlotProps(EffectSlot, AL_FALSE);
+ UpdateEffectSlotProps(EffectSlot);
}
return AL_NO_ERROR;
@@ -556,7 +556,8 @@ void DeinitEffectSlot(ALeffectslot *slot)
{
ALeffectState *state;
state = ATOMIC_LOAD(&props->State, almemory_order_relaxed);
- DELETE_OBJ(state);
+ if(state != slot->Params.EffectState)
+ DELETE_OBJ(state);
TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props);
al_free(props);
}
@@ -577,7 +578,7 @@ void DeinitEffectSlot(ALeffectslot *slot)
DELETE_OBJ(slot->Params.EffectState);
}
-void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate)
+void UpdateEffectSlotProps(ALeffectslot *slot)
{
struct ALeffectslotProps *props;
ALeffectState *oldstate;
@@ -605,10 +606,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate)
/* Swap out any stale effect state object there may be in the container, to
* delete it.
*/
- ATOMIC_STORE(&props->UpdateState, withstate, almemory_order_relaxed);
- oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State,
- withstate ? slot->Effect.State : NULL, almemory_order_relaxed
- );
+ oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State,
+ almemory_order_relaxed);
/* Set the new container for updating internal parameters. */
props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props,