Allocate voice properties in clusters
This commit is contained in:
parent
21bdea776a
commit
c9537abfb1
@ -100,15 +100,15 @@ void UpdateSourceProps(const ALsource *source, Voice *voice, ALCcontext *context
|
||||
/* Get an unused property container, or allocate a new one as needed. */
|
||||
VoicePropsItem *props{context->mFreeVoiceProps.load(std::memory_order_acquire)};
|
||||
if(!props)
|
||||
props = new VoicePropsItem{};
|
||||
else
|
||||
{
|
||||
VoicePropsItem *next;
|
||||
do {
|
||||
next = props->next.load(std::memory_order_relaxed);
|
||||
} while(context->mFreeVoiceProps.compare_exchange_weak(props, next,
|
||||
std::memory_order_acq_rel, std::memory_order_acquire) == 0);
|
||||
context->allocVoiceProps();
|
||||
props = context->mFreeVoiceProps.load(std::memory_order_acquire);
|
||||
}
|
||||
VoicePropsItem *next;
|
||||
do {
|
||||
next = props->next.load(std::memory_order_relaxed);
|
||||
} while(unlikely(context->mFreeVoiceProps.compare_exchange_weak(props, next,
|
||||
std::memory_order_acq_rel, std::memory_order_acquire) == false));
|
||||
|
||||
props->Pitch = source->Pitch;
|
||||
props->Gain = source->Gain;
|
||||
|
21
alc/alc.cpp
21
alc/alc.cpp
@ -2082,18 +2082,6 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear any pre-existing voice property structs, in case the number of
|
||||
* auxiliary sends is changing. Active sources will have updates
|
||||
* respecified in UpdateAllSourceProps.
|
||||
*/
|
||||
VoicePropsItem *vprops{context->mFreeVoiceProps.exchange(nullptr, std::memory_order_acq_rel)};
|
||||
while(vprops)
|
||||
{
|
||||
VoicePropsItem *next = vprops->next.load(std::memory_order_relaxed);
|
||||
delete vprops;
|
||||
vprops = next;
|
||||
}
|
||||
|
||||
auto voicelist = context->getVoicesSpan();
|
||||
for(Voice *voice : voicelist)
|
||||
{
|
||||
@ -2108,7 +2096,8 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
SendParams{});
|
||||
}
|
||||
|
||||
delete voice->mUpdate.exchange(nullptr, std::memory_order_acq_rel);
|
||||
if(VoicePropsItem *props{voice->mUpdate.exchange(nullptr, std::memory_order_relaxed)})
|
||||
AtomicReplaceHead(context->mFreeVoiceProps, props);
|
||||
|
||||
/* Force the voice to stopped if it was stopping. */
|
||||
Voice::State vstate{Voice::Stopping};
|
||||
@ -2119,6 +2108,9 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
||||
|
||||
voice->prepare(device);
|
||||
}
|
||||
/* Clear all voice props to let them get allocated again. */
|
||||
context->mVoicePropClusters.clear();
|
||||
context->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
|
||||
srclock.unlock();
|
||||
|
||||
context->mPropsDirty.test_and_clear(std::memory_order_release);
|
||||
@ -2173,6 +2165,9 @@ bool ResetDeviceParams(ALCdevice *device, const int *attrList)
|
||||
vchg = next;
|
||||
ctx->mCurrentVoiceChange.store(vchg, std::memory_order_release);
|
||||
|
||||
ctx->mVoicePropClusters.clear();
|
||||
ctx->mFreeVoiceProps.store(nullptr, std::memory_order_relaxed);
|
||||
|
||||
ctx->mVoiceClusters.clear();
|
||||
ctx->allocVoices(std::max<size_t>(256,
|
||||
ctx->mActiveVoiceCount.load(std::memory_order_relaxed)));
|
||||
|
@ -133,16 +133,6 @@ ContextBase::~ContextBase()
|
||||
delete curarray;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
VoicePropsItem *vprops{mFreeVoiceProps.exchange(nullptr, std::memory_order_acquire)};
|
||||
while(vprops)
|
||||
{
|
||||
std::unique_ptr<VoicePropsItem> old{vprops};
|
||||
vprops = old->next.load(std::memory_order_relaxed);
|
||||
++count;
|
||||
}
|
||||
TRACE("Freed %zu voice property object%s\n", count, (count==1)?"":"s");
|
||||
|
||||
delete mVoices.exchange(nullptr, std::memory_order_relaxed);
|
||||
|
||||
count = 0;
|
||||
@ -198,6 +188,25 @@ void ContextBase::allocVoiceChanges(size_t addcount)
|
||||
}
|
||||
}
|
||||
|
||||
void ContextBase::allocVoiceProps()
|
||||
{
|
||||
constexpr size_t clustersize{32};
|
||||
|
||||
TRACE("Increasing allocated voice properties to %zu\n",
|
||||
(mVoicePropClusters.size()+1) * clustersize);
|
||||
|
||||
VoicePropsCluster cluster{std::make_unique<VoicePropsItem[]>(clustersize)};
|
||||
for(size_t i{1};i < clustersize;++i)
|
||||
cluster[i-1].next.store(std::addressof(cluster[i]), std::memory_order_relaxed);
|
||||
mVoicePropClusters.emplace_back(std::move(cluster));
|
||||
|
||||
VoicePropsItem *oldhead{mFreeVoiceProps.load(std::memory_order_acquire)};
|
||||
do {
|
||||
mVoicePropClusters.back()[clustersize-1].next.store(oldhead, std::memory_order_relaxed);
|
||||
} while(mFreeVoiceProps.compare_exchange_weak(oldhead, mVoicePropClusters.back().get(),
|
||||
std::memory_order_acq_rel, std::memory_order_acquire) == false);
|
||||
}
|
||||
|
||||
void ContextBase::allocVoices(size_t addcount)
|
||||
{
|
||||
constexpr size_t clustersize{32};
|
||||
|
@ -122,6 +122,7 @@ struct ContextBase {
|
||||
std::atomic<VoiceChange*> mCurrentVoiceChange{};
|
||||
|
||||
void allocVoiceChanges(size_t addcount);
|
||||
void allocVoiceProps();
|
||||
|
||||
|
||||
ContextParams mParams;
|
||||
@ -162,6 +163,9 @@ struct ContextBase {
|
||||
using VoiceCluster = std::unique_ptr<Voice[]>;
|
||||
al::vector<VoiceCluster> mVoiceClusters;
|
||||
|
||||
using VoicePropsCluster = std::unique_ptr<VoicePropsItem[]>;
|
||||
al::vector<VoicePropsCluster> mVoicePropClusters;
|
||||
|
||||
|
||||
ContextBase(DeviceBase *device);
|
||||
ContextBase(const ContextBase&) = delete;
|
||||
|
@ -252,7 +252,7 @@ struct Voice {
|
||||
al::vector<ChannelData> mChans{2};
|
||||
|
||||
Voice() = default;
|
||||
~Voice() { delete mUpdate.exchange(nullptr, std::memory_order_acq_rel); }
|
||||
~Voice() = default;
|
||||
|
||||
Voice(const Voice&) = delete;
|
||||
Voice& operator=(const Voice&) = delete;
|
||||
|
Loading…
x
Reference in New Issue
Block a user