aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-04-17 21:16:01 -0700
committerChris Robinson <[email protected]>2017-04-17 21:16:01 -0700
commit14bc7baeb79f537cde9574934bee290908c43fb8 (patch)
treec4a902dfe02142296bbedfc9dbc25250a96e8333 /Alc
parent660971d0b73dc1abfc21827bd9b5e120a63944a2 (diff)
Store the source prop updates with the mixer voice
Also move its declaration and rename it for consistency.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c57
-rw-r--r--Alc/ALu.c43
2 files changed, 70 insertions, 30 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 7c6956ad..a352cacd 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2232,7 +2232,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
for(pos = 0;pos < context->SourceMap.size;pos++)
{
ALsource *source = context->SourceMap.values[pos];
- struct ALsourceProps *props;
if(old_sends != device->NumAuxSends)
{
@@ -2262,26 +2261,28 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release);
+ }
+ AllocateVoices(context, context->MaxVoices, old_sends);
+ for(pos = 0;pos < context->VoiceCount;pos++)
+ {
+ ALvoice *voice = context->Voices[pos];
+ struct ALvoiceProps *props;
- /* Clear any pre-existing source property structs, in case the
- * number of auxiliary sends changed. Playing (or paused) sources
- * will have updates respecified in UpdateAllSourceProps.
+ /* Clear any pre-existing voice property structs, in case the
+ * number of auxiliary sends changed. Active sources will have
+ * updates respecified in UpdateAllSourceProps.
*/
- props = ATOMIC_EXCHANGE_PTR_SEQ(&source->Update, NULL);
+ props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed);
al_free(props);
- props = ATOMIC_EXCHANGE_PTR(&source->FreeList, NULL, almemory_order_relaxed);
+ props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
while(props)
{
- struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
al_free(props);
props = next;
}
- }
- AllocateVoices(context, context->MaxVoices, old_sends);
- for(pos = 0;pos < context->VoiceCount;pos++)
- {
- ALvoice *voice = context->Voices[pos];
+
if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL)
continue;
@@ -2527,6 +2528,7 @@ static void FreeContext(ALCcontext *context)
struct ALeffectslotArray *auxslots;
struct ALlistenerProps *lprops;
size_t count;
+ ALsizei i;
TRACE("%p\n", context);
@@ -2549,6 +2551,8 @@ static void FreeContext(ALCcontext *context)
}
ResetUIntMap(&context->EffectSlotMap);
+ for(i = 0;i < context->VoiceCount;i++)
+ DeinitVoice(context->Voices[i]);
al_free(context->Voices);
context->Voices = NULL;
context->VoiceCount = 0;
@@ -2706,7 +2710,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
{
ALCdevice *device = context->Device;
ALsizei num_sends = device->NumAuxSends;
- struct ALsourceProps *props;
+ struct ALvoiceProps *props;
size_t sizeof_props;
size_t sizeof_voice;
ALvoice **voices;
@@ -2721,7 +2725,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
* property set (including the dynamically-sized Send[] array) in one
* chunk.
*/
- sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16);
+ sizeof_props = RoundUp(offsetof(struct ALvoiceProps, Send[num_sends]), 16);
sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16);
size = sizeof(ALvoice*) + sizeof_voice + sizeof_props;
@@ -2730,7 +2734,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
* paired together.
*/
voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16));
- props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
+ props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
if(context->Voices)
{
@@ -2738,17 +2742,18 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
for(;v < v_count;v++)
{
ALsizei s_count = mini(old_sends, num_sends);
+ ALvoice *old_voice = context->Voices[v];
ALsizei i;
/* Copy the old voice data and source property set to the new
* storage.
*/
- *voice = *(context->Voices[v]);
+ *voice = *old_voice;
for(i = 0;i < s_count;i++)
- voice->Send[i] = context->Voices[v]->Send[i];
- *props = *(context->Voices[v]->Props);
+ voice->Send[i] = old_voice->Send[i];
+ *props = *(old_voice->Props);
for(i = 0;i < s_count;i++)
- props->Send[i] = context->Voices[v]->Props->Send[i];
+ props->Send[i] = old_voice->Props->Send[i];
/* Set this voice's property set pointer and voice reference. */
voice->Props = props;
@@ -2756,17 +2761,27 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
/* Increment pointers to the next storage space. */
voice = (ALvoice*)((char*)props + sizeof_props);
- props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
+ props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
}
+ /* Deinit any left over voices that weren't copied over to the new
+ * array. NOTE: If this does anything, v equals num_voices and
+ * num_voices is less than VoiceCount, so the following loop won't do
+ * anything.
+ */
+ for(;v < context->VoiceCount;v++)
+ DeinitVoice(context->Voices[v]);
}
/* Finish setting the voices' property set pointers and references. */
for(;v < num_voices;v++)
{
+ ATOMIC_INIT(&voice->Update, NULL);
+ ATOMIC_INIT(&voice->FreeList, NULL);
+
voice->Props = props;
voices[v] = voice;
voice = (ALvoice*)((char*)props + sizeof_props);
- props = (struct ALsourceProps*)((char*)voice + sizeof_voice);
+ props = (struct ALvoiceProps*)((char*)voice + sizeof_voice);
}
al_free(context->Voices);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 89689fba..4a4709b0 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -100,6 +100,31 @@ const aluMatrixf IdentityMatrixf = {{
}};
+void DeinitVoice(ALvoice *voice)
+{
+ struct ALvoiceProps *props;
+ size_t count = 0;
+
+ props = ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL);
+ if(props) al_free(props);
+
+ props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed);
+ while(props)
+ {
+ struct ALvoiceProps *next;
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ al_free(props);
+ props = next;
+ ++count;
+ }
+ /* This is excessively spammy if it traces every voice destruction, so just
+ * warn if it was unexpectedly large.
+ */
+ if(count > 3)
+ WARN("Freed "SZFMT" voice property objects\n", count);
+}
+
+
static inline HrtfDirectMixerFunc SelectHrtfMixer(void)
{
#ifdef HAVE_NEON
@@ -324,7 +349,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
}
-static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
+static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
static const struct ChanMap MonoMap[1] = {
{ FrontCenter, 0.0f, 0.0f }
@@ -749,7 +774,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *
}
}
-static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
+static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext)
{
const ALCdevice *Device = ALContext->Device;
const ALlistener *Listener = ALContext->Listener;
@@ -1247,24 +1272,24 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro
}
}
-static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *context, ALboolean force)
+static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force)
{
const ALbufferlistitem *BufferListItem;
- struct ALsourceProps *props;
+ struct ALvoiceProps *props;
- props = ATOMIC_EXCHANGE_PTR(&source->Update, NULL, almemory_order_acq_rel);
+ props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel);
if(!props && !force) return;
if(props)
{
memcpy(voice->Props, props,
- offsetof(struct ALsourceProps, Send[context->Device->NumAuxSends])
+ offsetof(struct ALvoiceProps, Send[context->Device->NumAuxSends])
);
- ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props);
+ ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props);
}
- BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
+ BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed);
while(BufferListItem != NULL)
{
const ALbuffer *buffer;
@@ -1299,7 +1324,7 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray
for(;voice != voice_end;++voice)
{
source = ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire);
- if(source) CalcSourceParams(*voice, source, ctx, force);
+ if(source) CalcSourceParams(*voice, ctx, force);
}
}
IncrementRef(&ctx->UpdateCount);