aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c35
-rw-r--r--Alc/ALu.c58
2 files changed, 71 insertions, 22 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index b8dae07c..058dd242 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2064,7 +2064,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
ALsizei pos;
- ATOMIC_STORE(&context->UpdateSources, AL_FALSE);
LockUIntMapRead(&context->EffectSlotMap);
for(pos = 0;pos < context->EffectSlotMap.size;pos++)
{
@@ -2272,11 +2271,16 @@ static ALCboolean VerifyDevice(ALCdevice **device)
static ALvoid InitContext(ALCcontext *Context)
{
ALlistener *listener = Context->Listener;
+
//Initialise listener
listener->Gain = 1.0f;
listener->MetersPerUnit = 1.0f;
- aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f);
- aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
+ listener->Position[0] = 0.0f;
+ listener->Position[1] = 0.0f;
+ listener->Position[2] = 0.0f;
+ listener->Velocity[0] = 0.0f;
+ listener->Velocity[1] = 0.0f;
+ listener->Velocity[2] = 0.0f;
listener->Forward[0] = 0.0f;
listener->Forward[1] = 0.0f;
listener->Forward[2] = -1.0f;
@@ -2296,9 +2300,12 @@ static ALvoid InitContext(ALCcontext *Context)
listener->Params.DopplerFactor = 1.0f;
listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
+ ATOMIC_INIT(&listener->Update, NULL);
+ ATOMIC_INIT(&listener->FreeList, NULL);
+
//Validate Context
+ RWLockInit(&Context->PropLock);
ATOMIC_INIT(&Context->LastError, AL_NO_ERROR);
- ATOMIC_INIT(&Context->UpdateSources, AL_FALSE);
InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
@@ -2321,6 +2328,10 @@ static ALvoid InitContext(ALCcontext *Context)
*/
static void FreeContext(ALCcontext *context)
{
+ ALlistener *listener = context->Listener;
+ struct ALlistenerProps *lprops;
+ size_t count;
+
TRACE("%p\n", context);
if(context->SourceMap.size > 0)
@@ -2344,6 +2355,22 @@ static void FreeContext(ALCcontext *context)
VECTOR_DEINIT(context->ActiveAuxSlots);
+ if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL)
+ {
+ TRACE("Freed unapplied listener update %p\n", lprops);
+ al_free(lprops);
+ }
+ count = 0;
+ lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_consume);
+ while(lprops)
+ {
+ struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_consume);
+ al_free(lprops);
+ lprops = next;
+ ++count;
+ }
+ TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s");
+
ALCdevice_DecRef(context->Device);
context->Device = NULL;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 709b7127..82553cc7 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -266,19 +266,25 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state)
}
-static ALvoid CalcListenerParams(ALCcontext *Context)
+static ALboolean CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALdouble N[3], V[3], U[3], P[3];
+ struct ALlistenerProps *first;
+ struct ALlistenerProps *props;
+ aluVector vel;
+
+ props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel);
+ if(!props) return AL_FALSE;
/* AT then UP */
- N[0] = Listener->Forward[0];
- N[1] = Listener->Forward[1];
- N[2] = Listener->Forward[2];
+ N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed);
+ N[1] = ATOMIC_LOAD(&props->Forward[1], almemory_order_relaxed);
+ N[2] = ATOMIC_LOAD(&props->Forward[2], almemory_order_relaxed);
aluNormalized(N);
- V[0] = Listener->Up[0];
- V[1] = Listener->Up[1];
- V[2] = Listener->Up[2];
+ V[0] = ATOMIC_LOAD(&props->Up[0], almemory_order_relaxed);
+ V[1] = ATOMIC_LOAD(&props->Up[1], almemory_order_relaxed);
+ V[2] = ATOMIC_LOAD(&props->Up[2], almemory_order_relaxed);
aluNormalized(V);
/* Build and normalize right-vector */
aluCrossproductd(N, V, U);
@@ -291,19 +297,37 @@ static ALvoid CalcListenerParams(ALCcontext *Context)
0.0, 0.0, 0.0, 1.0
);
- P[0] = Listener->Position.v[0];
- P[1] = Listener->Position.v[1];
- P[2] = Listener->Position.v[2];
+ P[0] = ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed);
+ P[1] = ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed);
+ P[2] = ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed);
aluMatrixdDouble3(P, 1.0, &Listener->Params.Matrix);
aluMatrixdSetRow(&Listener->Params.Matrix, 3, -P[0], -P[1], -P[2], 1.0f);
- Listener->Params.Velocity = aluMatrixdVector(&Listener->Params.Matrix, &Listener->Velocity);
+ aluVectorSet(&vel, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed),
+ 0.0f);
+ Listener->Params.Velocity = aluMatrixdVector(&Listener->Params.Matrix, &vel);
+
+ Listener->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed);
+ Listener->Params.MetersPerUnit = ATOMIC_LOAD(&props->MetersPerUnit, almemory_order_relaxed);
- Listener->Params.Gain = Listener->Gain;
- Listener->Params.MetersPerUnit = Listener->MetersPerUnit;
+ Listener->Params.DopplerFactor = ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed);
+ Listener->Params.SpeedOfSound = ATOMIC_LOAD(&props->SpeedOfSound, almemory_order_relaxed) *
+ ATOMIC_LOAD(&props->DopplerVelocity, almemory_order_relaxed);
- Listener->Params.DopplerFactor = Context->DopplerFactor;
- Listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity;
+ /* 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(&Listener->FreeList);
+ do {
+ ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*,
+ &Listener->FreeList, &first, props) == 0);
+
+ return AL_TRUE;
}
ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
@@ -1223,10 +1247,8 @@ void UpdateContextSources(ALCcontext *ctx)
ALvoice *voice, *voice_end;
ALsource *source;
- if(ATOMIC_EXCHANGE(ALenum, &ctx->UpdateSources, AL_FALSE))
+ if(CalcListenerParams(ctx))
{
- CalcListenerParams(ctx);
-
voice = ctx->Voices;
voice_end = voice + ctx->VoiceCount;
for(;voice != voice_end;++voice)