aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alState.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-09-27 08:55:42 -0700
committerChris Robinson <[email protected]>2017-09-27 08:55:42 -0700
commit101d284a1801532e12b7867aed3499896d7a9a6f (patch)
treec9ae9c08e48b5c0a0dd579b43de40887a8e22a8d /OpenAL32/alState.c
parent2f6613905399aa06a253a421352e6fff57a1dce1 (diff)
Update the context state properties separately
The context state properties are less likely to change compared to the listener state, and future changes may prefer more infrequent updates to the context state. Note that this puts the MetersPerUnit in as a context state, even though it's handled through the listener functions. Considering the infrequency that it's updated at (generally set just once for the context's lifetime), it makes more sense to put it there than with the more frequently updated listener properties. The aforementioned future changes would also prefer MetersPerUnit to not be updated unnecessarily.
Diffstat (limited to 'OpenAL32/alState.c')
-rw-r--r--OpenAL32/alState.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 48c3498a..86534efb 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -72,7 +72,7 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
done:
WriteUnlock(&context->PropLock);
@@ -97,7 +97,7 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
}
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
done:
WriteUnlock(&context->PropLock);
@@ -648,7 +648,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerFactor = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -668,7 +668,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
WriteLock(&context->PropLock);
context->DopplerVelocity = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -688,7 +688,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
WriteLock(&context->PropLock);
context->SpeedOfSound = value;
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
WriteUnlock(&context->PropLock);
done:
@@ -713,7 +713,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
if(!context->SourceDistanceModel)
{
if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
- UpdateListenerProps(context);
+ UpdateContextProps(context);
}
WriteUnlock(&context->PropLock);
@@ -779,3 +779,42 @@ done:
return value;
}
+
+
+void UpdateContextProps(ALCcontext *context)
+{
+ struct ALcontextProps *props;
+
+ /* Get an unused proprty container, or allocate a new one as needed. */
+ props = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire);
+ if(!props)
+ props = al_calloc(16, sizeof(*props));
+ else
+ {
+ struct ALcontextProps *next;
+ do {
+ next = ATOMIC_LOAD(&props->next, almemory_order_relaxed);
+ } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeList, &props, next,
+ almemory_order_seq_cst, almemory_order_acquire) == 0);
+ }
+
+ /* Copy in current property values. */
+ props->MetersPerUnit = context->MetersPerUnit;
+
+ props->DopplerFactor = context->DopplerFactor;
+ props->DopplerVelocity = context->DopplerVelocity;
+ props->SpeedOfSound = context->SpeedOfSound;
+
+ props->SourceDistanceModel = context->SourceDistanceModel;
+ props->DistanceModel = context->DistanceModel;
+
+ /* Set the new container for updating internal parameters. */
+ props = ATOMIC_EXCHANGE_PTR(&context->Update, props, almemory_order_acq_rel);
+ if(props)
+ {
+ /* If there was an unused update container, put it back in the
+ * freelist.
+ */
+ ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeList, props);
+ }
+}