diff options
-rw-r--r-- | Alc/ALc.c | 2 | ||||
-rw-r--r-- | Alc/ALu.c | 29 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 6 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 2 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 13 |
5 files changed, 37 insertions, 15 deletions
@@ -2266,6 +2266,8 @@ static ALvoid InitContext(ALCcontext *Context) ATOMIC_INIT(&listener->FreeList, NULL); //Validate Context + InitRef(&Context->UpdateCount, 0); + ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE); RWLockInit(&Context->PropLock); ATOMIC_INIT(&Context->LastError, AL_NO_ERROR); InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources); @@ -1339,26 +1339,31 @@ ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, c } -void UpdateContextSources(ALCcontext *ctx) +static void UpdateContextSources(ALCcontext *ctx) { ALvoice *voice, *voice_end; ALsource *source; - CalcListenerParams(ctx); + IncrementRef(&ctx->UpdateCount); + if(!ATOMIC_LOAD(&ctx->HoldUpdates)) + { + CalcListenerParams(ctx); #define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); + VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); #undef UPDATE_SLOT - voice = ctx->Voices; - voice_end = voice + ctx->VoiceCount; - for(;voice != voice_end;++voice) - { - if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - voice->Source = NULL; - else - CalcSourceParams(voice, ctx); + voice = ctx->Voices; + voice_end = voice + ctx->VoiceCount; + for(;voice != voice_end;++voice) + { + if(!(source=voice->Source)) continue; + if(source->state != AL_PLAYING && source->state != AL_PAUSED) + voice->Source = NULL; + else + CalcSourceParams(voice, ctx); + } } + IncrementRef(&ctx->UpdateCount); } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index a624e078..f709e9bd 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -699,6 +699,12 @@ struct ALCcontext_struct { RWLock PropLock; + /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit + * indicates if updates are currently happening). + */ + RefCount UpdateCount; + ATOMIC(ALenum) HoldUpdates; + struct ALvoice *Voices; ALsizei VoiceCount; ALsizei MaxVoices; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 8e93dc6e..fc58bfb1 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -374,8 +374,6 @@ void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -ALvoid UpdateContextSources(ALCcontext *context); - ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index e2d6ca4f..1124c9c3 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2848,7 +2848,15 @@ void UpdateSourceProps(ALsource *source, ALuint num_sends) void UpdateAllSourceProps(ALCcontext *context) { ALuint num_sends = context->Device->NumAuxSends; + uint updates; ALsizei pos; + + /* Tell the mixer to stop applying updates, then wait for any active + * updating to finish, before providing source updates. + */ + ATOMIC_STORE(&context->HoldUpdates, AL_TRUE); + while(((updates=ReadRef(&context->UpdateCount))&1) != 0) + althrd_yield(); for(pos = 0;pos < context->VoiceCount;pos++) { ALvoice *voice = &context->Voices[pos]; @@ -2857,7 +2865,10 @@ void UpdateAllSourceProps(ALCcontext *context) source->state == AL_PAUSED)) UpdateSourceProps(source, num_sends); } - + /* Now with all updates declared, let the mixer continue applying them so + * they all happen at once. + */ + ATOMIC_STORE(&context->HoldUpdates, AL_FALSE); } |