aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/auxeffectslot.cpp25
-rw-r--r--alc/alc.cpp23
-rw-r--r--alc/alu.cpp2
-rw-r--r--core/context.cpp29
-rw-r--r--core/context.h7
5 files changed, 55 insertions, 31 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 5eea3425..673ca4c9 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -877,9 +877,8 @@ ALeffectslot::~ALeffectslot()
DecrementRef(Buffer->ref);
Buffer = nullptr;
- if(std::unique_ptr<EffectSlotProps> props{mSlot->Update.exchange(nullptr)})
- TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n",
- decltype(std::declval<void*>()){props.get()});
+ if(auto *slot = mSlot->Update.exchange(nullptr, std::memory_order_relaxed))
+ slot->State = nullptr;
mSlot->mEffectState = nullptr;
mSlot->InUse = false;
@@ -917,7 +916,7 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect
EffectId = effectId;
/* Remove state references from old effect slot property updates. */
- EffectSlotProps *props{context->mFreeEffectslotProps.load()};
+ EffectSlotProps *props{context->mFreeEffectSlotProps.load()};
while(props)
{
props->State = nullptr;
@@ -930,17 +929,17 @@ ALenum ALeffectslot::initEffect(ALuint effectId, ALenum effectType, const Effect
void ALeffectslot::updateProps(ALCcontext *context)
{
/* Get an unused property container, or allocate a new one as needed. */
- EffectSlotProps *props{context->mFreeEffectslotProps.load(std::memory_order_relaxed)};
+ EffectSlotProps *props{context->mFreeEffectSlotProps.load(std::memory_order_acquire)};
if(!props)
- props = new EffectSlotProps{};
- else
{
- EffectSlotProps *next;
- do {
- next = props->next.load(std::memory_order_relaxed);
- } while(context->mFreeEffectslotProps.compare_exchange_weak(props, next,
- std::memory_order_seq_cst, std::memory_order_acquire) == 0);
+ context->allocEffectSlotProps();
+ props = context->mFreeEffectSlotProps.load(std::memory_order_acquire);
}
+ EffectSlotProps *next;
+ do {
+ next = props->next.load(std::memory_order_relaxed);
+ } while(context->mFreeEffectSlotProps.compare_exchange_weak(props, next,
+ std::memory_order_acq_rel, std::memory_order_acquire) == false);
/* Copy in current property values. */
props->Gain = Gain;
@@ -959,7 +958,7 @@ void ALeffectslot::updateProps(ALCcontext *context)
* freelist.
*/
props->State = nullptr;
- AtomicReplaceHead(context->mFreeEffectslotProps, props);
+ AtomicReplaceHead(context->mFreeEffectSlotProps, props);
}
}
diff --git a/alc/alc.cpp b/alc/alc.cpp
index cc25177d..e5f2c545 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1667,12 +1667,16 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
if(ALeffectslot *slot{context->mDefaultSlot.get()})
{
- aluInitEffectPanning(slot->mSlot, context);
+ auto *slotbase = slot->mSlot;
+ aluInitEffectPanning(slotbase, context);
+
+ if(auto *props = slotbase->Update.exchange(nullptr, std::memory_order_relaxed))
+ AtomicReplaceHead(context->mFreeEffectSlotProps, props);
EffectState *state{slot->Effect.State.get()};
state->mOutTarget = device->Dry.Buffer;
state->deviceUpdate(device, slot->Buffer);
- slot->updateProps(context);
+ slot->mPropsDirty = true;
}
if(EffectSlotArray *curarray{context->mActiveAuxSlots.load(std::memory_order_relaxed)})
@@ -1686,14 +1690,21 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
auto &slot = (*sublist.EffectSlots)[idx];
usemask &= ~(1_u64 << idx);
- aluInitEffectPanning(slot.mSlot, context);
+ auto *slotbase = slot.mSlot;
+ aluInitEffectPanning(slotbase, context);
+
+ if(auto *props = slotbase->Update.exchange(nullptr, std::memory_order_relaxed))
+ AtomicReplaceHead(context->mFreeEffectSlotProps, props);
EffectState *state{slot.Effect.State.get()};
state->mOutTarget = device->Dry.Buffer;
state->deviceUpdate(device, slot.Buffer);
- slot.updateProps(context);
+ slot.mPropsDirty = true;
}
}
+ /* Clear all effect slot props to let them get allocated again. */
+ context->mEffectSlotPropClusters.clear();
+ context->mFreeEffectSlotProps.store(nullptr, std::memory_order_relaxed);
slotlock.unlock();
const uint num_sends{device->NumAuxSends};
@@ -1725,8 +1736,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
}
}
- auto voicelist = context->getVoicesSpan();
- for(Voice *voice : voicelist)
+ for(Voice *voice : context->getVoicesSpan())
{
/* Clear extraneous property set sends. */
std::fill(std::begin(voice->mProps.Send)+num_sends, std::end(voice->mProps.Send),
@@ -1758,6 +1768,7 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
context->mPropsDirty = false;
UpdateContextProps(context);
+ UpdateAllEffectSlotProps(context);
UpdateAllSourceProps(context);
}
mixer_mode.leave();
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 9e7a758e..59b5a551 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -498,7 +498,7 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ContextBa
}
}
- AtomicReplaceHead(context->mFreeEffectslotProps, props);
+ AtomicReplaceHead(context->mFreeEffectSlotProps, props);
EffectTarget output;
if(EffectSlot *target{slot->Target})
diff --git a/core/context.cpp b/core/context.cpp
index cb00ae70..46f703a9 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -40,15 +40,6 @@ ContextBase::~ContextBase()
}
TRACE("Freed %zu context property object%s\n", count, (count==1)?"":"s");
- count = 0;
- EffectSlotProps *eprops{mFreeEffectslotProps.exchange(nullptr, std::memory_order_acquire)};
- while(std::unique_ptr<EffectSlotProps> old{eprops})
- {
- eprops = old->next.load(std::memory_order_relaxed);
- ++count;
- }
- TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
-
if(std::unique_ptr<EffectSlotArray> curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)})
std::destroy_n(curarray->end(), curarray->size());
@@ -147,6 +138,26 @@ void ContextBase::allocVoices(size_t addcount)
}
+void ContextBase::allocEffectSlotProps()
+{
+ static constexpr size_t clustersize{std::tuple_size_v<EffectSlotPropsCluster::element_type>};
+
+ TRACE("Increasing allocated effect slot properties to %zu\n",
+ (mEffectSlotPropClusters.size()+1) * clustersize);
+
+ auto clusterptr = std::make_unique<EffectSlotPropsCluster::element_type>();
+ auto cluster = al::span{*clusterptr};
+ for(size_t i{1};i < clustersize;++i)
+ cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed);
+ auto *newcluster = mEffectSlotPropClusters.emplace_back(std::move(clusterptr)).get();
+
+ EffectSlotProps *oldhead{mFreeEffectSlotProps.load(std::memory_order_acquire)};
+ do {
+ newcluster->back().next.store(oldhead, std::memory_order_relaxed);
+ } while(mFreeEffectSlotProps.compare_exchange_weak(oldhead, newcluster->data(),
+ std::memory_order_acq_rel, std::memory_order_acquire) == false);
+}
+
EffectSlot *ContextBase::getEffectSlot()
{
for(auto& clusterptr : mEffectSlotClusters)
diff --git a/core/context.h b/core/context.h
index 6fc1ed5d..16d1b415 100644
--- a/core/context.h
+++ b/core/context.h
@@ -95,7 +95,7 @@ struct ContextBase {
*/
std::atomic<ContextProps*> mFreeContextProps{nullptr};
std::atomic<VoicePropsItem*> mFreeVoiceProps{nullptr};
- std::atomic<EffectSlotProps*> mFreeEffectslotProps{nullptr};
+ std::atomic<EffectSlotProps*> mFreeEffectSlotProps{nullptr};
/* The voice change tail is the beginning of the "free" elements, up to and
* *excluding* the current. If tail==current, there's no free elements and
@@ -107,7 +107,7 @@ struct ContextBase {
void allocVoiceChanges();
void allocVoiceProps();
-
+ void allocEffectSlotProps();
ContextParams mParams;
@@ -157,6 +157,9 @@ struct ContextBase {
using EffectSlotCluster = std::unique_ptr<std::array<EffectSlot,4>>;
std::vector<EffectSlotCluster> mEffectSlotClusters;
+ using EffectSlotPropsCluster = std::unique_ptr<std::array<EffectSlotProps,4>>;
+ std::vector<EffectSlotPropsCluster> mEffectSlotPropClusters;
+
ContextBase(DeviceBase *device);
ContextBase(const ContextBase&) = delete;