aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-08-25 06:17:36 -0700
committerChris Robinson <[email protected]>2016-08-25 06:17:36 -0700
commita16739f7651afb7653387b1e79b2985058d76e90 (patch)
tree0e0071564da36bb70293f36541a295682e13868f
parent4e4e597fa54cc3498ae28bea9c2684e1fee05389 (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.c1
-rw-r--r--Alc/ALu.c8
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h3
-rw-r--r--OpenAL32/alAuxEffectSlot.c39
4 files changed, 37 insertions, 14 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 15614dd1..b95c90f8 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1611,6 +1611,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
althrd_yield();
UpdateListenerProps(context);
+ UpdateAllEffectSlotProps(context);
LockUIntMapRead(&context->SourceMap);
V0(device->Backend,lock)();
diff --git a/Alc/ALu.c b/Alc/ALu.c
index d2aa381c..eafb082c 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -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;