diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 57 | ||||
-rw-r--r-- | Alc/ALu.c | 43 |
2 files changed, 70 insertions, 30 deletions
@@ -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); @@ -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); |