From f34f08573e1c9be818f9f8ee617a644f92e6279c Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 14 Feb 2021 21:47:44 +0100 Subject: [PATCH 1/5] Only one @setsphere effect is ever visible (broken when code moved to LLPipeline::renderFinalize) --- indra/newview/llvisualeffect.cpp | 26 +++++++++++++------------- indra/newview/llvisualeffect.h | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp index 88e0b35807..af68a57413 100644 --- a/indra/newview/llvisualeffect.cpp +++ b/indra/newview/llvisualeffect.cpp @@ -107,33 +107,33 @@ bool LLVfxManager::removeEffect(const LLUUID& idEffect) return true; } -void LLVfxManager::runEffect(EVisualEffect eCode, const LLVisualEffectParams* pParams) +void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams) { // *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact auto pred = [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }; - auto beginEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), + auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); - - auto effectRange = boost::make_iterator_range(beginEffect, endEffect); - for (LLVisualEffect* pEffect : effectRange) + for (; itEffect != endEffect; ++itEffect) { - pEffect->run(pParams); + if (pParams) + pParams->step(itEffect == endEffect); + (*itEffect)->run(pParams); } } -void LLVfxManager::runEffect(EVisualEffectType eType, const LLVisualEffectParams* pParams) +void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams) { // *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact auto pred = [eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType; }; - auto beginEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), - endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); - - auto effectRange = boost::make_iterator_range(beginEffect, endEffect); - for (LLVisualEffect* pEffect : effectRange) + auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), + endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); + for (; itEffect != endEffect; ++itEffect) { - pEffect->run(pParams); + if (pParams) + pParams->step(itEffect == endEffect); + (*itEffect)->run(pParams); } } diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h index fb11881e21..1ca5448f70 100644 --- a/indra/newview/llvisualeffect.h +++ b/indra/newview/llvisualeffect.h @@ -46,14 +46,23 @@ enum class EVisualEffectType struct LLVisualEffectParams { + virtual void step(bool isLast) = 0; }; struct LLShaderEffectParams : LLVisualEffectParams { - explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pDstBuffer) : m_pSrcBuffer(pSrcBuffer), m_pDstBuffer(pDstBuffer) {} + explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pScratchBuffer, bool fBindLast) : m_pSrcBuffer(pScratchBuffer), m_pDstBuffer(pSrcBuffer), m_fBindLast(fBindLast) {} + + void step(bool isLast) override + { + LLRenderTarget* pPrevSrc = m_pSrcBuffer, *pPrevDst = m_pDstBuffer; + m_pSrcBuffer = pPrevDst; + m_pDstBuffer = (!isLast || !m_fBindLast) ? pPrevSrc : nullptr; + } LLRenderTarget* m_pSrcBuffer = nullptr; LLRenderTarget* m_pDstBuffer = nullptr; + bool m_fBindLast = false; }; // ============================================================================ @@ -161,8 +170,8 @@ public: LLVisualEffect* getEffect(EVisualEffect eCode) const; template T* getEffect(EVisualEffect eCode) const { return dynamic_cast(getEffect(eCode)); } bool removeEffect(const LLUUID& idEffect); - void runEffect(EVisualEffect eCode, const LLVisualEffectParams* pParams = nullptr); - void runEffect(EVisualEffectType eType, const LLVisualEffectParams* pParams = nullptr); + void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr); + void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr); protected: /* From a2ec15a09d35c7e9a60ae67419213db9f3b6cc0d Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 24 Apr 2021 18:51:07 +0200 Subject: [PATCH 2/5] LLVisualEffectParams::step(bool isLast) will always be called with isLast == false (fixes RLVa spheres issues when AA is disabled) --- indra/newview/llvisualeffect.cpp | 7 ++++--- indra/newview/llvisualeffect.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp index af68a57413..efa0cbf2b1 100644 --- a/indra/newview/llvisualeffect.cpp +++ b/indra/newview/llvisualeffect.cpp @@ -114,11 +114,12 @@ void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams) auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); - for (; itEffect != endEffect; ++itEffect) + while (itEffect != endEffect) { + LLVisualEffect* pEffect = *itEffect; if (pParams) - pParams->step(itEffect == endEffect); - (*itEffect)->run(pParams); + pParams->step(++itEffect == endEffect); + pEffect->run(pParams); } } diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h index 1ca5448f70..ef346bde75 100644 --- a/indra/newview/llvisualeffect.h +++ b/indra/newview/llvisualeffect.h @@ -169,6 +169,7 @@ public: template T* getEffect(const LLUUID& idEffect) const { return dynamic_cast(getEffect(idEffect)); } LLVisualEffect* getEffect(EVisualEffect eCode) const; template T* getEffect(EVisualEffect eCode) const { return dynamic_cast(getEffect(eCode)); } + bool hasEffect(EVisualEffect eCode) const { return getEffect(eCode); } bool removeEffect(const LLUUID& idEffect); void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr); void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr); From 4f0c170a244d5c88c7ceda58b0b9dd65fbe48fce Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 13 Feb 2021 19:16:42 +0100 Subject: [PATCH 3/5] GCC and Clang warnings and error --- indra/newview/llvisualeffect.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h index ef346bde75..69387d49af 100644 --- a/indra/newview/llvisualeffect.h +++ b/indra/newview/llvisualeffect.h @@ -98,12 +98,6 @@ protected: // // -enum class LLTweenType -{ - None, - Lerp, -}; - template class LLTweenableValue { @@ -127,13 +121,13 @@ template class LLTweenableValueLerp : public LLTweenableValue { public: - LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue(defaultValue) {} + LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue(defaultValue) {} T get() override; void start(const T& endValue, double duration) override { m_StartValue = get(); - m_CurValue = boost::none; + this->m_CurValue = boost::none; m_EndValue = endValue; m_StartTime = LLTimer::getElapsedSeconds(); From 110b89e485b6601adffeca1900c4423fd443c337 Mon Sep 17 00:00:00 2001 From: Kitty_Barnett Date: Sun, 16 May 2021 22:32:16 +0200 Subject: [PATCH 4/5] @setoverlay can cause an infinite loop --- indra/newview/llvisualeffect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp index efa0cbf2b1..0f4ea959e8 100644 --- a/indra/newview/llvisualeffect.cpp +++ b/indra/newview/llvisualeffect.cpp @@ -116,9 +116,9 @@ void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams) endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); while (itEffect != endEffect) { - LLVisualEffect* pEffect = *itEffect; + LLVisualEffect* pEffect = *itEffect++; if (pParams) - pParams->step(++itEffect == endEffect); + pParams->step(itEffect == endEffect); pEffect->run(pParams); } } From a0ff6c354216cd1ee7e1b8606c3ef635aa1d962f Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 29 May 2021 17:37:57 +0200 Subject: [PATCH 5/5] Allow effect ids to be reused for each visual effect (but enforce uniqueness across all instances of the same effect) --- indra/newview/llvisualeffect.cpp | 21 ++++++++------------- indra/newview/llvisualeffect.h | 20 ++++++++++++++------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp index 0f4ea959e8..ae1ea11695 100644 --- a/indra/newview/llvisualeffect.cpp +++ b/indra/newview/llvisualeffect.cpp @@ -75,30 +75,25 @@ LLVfxManager::LLVfxManager() bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst) { - if (m_Effects.end() != m_Effects.find(pEffectInst)) + // Effect IDs can be reused across effects but should be unique for all effect instances sharing the same effect code + auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [pEffectInst](const LLVisualEffect* pEffect) { return pEffect->getCode() == pEffectInst->getCode() && pEffect->getId() == pEffectInst->getId(); }); + llassert(m_Effects.end() == itEffect); + if (m_Effects.end() != itEffect) return false; m_Effects.insert(pEffectInst); - return true; } -LLVisualEffect* LLVfxManager::getEffect(const LLUUID& idEffect) const +LLVisualEffect* LLVfxManager::getEffect(EVisualEffect eCode, const LLUUID& idEffect) const { - auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [&idEffect](const LLVisualEffect* pEffect) { return pEffect->getId() == idEffect; }); + auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode, &idEffect](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode && pEffect->getId() == idEffect; }); return (m_Effects.end() != itEffect) ? *itEffect : nullptr; } -LLVisualEffect* LLVfxManager::getEffect(EVisualEffect eCode) const +bool LLVfxManager::removeEffect(EVisualEffect eCode, const LLUUID& idEffect) { - // NOTE: returns the first found but there could be more - auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }); - return (m_Effects.end() != itEffect) ? *itEffect : nullptr; -} - -bool LLVfxManager::removeEffect(const LLUUID& idEffect) -{ - auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [&idEffect](const LLVisualEffect* pEffect) { return pEffect->getId() == idEffect; }); + auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode, &idEffect](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode && pEffect->getId() == idEffect; }); if (m_Effects.end() == itEffect) return false; diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h index 69387d49af..55fbd13468 100644 --- a/indra/newview/llvisualeffect.h +++ b/indra/newview/llvisualeffect.h @@ -159,12 +159,11 @@ protected: */ public: bool addEffect(LLVisualEffect* pEffectInst); - LLVisualEffect* getEffect(const LLUUID& idEffect) const; - template T* getEffect(const LLUUID& idEffect) const { return dynamic_cast(getEffect(idEffect)); } - LLVisualEffect* getEffect(EVisualEffect eCode) const; - template T* getEffect(EVisualEffect eCode) const { return dynamic_cast(getEffect(eCode)); } - bool hasEffect(EVisualEffect eCode) const { return getEffect(eCode); } - bool removeEffect(const LLUUID& idEffect); + LLVisualEffect* getEffect(EVisualEffect eCode, const LLUUID& idEffect) const; + template T* getEffect(const LLUUID& idEffect) const { return dynamic_cast(getEffect(T::EffectCode, idEffect)); } + bool hasEffect(EVisualEffect eCode) const; + bool removeEffect(EVisualEffect eCode, const LLUUID& idEffect); + template bool removeEffect(const LLUUID& idEffect) { return removeEffect(T::EffectCode, idEffect); } void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr); void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr); protected: @@ -177,3 +176,12 @@ protected: }; // ============================================================================ +// Inlined member functions +// + +inline bool LLVfxManager::hasEffect(EVisualEffect eCode) const +{ + return m_Effects.end() != std::find_if(m_Effects.begin(), m_Effects.end(), [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }); +} + +// ============================================================================