aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-08-23 18:56:01 -0700
committerChris Robinson <[email protected]>2016-08-23 18:56:01 -0700
commitdc8b7814c771d08abe61656b745e7763a010a3a3 (patch)
tree9d1f91b7829d2a7d29654d708a837bbf6cfb99c3
parentbd054632e0ba42ad93dd3bcad54042a126a65646 (diff)
Avoid resupplying unneeded source updates
The source's voice holds a copy of the last properties it received, so listener updates can make sources recalculate internal properties from that stored copy.
-rw-r--r--Alc/ALc.c4
-rw-r--r--Alc/ALu.c79
-rw-r--r--OpenAL32/Include/alSource.h71
-rw-r--r--OpenAL32/alAuxEffectSlot.c2
-rw-r--r--OpenAL32/alListener.c18
-rw-r--r--OpenAL32/alState.c9
6 files changed, 91 insertions, 92 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index dbda46f1..f5965716 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1602,8 +1602,6 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
{
ALsizei pos;
- UpdateListenerProps(context);
-
LockUIntMapRead(&context->SourceMap);
V0(device->Backend,lock)();
for(pos = 0;pos < context->SourceMap.size;pos++)
@@ -1626,6 +1624,8 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
}
V0(device->Backend,unlock)();
UnlockUIntMapRead(&context->SourceMap);
+
+ UpdateListenerProps(context);
UpdateAllSourceProps(context);
}
ReadUnlock(&context->PropLock);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index a9f89de0..115c9c59 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -228,7 +228,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state)
}
-static void CalcListenerParams(ALCcontext *Context)
+static ALboolean CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALfloat N[3], V[3], U[3], P[3];
@@ -237,7 +237,7 @@ static void CalcListenerParams(ALCcontext *Context)
aluVector vel;
props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel);
- if(!props) return;
+ if(!props) return AL_FALSE;
/* AT then UP */
N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed);
@@ -288,6 +288,8 @@ static void CalcListenerParams(ALCcontext *Context)
ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
} while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*,
&Listener->FreeList, &first, props) == 0);
+
+ return AL_TRUE;
}
static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
@@ -1281,7 +1283,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro
}
}
-static void CalcSourceParams(ALvoice *voice, ALCcontext *context)
+static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force)
{
ALsource *source = voice->Source;
const ALbufferlistitem *BufferListItem;
@@ -1289,33 +1291,54 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context)
struct ALsourceProps *props;
props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel);
- if(!props) return;
-
- BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
- while(BufferListItem != NULL)
+ if(!props)
{
- const ALbuffer *buffer;
- if((buffer=BufferListItem->buffer) != NULL)
+ if(!force)
+ return;
+ BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
+ while(BufferListItem != NULL)
{
- if(buffer->FmtChannels == FmtMono)
- CalcAttnSourceParams(voice, props, buffer, context);
- else
- CalcNonAttnSourceParams(voice, props, buffer, context);
- break;
+ const ALbuffer *buffer;
+ if((buffer=BufferListItem->buffer) != NULL)
+ {
+ if(buffer->FmtChannels == FmtMono)
+ CalcAttnSourceParams(voice, &voice->Props, buffer, context);
+ else
+ CalcNonAttnSourceParams(voice, &voice->Props, buffer, context);
+ break;
+ }
+ BufferListItem = BufferListItem->next;
}
- BufferListItem = BufferListItem->next;
}
-
- /* WARNING: A livelock is theoretically possible if another thread keeps
- * changing the freelist head without giving this a chance to actually swap
- * in the old container (practically impossible with this little code,
- * but...).
- */
- first = ATOMIC_LOAD(&source->FreeList);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
- &source->FreeList, &first, props) == 0);
+ else
+ {
+ BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
+ while(BufferListItem != NULL)
+ {
+ const ALbuffer *buffer;
+ if((buffer=BufferListItem->buffer) != NULL)
+ {
+ if(buffer->FmtChannels == FmtMono)
+ CalcAttnSourceParams(voice, props, buffer, context);
+ else
+ CalcNonAttnSourceParams(voice, props, buffer, context);
+ break;
+ }
+ BufferListItem = BufferListItem->next;
+ }
+ voice->Props = *props;
+
+ /* WARNING: A livelock is theoretically possible if another thread keeps
+ * changing the freelist head without giving this a chance to actually swap
+ * in the old container (practically impossible with this little code,
+ * but...).
+ */
+ first = ATOMIC_LOAD(&source->FreeList);
+ do {
+ ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
+ &source->FreeList, &first, props) == 0);
+ }
}
@@ -1327,7 +1350,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
IncrementRef(&ctx->UpdateCount);
if(!ATOMIC_LOAD(&ctx->HoldUpdates))
{
- CalcListenerParams(ctx);
+ ALboolean force = CalcListenerParams(ctx);
while(slot)
{
CalcEffectSlotParams(slot, ctx->Device);
@@ -1342,7 +1365,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
voice->Source = NULL;
else
- CalcSourceParams(voice, ctx);
+ CalcSourceParams(voice, ctx, force);
}
}
IncrementRef(&ctx->UpdateCount);
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 74987b34..b288937a 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -22,40 +22,6 @@ typedef struct ALbufferlistitem {
} ALbufferlistitem;
-typedef struct ALvoice {
- struct ALsource *volatile Source;
-
- /** Current target parameters used for mixing. */
- ALint Step;
-
- /* If not 'moving', gain/coefficients are set directly without fading. */
- ALboolean Moving;
-
- ALboolean IsHrtf;
-
- ALuint Offset; /* Number of output samples mixed since starting. */
-
- alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES];
-
- BsincState SincState;
-
- struct {
- ALfloat (*Buffer)[BUFFERSIZE];
- ALuint Channels;
- } DirectOut;
-
- struct {
- ALfloat (*Buffer)[BUFFERSIZE];
- ALuint Channels;
- } SendOut[MAX_SENDS];
-
- struct {
- DirectParams Direct;
- SendParams Send[MAX_SENDS];
- } Chan[MAX_INPUT_CHANNELS];
-} ALvoice;
-
-
struct ALsourceProps {
ATOMIC(ALfloat) Pitch;
ATOMIC(ALfloat) Gain;
@@ -108,6 +74,43 @@ struct ALsourceProps {
ATOMIC(struct ALsourceProps*) next;
};
+
+typedef struct ALvoice {
+ struct ALsourceProps Props;
+
+ struct ALsource *volatile Source;
+
+ /** Current target parameters used for mixing. */
+ ALint Step;
+
+ /* If not 'moving', gain/coefficients are set directly without fading. */
+ ALboolean Moving;
+
+ ALboolean IsHrtf;
+
+ ALuint Offset; /* Number of output samples mixed since starting. */
+
+ alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES];
+
+ BsincState SincState;
+
+ struct {
+ ALfloat (*Buffer)[BUFFERSIZE];
+ ALuint Channels;
+ } DirectOut;
+
+ struct {
+ ALfloat (*Buffer)[BUFFERSIZE];
+ ALuint Channels;
+ } SendOut[MAX_SENDS];
+
+ struct {
+ DirectParams Direct;
+ SendParams Send[MAX_SENDS];
+ } Chan[MAX_INPUT_CHANNELS];
+} ALvoice;
+
+
typedef struct ALsource {
/** Source properties. */
ALfloat Pitch;
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index db084e5a..50f1e5c5 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -210,7 +210,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param
slot->AuxSendAuto = value;
UpdateEffectSlotProps(slot);
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateAllSourceProps(context);
+ UpdateListenerProps(context);
break;
default:
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index c7f4955a..3ea23732 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -52,10 +52,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
@@ -93,10 +90,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
@@ -149,10 +143,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
@@ -174,10 +165,7 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value))
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
@@ -207,10 +195,7 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
@@ -256,10 +241,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
done:
WriteUnlock(&context->PropLock);
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 443ab884..59814a4b 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -557,10 +557,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerFactor = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
WriteUnlock(&context->PropLock);
done:
@@ -580,10 +577,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerVelocity = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
WriteUnlock(&context->PropLock);
done:
@@ -603,10 +597,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
WriteLock(&context->PropLock);
context->SpeedOfSound = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- {
UpdateListenerProps(context);
- UpdateAllSourceProps(context);
- }
WriteUnlock(&context->PropLock);
done: