From 1ab890262168444c2f6e1a9d84c3d65e5afe37f5 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 27 Sep 2017 11:13:18 -0700 Subject: [PATCH] Re-update effect slots when context properties change Also keep all free property update structs together in the context instead of per-object. --- Alc/ALc.c | 74 +++++++++++++++++++---------- Alc/ALu.c | 95 ++++++++++++++++---------------------- OpenAL32/Include/alAuxEffectSlot.h | 8 ++-- OpenAL32/Include/alListener.h | 5 -- OpenAL32/Include/alMain.h | 12 ++++- OpenAL32/Include/alu.h | 1 - OpenAL32/alAuxEffectSlot.c | 34 +++++--------- OpenAL32/alListener.c | 6 +-- OpenAL32/alSource.c | 18 ++++---- OpenAL32/alState.c | 6 +-- 10 files changed, 133 insertions(+), 126 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index 44170434..7b4c1cfc 100644 --- a/Alc/ALc.c +++ b/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"); } diff --git a/Alc/ALu.c b/Alc/ALu.c index 20b2d817..0da610d1 100644 --- a/Alc/ALu.c +++ b/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,48 +316,54 @@ 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; - slot->Params.Gain = props->Gain; - slot->Params.AuxSendAuto = props->AuxSendAuto; - slot->Params.EffectType = props->Type; - if(IsReverbEffect(slot->Params.EffectType)) - { - slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; - slot->Params.DecayTime = props->Props.Reverb.DecayTime; - slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; - slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; - slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; - } - else + if(props) { - slot->Params.RoomRolloff = 0.0f; - slot->Params.DecayTime = 0.0f; - slot->Params.DecayHFRatio = 0.0f; - slot->Params.DecayHFLimit = AL_FALSE; - slot->Params.AirAbsorptionGainHF = 1.0f; - } + slot->Params.Gain = props->Gain; + slot->Params.AuxSendAuto = props->AuxSendAuto; + slot->Params.EffectType = props->Type; + slot->Params.EffectProps = props->Props; + if(IsReverbEffect(props->Type)) + { + slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; + slot->Params.DecayTime = props->Props.Reverb.DecayTime; + slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; + slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; + slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + } + else + { + slot->Params.RoomRolloff = 0.0f; + slot->Params.DecayTime = 0.0f; + slot->Params.DecayHFRatio = 0.0f; + slot->Params.DecayHFLimit = AL_FALSE; + slot->Params.AirAbsorptionGainHF = 1.0f; + } - /* 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; + /* 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; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index fe05e008..908c72c5 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -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 diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index 8b212d47..0d80a8d7 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -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; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 7ac7eb13..776fb37b 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -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; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 2344cc6d..049a9dcd 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -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; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 02288a31..12092100 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -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); } diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 7062f8c4..9a90c16e 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -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); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index be191fdb..db698692 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -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); } } diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 14646043..a5565f87 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -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); } } -- 2.11.4.GIT