Don't update context and listener props unnecessarily
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -853,6 +853,8 @@ struct ALCcontext_struct {
|
||||
ALfloat DopplerVelocity;
|
||||
ALfloat SpeedOfSound;
|
||||
ALfloat MetersPerUnit;
|
||||
|
||||
ATOMIC_FLAG PropsClean;
|
||||
ATOMIC(ALenum) DeferUpdates;
|
||||
|
||||
RWLock PropLock;
|
||||
|
||||
+34
-26
@@ -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);
|
||||
|
||||
+14
-14
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user