diff options
-rw-r--r-- | Alc/ALc.c | 8 | ||||
-rw-r--r-- | Alc/ALu.c | 40 | ||||
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 67 |
5 files changed, 59 insertions, 60 deletions
@@ -2324,8 +2324,6 @@ static void FreeContext(ALCcontext *context) context->VoiceCount = 0; context->MaxVoices = 0; - VECTOR_DEINIT(context->ActiveAuxSlots); - if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL) { TRACE("Freed unapplied listener update %p\n", lprops); @@ -3115,7 +3113,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin InitRef(&ALContext->ref, 1); ALContext->Listener = (ALlistener*)ALContext->_listener_mem; - VECTOR_INIT(ALContext->ActiveAuxSlots); + ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL); ALContext->VoiceCount = 0; ALContext->MaxVoices = 256; @@ -3130,8 +3128,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin al_free(ALContext->Voices); ALContext->Voices = NULL; - VECTOR_DEINIT(ALContext->ActiveAuxSlots); - al_free(ALContext); ALContext = NULL; } @@ -3148,8 +3144,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin al_free(ALContext->Voices); ALContext->Voices = NULL; - VECTOR_DEINIT(ALContext->ActiveAuxSlots); - al_free(ALContext); ALContext = NULL; @@ -1320,7 +1320,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context) } -static void UpdateContextSources(ALCcontext *ctx) +static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) { ALvoice *voice, *voice_end; ALsource *source; @@ -1329,9 +1329,11 @@ static void UpdateContextSources(ALCcontext *ctx) if(!ATOMIC_LOAD(&ctx->HoldUpdates)) { CalcListenerParams(ctx); -#define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); -#undef UPDATE_SLOT + while(slot) + { + CalcEffectSlotParams(slot, ctx->Device); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; @@ -1440,13 +1442,18 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) { - UpdateContextSources(ctx); -#define CLEAR_WET_BUFFER(iter) do { \ - for(i = 0;i < (*iter)->NumChannels;i++) \ - memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ -} while(0) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, CLEAR_WET_BUFFER); -#undef CLEAR_WET_BUFFER + ALeffectslot *slotroot; + + slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList); + UpdateContextSources(ctx, slotroot); + + slot = slotroot; + while(slot) + { + for(i = 0;i < slot->NumChannels;i++) + memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } /* source processing */ voice = ctx->Voices; @@ -1459,13 +1466,14 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) } /* effect slot processing */ - c = VECTOR_SIZE(ctx->ActiveAuxSlots); - for(i = 0;i < c;i++) + slot = slotroot; + while(slot) { - const ALeffectslot *slot = VECTOR_ELEM(ctx->ActiveAuxSlots, i); - ALeffectState *state = slot->Params.EffectState; - V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, + const ALeffectslot *cslot = slot; + ALeffectState *state = cslot->Params.EffectState; + V(state,process)(SamplesToDo, cslot->WetBuffer, state->OutBuffer, state->OutChannels); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } ctx = ctx->next; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 85d730f8..a9b50387 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -129,6 +129,8 @@ typedef struct ALeffectslot { * first-order device output (FOAOut). */ alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]; + + ATOMIC(struct ALeffectslot*) next; } ALeffectslot; inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 50162b0e..d7b54310 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -711,7 +711,7 @@ struct ALCcontext_struct { ALsizei VoiceCount; ALsizei MaxVoices; - VECTOR(struct ALeffectslot*) ActiveAuxSlots; + ATOMIC(struct ALeffectslot*) ActiveAuxSlotList; ALCdevice *Device; const ALCchar *ExtensionList; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index c37ecd58..8da7aeb2 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -38,8 +38,8 @@ extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); -static ALenum AddEffectSlotArray(ALCcontext *Context, ALeffectslot **start, ALsizei count); -static void RemoveEffectSlotArray(ALCcontext *Context, const ALeffectslot *slot); +static void AddEffectSlotList(ALCcontext *Context, ALeffectslot *first, ALeffectslot *last); +static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot); static UIntMap EffectStateFactoryMap; @@ -55,20 +55,17 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *context; - VECTOR(ALeffectslot*) slotvec; + ALeffectslot *first, *last; ALsizei cur; ALenum err; context = GetContextRef(); if(!context) return; - VECTOR_INIT(slotvec); - if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if(!VECTOR_RESERVE(slotvec, n)) - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + first = last = NULL; for(cur = 0;cur < n;cur++) { ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); @@ -95,20 +92,15 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo aluInitEffectPanning(slot); - VECTOR_PUSH_BACK(slotvec, slot); + if(!first) first = slot; + if(last) ATOMIC_STORE(&last->next, slot); + last = slot; effectslots[cur] = slot->id; } - err = AddEffectSlotArray(context, VECTOR_BEGIN(slotvec), n); - if(err != AL_NO_ERROR) - { - alDeleteAuxiliaryEffectSlots(cur, effectslots); - SET_ERROR_AND_GOTO(context, err, done); - } + AddEffectSlotList(context, first, last); done: - VECTOR_DEINIT(slotvec); - ALCcontext_DecRef(context); } @@ -138,7 +130,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * continue; FreeThunkEntry(slot->id); - RemoveEffectSlotArray(context, slot); + RemoveEffectSlotList(context, slot); DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); @@ -399,32 +391,33 @@ done: } -static ALenum AddEffectSlotArray(ALCcontext *context, ALeffectslot **start, ALsizei count) +static void AddEffectSlotList(ALCcontext *context, ALeffectslot *start, ALeffectslot *last) { - ALenum err = AL_NO_ERROR; - - LockContext(context); - if(!VECTOR_INSERT(context->ActiveAuxSlots, VECTOR_END(context->ActiveAuxSlots), start, start+count)) - err = AL_OUT_OF_MEMORY; - UnlockContext(context); - - return err; + ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); + do { + ATOMIC_STORE(&last->next, root, almemory_order_relaxed); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, + &root, start)); } -static void RemoveEffectSlotArray(ALCcontext *context, const ALeffectslot *slot) +static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot) { - ALeffectslot **iter; + ALCdevice *device = context->Device; + const ALeffectslot *root, *next; - LockContext(context); -#define MATCH_SLOT(_i) (slot == *(_i)) - VECTOR_FIND_IF(iter, ALeffectslot*, context->ActiveAuxSlots, MATCH_SLOT); - if(iter != VECTOR_END(context->ActiveAuxSlots)) + root = slot; + next = ATOMIC_LOAD(&slot->next); + if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) { - *iter = VECTOR_BACK(context->ActiveAuxSlots); - VECTOR_POP_BACK(context->ActiveAuxSlots); + const ALeffectslot *cur; + do { + cur = root; + root = slot; + } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next)); } -#undef MATCH_SLOT - UnlockContext(context); + /* Wait for any mix that may be using these effect slots to finish. */ + while((ReadRef(&device->MixCount)&1) != 0) + althrd_yield(); } @@ -539,6 +532,8 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; + ATOMIC_INIT(&slot->next, NULL); + return AL_NO_ERROR; } |