diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp
index ae1ea11695faccf0e24cf56238edf7f67ce0c4ba..3a4594ff09194b8dd01df3978af125c7e2796f7d 100644
--- a/indra/newview/llvisualeffect.cpp
+++ b/indra/newview/llvisualeffect.cpp
@@ -70,7 +70,6 @@ LLVector4 LLTweenableValueLerp<LLVector4>::get()
 
 LLVfxManager::LLVfxManager()
 {
-
 }
 
 bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst)
@@ -81,7 +80,7 @@ bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst)
 	if (m_Effects.end() != itEffect)
 		return false;
 
-	m_Effects.insert(pEffectInst);
+	m_Effects.insert(std::upper_bound(m_Effects.begin(), m_Effects.end(), pEffectInst, cmpEffect), pEffectInst);
 	return true;
 }
 
@@ -91,6 +90,20 @@ LLVisualEffect* LLVfxManager::getEffect(EVisualEffect eCode, const LLUUID& idEff
 	return (m_Effects.end() != itEffect) ? *itEffect : nullptr;
 }
 
+bool LLVfxManager::getEffects(std::list<LLVisualEffect*>& effectList, std::function<bool(const LLVisualEffect*)> fnFilter)
+{
+	effectList.clear();
+
+	auto itEffect  = boost::make_filter_iterator(fnFilter, m_Effects.begin(), m_Effects.end()),
+	     endEffect = boost::make_filter_iterator(fnFilter, m_Effects.end(), m_Effects.end());
+	while (itEffect != endEffect)
+	{
+		effectList.push_back(*itEffect++);
+	}
+
+	return effectList.size();
+}
+
 bool LLVfxManager::removeEffect(EVisualEffect eCode, const LLUUID& idEffect)
 {
 	auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode, &idEffect](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode && pEffect->getId() == idEffect; });
@@ -104,33 +117,54 @@ bool LLVfxManager::removeEffect(EVisualEffect eCode, const LLUUID& idEffect)
 
 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; };
+	runEffect([eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }, pParams);
+}
+
+void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams)
+{
+	runEffect([eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType; }, 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());
+void LLVfxManager::runEffect(std::function<bool(const LLVisualEffect*)> predicate, LLVisualEffectParams* pParams)
+{
+	// *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact
+	auto itEffect  = boost::make_filter_iterator(predicate, m_Effects.begin(), m_Effects.end()),
+	     endEffect = boost::make_filter_iterator(predicate, m_Effects.end(), m_Effects.end());
 	while (itEffect != endEffect)
 	{
 		LLVisualEffect* pEffect = *itEffect++;
-		if (pParams)
-			pParams->step(itEffect == endEffect);
-		pEffect->run(pParams);
+		if (pEffect->getEnabled())
+		{
+			if (pParams)
+				pParams->step(itEffect == endEffect);
+			pEffect->run(pParams);
+		}
 	}
 }
 
-void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams)
+void  LLVfxManager::updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority)
 {
-	// *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;  };
+	llassert(m_Effects.end() != std::find(m_Effects.begin(), m_Effects.end(), pEffect));
+
+	if ( (pEffect->getEnabled() != fEnabled) || (pEffect->getPriority() != nPriority) )
+	{
+		pEffect->setEnabled(fEnabled);
+		pEffect->setPriority(nPriority);
+		std::sort(m_Effects.begin(), m_Effects.end(), cmpEffect);
+	}
+}
 
-	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)
+// static
+bool LLVfxManager::cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS)
+{
+	if (pLHS && pRHS)
 	{
-		if (pParams)
-			pParams->step(itEffect == endEffect);
-		(*itEffect)->run(pParams);
+		// Sort by code, then priority, then memory address
+		return (pLHS->getCode() == pRHS->getCode()) ? (pLHS->getPriority() == pRHS->getPriority() ? pLHS < pRHS
+		                                                                                          : pLHS->getPriority() > pRHS->getPriority())
+			                                        : pLHS->getCode() < pRHS->getCode();
 	}
+	return (pLHS);
 }
 
 // ============================================================================
diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h
index 55fbd13468136e8d807846b35c65c4e260c1d4cc..959e0dbc836210406980b9e9b884fd73eb2439af 100644
--- a/indra/newview/llvisualeffect.h
+++ b/indra/newview/llvisualeffect.h
@@ -71,6 +71,7 @@ struct LLShaderEffectParams : LLVisualEffectParams
 
 class LLVisualEffect
 {
+	friend class LLVfxManager;
 public:
 	LLVisualEffect(LLUUID id, EVisualEffect eCode, EVisualEffectType eType)
 		: m_id(id), m_eCode(eCode), m_eType(eType)
@@ -78,12 +79,17 @@ class LLVisualEffect
 	virtual ~LLVisualEffect() {}
 
 	EVisualEffect     getCode() const     { return m_eCode;}
+	bool              getEnabled() const  { return m_fEnabled; }
 	const LLUUID&     getId() const       { return m_id;}
 	U32               getPriority() const { return m_nPriority; }
 	EVisualEffectType getType() const     { return m_eType;}
+	void              setEnabled(bool enable) { m_fEnabled = enable; }
 
 	virtual void      run(const LLVisualEffectParams* pParams) = 0;
 
+protected:
+	void              setPriority(U32 priority) { m_nPriority = priority; }
+
 	/*
 	 * Member variables
 	 */
@@ -91,7 +97,8 @@ class LLVisualEffect
 	LLUUID            m_id;
 	EVisualEffect     m_eCode;
 	EVisualEffectType m_eType;
-	U32               m_nPriority;
+	bool              m_fEnabled = true;
+	U32               m_nPriority = 0;
 };
 
 // ============================================================================
@@ -161,18 +168,23 @@ class LLVfxManager : public LLSingleton<LLVfxManager>
 	bool            addEffect(LLVisualEffect* pEffectInst);
 	LLVisualEffect* getEffect(EVisualEffect eCode, const LLUUID& idEffect) const;
 	template<typename T> T* getEffect(const LLUUID& idEffect) const { return dynamic_cast<T*>(getEffect(T::EffectCode, idEffect)); }
+	bool            getEffects(std::list<LLVisualEffect*>& effectList, std::function<bool(const LLVisualEffect*)> fnFilter);
+	template<typename T> bool getEffects(std::list<LLVisualEffect*>& effectList) { return getEffects(effectList, [](const LLVisualEffect* pEffect) { return pEffect->getCode() == T::EffectCode; }); }
 	bool            hasEffect(EVisualEffect eCode) const;
 	bool            removeEffect(EVisualEffect eCode, const LLUUID& idEffect);
 	template<typename T> bool removeEffect(const LLUUID& idEffect) { return removeEffect(T::EffectCode, idEffect); }
 	void            runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr);
 	void            runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr);
+	void            updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority);
 protected:
+	void            runEffect(std::function<bool(const LLVisualEffect*)> fnFilter, LLVisualEffectParams* pParams);
+	static bool     cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS);
 
 	/*
 	 * Member variables
 	 */
 protected:
-	std::set<LLVisualEffect*> m_Effects;
+	std::vector<LLVisualEffect*> m_Effects;
 };
 
 // ============================================================================