aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c51
-rw-r--r--Alc/ALu.c52
-rw-r--r--OpenAL32/Include/alListener.h19
-rw-r--r--OpenAL32/Include/alMain.h5
-rw-r--r--OpenAL32/Include/alu.h2
-rw-r--r--OpenAL32/alListener.c18
-rw-r--r--OpenAL32/alState.c51
7 files changed, 138 insertions, 60 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 901b5447..cef5749d 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1669,6 +1669,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0)
althrd_yield();
+ UpdateContextProps(context);
UpdateListenerProps(context);
UpdateAllEffectSlotProps(context);
UpdateAllSourceProps(context);
@@ -2519,7 +2520,6 @@ static ALvoid InitContext(ALCcontext *Context)
//Initialise listener
listener->Gain = 1.0f;
- listener->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT;
listener->Position[0] = 0.0f;
listener->Position[1] = 0.0f;
listener->Position[2] = 0.0f;
@@ -2533,19 +2533,6 @@ static ALvoid InitContext(ALCcontext *Context)
listener->Up[1] = 1.0f;
listener->Up[2] = 0.0f;
- aluMatrixfSet(&listener->Params.Matrix,
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f
- );
- aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
- listener->Params.Gain = 1.0f;
- listener->Params.MetersPerUnit = listener->MetersPerUnit;
- listener->Params.DopplerFactor = 1.0f;
- listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
- listener->Params.ReverbSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
-
ATOMIC_INIT(&listener->Update, NULL);
ATOMIC_INIT(&listener->FreeList, NULL);
@@ -2577,9 +2564,28 @@ static ALvoid InitContext(ALCcontext *Context)
Context->DopplerFactor = 1.0f;
Context->DopplerVelocity = 1.0f;
Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
+ Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT;
ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
+ ATOMIC_INIT(&Context->Update, NULL);
+ ATOMIC_INIT(&Context->FreeList, NULL);
+
Context->ExtensionList = alExtList;
+
+
+ aluMatrixfSet(&listener->Params.Matrix,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ );
+ aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
+ listener->Params.Gain = listener->Gain;
+ listener->Params.MetersPerUnit = Context->MetersPerUnit;
+ listener->Params.DopplerFactor = Context->DopplerFactor;
+ listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity;
+ listener->Params.ReverbSpeedOfSound = listener->Params.SpeedOfSound *
+ listener->Params.MetersPerUnit;
}
@@ -2593,11 +2599,28 @@ static void FreeContext(ALCcontext *context)
ALlistener *listener = context->Listener;
struct ALeffectslotArray *auxslots;
struct ALlistenerProps *lprops;
+ struct ALcontextProps *cprops;
size_t count;
ALsizei i;
TRACE("%p\n", context);
+ if((cprops=ATOMIC_LOAD(&context->Update, almemory_order_acquire)) != NULL)
+ {
+ TRACE("Freed unapplied context update %p\n", cprops);
+ al_free(cprops);
+ }
+ count = 0;
+ cprops = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire);
+ while(cprops)
+ {
+ struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire);
+ al_free(cprops);
+ cprops = next;
+ ++count;
+ }
+ TRACE("Freed "SZFMT" context property object%s\n", count, (count==1)?"":"s");
+
if(context->DefaultSlot)
{
DeinitEffectSlot(context->DefaultSlot);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index a2ea4811..20b2d817 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -271,7 +271,30 @@ ALboolean BsincPrepare(const ALuint increment, BsincState *state, const BSincTab
}
-static ALboolean CalcListenerParams(ALCcontext *Context)
+static bool CalcContextParams(ALCcontext *Context)
+{
+ ALlistener *Listener = Context->Listener;
+ struct ALcontextProps *props;
+
+ props = ATOMIC_EXCHANGE_PTR(&Context->Update, NULL, almemory_order_acq_rel);
+ if(!props) return false;
+
+ Listener->Params.MetersPerUnit = props->MetersPerUnit;
+
+ Listener->Params.DopplerFactor = props->DopplerFactor;
+ Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity;
+ if(!OverrideReverbSpeedOfSound)
+ Listener->Params.ReverbSpeedOfSound = Listener->Params.SpeedOfSound *
+ Listener->Params.MetersPerUnit;
+
+ Listener->Params.SourceDistanceModel = props->SourceDistanceModel;
+ Listener->Params.DistanceModel = props->DistanceModel;
+
+ ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeList, props);
+ return true;
+}
+
+static bool CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALfloat N[3], V[3], U[3], P[3];
@@ -279,7 +302,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
aluVector vel;
props = ATOMIC_EXCHANGE_PTR(&Listener->Update, NULL, almemory_order_acq_rel);
- if(!props) return AL_FALSE;
+ if(!props) return false;
/* AT then UP */
N[0] = props->Forward[0];
@@ -311,30 +334,18 @@ static ALboolean CalcListenerParams(ALCcontext *Context)
Listener->Params.Velocity = aluMatrixfVector(&Listener->Params.Matrix, &vel);
Listener->Params.Gain = props->Gain * Context->GainBoost;
- Listener->Params.MetersPerUnit = props->MetersPerUnit;
-
- Listener->Params.DopplerFactor = props->DopplerFactor;
- Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity;
- if(OverrideReverbSpeedOfSound)
- Listener->Params.ReverbSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
- else
- Listener->Params.ReverbSpeedOfSound = Listener->Params.SpeedOfSound *
- Listener->Params.MetersPerUnit;
-
- Listener->Params.SourceDistanceModel = props->SourceDistanceModel;
- Listener->Params.DistanceModel = props->DistanceModel;
ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props);
- return AL_TRUE;
+ return true;
}
-static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
+static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
{
struct ALeffectslotProps *props;
ALeffectState *state;
props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel);
- if(!props) return AL_FALSE;
+ if(!props) return false;
slot->Params.Gain = props->Gain;
slot->Params.AuxSendAuto = props->AuxSendAuto;
@@ -366,7 +377,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context)
V(state,update)(context, slot, &props->Props);
ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props);
- return AL_TRUE;
+ return true;
}
@@ -1430,7 +1441,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop
WetGainLF, WetGainHF, SendSlots, ALBuffer, props, Listener, Device);
}
-static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force)
+static void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
{
ALbufferlistitem *BufferListItem;
struct ALvoiceProps *props;
@@ -1475,7 +1486,8 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray
IncrementRef(&ctx->UpdateCount);
if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire))
{
- ALboolean force = CalcListenerParams(ctx);
+ ALboolean cforce = CalcContextParams(ctx);
+ ALboolean force = CalcListenerParams(ctx) | cforce;
for(i = 0;i < slots->count;i++)
force |= CalcEffectSlotParams(slots->slot[i], ctx);
diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h
index eb386f7f..ae66b0e3 100644
--- a/OpenAL32/Include/alListener.h
+++ b/OpenAL32/Include/alListener.h
@@ -8,19 +8,23 @@
extern "C" {
#endif
+struct ALcontextProps {
+ ALfloat DopplerFactor;
+ ALfloat DopplerVelocity;
+ ALfloat SpeedOfSound;
+ ALboolean SourceDistanceModel;
+ enum DistanceModel DistanceModel;
+ ALfloat MetersPerUnit;
+
+ ATOMIC(struct ALcontextProps*) next;
+};
+
struct ALlistenerProps {
ALfloat Position[3];
ALfloat Velocity[3];
ALfloat Forward[3];
ALfloat Up[3];
ALfloat Gain;
- ALfloat MetersPerUnit;
-
- ALfloat DopplerFactor;
- ALfloat DopplerVelocity;
- ALfloat SpeedOfSound;
- ALboolean SourceDistanceModel;
- enum DistanceModel DistanceModel;
ATOMIC(struct ALlistenerProps*) next;
};
@@ -31,7 +35,6 @@ typedef struct ALlistener {
ALfloat Forward[3];
ALfloat Up[3];
ALfloat Gain;
- ALfloat MetersPerUnit;
/* Pointer to the most recent property values that are awaiting an update.
*/
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 614c3b43..95137972 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -382,6 +382,7 @@ struct Hrtf;
struct HrtfEntry;
struct FrontStablizer;
struct Compressor;
+struct ALcontextProps;
#define DEFAULT_OUTPUT_RATE (44100)
@@ -851,6 +852,7 @@ struct ALCcontext_struct {
ALfloat DopplerFactor;
ALfloat DopplerVelocity;
ALfloat SpeedOfSound;
+ ALfloat MetersPerUnit;
ATOMIC(ALenum) DeferUpdates;
RWLock PropLock;
@@ -863,6 +865,9 @@ struct ALCcontext_struct {
ALfloat GainBoost;
+ ATOMIC(struct ALcontextProps*) Update;
+ ATOMIC(struct ALcontextProps*) FreeList;
+
struct ALvoice **Voices;
ALsizei VoiceCount;
ALsizei MaxVoices;
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 1295fee3..2344cc6d 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -514,6 +514,8 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples);
/* Caller must lock the device. */
void aluHandleDisconnect(ALCdevice *device);
+void UpdateContextProps(ALCcontext *context);
+
extern ALfloat ConeScale;
extern ALfloat ZScale;
extern ALboolean OverrideReverbSpeedOfSound;
diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c
index 5a12673d..a4471539 100644
--- a/OpenAL32/alListener.c
+++ b/OpenAL32/alListener.c
@@ -21,7 +21,7 @@
#include "config.h"
#include "alMain.h"
-#include "AL/alc.h"
+#include "alu.h"
#include "alError.h"
#include "alListener.h"
#include "alSource.h"
@@ -45,8 +45,10 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
case AL_METERS_PER_UNIT:
if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT))
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
- context->Listener->MetersPerUnit = value;
- break;
+ context->MetersPerUnit = value;
+ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
+ UpdateContextProps(context);
+ goto done;
default:
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
@@ -266,7 +268,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
break;
case AL_METERS_PER_UNIT:
- *value = context->Listener->MetersPerUnit;
+ *value = context->MetersPerUnit;
break;
default:
@@ -489,14 +491,6 @@ void UpdateListenerProps(ALCcontext *context)
props->Up[2] = listener->Up[2];
props->Gain = listener->Gain;
- props->MetersPerUnit = listener->MetersPerUnit;
-
- props->DopplerFactor = context->DopplerFactor;
- props->DopplerVelocity = context->DopplerVelocity;
- props->SpeedOfSound = context->SpeedOfSound;
-
- props->SourceDistanceModel = context->SourceDistanceModel;
- props->DistanceModel = context->DistanceModel;;
/* Set the new container for updating internal parameters. */
props = ATOMIC_EXCHANGE_PTR(&listener->Update, props, almemory_order_acq_rel);
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 48c3498a..86534efb 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -72,7 +72,7 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
done:
WriteUnlock(&context->PropLock);
@@ -97,7 +97,7 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
done:
WriteUnlock(&context->PropLock);
@@ -648,7 +648,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerFactor = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -668,7 +668,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerVelocity = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -688,7 +688,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
WriteLock(&context->PropLock);
context->SpeedOfSound = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -713,7 +713,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
if(!context->SourceDistanceModel)
{
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
}
WriteUnlock(&context->PropLock);
@@ -779,3 +779,42 @@ done:
return value;
}
+
+
+void UpdateContextProps(ALCcontext *context)
+{
+ struct ALcontextProps *props;
+
+ /* Get an unused proprty container, or allocate a new one as needed. */
+ props = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire);
+ if(!props)
+ props = al_calloc(16, sizeof(*props));
+ else
+ {
+ struct ALcontextProps *next;
+ do {
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeList, &props, next,
+ almemory_order_seq_cst, almemory_order_acquire) == 0);
+ }
+
+ /* Copy in current property values. */
+ props->MetersPerUnit = context->MetersPerUnit;
+
+ props->DopplerFactor = context->DopplerFactor;
+ props->DopplerVelocity = context->DopplerVelocity;
+ props->SpeedOfSound = context->SpeedOfSound;
+
+ props->SourceDistanceModel = context->SourceDistanceModel;
+ props->DistanceModel = context->DistanceModel;
+
+ /* Set the new container for updating internal parameters. */
+ props = ATOMIC_EXCHANGE_PTR(&context->Update, props, almemory_order_acq_rel);
+ if(props)
+ {
+ /* If there was an unused update container, put it back in the
+ * freelist.
+ */
+ ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeList, props);
+ }
+}