diff options
author | Chris Robinson <[email protected]> | 2022-02-13 17:22:41 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-02-13 17:22:41 -0800 |
commit | 66f6cf121e5a65f5ec0c93872b60e123fa2ad0f3 (patch) | |
tree | 4447ce8435f93983f5a3217e022d768d868660be | |
parent | 1bebc011778d6bd3cdf4fcbd2704c8cf65446602 (diff) |
Commit source EAX properties when not deferring
And make sure they get committed when resuming processing.
-rw-r--r-- | al/source.cpp | 139 | ||||
-rw-r--r-- | al/source.h | 6 | ||||
-rw-r--r-- | alc/context.cpp | 7 | ||||
-rw-r--r-- | alc/context.h | 1 |
4 files changed, 81 insertions, 72 deletions
diff --git a/al/source.cpp b/al/source.cpp index e009b885..1ad685e7 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -1150,6 +1150,28 @@ bool UpdateSourceProps(ALsource *source, ALCcontext *context) source->mPropsDirty.set(std::memory_order_release); return true; } +#ifdef ALSOFT_EAX +bool CommitAndUpdateSourceProps(ALsource *source, ALCcontext *context) +{ + Voice *voice; + if(!context->mDeferUpdates.load(std::memory_order_acquire)) + { + if(source->eax_is_initialized()) + source->eax_commit(); + if(IsPlayingOrPaused(source) && (voice=GetSourceVoice(source, context)) != nullptr) + UpdateSourceProps(source, voice, context); + } + else + source->mPropsDirty.set(std::memory_order_release); + return true; +} + +#else + +inline bool CommitAndUpdateSourceProps(ALsource *source, ALCcontext *context) +{ return UpdateSourceProps(source, context); +#endif + bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const al::span<const float> values) { @@ -1176,20 +1198,14 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f); Source->InnerAngle = values[0]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_CONE_OUTER_ANGLE: CHECKSIZE(values, 1); CHECKVAL(values[0] >= 0.0f && values[0] <= 360.0f); Source->OuterAngle = values[0]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_GAIN: CHECKSIZE(values, 1); @@ -1203,30 +1219,21 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a CHECKVAL(values[0] >= 0.0f); Source->MaxDistance = values[0]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_ROLLOFF_FACTOR: CHECKSIZE(values, 1); CHECKVAL(values[0] >= 0.0f); Source->RolloffFactor = values[0]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_REFERENCE_DISTANCE: CHECKSIZE(values, 1); CHECKVAL(values[0] >= 0.0f); Source->RefDistance = values[0]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_MIN_GAIN: CHECKSIZE(values, 1); @@ -1328,10 +1335,7 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a Source->Position[0] = values[0]; Source->Position[1] = values[1]; Source->Position[2] = values[2]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_VELOCITY: CHECKSIZE(values, 3); @@ -1340,10 +1344,7 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a Source->Velocity[0] = values[0]; Source->Velocity[1] = values[1]; Source->Velocity[2] = values[2]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_DIRECTION: CHECKSIZE(values, 3); @@ -1352,10 +1353,7 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a Source->Direction[0] = values[0]; Source->Direction[1] = values[1]; Source->Direction[2] = values[2]; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_ORIENTATION: CHECKSIZE(values, 6); @@ -1433,10 +1431,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE); Source->HeadRelative = values[0] != AL_FALSE; -#ifdef ALSOFT_EAX - Source->eax_commit(); -#endif // ALSOFT_EAX - return UpdateSourceProps(Source, Context); + return CommitAndUpdateSourceProps(Source, Context); case AL_LOOPING: CHECKSIZE(values, 1); @@ -3139,7 +3134,8 @@ START_API_FUNC cur->mState = VChangeState::Play; source->state = AL_PLAYING; #ifdef ALSOFT_EAX - source->eax_commit(); + if(source->eax_is_initialized()) + source->eax_commit(); #endif // ALSOFT_EAX continue; @@ -3158,7 +3154,8 @@ START_API_FUNC assert(voice == nullptr); cur->mOldVoice = nullptr; #ifdef ALSOFT_EAX - source->eax_commit(); + if(source->eax_is_initialized()) + source->eax_commit(); #endif // ALSOFT_EAX break; } @@ -3633,18 +3630,47 @@ ALsource::~ALsource() void UpdateAllSourceProps(ALCcontext *context) { std::lock_guard<std::mutex> _{context->mSourceLock}; - auto voicelist = context->getVoicesSpan(); - ALuint vidx{0u}; - for(Voice *voice : voicelist) +#ifdef ALSOFT_EAX + if(context->has_eax()) { - ALuint sid{voice->mSourceID.load(std::memory_order_acquire)}; - ALsource *source = sid ? LookupSource(context, sid) : nullptr; - if(source && source->VoiceIdx == vidx) + /* If EAX is enabled, we need to go through and commit all sources' EAX + * changes, along with updating its voice, if any. + */ + for(auto &sublist : context->mSourceList) { - if(source->mPropsDirty.test_and_clear(std::memory_order_acq_rel)) - UpdateSourceProps(source, voice, context); + uint64_t usemask{~sublist.FreeMask}; + while(usemask) + { + const int idx{al::countr_zero(usemask)}; + usemask &= ~(1_u64 << idx); + + ALsource *source{sublist.Sources + idx}; + source->eax_commit(); + + if(Voice *voice{GetSourceVoice(source, context)}) + { + if(source->mPropsDirty.test_and_clear(std::memory_order_relaxed)) + UpdateSourceProps(source, voice, context); + } + } + } + } + else +#endif + { + auto voicelist = context->getVoicesSpan(); + ALuint vidx{0u}; + for(Voice *voice : voicelist) + { + ALuint sid{voice->mSourceID.load(std::memory_order_acquire)}; + ALsource *source = sid ? LookupSource(context, sid) : nullptr; + if(source && source->VoiceIdx == vidx) + { + if(source->mPropsDirty.test_and_clear(std::memory_order_acq_rel)) + UpdateSourceProps(source, voice, context); + } + ++vidx; } - ++vidx; } } @@ -3654,8 +3680,8 @@ SourceSubList::~SourceSubList() while(usemask) { const int idx{al::countr_zero(usemask)}; - al::destroy_at(Sources+idx); usemask &= ~(1_u64 << idx); + al::destroy_at(Sources+idx); } FreeMask = ~usemask; al_free(Sources); @@ -3743,21 +3769,11 @@ void ALsource::eax_update( } } -void ALsource::eax_commit() -{ - if (!eax_is_initialized()) - return; - - eax_apply_deferred(); -} - void ALsource::eax_commit_and_update() { - if (!eax_is_initialized()) - return; - eax_apply_deferred(); - UpdateSourceProps(this, eax_al_context_); + if(mPropsDirty.test_and_clear(std::memory_order_acq_rel)) + UpdateSourceProps(this, eax_al_context_); } ALsource* ALsource::eax_lookup_source( @@ -5621,7 +5637,8 @@ void ALsource::eax_set( if (!eax_call.is_deferred()) { eax_apply_deferred(); - UpdateSourceProps(this, eax_al_context_); + if(mPropsDirty.test_and_clear(std::memory_order_acq_rel)) + UpdateSourceProps(this, eax_al_context_); } } diff --git a/al/source.h b/al/source.h index 4f409288..a89a8297 100644 --- a/al/source.h +++ b/al/source.h @@ -220,9 +220,11 @@ public: void eax_update( EaxContextSharedDirtyFlags dirty_flags); - void eax_commit(); + void eax_commit() { eax_apply_deferred(); } void eax_commit_and_update(); + bool eax_is_initialized() const noexcept { return eax_al_context_; } + static ALsource* eax_lookup_source( ALCcontext& al_context, @@ -268,8 +270,6 @@ private: const char* message); - bool eax_is_initialized() const noexcept { return eax_al_context_; } - void eax_set_source_defaults() noexcept; void eax_set_active_fx_slots_defaults() noexcept; void eax_set_send_defaults(EAXSOURCEALLSENDPROPERTIES& eax_send) noexcept; diff --git a/alc/context.cpp b/alc/context.cpp index 36818537..07dc76bf 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -549,13 +549,6 @@ void ALCcontext::eax_update_filters() } } -void ALCcontext::eax_commit_sources() -{ - std::unique_lock<std::mutex> source_lock{mSourceLock}; - for (auto& source : SourceListEnumerator{mSourceList}) - source.eax_commit(); -} - void ALCcontext::eax_commit_and_update_sources() { std::unique_lock<std::mutex> source_lock{mSourceLock}; diff --git a/alc/context.h b/alc/context.h index 613c6c12..bd966704 100644 --- a/alc/context.h +++ b/alc/context.h @@ -243,7 +243,6 @@ public: void eax_update_filters(); - void eax_commit_sources(); void eax_commit_and_update_sources(); |