aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c65
-rw-r--r--Alc/ALu.c267
-rw-r--r--Alc/mixer.c2
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/Include/alSource.h104
-rw-r--r--OpenAL32/Include/alu.h5
-rw-r--r--OpenAL32/alAuxEffectSlot.c2
-rw-r--r--OpenAL32/alListener.c36
-rw-r--r--OpenAL32/alSource.c452
-rw-r--r--OpenAL32/alState.c48
10 files changed, 627 insertions, 356 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 47aa0f04..e5c18d8c 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1558,22 +1558,7 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS
*/
void ALCcontext_DeferUpdates(ALCcontext *context)
{
- ALCdevice *device = context->Device;
- FPUCtl oldMode;
-
- SetMixerFPUMode(&oldMode);
-
- V0(device->Backend,lock)();
- if(!context->DeferUpdates)
- {
- context->DeferUpdates = AL_TRUE;
-
- /* Make sure all pending updates are performed */
- UpdateContextSources(context);
- }
- V0(device->Backend,unlock)();
-
- RestoreFPUMode(&oldMode);
+ ATOMIC_STORE(&context->DeferUpdates, AL_TRUE);
}
/* ALCcontext_ProcessUpdates
@@ -1584,14 +1569,15 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
{
ALCdevice *device = context->Device;
- V0(device->Backend,lock)();
- if(context->DeferUpdates)
+ ReadLock(&context->PropLock);
+ if(ATOMIC_EXCHANGE(ALenum, &context->DeferUpdates, AL_FALSE))
{
ALsizei pos;
- context->DeferUpdates = AL_FALSE;
+ UpdateListenerProps(context);
LockUIntMapRead(&context->SourceMap);
+ V0(device->Backend,lock)();
for(pos = 0;pos < context->SourceMap.size;pos++)
{
ALsource *Source = context->SourceMap.array[pos].value;
@@ -1610,9 +1596,11 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
if(new_state)
SetSourceState(Source, context, new_state);
}
+ V0(device->Backend,unlock)();
UnlockUIntMapRead(&context->SourceMap);
+ UpdateAllSourceProps(context);
}
- V0(device->Backend,unlock)();
+ ReadUnlock(&context->PropLock);
}
@@ -2052,7 +2040,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
SetMixerFPUMode(&oldMode);
- V0(device->Backend,lock)();
if(device->DefaultSlot)
{
ALeffectslot *slot = device->DefaultSlot;
@@ -2062,7 +2049,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
state->OutChannels = device->Dry.NumChannels;
if(V(state,deviceUpdate)(device) == AL_FALSE)
{
- V0(device->Backend,unlock)();
RestoreFPUMode(&oldMode);
return ALC_INVALID_DEVICE;
}
@@ -2074,6 +2060,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
{
ALsizei pos;
+ ReadLock(&context->PropLock);
LockUIntMapRead(&context->EffectSlotMap);
for(pos = 0;pos < context->EffectSlotMap.size;pos++)
{
@@ -2085,10 +2072,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
if(V(state,deviceUpdate)(device) == AL_FALSE)
{
UnlockUIntMapRead(&context->EffectSlotMap);
- V0(device->Backend,unlock)();
+ ReadUnlock(&context->PropLock);
RestoreFPUMode(&oldMode);
return ALC_INVALID_DEVICE;
}
+
UpdateEffectSlotProps(slot, AL_FALSE);
}
UnlockUIntMapRead(&context->EffectSlotMap);
@@ -2105,38 +2093,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
source->Send[s].Slot = NULL;
source->Send[s].Gain = 1.0f;
source->Send[s].GainHF = 1.0f;
+ source->Send[s].HFReference = LOWPASSFREQREF;
+ source->Send[s].GainLF = 1.0f;
+ source->Send[s].LFReference = HIGHPASSFREQREF;
s++;
}
- ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE);
}
UnlockUIntMapRead(&context->SourceMap);
- for(pos = 0;pos < context->VoiceCount;pos++)
- {
- ALvoice *voice = &context->Voices[pos];
- ALsource *source = voice->Source;
- ALbufferlistitem *BufferListItem;
-
- if(!source)
- continue;
-
- BufferListItem = ATOMIC_LOAD(&source->queue);
- while(BufferListItem != NULL)
- {
- ALbuffer *buffer;
- if((buffer=BufferListItem->buffer) != NULL)
- {
- ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
- voice->Update(voice, source, buffer, context);
- break;
- }
- BufferListItem = BufferListItem->next;
- }
- }
+ UpdateAllSourceProps(context);
+ ReadUnlock(&context->PropLock);
context = context->next;
}
- V0(device->Backend,unlock)();
RestoreFPUMode(&oldMode);
if(!(device->Flags&DEVICE_PAUSED))
@@ -2308,7 +2277,7 @@ static ALvoid InitContext(ALCcontext *Context)
Context->DopplerFactor = 1.0f;
Context->DopplerVelocity = 1.0f;
Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
- Context->DeferUpdates = AL_FALSE;
+ ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
Context->ExtensionList = alExtList;
}
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 4a9a59cf..2fffdcd9 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -266,7 +266,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state)
}
-static ALboolean CalcListenerParams(ALCcontext *Context)
+static void CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALdouble N[3], V[3], U[3], P[3];
@@ -275,7 +275,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
aluVector vel;
props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel);
- if(!props) return AL_FALSE;
+ if(!props) return;
/* AT then UP */
N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed);
@@ -330,17 +330,15 @@ static ALboolean 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 ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
+static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
{
struct ALeffectslotProps *first;
struct ALeffectslotProps *props;
props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel);
- if(!props) return AL_FALSE;
+ if(!props) return;
slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed);
slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed);
@@ -377,11 +375,43 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
} while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*,
&slot->FreeList, &first, props) == 0);
+}
+
+static void CalcSourceParams(ALvoice *voice, ALCcontext *context)
+{
+ ALsource *source = voice->Source;
+ ALbufferlistitem *BufferListItem;
+ struct ALsourceProps *first;
+ 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)
+ {
+ ALbuffer *buffer;
+ if((buffer=BufferListItem->buffer) != NULL)
+ {
+ voice->Update(voice, props, buffer, context);
+ break;
+ }
+ BufferListItem = BufferListItem->next;
+ }
- return AL_TRUE;
+ /* 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);
}
-ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
+ALvoid CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
static const struct ChanMap MonoMap[1] = {
{ FrontCenter, 0.0f, 0.0f }
@@ -448,22 +478,22 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
ListenerGain = Listener->Params.Gain;
/* Get source properties */
- SourceVolume = ALSource->Gain;
- MinVolume = ALSource->MinGain;
- MaxVolume = ALSource->MaxGain;
- Pitch = ALSource->Pitch;
- Relative = ALSource->HeadRelative;
- DirectChannels = ALSource->DirectChannels;
+ SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed);
+ MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed);
+ MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed);
+ Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed);
+ Relative = ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed);
+ DirectChannels = ATOMIC_LOAD(&props->DirectChannels, almemory_order_relaxed);
/* Convert counter-clockwise to clockwise. */
- StereoMap[0].angle = -ALSource->StereoPan[0];
- StereoMap[1].angle = -ALSource->StereoPan[1];
+ StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed);
+ StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed);
voice->Direct.OutBuffer = Device->Dry.Buffer;
voice->Direct.OutChannels = Device->Dry.NumChannels;
for(i = 0;i < NumSends;i++)
{
- SendSlots[i] = ALSource->Send[i].Slot;
+ SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed);
if(!SendSlots[i] && i == 0)
SendSlots[i] = Device->DefaultSlot;
if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL)
@@ -489,15 +519,15 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
/* Calculate gains */
DryGain = clampf(SourceVolume, MinVolume, MaxVolume);
- DryGain *= ALSource->Direct.Gain * ListenerGain;
- DryGainHF = ALSource->Direct.GainHF;
- DryGainLF = ALSource->Direct.GainLF;
+ DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain;
+ DryGainHF = ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed);
+ DryGainLF = ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed);
for(i = 0;i < NumSends;i++)
{
WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume);
- WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
- WetGainHF[i] = ALSource->Send[i].GainHF;
- WetGainLF[i] = ALSource->Send[i].GainLF;
+ WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain;
+ WetGainHF[i] = ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed);
+ WetGainLF[i] = ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed);
}
switch(ALBuffer->FmtChannels)
@@ -557,13 +587,13 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
ALfloat scale;
/* AT then UP */
- N[0] = ALSource->Orientation[0][0];
- N[1] = ALSource->Orientation[0][1];
- N[2] = ALSource->Orientation[0][2];
+ N[0] = ATOMIC_LOAD(&props->Orientation[0][0], almemory_order_relaxed);
+ N[1] = ATOMIC_LOAD(&props->Orientation[0][1], almemory_order_relaxed);
+ N[2] = ATOMIC_LOAD(&props->Orientation[0][2], almemory_order_relaxed);
aluNormalize(N);
- V[0] = ALSource->Orientation[1][0];
- V[1] = ALSource->Orientation[1][1];
- V[2] = ALSource->Orientation[1][2];
+ V[0] = ATOMIC_LOAD(&props->Orientation[1][0], almemory_order_relaxed);
+ V[1] = ATOMIC_LOAD(&props->Orientation[1][1], almemory_order_relaxed);
+ V[2] = ATOMIC_LOAD(&props->Orientation[1][2], almemory_order_relaxed);
aluNormalize(V);
if(!Relative)
{
@@ -779,8 +809,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
}
{
- ALfloat hfscale = ALSource->Direct.HFReference / Frequency;
- ALfloat lfscale = ALSource->Direct.LFReference / Frequency;
+ ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) /
+ Frequency;
+ ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) /
+ Frequency;
DryGainHF = maxf(DryGainHF, 0.0001f);
DryGainLF = maxf(DryGainLF, 0.0001f);
for(c = 0;c < num_channels;c++)
@@ -800,8 +832,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
}
for(i = 0;i < NumSends;i++)
{
- ALfloat hfscale = ALSource->Send[i].HFReference / Frequency;
- ALfloat lfscale = ALSource->Send[i].LFReference / Frequency;
+ ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) /
+ Frequency;
+ ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) /
+ Frequency;
WetGainHF[i] = maxf(WetGainHF[i], 0.0001f);
WetGainLF[i] = maxf(WetGainLF[i], 0.0001f);
for(c = 0;c < num_channels;c++)
@@ -821,7 +855,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
}
}
-ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
+ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
const ALCdevice *Device = ALContext->Device;
const ALlistener *Listener = ALContext->Listener;
@@ -862,7 +896,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
}
/* Get context/device properties */
- DopplerFactor = Listener->Params.DopplerFactor * ALSource->DopplerFactor;
+ DopplerFactor = Listener->Params.DopplerFactor;
SpeedOfSound = Listener->Params.SpeedOfSound;
NumSends = Device->NumAuxSends;
Frequency = Device->Frequency;
@@ -872,29 +906,39 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
MetersPerUnit = Listener->Params.MetersPerUnit;
/* Get source properties */
- SourceVolume = ALSource->Gain;
- MinVolume = ALSource->MinGain;
- MaxVolume = ALSource->MaxGain;
- Pitch = ALSource->Pitch;
- Position = ALSource->Position;
- Direction = ALSource->Direction;
- Velocity = ALSource->Velocity;
- MinDist = ALSource->RefDistance;
- MaxDist = ALSource->MaxDistance;
- Rolloff = ALSource->RollOffFactor;
- InnerAngle = ALSource->InnerAngle;
- OuterAngle = ALSource->OuterAngle;
- AirAbsorptionFactor = ALSource->AirAbsorptionFactor;
- DryGainHFAuto = ALSource->DryGainHFAuto;
- WetGainAuto = ALSource->WetGainAuto;
- WetGainHFAuto = ALSource->WetGainHFAuto;
- RoomRolloffBase = ALSource->RoomRolloffFactor;
+ SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed);
+ MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed);
+ MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed);
+ Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed);
+ aluVectorSet(&Position, ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed),
+ 1.0f);
+ aluVectorSet(&Direction, ATOMIC_LOAD(&props->Direction[0], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Direction[1], almemory_order_relaxed),
+ ATOMIC_LOAD(&props->Direction[2], almemory_order_relaxed),
+ 0.0f);
+ aluVectorSet(&Velocity, 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);
+ MinDist = ATOMIC_LOAD(&props->RefDistance, almemory_order_relaxed);
+ MaxDist = ATOMIC_LOAD(&props->MaxDistance, almemory_order_relaxed);
+ Rolloff = ATOMIC_LOAD(&props->RollOffFactor, almemory_order_relaxed);
+ DopplerFactor *= ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed);
+ InnerAngle = ATOMIC_LOAD(&props->InnerAngle, almemory_order_relaxed);
+ OuterAngle = ATOMIC_LOAD(&props->OuterAngle, almemory_order_relaxed);
+ AirAbsorptionFactor = ATOMIC_LOAD(&props->AirAbsorptionFactor, almemory_order_relaxed);
+ DryGainHFAuto = ATOMIC_LOAD(&props->DryGainHFAuto, almemory_order_relaxed);
+ WetGainAuto = ATOMIC_LOAD(&props->WetGainAuto, almemory_order_relaxed);
+ WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed);
+ RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed);
voice->Direct.OutBuffer = Device->Dry.Buffer;
voice->Direct.OutChannels = Device->Dry.NumChannels;
for(i = 0;i < NumSends;i++)
{
- SendSlots[i] = ALSource->Send[i].Slot;
+ SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed);
if(!SendSlots[i] && i == 0)
SendSlots[i] = Device->DefaultSlot;
@@ -905,7 +949,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
DecayDistance[i] = 0.0f;
RoomAirAbsorption[i] = 1.0f;
}
- else if(SendSlots[i]->AuxSendAuto)
+ else if(SendSlots[i]->Params.AuxSendAuto)
{
RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + RoomRolloffBase;
DecayDistance[i] = SendSlots[i]->Params.DecayTime *
@@ -934,7 +978,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
}
/* Transform source to listener space (convert to head relative) */
- if(ALSource->HeadRelative == AL_FALSE)
+ if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE)
{
const aluMatrixd *Matrix = &Listener->Params.Matrix;
/* Transform source vectors */
@@ -964,8 +1008,9 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
Attenuation = 1.0f;
for(i = 0;i < NumSends;i++)
RoomAttenuation[i] = 1.0f;
- switch(Listener->Params.SourceDistanceModel ? ALSource->DistanceModel :
- Listener->Params.DistanceModel)
+ switch(Listener->Params.SourceDistanceModel ?
+ ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) :
+ Listener->Params.DistanceModel)
{
case InverseDistanceClamped:
ClampedDist = clampf(ClampedDist, MinDist, MaxDist);
@@ -1059,13 +1104,15 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
if(Angle > InnerAngle && Angle <= OuterAngle)
{
ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
- ConeVolume = lerp(1.0f, ALSource->OuterGain, scale);
- ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale);
+ ConeVolume = lerp(1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed),
+ scale);
+ ConeHF = lerp(1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed),
+ scale);
}
else if(Angle > OuterAngle)
{
- ConeVolume = ALSource->OuterGain;
- ConeHF = ALSource->OuterGainHF;
+ ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed);
+ ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed);
}
else
{
@@ -1093,14 +1140,14 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume);
/* Apply gain and frequency filters */
- DryGain *= ALSource->Direct.Gain * ListenerGain;
- DryGainHF *= ALSource->Direct.GainHF;
- DryGainLF *= ALSource->Direct.GainLF;
+ DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain;
+ DryGainHF *= ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed);
+ DryGainLF *= ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed);
for(i = 0;i < NumSends;i++)
{
- WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
- WetGainHF[i] *= ALSource->Send[i].GainHF;
- WetGainLF[i] *= ALSource->Send[i].GainLF;
+ WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain;
+ WetGainHF[i] *= ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed);
+ WetGainLF[i] *= ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed);
}
/* Calculate velocity-based doppler effect */
@@ -1139,7 +1186,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
*/
ALfloat dir[3] = { 0.0f, 0.0f, -1.0f };
ALfloat ev = 0.0f, az = 0.0f;
- ALfloat radius = ALSource->Radius;
+ ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed);
ALfloat coeffs[MAX_AMBI_COEFFS];
ALfloat spread = 0.0f;
@@ -1193,7 +1240,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
{
/* Non-HRTF rendering. */
ALfloat dir[3] = { 0.0f, 0.0f, -1.0f };
- ALfloat radius = ALSource->Radius;
+ ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed);
ALfloat coeffs[MAX_AMBI_COEFFS];
ALfloat spread = 0.0f;
@@ -1247,8 +1294,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
}
{
- ALfloat hfscale = ALSource->Direct.HFReference / Frequency;
- ALfloat lfscale = ALSource->Direct.LFReference / Frequency;
+ ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) /
+ Frequency;
+ ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) /
+ Frequency;
DryGainHF = maxf(DryGainHF, 0.0001f);
DryGainLF = maxf(DryGainLF, 0.0001f);
voice->Direct.Filters[0].ActiveType = AF_None;
@@ -1265,8 +1314,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
}
for(i = 0;i < NumSends;i++)
{
- ALfloat hfscale = ALSource->Send[i].HFReference / Frequency;
- ALfloat lfscale = ALSource->Send[i].LFReference / Frequency;
+ ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) /
+ Frequency;
+ ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) /
+ Frequency;
WetGainHF[i] = maxf(WetGainHF[i], 0.0001f);
WetGainLF[i] = maxf(WetGainLF[i], 0.0001f);
voice->Send[i].Filters[0].ActiveType = AF_None;
@@ -1287,69 +1338,22 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer
void UpdateContextSources(ALCcontext *ctx)
{
ALvoice *voice, *voice_end;
- ALboolean fullupdate;
ALsource *source;
- fullupdate = CalcListenerParams(ctx);
-#define UPDATE_SLOT(iter) do { \
- if(CalcEffectSlotParams(*iter, ctx->Device)) \
- fullupdate = AL_TRUE; \
-} while(0)
+ CalcListenerParams(ctx);
+#define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device)
VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT);
#undef UPDATE_SLOT
- if(fullupdate)
+ voice = ctx->Voices;
+ voice_end = voice + ctx->VoiceCount;
+ for(;voice != voice_end;++voice)
{
- voice = ctx->Voices;
- voice_end = voice + ctx->VoiceCount;
- for(;voice != voice_end;++voice)
- {
- if(!(source=voice->Source)) continue;
- if(source->state != AL_PLAYING && source->state != AL_PAUSED)
- voice->Source = NULL;
- else
- {
- ALbufferlistitem *BufferListItem;
- BufferListItem = ATOMIC_LOAD(&source->queue);
- while(BufferListItem != NULL)
- {
- ALbuffer *buffer;
- if((buffer=BufferListItem->buffer) != NULL)
- {
- ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
- voice->Update(voice, source, buffer, ctx);
- break;
- }
- BufferListItem = BufferListItem->next;
- }
- }
- }
- }
- else
- {
- voice = ctx->Voices;
- voice_end = voice + ctx->VoiceCount;
- for(;voice != voice_end;++voice)
- {
- if(!(source=voice->Source)) continue;
- if(source->state != AL_PLAYING && source->state != AL_PAUSED)
- voice->Source = NULL;
- else if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE))
- {
- ALbufferlistitem *BufferListItem;
- BufferListItem = ATOMIC_LOAD(&source->queue);
- while(BufferListItem != NULL)
- {
- ALbuffer *buffer;
- if((buffer=BufferListItem->buffer) != NULL)
- {
- voice->Update(voice, source, buffer, ctx);
- break;
- }
- BufferListItem = BufferListItem->next;
- }
- }
- }
+ if(!(source=voice->Source)) continue;
+ if(source->state != AL_PLAYING && source->state != AL_PAUSED)
+ voice->Source = NULL;
+ else
+ CalcSourceParams(voice, ctx);
}
}
@@ -1447,8 +1451,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ctx = ATOMIC_LOAD(&device->ContextList);
while(ctx)
{
- if(!ctx->DeferUpdates)
- UpdateContextSources(ctx);
+ UpdateContextSources(ctx);
#define CLEAR_WET_BUFFER(iter) do { \
for(i = 0;i < (*iter)->NumChannels;i++) \
memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \
diff --git a/Alc/mixer.c b/Alc/mixer.c
index 44495d72..38ec295c 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -388,9 +388,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
BufferListItem = ATOMIC_LOAD(&Source->current_buffer);
DataPosInt = Source->position;
DataPosFrac = Source->position_fraction;
- Looping = Source->Looping;
NumChannels = Source->NumChannels;
SampleSize = Source->SampleSize;
+ Looping = voice->Looping;
increment = voice->Step;
IrSize = (Device->Hrtf ? GetHrtfIrSize(Device->Hrtf) : 0);
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 44ce4fe0..a624e078 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -695,7 +695,7 @@ struct ALCcontext_struct {
volatile ALfloat DopplerFactor;
volatile ALfloat DopplerVelocity;
volatile ALfloat SpeedOfSound;
- volatile ALenum DeferUpdates;
+ ATOMIC(ALenum) DeferUpdates;
RWLock PropLock;
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 187d7e07..6d915153 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -13,6 +13,7 @@ extern "C" {
struct ALbuffer;
struct ALsource;
+struct ALsourceProps;
typedef struct ALbufferlistitem {
@@ -25,11 +26,13 @@ typedef struct ALvoice {
struct ALsource *volatile Source;
/** Method to update mixing parameters. */
- ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const struct ALbuffer *ALBuffer, const ALCcontext *context);
+ ALvoid (*Update)(struct ALvoice *self, const struct ALsourceProps *props, const struct ALbuffer *ALBuffer, const ALCcontext *context);
/** Current target parameters used for mixing. */
ALint Step;
+ ALboolean Looping;
+
/* If not 'moving', gain/coefficients are set directly without fading. */
ALboolean Moving;
@@ -46,6 +49,59 @@ typedef struct ALvoice {
} ALvoice;
+struct ALsourceProps {
+ ATOMIC(ALfloat) Pitch;
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) OuterGain;
+ ATOMIC(ALfloat) MinGain;
+ ATOMIC(ALfloat) MaxGain;
+ ATOMIC(ALfloat) InnerAngle;
+ ATOMIC(ALfloat) OuterAngle;
+ ATOMIC(ALfloat) RefDistance;
+ ATOMIC(ALfloat) MaxDistance;
+ ATOMIC(ALfloat) RollOffFactor;
+ ATOMIC(ALfloat) Position[3];
+ ATOMIC(ALfloat) Velocity[3];
+ ATOMIC(ALfloat) Direction[3];
+ ATOMIC(ALfloat) Orientation[2][3];
+ ATOMIC(ALboolean) HeadRelative;
+ ATOMIC(ALboolean) Looping;
+ ATOMIC(enum DistanceModel) DistanceModel;
+ ATOMIC(ALboolean) DirectChannels;
+
+ ATOMIC(ALboolean) DryGainHFAuto;
+ ATOMIC(ALboolean) WetGainAuto;
+ ATOMIC(ALboolean) WetGainHFAuto;
+ ATOMIC(ALfloat) OuterGainHF;
+
+ ATOMIC(ALfloat) AirAbsorptionFactor;
+ ATOMIC(ALfloat) RoomRolloffFactor;
+ ATOMIC(ALfloat) DopplerFactor;
+
+ ATOMIC(ALfloat) StereoPan[2];
+
+ ATOMIC(ALfloat) Radius;
+
+ /** Direct filter and auxiliary send info. */
+ struct {
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) GainHF;
+ ATOMIC(ALfloat) HFReference;
+ ATOMIC(ALfloat) GainLF;
+ ATOMIC(ALfloat) LFReference;
+ } Direct;
+ struct {
+ ATOMIC(struct ALeffectslot*) Slot;
+ ATOMIC(ALfloat) Gain;
+ ATOMIC(ALfloat) GainHF;
+ ATOMIC(ALfloat) HFReference;
+ ATOMIC(ALfloat) GainLF;
+ ATOMIC(ALfloat) LFReference;
+ } Send[MAX_SENDS];
+
+ ATOMIC(struct ALsourceProps*) next;
+};
+
typedef struct ALsource {
/** Source properties. */
volatile ALfloat Pitch;
@@ -58,9 +114,9 @@ typedef struct ALsource {
volatile ALfloat RefDistance;
volatile ALfloat MaxDistance;
volatile ALfloat RollOffFactor;
- aluVector Position;
- aluVector Velocity;
- aluVector Direction;
+ volatile ALfloat Position[3];
+ volatile ALfloat Velocity[3];
+ volatile ALfloat Direction[3];
volatile ALfloat Orientation[2][3];
volatile ALboolean HeadRelative;
volatile ALboolean Looping;
@@ -83,6 +139,23 @@ typedef struct ALsource {
volatile ALfloat Radius;
+ /** Direct filter and auxiliary send info. */
+ struct {
+ ALfloat Gain;
+ ALfloat GainHF;
+ ALfloat HFReference;
+ ALfloat GainLF;
+ ALfloat LFReference;
+ } Direct;
+ struct {
+ struct ALeffectslot *Slot;
+ ALfloat Gain;
+ ALfloat GainHF;
+ ALfloat HFReference;
+ ALfloat GainLF;
+ ALfloat LFReference;
+ } Send[MAX_SENDS];
+
/**
* Last user-specified offset, and the offset type (bytes, samples, or
* seconds).
@@ -114,25 +187,8 @@ typedef struct ALsource {
ALuint NumChannels;
ALuint SampleSize;
- /** Direct filter and auxiliary send info. */
- struct {
- ALfloat Gain;
- ALfloat GainHF;
- ALfloat HFReference;
- ALfloat GainLF;
- ALfloat LFReference;
- } Direct;
- struct {
- struct ALeffectslot *Slot;
- ALfloat Gain;
- ALfloat GainHF;
- ALfloat HFReference;
- ALfloat GainLF;
- ALfloat LFReference;
- } Send[MAX_SENDS];
-
- /** Source needs to update its mixing parameters. */
- ATOMIC(ALenum) NeedsUpdate;
+ ATOMIC(struct ALsourceProps*) Update;
+ ATOMIC(struct ALsourceProps*) FreeList;
/** Self ID */
ALuint id;
@@ -152,6 +208,8 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id)
inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id)
{ return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); }
+void UpdateSourceProps(ALsource *source, ALuint num_sends);
+void UpdateAllSourceProps(ALCcontext *context);
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state);
ALboolean ApplyOffset(ALsource *Source);
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index c20c6404..8e93dc6e 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -34,6 +34,7 @@ extern "C" {
#endif
struct ALsource;
+struct ALsourceProps;
struct ALvoice;
struct ALeffectslot;
struct ALbuffer;
@@ -375,8 +376,8 @@ void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, c
ALvoid UpdateContextSources(ALCcontext *context);
-ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext);
-ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext);
+ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext);
+ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext);
ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo);
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index 98ee9328..6d1423db 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -202,6 +202,8 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
slot->AuxSendAuto = value;
UpdateEffectSlotProps(slot, AL_FALSE);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ UpdateAllSourceProps(context);
break;
default:
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index 1c40c399..c59d644b 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -51,7 +51,11 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -88,7 +92,11 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -140,7 +148,11 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -161,7 +173,11 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value))
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -190,7 +206,11 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -235,7 +255,11 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index a62bf59e..e2d6ca4f 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -48,6 +48,7 @@ extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id);
extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id);
static ALvoid InitSourceParams(ALsource *Source);
+static ALvoid DeinitSource(ALsource *source);
static ALint64 GetSourceSampleOffset(ALsource *Source);
static ALdouble GetSourceSecOffset(ALsource *Source);
static ALdouble GetSourceOffset(ALsource *Source, ALenum name);
@@ -123,6 +124,12 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values);
static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values);
+static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context)
+{
+ return (source->state == AL_PLAYING || source->state == AL_PAUSED) &&
+ !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
+}
+
static ALint FloatValsByProp(ALenum prop)
{
if(prop != (ALenum)((SourceProp)prop))
@@ -376,8 +383,14 @@ static ALint Int64ValsByProp(ALenum prop)
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \
} while(0)
+#define DO_UPDATEPROPS() do { \
+ if(SourceShouldUpdate(Source, Context)) \
+ UpdateSourceProps(Source, device->NumAuxSends); \
+} while(0)
+
static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values)
{
+ ALCdevice *device = Context->Device;
ALint ival;
switch(prop)
@@ -393,98 +406,98 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
CHECKVAL(*values >= 0.0f);
Source->Pitch = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_INNER_ANGLE:
CHECKVAL(*values >= 0.0f && *values <= 360.0f);
Source->InnerAngle = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_ANGLE:
CHECKVAL(*values >= 0.0f && *values <= 360.0f);
Source->OuterAngle = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_GAIN:
CHECKVAL(*values >= 0.0f);
Source->Gain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MAX_DISTANCE:
CHECKVAL(*values >= 0.0f);
Source->MaxDistance = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ROLLOFF_FACTOR:
CHECKVAL(*values >= 0.0f);
Source->RollOffFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_REFERENCE_DISTANCE:
CHECKVAL(*values >= 0.0f);
Source->RefDistance = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MIN_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->MinGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_MAX_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->MaxGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_GAIN:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->OuterGain = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_CONE_OUTER_GAINHF:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->OuterGainHF = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AIR_ABSORPTION_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 10.0f);
Source->AirAbsorptionFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ROOM_ROLLOFF_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 10.0f);
Source->RoomRolloffFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DOPPLER_FACTOR:
CHECKVAL(*values >= 0.0f && *values <= 1.0f);
Source->DopplerFactor = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_SEC_OFFSET:
@@ -492,13 +505,13 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_BYTE_OFFSET:
CHECKVAL(*values >= 0.0f);
- LockContext(Context);
Source->OffsetType = prop;
Source->Offset = *values;
if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
- !Context->DeferUpdates)
+ !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire))
{
+ LockContext(Context);
WriteLock(&Source->queue_lock);
if(ApplyOffset(Source) == AL_FALSE)
{
@@ -507,68 +520,64 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
WriteUnlock(&Source->queue_lock);
+ UnlockContext(Context);
}
- UnlockContext(Context);
return AL_TRUE;
case AL_SOURCE_RADIUS:
CHECKVAL(*values >= 0.0f && isfinite(*values));
Source->Radius = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_STEREO_ANGLES:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]));
- LockContext(Context);
Source->StereoPan[0] = values[0];
Source->StereoPan[1] = values[1];
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_POSITION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Position, values[0], values[1], values[2], 1.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Position[0] = values[0];
+ Source->Position[1] = values[1];
+ Source->Position[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_VELOCITY:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Velocity, values[0], values[1], values[2], 0.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Velocity[0] = values[0];
+ Source->Velocity[1] = values[1];
+ Source->Velocity[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECTION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
- LockContext(Context);
- aluVectorSet(&Source->Direction, values[0], values[1], values[2], 0.0f);
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ Source->Direction[0] = values[0];
+ Source->Direction[1] = values[1];
+ Source->Direction[2] = values[2];
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_ORIENTATION:
CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) &&
isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]));
- LockContext(Context);
Source->Orientation[0][0] = values[0];
Source->Orientation[0][1] = values[1];
Source->Orientation[0][2] = values[2];
Source->Orientation[1][0] = values[3];
Source->Orientation[1][1] = values[4];
Source->Orientation[1][2] = values[5];
- UnlockContext(Context);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
@@ -626,13 +635,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->HeadRelative = (ALboolean)*values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_LOOPING:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->Looping = (ALboolean)*values;
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_BUFFER:
@@ -695,13 +705,13 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
case AL_BYTE_OFFSET:
CHECKVAL(*values >= 0);
- LockContext(Context);
Source->OffsetType = prop;
Source->Offset = *values;
if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
- !Context->DeferUpdates)
+ !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire))
{
+ LockContext(Context);
WriteLock(&Source->queue_lock);
if(ApplyOffset(Source) == AL_FALSE)
{
@@ -710,8 +720,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
WriteUnlock(&Source->queue_lock);
+ UnlockContext(Context);
}
- UnlockContext(Context);
return AL_TRUE;
case AL_DIRECT_FILTER:
@@ -722,7 +732,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
- LockContext(Context);
if(!filter)
{
Source->Direct.Gain = 1.0f;
@@ -739,37 +748,36 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->Direct.GainLF = filter->GainLF;
Source->Direct.LFReference = filter->LFReference;
}
- UnlockContext(Context);
UnlockFiltersRead(device);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECT_FILTER_GAINHF_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->DryGainHFAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->WetGainAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->WetGainHFAuto = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DIRECT_CHANNELS_SOFT:
CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
Source->DirectChannels = *values;
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_DISTANCE_MODEL:
@@ -783,27 +791,20 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->DistanceModel = *values;
if(Context->SourceDistanceModel)
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ DO_UPDATEPROPS();
return AL_TRUE;
case AL_AUXILIARY_SEND_FILTER:
LockFiltersRead(device);
- LockContext(Context);
if(!((ALuint)values[1] < device->NumAuxSends &&
(values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) &&
(values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)))
{
- UnlockContext(Context);
UnlockFiltersRead(device);
SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE);
}
- /* Add refcount on the new slot, and release the previous slot */
- if(slot) IncrementRef(&slot->ref);
- slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
- if(slot) DecrementRef(&slot->ref);
-
if(!filter)
{
/* Disable filter */
@@ -821,9 +822,28 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
Source->Send[values[1]].GainLF = filter->GainLF;
Source->Send[values[1]].LFReference = filter->LFReference;
}
- UnlockContext(Context);
UnlockFiltersRead(device);
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+
+ if(slot != Source->Send[values[1]].Slot &&
+ (Source->state == AL_PLAYING || Source->state == AL_PAUSED))
+ {
+ /* Add refcount on the new slot, and release the previous slot */
+ if(slot) IncrementRef(&slot->ref);
+ slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
+ if(slot) DecrementRef(&slot->ref);
+ /* We must force an update if the auxiliary slot changed on a
+ * playing source, in case the slot is about to be deleted.
+ */
+ UpdateSourceProps(Source, device->NumAuxSends);
+ }
+ else
+ {
+ if(slot) IncrementRef(&slot->ref);
+ slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
+ if(slot) DecrementRef(&slot->ref);
+ DO_UPDATEPROPS();
+ }
+
return AL_TRUE;
@@ -1078,10 +1098,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_STEREO_ANGLES:
- LockContext(Context);
values[0] = Source->StereoPan[0];
values[1] = Source->StereoPan[1];
- UnlockContext(Context);
return AL_TRUE;
case AL_SEC_OFFSET_LATENCY_SOFT:
@@ -1093,38 +1111,30 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p
return AL_TRUE;
case AL_POSITION:
- LockContext(Context);
- values[0] = Source->Position.v[0];
- values[1] = Source->Position.v[1];
- values[2] = Source->Position.v[2];
- UnlockContext(Context);
+ values[0] = Source->Position[0];
+ values[1] = Source->Position[1];
+ values[2] = Source->Position[2];
return AL_TRUE;
case AL_VELOCITY:
- LockContext(Context);
- values[0] = Source->Velocity.v[0];
- values[1] = Source->Velocity.v[1];
- values[2] = Source->Velocity.v[2];
- UnlockContext(Context);
+ values[0] = Source->Velocity[0];
+ values[1] = Source->Velocity[1];
+ values[2] = Source->Velocity[2];
return AL_TRUE;
case AL_DIRECTION:
- LockContext(Context);
- values[0] = Source->Direction.v[0];
- values[1] = Source->Direction.v[1];
- values[2] = Source->Direction.v[2];
- UnlockContext(Context);
+ values[0] = Source->Direction[0];
+ values[1] = Source->Direction[1];
+ values[2] = Source->Direction[2];
return AL_TRUE;
case AL_ORIENTATION:
- LockContext(Context);
values[0] = Source->Orientation[0][0];
values[1] = Source->Orientation[0][1];
values[2] = Source->Orientation[0][2];
values[3] = Source->Orientation[1][0];
values[4] = Source->Orientation[1][1];
values[5] = Source->Orientation[1][2];
- UnlockContext(Context);
return AL_TRUE;
/* 1x int */
@@ -1522,9 +1532,8 @@ done:
AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
{
ALCcontext *context;
- ALbufferlistitem *BufferList;
ALsource *Source;
- ALsizei i, j;
+ ALsizei i;
context = GetContextRef();
if(!context) return;
@@ -1559,22 +1568,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
}
UnlockContext(context);
- BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, NULL);
- while(BufferList != NULL)
- {
- ALbufferlistitem *next = BufferList->next;
- if(BufferList->buffer != NULL)
- DecrementRef(&BufferList->buffer->ref);
- free(BufferList);
- BufferList = next;
- }
-
- for(j = 0;j < MAX_SENDS;++j)
- {
- if(Source->Send[j].Slot)
- DecrementRef(&Source->Send[j].Slot->ref);
- Source->Send[j].Slot = NULL;
- }
+ DeinitSource(Source);
memset(Source, 0, sizeof(*Source));
al_free(Source);
@@ -1612,6 +1606,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1620,6 +1615,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
else
SetSourcefv(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1632,6 +1628,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1643,6 +1640,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1655,6 +1653,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1665,6 +1664,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat
else
SetSourcefv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1678,6 +1678,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1689,6 +1690,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va
SetSourcefv(Source, Context, param, &fval);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1701,6 +1703,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1712,6 +1715,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1725,6 +1729,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1742,6 +1747,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo
SetSourcefv(Source, Context, param, fvals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1755,6 +1761,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1763,6 +1770,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
else
SetSourceiv(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1775,6 +1783,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1786,6 +1795,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL
SetSourceiv(Source, Context, param, ivals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1798,6 +1808,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1808,6 +1819,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val
else
SetSourceiv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1821,6 +1833,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1829,6 +1842,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO
else
SetSourcei64v(Source, Context, param, &value);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1841,6 +1855,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1852,6 +1867,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF
SetSourcei64v(Source, Context, param, i64vals);
}
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1864,6 +1880,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin
Context = GetContextRef();
if(!Context) return;
+ WriteLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1874,6 +1891,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin
else
SetSourcei64v(Source, Context, param, values);
UnlockSourcesRead(Context);
+ WriteUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1887,6 +1905,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1901,6 +1920,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val
*value = (ALfloat)dval;
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1914,6 +1934,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1932,6 +1953,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1946,6 +1968,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1964,6 +1987,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1977,6 +2001,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -1987,6 +2012,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *
else
GetSourcedv(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -1999,6 +2025,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2017,6 +2044,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2029,6 +2057,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2039,6 +2068,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble
else
GetSourcedv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2052,6 +2082,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2062,6 +2093,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value
else
GetSourceiv(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2075,6 +2107,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2093,6 +2126,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2106,6 +2140,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2116,6 +2151,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values
else
GetSourceiv(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2129,6 +2165,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2139,6 +2176,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S
else
GetSourcei64v(Source, Context, param, value);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2151,6 +2189,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2169,6 +2208,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64
}
}
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2181,6 +2221,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
Context = GetContextRef();
if(!Context) return;
+ ReadLock(&Context->PropLock);
LockSourcesRead(Context);
if((Source=LookupSource(Context, source)) == NULL)
alSetError(Context, AL_INVALID_NAME);
@@ -2191,6 +2232,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64
else
GetSourcei64v(Source, Context, param, values);
UnlockSourcesRead(Context);
+ ReadUnlock(&Context->PropLock);
ALCcontext_DecRef(Context);
}
@@ -2241,8 +2283,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
for(i = 0;i < n;i++)
{
source = LookupSource(context, sources[i]);
- if(context->DeferUpdates) source->new_state = AL_PLAYING;
- else SetSourceState(source, context, AL_PLAYING);
+ if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ source->new_state = AL_PLAYING;
+ else
+ SetSourceState(source, context, AL_PLAYING);
}
UnlockContext(context);
@@ -2277,8 +2321,10 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources)
for(i = 0;i < n;i++)
{
source = LookupSource(context, sources[i]);
- if(context->DeferUpdates) source->new_state = AL_PAUSED;
- else SetSourceState(source, context, AL_PAUSED);
+ if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ source->new_state = AL_PAUSED;
+ else
+ SetSourceState(source, context, AL_PAUSED);
}
UnlockContext(context);
@@ -2594,9 +2640,15 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->InnerAngle = 360.0f;
Source->OuterAngle = 360.0f;
Source->Pitch = 1.0f;
- aluVectorSet(&Source->Position, 0.0f, 0.0f, 0.0f, 1.0f);
- aluVectorSet(&Source->Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
- aluVectorSet(&Source->Direction, 0.0f, 0.0f, 0.0f, 0.0f);
+ Source->Position[0] = 0.0f;
+ Source->Position[1] = 0.0f;
+ Source->Position[2] = 0.0f;
+ Source->Velocity[0] = 0.0f;
+ Source->Velocity[1] = 0.0f;
+ Source->Velocity[2] = 0.0f;
+ Source->Direction[0] = 0.0f;
+ Source->Direction[1] = 0.0f;
+ Source->Direction[2] = 0.0f;
Source->Orientation[0][0] = 0.0f;
Source->Orientation[0][1] = 0.0f;
Source->Orientation[0][2] = -1.0f;
@@ -2628,15 +2680,6 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->DistanceModel = DefaultDistanceModel;
- Source->state = AL_INITIAL;
- Source->new_state = AL_NONE;
- Source->SourceType = AL_UNDETERMINED;
- Source->OffsetType = AL_NONE;
- Source->Offset = 0.0;
-
- ATOMIC_INIT(&Source->queue, NULL);
- ATOMIC_INIT(&Source->current_buffer, NULL);
-
Source->Direct.Gain = 1.0f;
Source->Direct.GainHF = 1.0f;
Source->Direct.HFReference = LOWPASSFREQREF;
@@ -2651,7 +2694,170 @@ static ALvoid InitSourceParams(ALsource *Source)
Source->Send[i].LFReference = HIGHPASSFREQREF;
}
- ATOMIC_INIT(&Source->NeedsUpdate, AL_TRUE);
+ Source->state = AL_INITIAL;
+ Source->new_state = AL_NONE;
+ Source->SourceType = AL_UNDETERMINED;
+ Source->OffsetType = AL_NONE;
+ Source->Offset = 0.0;
+
+ ATOMIC_INIT(&Source->queue, NULL);
+ ATOMIC_INIT(&Source->current_buffer, NULL);
+
+ ATOMIC_INIT(&Source->Update, NULL);
+ ATOMIC_INIT(&Source->FreeList, NULL);
+}
+
+static ALvoid DeinitSource(ALsource *source)
+{
+ ALbufferlistitem *BufferList;
+ struct ALsourceProps *props;
+ size_t count = 0;
+ size_t i;
+
+ props = ATOMIC_LOAD(&source->Update);
+ if(props) al_free(props);
+
+ props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed);
+ while(props)
+ {
+ struct ALsourceProps *next;
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ al_free(props);
+ props = next;
+ ++count;
+ }
+ /* This is excessively spammy if it traces every source destruction, so
+ * just warn if it was unexpectedly large.
+ */
+ if(count > 3)
+ WARN("Freed "SZFMT" Source property objects\n", count);
+
+ BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NULL);
+ while(BufferList != NULL)
+ {
+ ALbufferlistitem *next = BufferList->next;
+ if(BufferList->buffer != NULL)
+ DecrementRef(&BufferList->buffer->ref);
+ free(BufferList);
+ BufferList = next;
+ }
+
+ for(i = 0;i < MAX_SENDS;++i)
+ {
+ if(source->Send[i].Slot)
+ DecrementRef(&source->Send[i].Slot->ref);
+ source->Send[i].Slot = NULL;
+ }
+}
+
+void UpdateSourceProps(ALsource *source, ALuint num_sends)
+{
+ struct ALsourceProps *props;
+ size_t i;
+
+ /* Get an unused property container, or allocate a new one as needed. */
+ props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire);
+ if(!props)
+ props = al_calloc(16, sizeof(*props));
+ else
+ {
+ struct ALsourceProps *next;
+ do {
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
+ &source->FreeList, &props, next, almemory_order_seq_cst,
+ almemory_order_consume) == 0);
+ }
+
+ /* Copy in current property values. */
+ ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed);
+ ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed);
+ for(i = 0;i < 3;i++)
+ ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed);
+ for(i = 0;i < 2;i++)
+ {
+ size_t j;
+ for(j = 0;j < 3;j++)
+ ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j],
+ almemory_order_relaxed);
+ }
+ ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed);
+ ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed);
+ ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed);
+ ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed);
+ ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed);
+ ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed);
+ ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed);
+
+ ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed);
+
+ for(i = 0;i < num_sends;i++)
+ {
+ ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference,
+ almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed);
+ ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference,
+ almemory_order_relaxed);
+ }
+
+ /* Set the new container for updating internal parameters. */
+ props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel);
+ if(props)
+ {
+ /* If there was an unused update container, put it back in the
+ * freelist.
+ */
+ struct ALsourceProps *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);
+ }
+}
+
+void UpdateAllSourceProps(ALCcontext *context)
+{
+ ALuint num_sends = context->Device->NumAuxSends;
+ ALsizei pos;
+ for(pos = 0;pos < context->VoiceCount;pos++)
+ {
+ ALvoice *voice = &context->Voices[pos];
+ ALsource *source = voice->Source;
+ if(source != NULL && (source->state == AL_PLAYING ||
+ source->state == AL_PAUSED))
+ UpdateSourceProps(source, num_sends);
+ }
+
}
@@ -2749,11 +2955,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
}
if(BufferList->buffer->FmtChannels == FmtMono)
- voice->Update = CalcSourceParams;
+ voice->Update = CalcAttnSourceParams;
else
voice->Update = CalcNonAttnSourceParams;
-
- ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE);
+ UpdateSourceProps(Source, device->NumAuxSends);
}
else if(state == AL_PAUSED)
{
@@ -3084,30 +3289,13 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac)
*/
ALvoid ReleaseALSources(ALCcontext *Context)
{
- ALbufferlistitem *item;
ALsizei pos;
- ALuint j;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *temp = Context->SourceMap.array[pos].value;
Context->SourceMap.array[pos].value = NULL;
- item = ATOMIC_EXCHANGE(ALbufferlistitem*, &temp->queue, NULL);
- while(item != NULL)
- {
- ALbufferlistitem *next = item->next;
- if(item->buffer != NULL)
- DecrementRef(&item->buffer->ref);
- free(item);
- item = next;
- }
-
- for(j = 0;j < MAX_SENDS;++j)
- {
- if(temp->Send[j].Slot)
- DecrementRef(&temp->Send[j].Slot->ref);
- temp->Send[j].Slot = NULL;
- }
+ DeinitSource(temp);
FreeThunkEntry(temp->id);
memset(temp, 0, sizeof(*temp));
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index c0c2ca82..e8a8d391 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -62,7 +62,11 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -86,7 +90,11 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
done:
WriteUnlock(&context->PropLock);
@@ -148,7 +156,7 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = context->DeferUpdates;
+ value = ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -188,7 +196,7 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALdouble)context->DeferUpdates;
+ value = (ALdouble)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -228,7 +236,7 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALfloat)context->DeferUpdates;
+ value = (ALfloat)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -268,7 +276,7 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALint)context->DeferUpdates;
+ value = (ALint)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -308,7 +316,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
break;
case AL_DEFERRED_UPDATES_SOFT:
- value = (ALint64SOFT)context->DeferUpdates;
+ value = (ALint64SOFT)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire);
break;
default:
@@ -554,7 +562,11 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerFactor = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -573,7 +585,11 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerVelocity = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -592,7 +608,11 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
WriteLock(&context->PropLock);
context->SpeedOfSound = value;
- UpdateListenerProps(context);
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
WriteUnlock(&context->PropLock);
done:
@@ -615,7 +635,13 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
WriteLock(&context->PropLock);
context->DistanceModel = value;
if(!context->SourceDistanceModel)
- UpdateListenerProps(context);
+ {
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ {
+ UpdateListenerProps(context);
+ UpdateAllSourceProps(context);
+ }
+ }
WriteUnlock(&context->PropLock);
done: