aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c2
-rw-r--r--Alc/ALu.c29
-rw-r--r--OpenAL32/Include/alMain.h6
-rw-r--r--OpenAL32/Include/alu.h2
-rw-r--r--OpenAL32/alSource.c13
5 files changed, 37 insertions, 15 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 0019de9e..86b8e59e 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 329d01eb..34c36d5b 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -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);
}