From de87cc98d5eef40eeb565b781ac90c1c6f55b42e Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Tue, 8 Feb 2022 20:27:40 -0800
Subject: Apply updates for EAX context properties

---
 al/listener.cpp | 20 --------------------
 al/listener.h   |  7 -------
 alc/context.cpp | 57 +++++++++++++++++++++++++++++++++++----------------------
 alc/context.h   | 12 +++++++++++-
 4 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/al/listener.cpp b/al/listener.cpp
index cae4ba68..11b7162a 100644
--- a/al/listener.cpp
+++ b/al/listener.cpp
@@ -481,23 +481,3 @@ void UpdateListenerProps(ALCcontext *context)
         AtomicReplaceHead(context->mFreeListenerProps, props);
     }
 }
-
-#ifdef ALSOFT_EAX
-// `alListenerf(AL_METERS_PER_UNIT, value)`
-void eax_set_al_listener_meters_per_unit(
-    ALCcontext& al_context,
-    ALfloat meters_per_unit)
-{
-    auto& listener = al_context.mListener;
-
-    if (meters_per_unit < AL_MIN_METERS_PER_UNIT ||
-        meters_per_unit > AL_MAX_METERS_PER_UNIT)
-    {
-        SETERR_RETURN(&al_context, AL_INVALID_VALUE,, "Listener meters per unit out of range");
-    }
-
-    listener.mMetersPerUnit = meters_per_unit;
-
-    UpdateProps(listener, &al_context);
-}
-#endif // ALSOFT_EAX
diff --git a/al/listener.h b/al/listener.h
index df20ee69..f3332763 100644
--- a/al/listener.h
+++ b/al/listener.h
@@ -29,11 +29,4 @@ struct ALlistener {
 
 void UpdateListenerProps(ALCcontext *context);
 
-#ifdef ALSOFT_EAX
-// `alListenerf(AL_METERS_PER_UNIT, value)`
-void eax_set_al_listener_meters_per_unit(
-    ALCcontext& al_context,
-    ALfloat meters_per_unit);
-#endif // ALSOFT_EAX
-
 #endif
diff --git a/alc/context.cpp b/alc/context.cpp
index 1bee2ea7..525d4a5f 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -247,30 +247,27 @@ bool ALCcontext::deinit()
     return ret;
 }
 
-void ALCcontext::processUpdates()
+void ALCcontext::applyAllUpdates()
 {
-    if(mDeferUpdates.exchange(false, std::memory_order_acq_rel))
-    {
-        /* Tell the mixer to stop applying updates, then wait for any active
-         * updating to finish, before providing updates.
-         */
-        mHoldUpdates.store(true, std::memory_order_release);
-        while((mUpdateCount.load(std::memory_order_acquire)&1) != 0) {
-            /* busy-wait */
-        }
+    /* Tell the mixer to stop applying updates, then wait for any active
+     * updating to finish, before providing updates.
+     */
+    mHoldUpdates.store(true, std::memory_order_release);
+    while((mUpdateCount.load(std::memory_order_acquire)&1) != 0) {
+        /* busy-wait */
+    }
 
-        if(mPropsDirty.test_and_clear(std::memory_order_acq_rel))
-            UpdateContextProps(this);
-        if(mListener.mPropsDirty.test_and_clear(std::memory_order_acq_rel))
-            UpdateListenerProps(this);
-        UpdateAllEffectSlotProps(this);
-        UpdateAllSourceProps(this);
+    if(mPropsDirty.test_and_clear(std::memory_order_acq_rel))
+        UpdateContextProps(this);
+    if(mListener.mPropsDirty.test_and_clear(std::memory_order_acq_rel))
+        UpdateListenerProps(this);
+    UpdateAllEffectSlotProps(this);
+    UpdateAllSourceProps(this);
 
-        /* Now with all updates declared, let the mixer continue applying them
-         * so they all happen at once.
-         */
-        mHoldUpdates.store(false, std::memory_order_release);
-    }
+    /* Now with all updates declared, let the mixer continue applying them so
+     * they all happen at once.
+     */
+    mHoldUpdates.store(false, std::memory_order_release);
 }
 
 #ifdef ALSOFT_EAX
@@ -950,7 +947,8 @@ void ALCcontext::eax_set_primary_fx_slot_id()
 
 void ALCcontext::eax_set_distance_factor()
 {
-    eax_set_al_listener_meters_per_unit(*this, eax_.context.flDistanceFactor);
+    mListener.mMetersPerUnit = eax_.context.flDistanceFactor;
+    mListener.mPropsDirty.set(std::memory_order_release);
 }
 
 void ALCcontext::eax_set_air_absorbtion_hf()
@@ -1326,6 +1324,21 @@ void ALCcontext::eax_set(
     if (!eax_call.is_deferred())
     {
         eax_apply_deferred();
+        if(!mDeferUpdates.load(std::memory_order_acquire))
+        {
+            mHoldUpdates.store(true, std::memory_order_release);
+            while((mUpdateCount.load(std::memory_order_acquire)&1) != 0) {
+                /* busy-wait */
+            }
+
+            if(mPropsDirty.test_and_clear(std::memory_order_acq_rel))
+                UpdateContextProps(this);
+            if(mListener.mPropsDirty.test_and_clear(std::memory_order_acq_rel))
+                UpdateListenerProps(this);
+            UpdateAllSourceProps(this);
+
+            mHoldUpdates.store(false, std::memory_order_release);
+        }
     }
 }
 
diff --git a/alc/context.h b/alc/context.h
index 4b3e3461..26aeedb7 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -162,7 +162,17 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase {
      * Resumes update processing after being deferred. mPropLock must be held
      * when called.
      */
-    void processUpdates();
+    void processUpdates()
+    {
+        if(mDeferUpdates.exchange(false, std::memory_order_acq_rel))
+            applyAllUpdates();
+    }
+
+    /**
+     * Applies all pending updates for the context, listener, effect slots, and
+     * sources.
+     */
+    void applyAllUpdates();
 
 #ifdef __USE_MINGW_ANSI_STDIO
     [[gnu::format(gnu_printf, 3, 4)]]
-- 
cgit v1.2.3