Re-update effect slots when context properties change
Also keep all free property update structs together in the context instead of per-object.
This commit is contained in:
parent
fd70b0bca6
commit
1ab8902621
74
Alc/ALc.c
74
Alc/ALc.c
@ -2255,6 +2255,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
context = ATOMIC_LOAD_SEQ(&device->ContextList);
|
||||
while(context)
|
||||
{
|
||||
struct ALvoiceProps *vprops;
|
||||
ALsizei pos;
|
||||
|
||||
if(context->DefaultSlot)
|
||||
@ -2267,7 +2268,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
if(V(state,deviceUpdate)(device) == AL_FALSE)
|
||||
update_failed = AL_TRUE;
|
||||
else
|
||||
UpdateEffectSlotProps(slot);
|
||||
UpdateEffectSlotProps(slot, context);
|
||||
}
|
||||
|
||||
WriteLock(&context->PropLock);
|
||||
@ -2282,7 +2283,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
if(V(state,deviceUpdate)(device) == AL_FALSE)
|
||||
update_failed = AL_TRUE;
|
||||
else
|
||||
UpdateEffectSlotProps(slot);
|
||||
UpdateEffectSlotProps(slot, context);
|
||||
}
|
||||
UnlockUIntMapRead(&context->EffectSlotMap);
|
||||
|
||||
@ -2321,26 +2322,25 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
|
||||
ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
|
||||
}
|
||||
|
||||
/* Clear any pre-existing voice property structs, in case the number of
|
||||
* auxiliary sends is changing. Active sources will have updates
|
||||
* respecified in UpdateAllSourceProps.
|
||||
*/
|
||||
vprops = ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps, NULL, almemory_order_acq_rel);
|
||||
while(vprops)
|
||||
{
|
||||
struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
|
||||
al_free(vprops);
|
||||
vprops = next;
|
||||
}
|
||||
|
||||
AllocateVoices(context, context->MaxVoices, old_sends);
|
||||
for(pos = 0;pos < context->VoiceCount;pos++)
|
||||
{
|
||||
ALvoice *voice = context->Voices[pos];
|
||||
struct ALvoiceProps *props;
|
||||
|
||||
/* Clear any pre-existing voice property structs, in case the
|
||||
* number of auxiliary sends changed. Active sources will have
|
||||
* updates respecified in UpdateAllSourceProps.
|
||||
*/
|
||||
props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
|
||||
al_free(props);
|
||||
|
||||
props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
|
||||
while(props)
|
||||
{
|
||||
struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
al_free(props);
|
||||
props = next;
|
||||
}
|
||||
al_free(ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel));
|
||||
|
||||
if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
|
||||
continue;
|
||||
@ -2540,7 +2540,6 @@ static ALvoid InitContext(ALCcontext *Context)
|
||||
ATOMIC_FLAG_TEST_AND_SET(&listener->PropsClean, almemory_order_relaxed);
|
||||
|
||||
ATOMIC_INIT(&listener->Update, NULL);
|
||||
ATOMIC_INIT(&listener->FreeList, NULL);
|
||||
|
||||
//Validate Context
|
||||
InitRef(&Context->UpdateCount, 0);
|
||||
@ -2575,7 +2574,10 @@ static ALvoid InitContext(ALCcontext *Context)
|
||||
ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
|
||||
|
||||
ATOMIC_INIT(&Context->Update, NULL);
|
||||
ATOMIC_INIT(&Context->FreeList, NULL);
|
||||
ATOMIC_INIT(&Context->FreeContextProps, NULL);
|
||||
ATOMIC_INIT(&Context->FreeListenerProps, NULL);
|
||||
ATOMIC_INIT(&Context->FreeVoiceProps, NULL);
|
||||
ATOMIC_INIT(&Context->FreeEffectslotProps, NULL);
|
||||
|
||||
Context->ExtensionList = alExtList;
|
||||
|
||||
@ -2605,8 +2607,10 @@ static void FreeContext(ALCcontext *context)
|
||||
{
|
||||
ALlistener *listener = context->Listener;
|
||||
struct ALeffectslotArray *auxslots;
|
||||
struct ALeffectslotProps *eprops;
|
||||
struct ALlistenerProps *lprops;
|
||||
struct ALcontextProps *cprops;
|
||||
struct ALvoiceProps *vprops;
|
||||
size_t count;
|
||||
ALsizei i;
|
||||
|
||||
@ -2617,8 +2621,9 @@ static void FreeContext(ALCcontext *context)
|
||||
TRACE("Freed unapplied context update %p\n", cprops);
|
||||
al_free(cprops);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
cprops = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire);
|
||||
cprops = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire);
|
||||
while(cprops)
|
||||
{
|
||||
struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire);
|
||||
@ -2645,6 +2650,17 @@ static void FreeContext(ALCcontext *context)
|
||||
}
|
||||
ResetUIntMap(&context->SourceMap);
|
||||
|
||||
count = 0;
|
||||
eprops = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed);
|
||||
while(eprops)
|
||||
{
|
||||
struct ALeffectslotProps *next = ATOMIC_LOAD(&eprops->next, almemory_order_relaxed);
|
||||
if(eprops->State) ALeffectState_DecRef(eprops->State);
|
||||
al_free(eprops);
|
||||
eprops = next;
|
||||
++count;
|
||||
}
|
||||
TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
|
||||
if(context->EffectSlotMap.size > 0)
|
||||
{
|
||||
WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size,
|
||||
@ -2653,6 +2669,17 @@ static void FreeContext(ALCcontext *context)
|
||||
}
|
||||
ResetUIntMap(&context->EffectSlotMap);
|
||||
|
||||
count = 0;
|
||||
vprops = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_relaxed);
|
||||
while(vprops)
|
||||
{
|
||||
struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed);
|
||||
al_free(vprops);
|
||||
vprops = next;
|
||||
++count;
|
||||
}
|
||||
TRACE("Freed "SZFMT" voice property object%s\n", count, (count==1)?"":"s");
|
||||
|
||||
for(i = 0;i < context->VoiceCount;i++)
|
||||
DeinitVoice(context->Voices[i]);
|
||||
al_free(context->Voices);
|
||||
@ -2666,7 +2693,7 @@ static void FreeContext(ALCcontext *context)
|
||||
al_free(lprops);
|
||||
}
|
||||
count = 0;
|
||||
lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
|
||||
lprops = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire);
|
||||
while(lprops)
|
||||
{
|
||||
struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire);
|
||||
@ -2878,7 +2905,6 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
|
||||
for(;v < num_voices;v++)
|
||||
{
|
||||
ATOMIC_INIT(&voice->Update, NULL);
|
||||
ATOMIC_INIT(&voice->FreeList, NULL);
|
||||
|
||||
voice->Props = props;
|
||||
voices[v] = voice;
|
||||
@ -3725,8 +3751,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
|
||||
|
||||
if(ALContext->DefaultSlot)
|
||||
{
|
||||
if(InitializeEffect(device, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR)
|
||||
UpdateEffectSlotProps(ALContext->DefaultSlot);
|
||||
if(InitializeEffect(ALContext, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR)
|
||||
UpdateEffectSlotProps(ALContext->DefaultSlot, ALContext);
|
||||
else
|
||||
ERR("Failed to initialize the default effect\n");
|
||||
}
|
||||
|
53
Alc/ALu.c
53
Alc/ALu.c
@ -111,26 +111,7 @@ static HrtfDirectMixerFunc MixDirectHrtf = MixDirectHrtf_C;
|
||||
|
||||
void DeinitVoice(ALvoice *voice)
|
||||
{
|
||||
struct ALvoiceProps *props;
|
||||
size_t count = 0;
|
||||
|
||||
props = ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL);
|
||||
if(props) al_free(props);
|
||||
|
||||
props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
|
||||
while(props)
|
||||
{
|
||||
struct ALvoiceProps *next;
|
||||
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
al_free(props);
|
||||
props = next;
|
||||
++count;
|
||||
}
|
||||
/* This is excessively spammy if it traces every voice destruction, so just
|
||||
* warn if it was unexpectedly large.
|
||||
*/
|
||||
if(count > 3)
|
||||
WARN("Freed "SZFMT" voice property objects\n", count);
|
||||
al_free(ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL));
|
||||
}
|
||||
|
||||
|
||||
@ -290,7 +271,7 @@ static bool CalcContextParams(ALCcontext *Context)
|
||||
Listener->Params.SourceDistanceModel = props->SourceDistanceModel;
|
||||
Listener->Params.DistanceModel = props->DistanceModel;
|
||||
|
||||
ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeContextProps, props);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -335,22 +316,25 @@ static bool CalcListenerParams(ALCcontext *Context)
|
||||
|
||||
Listener->Params.Gain = props->Gain * Context->GainBoost;
|
||||
|
||||
ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Context->FreeListenerProps, props);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
|
||||
static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force)
|
||||
{
|
||||
struct ALeffectslotProps *props;
|
||||
ALeffectState *state;
|
||||
|
||||
props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel);
|
||||
if(!props) return false;
|
||||
if(!props && !force) return false;
|
||||
|
||||
if(props)
|
||||
{
|
||||
slot->Params.Gain = props->Gain;
|
||||
slot->Params.AuxSendAuto = props->AuxSendAuto;
|
||||
slot->Params.EffectType = props->Type;
|
||||
if(IsReverbEffect(slot->Params.EffectType))
|
||||
slot->Params.EffectProps = props->Props;
|
||||
if(IsReverbEffect(props->Type))
|
||||
{
|
||||
slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor;
|
||||
slot->Params.DecayTime = props->Props.Reverb.DecayTime;
|
||||
@ -367,16 +351,19 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
|
||||
slot->Params.AirAbsorptionGainHF = 1.0f;
|
||||
}
|
||||
|
||||
/* Swap effect states. No need to play with the ref counts since they keep
|
||||
* the same number of refs.
|
||||
/* Swap effect states. No need to play with the ref counts since they
|
||||
* keep the same number of refs.
|
||||
*/
|
||||
state = props->State;
|
||||
props->State = slot->Params.EffectState;
|
||||
slot->Params.EffectState = state;
|
||||
|
||||
V(state,update)(context, slot, &props->Props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props);
|
||||
}
|
||||
else
|
||||
state = slot->Params.EffectState;
|
||||
|
||||
ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props);
|
||||
V(state,update)(context, slot, &slot->Params.EffectProps);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1455,7 +1442,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
|
||||
FAM_SIZE(struct ALvoiceProps, Send, context->Device->NumAuxSends)
|
||||
);
|
||||
|
||||
ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &context->FreeVoiceProps, props);
|
||||
}
|
||||
props = voice->Props;
|
||||
|
||||
@ -1486,10 +1473,10 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray
|
||||
IncrementRef(&ctx->UpdateCount);
|
||||
if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire))
|
||||
{
|
||||
ALboolean cforce = CalcContextParams(ctx);
|
||||
ALboolean force = CalcListenerParams(ctx) | cforce;
|
||||
bool cforce = CalcContextParams(ctx);
|
||||
bool force = CalcListenerParams(ctx) | cforce;
|
||||
for(i = 0;i < slots->count;i++)
|
||||
force |= CalcEffectSlotParams(slots->slot[i], ctx);
|
||||
force |= CalcEffectSlotParams(slots->slot[i], ctx, cforce);
|
||||
|
||||
voice = ctx->Voices;
|
||||
voice_end = voice + ctx->VoiceCount;
|
||||
|
@ -110,13 +110,13 @@ typedef struct ALeffectslot {
|
||||
RefCount ref;
|
||||
|
||||
ATOMIC(struct ALeffectslotProps*) Update;
|
||||
ATOMIC(struct ALeffectslotProps*) FreeList;
|
||||
|
||||
struct {
|
||||
ALfloat Gain;
|
||||
ALboolean AuxSendAuto;
|
||||
|
||||
ALenum EffectType;
|
||||
ALeffectProps EffectProps;
|
||||
ALeffectState *EffectState;
|
||||
|
||||
ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */
|
||||
@ -160,7 +160,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, ALCcontext *context);
|
||||
void UpdateAllEffectSlotProps(ALCcontext *context);
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
||||
|
||||
@ -178,11 +178,13 @@ ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void);
|
||||
ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void);
|
||||
|
||||
|
||||
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect);
|
||||
ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect);
|
||||
|
||||
void InitEffectFactoryMap(void);
|
||||
void DeinitEffectFactoryMap(void);
|
||||
|
||||
void ALeffectState_DecRef(ALeffectState *state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -42,11 +42,6 @@ typedef struct ALlistener {
|
||||
*/
|
||||
ATOMIC(struct ALlistenerProps*) Update;
|
||||
|
||||
/* A linked list of unused property containers, free to use for future
|
||||
* updates.
|
||||
*/
|
||||
ATOMIC(struct ALlistenerProps*) FreeList;
|
||||
|
||||
struct {
|
||||
aluMatrixf Matrix;
|
||||
aluVector Velocity;
|
||||
|
@ -383,6 +383,9 @@ struct HrtfEntry;
|
||||
struct FrontStablizer;
|
||||
struct Compressor;
|
||||
struct ALcontextProps;
|
||||
struct ALlistenerProps;
|
||||
struct ALvoiceProps;
|
||||
struct ALeffectslotProps;
|
||||
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE (44100)
|
||||
@ -868,7 +871,14 @@ struct ALCcontext_struct {
|
||||
ALfloat GainBoost;
|
||||
|
||||
ATOMIC(struct ALcontextProps*) Update;
|
||||
ATOMIC(struct ALcontextProps*) FreeList;
|
||||
|
||||
/* Linked lists of unused property containers, free to use for future
|
||||
* updates.
|
||||
*/
|
||||
ATOMIC(struct ALcontextProps*) FreeContextProps;
|
||||
ATOMIC(struct ALlistenerProps*) FreeListenerProps;
|
||||
ATOMIC(struct ALvoiceProps*) FreeVoiceProps;
|
||||
ATOMIC(struct ALeffectslotProps*) FreeEffectslotProps;
|
||||
|
||||
struct ALvoice **Voices;
|
||||
ALsizei VoiceCount;
|
||||
|
@ -251,7 +251,6 @@ typedef struct ALvoice {
|
||||
struct ALvoiceProps *Props;
|
||||
|
||||
ATOMIC(struct ALvoiceProps*) Update;
|
||||
ATOMIC(struct ALvoiceProps*) FreeList;
|
||||
|
||||
ATOMIC(struct ALsource*) Source;
|
||||
ATOMIC(bool) Playing;
|
||||
|
@ -52,11 +52,10 @@ 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); \
|
||||
UpdateEffectSlotProps(slot, context); \
|
||||
else \
|
||||
ATOMIC_FLAG_CLEAR(&slot->PropsClean, almemory_order_release); \
|
||||
} while(0)
|
||||
@ -251,7 +250,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param
|
||||
UnlockEffectsRead(device);
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
}
|
||||
err = InitializeEffect(device, slot, effect);
|
||||
err = InitializeEffect(context, slot, effect);
|
||||
UnlockEffectsRead(device);
|
||||
|
||||
if(err != AL_NO_ERROR)
|
||||
@ -497,8 +496,9 @@ void DeinitEffectFactoryMap(void)
|
||||
}
|
||||
|
||||
|
||||
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect)
|
||||
ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
|
||||
{
|
||||
ALCdevice *Device = Context->Device;
|
||||
ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL);
|
||||
struct ALeffectslotProps *props;
|
||||
ALeffectState *State;
|
||||
@ -548,7 +548,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
EffectSlot->Effect.Props = effect->Props;
|
||||
|
||||
/* Remove state references from old effect slot property updates. */
|
||||
props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList);
|
||||
props = ATOMIC_LOAD_SEQ(&Context->FreeEffectslotProps);
|
||||
while(props)
|
||||
{
|
||||
if(props->State)
|
||||
@ -568,7 +568,7 @@ static void ALeffectState_IncRef(ALeffectState *state)
|
||||
TRACEREF("%p increasing refcount to %u\n", state, ref);
|
||||
}
|
||||
|
||||
static void ALeffectState_DecRef(ALeffectState *state)
|
||||
void ALeffectState_DecRef(ALeffectState *state)
|
||||
{
|
||||
uint ref;
|
||||
ref = DecrementRef(&state->Ref);
|
||||
@ -606,7 +606,6 @@ ALenum InitEffectSlot(ALeffectslot *slot)
|
||||
InitRef(&slot->ref, 0);
|
||||
|
||||
ATOMIC_INIT(&slot->Update, NULL);
|
||||
ATOMIC_INIT(&slot->FreeList, NULL);
|
||||
|
||||
slot->Params.Gain = 1.0f;
|
||||
slot->Params.AuxSendAuto = AL_TRUE;
|
||||
@ -624,7 +623,6 @@ ALenum InitEffectSlot(ALeffectslot *slot)
|
||||
void DeinitEffectSlot(ALeffectslot *slot)
|
||||
{
|
||||
struct ALeffectslotProps *props;
|
||||
size_t count = 0;
|
||||
|
||||
props = ATOMIC_LOAD_SEQ(&slot->Update);
|
||||
if(props)
|
||||
@ -633,29 +631,19 @@ void DeinitEffectSlot(ALeffectslot *slot)
|
||||
TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props);
|
||||
al_free(props);
|
||||
}
|
||||
props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed);
|
||||
while(props)
|
||||
{
|
||||
struct ALeffectslotProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
if(props->State) ALeffectState_DecRef(props->State);
|
||||
al_free(props);
|
||||
props = next;
|
||||
++count;
|
||||
}
|
||||
TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
|
||||
|
||||
ALeffectState_DecRef(slot->Effect.State);
|
||||
if(slot->Params.EffectState)
|
||||
ALeffectState_DecRef(slot->Params.EffectState);
|
||||
}
|
||||
|
||||
void UpdateEffectSlotProps(ALeffectslot *slot)
|
||||
void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context)
|
||||
{
|
||||
struct ALeffectslotProps *props;
|
||||
ALeffectState *oldstate;
|
||||
|
||||
/* Get an unused property container, or allocate a new one as needed. */
|
||||
props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed);
|
||||
props = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed);
|
||||
if(!props)
|
||||
props = al_calloc(16, sizeof(*props));
|
||||
else
|
||||
@ -663,7 +651,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot)
|
||||
struct ALeffectslotProps *next;
|
||||
do {
|
||||
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&slot->FreeList, &props, next,
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeEffectslotProps, &props, next,
|
||||
almemory_order_seq_cst, almemory_order_acquire) == 0);
|
||||
}
|
||||
|
||||
@ -687,7 +675,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot)
|
||||
/* If there was an unused update container, put it back in the
|
||||
* freelist.
|
||||
*/
|
||||
ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props);
|
||||
}
|
||||
|
||||
if(oldstate)
|
||||
@ -705,7 +693,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context)
|
||||
{
|
||||
ALeffectslot *slot = auxslots->slot[i];
|
||||
if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel))
|
||||
UpdateEffectSlotProps(slot);
|
||||
UpdateEffectSlotProps(slot, context);
|
||||
}
|
||||
UnlockEffectSlotsRead(context);
|
||||
}
|
||||
|
@ -470,7 +470,7 @@ void UpdateListenerProps(ALCcontext *context)
|
||||
struct ALlistenerProps *props;
|
||||
|
||||
/* Get an unused proprty container, or allocate a new one as needed. */
|
||||
props = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire);
|
||||
props = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire);
|
||||
if(!props)
|
||||
props = al_calloc(16, sizeof(*props));
|
||||
else
|
||||
@ -478,7 +478,7 @@ void UpdateListenerProps(ALCcontext *context)
|
||||
struct ALlistenerProps *next;
|
||||
do {
|
||||
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&listener->FreeList, &props, next,
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeListenerProps, &props, next,
|
||||
almemory_order_seq_cst, almemory_order_acquire) == 0);
|
||||
}
|
||||
|
||||
@ -507,6 +507,6 @@ void UpdateListenerProps(ALCcontext *context)
|
||||
/* If there was an unused update container, put it back in the
|
||||
* freelist.
|
||||
*/
|
||||
ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &listener->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &context->FreeListenerProps, props);
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id);
|
||||
|
||||
static void InitSourceParams(ALsource *Source, ALsizei num_sends);
|
||||
static void DeinitSource(ALsource *source, ALsizei num_sends);
|
||||
static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends);
|
||||
static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends, ALCcontext *context);
|
||||
static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime);
|
||||
static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime);
|
||||
static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context);
|
||||
@ -447,7 +447,7 @@ static ALint Int64ValsByProp(ALenum prop)
|
||||
ALvoice *voice; \
|
||||
if(SourceShouldUpdate(Source, Context) && \
|
||||
(voice=GetSourceVoice(Source, Context)) != NULL) \
|
||||
UpdateSourceProps(Source, voice, device->NumAuxSends); \
|
||||
UpdateSourceProps(Source, voice, device->NumAuxSends, Context); \
|
||||
else \
|
||||
ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); \
|
||||
} while(0)
|
||||
@ -948,7 +948,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
|
||||
* active source, in case the slot is about to be deleted.
|
||||
*/
|
||||
if((voice=GetSourceVoice(Source, Context)) != NULL)
|
||||
UpdateSourceProps(Source, voice, device->NumAuxSends);
|
||||
UpdateSourceProps(Source, voice, device->NumAuxSends, Context);
|
||||
else
|
||||
ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release);
|
||||
}
|
||||
@ -2528,7 +2528,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
|
||||
ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
|
||||
|
||||
ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acquire);
|
||||
UpdateSourceProps(source, voice, device->NumAuxSends);
|
||||
UpdateSourceProps(source, voice, device->NumAuxSends, context);
|
||||
|
||||
/* A source that's not playing or paused has any offset applied when it
|
||||
* starts playing.
|
||||
@ -3061,13 +3061,13 @@ static void DeinitSource(ALsource *source, ALsizei num_sends)
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends)
|
||||
static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends, ALCcontext *context)
|
||||
{
|
||||
struct ALvoiceProps *props;
|
||||
ALsizei i;
|
||||
|
||||
/* Get an unused property container, or allocate a new one as needed. */
|
||||
props = ATOMIC_LOAD(&voice->FreeList, almemory_order_acquire);
|
||||
props = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_acquire);
|
||||
if(!props)
|
||||
props = al_calloc(16, FAM_SIZE(struct ALvoiceProps, Send, num_sends));
|
||||
else
|
||||
@ -3075,7 +3075,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send
|
||||
struct ALvoiceProps *next;
|
||||
do {
|
||||
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&voice->FreeList, &props, next,
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeVoiceProps, &props, next,
|
||||
almemory_order_acq_rel, almemory_order_acquire) == 0);
|
||||
}
|
||||
|
||||
@ -3145,7 +3145,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send
|
||||
/* If there was an unused update container, put it back in the
|
||||
* freelist.
|
||||
*/
|
||||
ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &context->FreeVoiceProps, props);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3159,7 +3159,7 @@ void UpdateAllSourceProps(ALCcontext *context)
|
||||
ALvoice *voice = context->Voices[pos];
|
||||
ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire);
|
||||
if(source && !ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel))
|
||||
UpdateSourceProps(source, voice, num_sends);
|
||||
UpdateSourceProps(source, voice, num_sends, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,7 +786,7 @@ void UpdateContextProps(ALCcontext *context)
|
||||
struct ALcontextProps *props;
|
||||
|
||||
/* Get an unused proprty container, or allocate a new one as needed. */
|
||||
props = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire);
|
||||
props = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire);
|
||||
if(!props)
|
||||
props = al_calloc(16, sizeof(*props));
|
||||
else
|
||||
@ -794,7 +794,7 @@ void UpdateContextProps(ALCcontext *context)
|
||||
struct ALcontextProps *next;
|
||||
do {
|
||||
next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeList, &props, next,
|
||||
} while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeContextProps, &props, next,
|
||||
almemory_order_seq_cst, almemory_order_acquire) == 0);
|
||||
}
|
||||
|
||||
@ -815,6 +815,6 @@ void UpdateContextProps(ALCcontext *context)
|
||||
/* If there was an unused update container, put it back in the
|
||||
* freelist.
|
||||
*/
|
||||
ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeList, props);
|
||||
ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeContextProps, props);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user