aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c8
-rw-r--r--Alc/ALu.c40
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h2
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/alAuxEffectSlot.c67
5 files changed, 59 insertions, 60 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index e8e5c3ee..b4582b0e 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index b64cbf49..3ba068a2 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -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;
}