diff options
author | Chris Robinson <[email protected]> | 2016-08-23 18:56:01 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-08-23 18:56:01 -0700 |
commit | dc8b7814c771d08abe61656b745e7763a010a3a3 (patch) | |
tree | 9d1f91b7829d2a7d29654d708a837bbf6cfb99c3 | |
parent | bd054632e0ba42ad93dd3bcad54042a126a65646 (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.c | 4 | ||||
-rw-r--r-- | Alc/ALu.c | 79 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 71 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 2 | ||||
-rw-r--r-- | OpenAL32/alListener.c | 18 | ||||
-rw-r--r-- | OpenAL32/alState.c | 9 |
6 files changed, 91 insertions, 92 deletions
@@ -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); @@ -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: |