aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c4
-rw-r--r--Alc/ALu.c79
2 files changed, 53 insertions, 30 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index dbda46f1..f5965716 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1602,8 +1602,6 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
{
ALsizei pos;
- UpdateListenerProps(context);
-
LockUIntMapRead(&context->SourceMap);
V0(device->Backend,lock)();
for(pos = 0;pos < context->SourceMap.size;pos++)
@@ -1626,6 +1624,8 @@ void ALCcontext_ProcessUpdates(ALCcontext *context)
}
V0(device->Backend,unlock)();
UnlockUIntMapRead(&context->SourceMap);
+
+ UpdateListenerProps(context);
UpdateAllSourceProps(context);
}
ReadUnlock(&context->PropLock);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index a9f89de0..115c9c59 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -228,7 +228,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state)
}
-static void CalcListenerParams(ALCcontext *Context)
+static ALboolean CalcListenerParams(ALCcontext *Context)
{
ALlistener *Listener = Context->Listener;
ALfloat N[3], V[3], U[3], P[3];
@@ -237,7 +237,7 @@ static void CalcListenerParams(ALCcontext *Context)
aluVector vel;
props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel);
- if(!props) return;
+ if(!props) return AL_FALSE;
/* AT then UP */
N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed);
@@ -288,6 +288,8 @@ static void CalcListenerParams(ALCcontext *Context)
ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
} while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*,
&Listener->FreeList, &first, props) == 0);
+
+ return AL_TRUE;
}
static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device)
@@ -1281,7 +1283,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro
}
}
-static void CalcSourceParams(ALvoice *voice, ALCcontext *context)
+static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force)
{
ALsource *source = voice->Source;
const ALbufferlistitem *BufferListItem;
@@ -1289,33 +1291,54 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context)
struct ALsourceProps *props;
props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel);
- if(!props) return;
-
- BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
- while(BufferListItem != NULL)
+ if(!props)
{
- const ALbuffer *buffer;
- if((buffer=BufferListItem->buffer) != NULL)
+ if(!force)
+ return;
+ BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
+ while(BufferListItem != NULL)
{
- if(buffer->FmtChannels == FmtMono)
- CalcAttnSourceParams(voice, props, buffer, context);
- else
- CalcNonAttnSourceParams(voice, props, buffer, context);
- break;
+ const ALbuffer *buffer;
+ if((buffer=BufferListItem->buffer) != NULL)
+ {
+ if(buffer->FmtChannels == FmtMono)
+ CalcAttnSourceParams(voice, &voice->Props, buffer, context);
+ else
+ CalcNonAttnSourceParams(voice, &voice->Props, buffer, context);
+ break;
+ }
+ BufferListItem = BufferListItem->next;
}
- BufferListItem = BufferListItem->next;
}
-
- /* WARNING: A livelock is theoretically possible if another thread keeps
- * changing the freelist head without giving this a chance to actually swap
- * in the old container (practically impossible with this little code,
- * but...).
- */
- first = ATOMIC_LOAD(&source->FreeList);
- do {
- ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
- } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
- &source->FreeList, &first, props) == 0);
+ else
+ {
+ BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed);
+ while(BufferListItem != NULL)
+ {
+ const ALbuffer *buffer;
+ if((buffer=BufferListItem->buffer) != NULL)
+ {
+ if(buffer->FmtChannels == FmtMono)
+ CalcAttnSourceParams(voice, props, buffer, context);
+ else
+ CalcNonAttnSourceParams(voice, props, buffer, context);
+ break;
+ }
+ BufferListItem = BufferListItem->next;
+ }
+ voice->Props = *props;
+
+ /* WARNING: A livelock is theoretically possible if another thread keeps
+ * changing the freelist head without giving this a chance to actually swap
+ * in the old container (practically impossible with this little code,
+ * but...).
+ */
+ first = ATOMIC_LOAD(&source->FreeList);
+ do {
+ ATOMIC_STORE(&props->next, first, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*,
+ &source->FreeList, &first, props) == 0);
+ }
}
@@ -1327,7 +1350,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
IncrementRef(&ctx->UpdateCount);
if(!ATOMIC_LOAD(&ctx->HoldUpdates))
{
- CalcListenerParams(ctx);
+ ALboolean force = CalcListenerParams(ctx);
while(slot)
{
CalcEffectSlotParams(slot, ctx->Device);
@@ -1342,7 +1365,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot)
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
voice->Source = NULL;
else
- CalcSourceParams(voice, ctx);
+ CalcSourceParams(voice, ctx, force);
}
}
IncrementRef(&ctx->UpdateCount);