From fd70b0bca6dcc97edf16d4567c84933576828230 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 27 Sep 2017 09:36:34 -0700 Subject: [PATCH] Don't update context and listener props unnecessarily --- Alc/ALc.c | 11 ++++++-- OpenAL32/Include/alListener.h | 2 ++ OpenAL32/Include/alMain.h | 2 ++ OpenAL32/alListener.c | 60 ++++++++++++++++++++++++------------------- OpenAL32/alState.c | 28 ++++++++++---------- 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index cef5749d..44170434 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1669,8 +1669,10 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0) althrd_yield(); - UpdateContextProps(context); - UpdateListenerProps(context); + if(!ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_acq_rel)) + UpdateContextProps(context); + if(!ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_acq_rel)) + UpdateListenerProps(context); UpdateAllEffectSlotProps(context); UpdateAllSourceProps(context); @@ -2358,6 +2360,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } UnlockUIntMapRead(&context->SourceMap); + ATOMIC_FLAG_TEST_AND_SET(&context->PropsClean, almemory_order_release); + UpdateContextProps(context); + ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_release); UpdateListenerProps(context); UpdateAllSourceProps(context); WriteUnlock(&context->PropLock); @@ -2532,6 +2537,7 @@ static ALvoid InitContext(ALCcontext *Context) listener->Up[0] = 0.0f; listener->Up[1] = 1.0f; listener->Up[2] = 0.0f; + ATOMIC_FLAG_TEST_AND_SET(&listener->PropsClean, almemory_order_relaxed); ATOMIC_INIT(&listener->Update, NULL); ATOMIC_INIT(&listener->FreeList, NULL); @@ -2565,6 +2571,7 @@ static ALvoid InitContext(ALCcontext *Context) Context->DopplerVelocity = 1.0f; Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT; + ATOMIC_FLAG_TEST_AND_SET(&Context->PropsClean, almemory_order_relaxed); ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE); ATOMIC_INIT(&Context->Update, NULL); diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index ae66b0e3..8b212d47 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -36,6 +36,8 @@ typedef struct ALlistener { ALfloat Up[3]; ALfloat Gain; + ATOMIC_FLAG PropsClean; + /* Pointer to the most recent property values that are awaiting an update. */ ATOMIC(struct ALlistenerProps*) Update; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 95137972..7ac7eb13 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -853,6 +853,8 @@ struct ALCcontext_struct { ALfloat DopplerVelocity; ALfloat SpeedOfSound; ALfloat MetersPerUnit; + + ATOMIC_FLAG PropsClean; ATOMIC(ALenum) DeferUpdates; RWLock PropLock; diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index a4471539..7062f8c4 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -26,20 +26,31 @@ #include "alListener.h" #include "alSource.h" +#define DO_UPDATEPROPS() do { \ + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ + UpdateListenerProps(context); \ + else \ + ATOMIC_FLAG_CLEAR(&listener->PropsClean, almemory_order_release); \ +} while(0) + + AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) { + ALlistener *listener; ALCcontext *context; context = GetContextRef(); if(!context) return; + listener = context->Listener; WriteLock(&context->PropLock); switch(param) { case AL_GAIN: if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->Gain = value; + listener->Gain = value; + DO_UPDATEPROPS(); break; case AL_METERS_PER_UNIT: @@ -48,13 +59,13 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) context->MetersPerUnit = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) UpdateContextProps(context); - goto done; + else + ATOMIC_FLAG_CLEAR(&context->PropsClean, almemory_order_release); + break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); @@ -64,35 +75,37 @@ done: AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) { + ALlistener *listener; ALCcontext *context; context = GetContextRef(); if(!context) return; + listener = context->Listener; WriteLock(&context->PropLock); switch(param) { case AL_POSITION: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->Position[0] = value1; - context->Listener->Position[1] = value2; - context->Listener->Position[2] = value3; + listener->Position[0] = value1; + listener->Position[1] = value2; + listener->Position[2] = value3; + DO_UPDATEPROPS(); break; case AL_VELOCITY: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->Velocity[0] = value1; - context->Listener->Velocity[1] = value2; - context->Listener->Velocity[2] = value3; + listener->Velocity[0] = value1; + listener->Velocity[1] = value2; + listener->Velocity[2] = value3; + DO_UPDATEPROPS(); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); @@ -102,6 +115,7 @@ done: AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) { + ALlistener *listener; ALCcontext *context; if(values) @@ -123,6 +137,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) context = GetContextRef(); if(!context) return; + listener = context->Listener; WriteLock(&context->PropLock); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); @@ -133,19 +148,18 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); /* AT then UP */ - context->Listener->Forward[0] = values[0]; - context->Listener->Forward[1] = values[1]; - context->Listener->Forward[2] = values[2]; - context->Listener->Up[0] = values[3]; - context->Listener->Up[1] = values[4]; - context->Listener->Up[2] = values[5]; + listener->Forward[0] = values[0]; + listener->Forward[1] = values[1]; + listener->Forward[2] = values[2]; + listener->Up[0] = values[3]; + listener->Up[1] = values[4]; + listener->Up[2] = values[5]; + DO_UPDATEPROPS(); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); @@ -166,8 +180,6 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); @@ -196,8 +208,6 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); @@ -242,8 +252,6 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); done: WriteUnlock(&context->PropLock); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 86534efb..14646043 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -54,6 +54,14 @@ static const ALchar alSinc4Resampler[] = "3rd order Sinc"; static const ALchar alBSinc12Resampler[] = "11th order Sinc"; static const ALchar alBSinc24Resampler[] = "23rd order Sinc"; +#define DO_UPDATEPROPS() do { \ + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ + UpdateContextProps(context); \ + else \ + ATOMIC_FLAG_CLEAR(&context->PropsClean, almemory_order_release); \ +} while(0) + + AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { ALCcontext *context; @@ -66,13 +74,12 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_TRUE; + DO_UPDATEPROPS(); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); done: WriteUnlock(&context->PropLock); @@ -91,13 +98,12 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_FALSE; + DO_UPDATEPROPS(); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); done: WriteUnlock(&context->PropLock); @@ -647,8 +653,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) WriteLock(&context->PropLock); context->DopplerFactor = value; - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); + DO_UPDATEPROPS(); WriteUnlock(&context->PropLock); done: @@ -667,8 +672,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) WriteLock(&context->PropLock); context->DopplerVelocity = value; - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); + DO_UPDATEPROPS(); WriteUnlock(&context->PropLock); done: @@ -687,8 +691,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) WriteLock(&context->PropLock); context->SpeedOfSound = value; - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); + DO_UPDATEPROPS(); WriteUnlock(&context->PropLock); done: @@ -711,10 +714,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) WriteLock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) - { - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateContextProps(context); - } + DO_UPDATEPROPS(); WriteUnlock(&context->PropLock); done: -- 2.11.4.GIT