diff options
author | Chris Robinson <[email protected]> | 2019-09-04 23:04:55 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-09-04 23:04:55 -0700 |
commit | ef2769af03825f278b855858681e4cbe55c0734b (patch) | |
tree | 527d0ffb2be392ce90824cacfb3466ca1d409793 | |
parent | c47a6d2279b80031db9b012713c27885b2d14047 (diff) |
Use a normal vector for the voices array
-rw-r--r-- | al/source.cpp | 55 | ||||
-rw-r--r-- | alc/alc.cpp | 50 | ||||
-rw-r--r-- | alc/alcontext.h | 5 | ||||
-rw-r--r-- | alc/alu.cpp | 7 | ||||
-rw-r--r-- | alc/alu.h | 1 |
5 files changed, 26 insertions, 92 deletions
diff --git a/al/source.cpp b/al/source.cpp index 86a7d94c..be565d58 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -77,10 +77,10 @@ using namespace std::placeholders; ALvoice *GetSourceVoice(ALsource *source, ALCcontext *context) { ALuint idx{source->VoiceIdx}; - if(idx < context->mVoiceCount.load(std::memory_order_relaxed)) + if(idx < context->mVoices.size()) { ALuint sid{source->id}; - ALvoice &voice = (*context->mVoices)[idx]; + ALvoice &voice = context->mVoices[idx]; if(voice.mSourceID.load(std::memory_order_acquire) == sid) return &voice; } @@ -2671,38 +2671,20 @@ START_API_FUNC } /* Count the number of reusable voices. */ - auto voices_end = context->mVoices->begin() + - context->mVoiceCount.load(std::memory_order_relaxed); - auto free_voices = std::accumulate(context->mVoices->begin(), voices_end, ALsizei{0}, - [](const ALsizei count, const ALvoice &voice) noexcept -> ALsizei - { - if(voice.mPlayState.load(std::memory_order_acquire) == ALvoice::Stopped && - voice.mSourceID.load(std::memory_order_relaxed) == 0u) - return count + 1; - return count; - } - ); + auto count_free_voices = [](const ALsizei count, const ALvoice &voice) noexcept -> ALsizei + { + if(voice.mPlayState.load(std::memory_order_acquire) == ALvoice::Stopped && + voice.mSourceID.load(std::memory_order_relaxed) == 0u) + return count + 1; + return count; + }; + auto free_voices = std::accumulate(context->mVoices.begin(), context->mVoices.end(), + ALsizei{0}, count_free_voices); if UNLIKELY(n > free_voices) { - /* Increment the number of voices to handle the request. */ + /* Increase the number of voices to handle the request. */ const ALuint need_voices{static_cast<ALuint>(n) - free_voices}; - const size_t rem_voices{context->mVoices->size() - - context->mVoiceCount.load(std::memory_order_relaxed)}; - - if UNLIKELY(need_voices > rem_voices) - { - /* Allocate more voices to get enough. */ - const size_t alloc_count{need_voices - rem_voices}; - if UNLIKELY(context->mVoices->size() > std::numeric_limits<ALsizei>::max()-alloc_count) - SETERR_RETURN(context, AL_OUT_OF_MEMORY,, - "Overflow increasing voice count to %zu + %zu", context->mVoices->size(), - alloc_count); - - const size_t newcount{context->mVoices->size() + alloc_count}; - context->allocVoices(newcount); - } - - context->mVoiceCount.fetch_add(need_voices, std::memory_order_relaxed); + context->mVoices.resize(context->mVoices.size() + need_voices); } auto start_source = [&context,device](ALsource *source) -> void @@ -2757,9 +2739,8 @@ START_API_FUNC } /* Look for an unused voice to play this source with. */ - auto voices_end = context->mVoices->begin() + - context->mVoiceCount.load(std::memory_order_relaxed); - voice = std::find_if(context->mVoices->begin(), voices_end, + auto voices_end = context->mVoices.data() + context->mVoices.size(); + voice = std::find_if(context->mVoices.data(), voices_end, [](const ALvoice &voice) noexcept -> bool { return voice.mPlayState.load(std::memory_order_acquire) == ALvoice::Stopped && @@ -2767,7 +2748,7 @@ START_API_FUNC } ); assert(voice != voices_end); - auto vidx = static_cast<ALuint>(std::distance(context->mVoices->begin(), voice)); + auto vidx = static_cast<ALuint>(std::distance(context->mVoices.data(), voice)); voice->mPlayState.store(ALvoice::Stopped, std::memory_order_release); source->PropsClean.test_and_set(std::memory_order_acquire); @@ -3317,9 +3298,7 @@ ALsource::~ALsource() void UpdateAllSourceProps(ALCcontext *context) { std::lock_guard<std::mutex> _{context->mSourceLock}; - auto voices_end = context->mVoices->begin() + - context->mVoiceCount.load(std::memory_order_relaxed); - std::for_each(context->mVoices->begin(), voices_end, + std::for_each(context->mVoices.begin(), context->mVoices.end(), [context](ALvoice &voice) -> void { ALuint sid{voice.mSourceID.load(std::memory_order_acquire)}; diff --git a/alc/alc.cpp b/alc/alc.cpp index 7964a2b3..81afaeb0 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2182,8 +2182,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) vprops = next; } - auto voices = context->mVoices.get(); - auto voices_end = voices->begin() + context->mVoiceCount.load(std::memory_order_relaxed); if(device->NumAuxSends < old_sends) { const ALsizei num_sends{device->NumAuxSends}; @@ -2201,7 +2199,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) }; std::for_each(voice.mChans.begin(), voice.mChans.end(), clear_chan_sends); }; - std::for_each(voices->begin(), voices_end, clear_sends); + std::for_each(context->mVoices.begin(), context->mVoices.end(), clear_sends); } auto reset_voice = [device](ALvoice &voice) -> void { @@ -2225,7 +2223,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) init_nfc); } }; - std::for_each(voices->begin(), voices_end, reset_voice); + std::for_each(context->mVoices.begin(), context->mVoices.end(), reset_voice); srclock.unlock(); context->mPropsClean.test_and_set(std::memory_order_release); @@ -2378,8 +2376,7 @@ ALCcontext::~ALCcontext() } TRACE("Freed %zu voice property object%s\n", count, (count==1)?"":"s"); - mVoices = nullptr; - mVoiceCount.store(0, std::memory_order_relaxed); + mVoices.clear(); ALlistenerProps *lprops{mListener.Params.Update.exchange(nullptr, std::memory_order_relaxed)}; if(lprops) @@ -2459,7 +2456,8 @@ void ALCcontext::init() StartEventThrd(this); - allocVoices(256); + mVoices.reserve(256); + mVoices.resize(64); } bool ALCcontext::deinit() @@ -2548,44 +2546,6 @@ ContextRef GetContextRef(void) } -void ALCcontext::allocVoices(size_t num_voices) -{ - const ALsizei num_sends{mDevice->NumAuxSends}; - - if(mVoices && num_voices == mVoices->size()) - return; - - using ALvoiceArray = al::FlexArray<ALvoice>; - std::unique_ptr<ALvoiceArray> voices{ALvoiceArray::Create(num_voices)}; - - const size_t v_count{minz(mVoiceCount.load(std::memory_order_relaxed), num_voices)}; - if(mVoices) - { - /* Copy the old voice data to the new storage. */ - auto viter = std::move(mVoices->begin(), mVoices->begin()+v_count, voices->begin()); - - /* Clear extraneous property set sends. */ - auto clear_sends = [num_sends](ALvoice &voice) -> void - { - std::fill(std::begin(voice.mProps.Send)+num_sends, std::end(voice.mProps.Send), - ALvoiceProps::SendData{}); - - std::fill(voice.mSend.begin()+num_sends, voice.mSend.end(), ALvoice::SendData{}); - auto clear_chan_sends = [num_sends](ALvoice::ChannelData &chandata) -> void - { - std::fill(chandata.mWetParams.begin()+num_sends, chandata.mWetParams.end(), - SendParams{}); - }; - std::for_each(voice.mChans.begin(), voice.mChans.end(), clear_chan_sends); - }; - std::for_each(voices->begin(), viter, clear_sends); - } - - mVoices = std::move(voices); - mVoiceCount.store(static_cast<ALuint>(v_count), std::memory_order_relaxed); -} - - /************************************************ * Standard ALC functions ************************************************/ diff --git a/alc/alcontext.h b/alc/alcontext.h index c91d0a21..dd622654 100644 --- a/alc/alcontext.h +++ b/alc/alcontext.h @@ -127,8 +127,7 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> { std::atomic<ALvoiceProps*> mFreeVoiceProps{nullptr}; std::atomic<ALeffectslotProps*> mFreeEffectslotProps{nullptr}; - std::unique_ptr<al::FlexArray<ALvoice>> mVoices{nullptr}; - std::atomic<ALuint> mVoiceCount{0u}; + al::vector<ALvoice> mVoices; using ALeffectslotArray = al::FlexArray<ALeffectslot*>; std::atomic<ALeffectslotArray*> mActiveAuxSlots{nullptr}; @@ -163,8 +162,6 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext> { */ bool deinit(); - void allocVoices(size_t num_voices); - /** * Defers/suspends updates for the given context's listener and sources. * This does *NOT* stop mixing, but rather prevents certain property diff --git a/alc/alu.cpp b/alc/alu.cpp index 861929ef..e58ff3b4 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -1348,8 +1348,7 @@ void ProcessContext(ALCcontext *ctx, const ALuint SamplesToDo) ASSUME(SamplesToDo > 0); const ALeffectslotArray &auxslots = *ctx->mActiveAuxSlots.load(std::memory_order_acquire); - const al::span<ALvoice> voices{ctx->mVoices->data(), - ctx->mVoiceCount.load(std::memory_order_acquire)}; + const al::span<ALvoice> voices{ctx->mVoices.data(), ctx->mVoices.size()}; /* Process pending propery updates for objects on the context. */ ProcessParamUpdates(ctx, auxslots, voices); @@ -1755,9 +1754,7 @@ void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) voice.mSourceID.store(0u, std::memory_order_relaxed); voice.mPlayState.store(ALvoice::Stopped, std::memory_order_release); }; - std::for_each(ctx->mVoices->begin(), - ctx->mVoices->begin() + ctx->mVoiceCount.load(std::memory_order_acquire), - stop_voice); + std::for_each(ctx->mVoices.begin(), ctx->mVoices.end(), stop_voice); } IncrementRef(device->MixCount); } @@ -269,6 +269,7 @@ struct ALvoice { ALvoice() = default; ALvoice(const ALvoice&) = delete; + ALvoice(ALvoice&& rhs) noexcept { *this = std::move(rhs); } ~ALvoice() { delete mUpdate.exchange(nullptr, std::memory_order_acq_rel); } ALvoice& operator=(const ALvoice&) = delete; ALvoice& operator=(ALvoice&& rhs) noexcept |