From cd24e42b3f7887867735db2cd35a0c4137163379 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 Feb 2017 11:17:47 -0800 Subject: [PATCH] Make the voices' Send[] array dynamically sized The voices are still all allocated in one chunk to avoid memory fragmentation. But they're accessed as an array of pointers since the size isn't static. --- Alc/ALc.c | 40 ++++++++++++++++++++++++++++------------ Alc/ALu.c | 22 +++++++++++----------- OpenAL32/Include/alMain.h | 2 +- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 16 ++++++++-------- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index c831ca9d..5a382d6e 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2607,21 +2607,26 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) ALsizei num_sends = device->NumAuxSends; struct ALsourceProps *props; size_t sizeof_props; - ALvoice *voices; + size_t sizeof_voice; + ALvoice **voices; + ALvoice *voice; ALsizei v = 0; size_t size; if(num_voices == context->MaxVoices && num_sends == old_sends) return; - /* Allocate the voices, and the voices' stored source property set - * (including the dynamically-sized Send[] array) in one chunk. + /* Allocate the voice pointers, voices, and the voices' stored source + * property set (including the dynamically-sized Send[] array) in one + * chunk. */ sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16); - size = sizeof(*voices) + sizeof_props; + sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16); + size = sizeof(ALvoice*) + sizeof_voice + sizeof_props; - voices = al_calloc(16, size * num_voices); - props = (struct ALsourceProps*)(voices + num_voices); + voices = al_calloc(16, RoundUp(size*num_voices, 16)); + voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16)); + props = (struct ALsourceProps*)((char*)voice + num_voices*sizeof_voice); if(context->Voices) { @@ -2634,23 +2639,34 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) /* Copy the old voice data and source property set to the new * storage. */ - voices[v] = context->Voices[v]; - *props = *(context->Voices[v].Props); + *voice = *(context->Voices[v]); for(i = 0;i < s_count;i++) - props->Send[i] = context->Voices[v].Props->Send[i]; + voice->Send[i] = context->Voices[v]->Send[i]; + *props = *(context->Voices[v]->Props); + for(i = 0;i < s_count;i++) + props->Send[i] = context->Voices[v]->Props->Send[i]; /* Set this voice's property set pointer and increment 'props' to * the next property storage space. */ - voices[v].Props = props; + voice->Props = props; props = (struct ALsourceProps*)((char*)props + sizeof_props); + + /* Set this voice's reference and increment 'voice' to the next + * voice storage space. + */ + voices[v] = voice; + voice = (ALvoice*)((char*)voice + sizeof_voice); } } - /* Finish setting the voices' property set pointers. */ + /* Finish setting the voices' property set pointers and references. */ for(;v < num_voices;v++) { - voices[v].Props = props; + voice->Props = props; props = (struct ALsourceProps*)((char*)props + sizeof_props); + + voices[v] = voice; + voice = (ALvoice*)((char*)voice + sizeof_voice); } al_free(context->Voices); diff --git a/Alc/ALu.c b/Alc/ALu.c index 1fca0ed0..edb23128 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1313,7 +1313,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) { - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; ALsource *source; IncrementRef(&ctx->UpdateCount); @@ -1330,11 +1330,11 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - if(!(source=voice->Source)) continue; + if(!(source=(*voice)->Source)) continue; if(!IsPlayingOrPaused(source)) - voice->Source = NULL; + (*voice)->Source = NULL; else - CalcSourceParams(voice, ctx, force); + CalcSourceParams(*voice, ctx, force); } } IncrementRef(&ctx->UpdateCount); @@ -1424,7 +1424,7 @@ DECL_TEMPLATE(ALbyte, aluF2B) void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { ALsizei SamplesToDo; - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; ALeffectslot *slot; ALsource *source; ALCcontext *ctx; @@ -1475,11 +1475,11 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - ALboolean IsVoiceInit = (voice->Step > 0); - source = voice->Source; + ALboolean IsVoiceInit = ((*voice)->Step > 0); + source = (*voice)->Source; if(IsVoiceInit && source && ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING) - MixSource(voice, source, device, SamplesToDo); + MixSource(*voice, source, device, SamplesToDo); } /* effect slot processing */ @@ -1637,15 +1637,15 @@ void aluHandleDisconnect(ALCdevice *device) Context = ATOMIC_LOAD_SEQ(&device->ContextList); while(Context) { - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; voice = Context->Voices; voice_end = voice + Context->VoiceCount; while(voice != voice_end) { ALenum playing = AL_PLAYING; - ALsource *source = voice->Source; - voice->Source = NULL; + ALsource *source = (*voice)->Source; + (*voice)->Source = NULL; if(source && ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED)) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index bb8a57ce..76862f38 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -812,7 +812,7 @@ struct ALCcontext_struct { ALfloat GainBoost; - struct ALvoice *Voices; + struct ALvoice **Voices; ALsizei VoiceCount; ALsizei MaxVoices; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index c63aef70..53e9a2f4 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -106,7 +106,7 @@ typedef struct ALvoice { ALfloat (*Buffer)[BUFFERSIZE]; ALsizei Channels; - } Send[MAX_SENDS]; + } Send[]; } ALvoice; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 395bc8c2..c541884b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -128,12 +128,12 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext *context) { - ALvoice *voice = context->Voices; - ALvoice *voice_end = voice + context->VoiceCount; + ALvoice **voice = context->Voices; + ALvoice **voice_end = voice + context->VoiceCount; while(voice != voice_end) { - if(voice->Source == source) - return voice; + if((*voice)->Source == source) + return *voice; ++voice; } return NULL; @@ -2915,7 +2915,7 @@ void UpdateAllSourceProps(ALCcontext *context) for(pos = 0;pos < context->VoiceCount;pos++) { - ALvoice *voice = &context->Voices[pos]; + ALvoice *voice = context->Voices[pos]; ALsource *source = voice->Source; if(source != NULL && source->NeedsUpdate && IsPlayingOrPaused(source)) { @@ -2982,16 +2982,16 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { for(i = 0;i < Context->VoiceCount;i++) { - if(Context->Voices[i].Source == NULL) + if(Context->Voices[i]->Source == NULL) { - voice = &Context->Voices[i]; + voice = Context->Voices[i]; voice->Source = Source; break; } } if(voice == NULL) { - voice = &Context->Voices[Context->VoiceCount++]; + voice = Context->Voices[Context->VoiceCount++]; voice->Source = Source; } discontinuity = AL_TRUE; -- 2.11.4.GIT