From df08808640031bd27a11177ea49a08f797d2d570 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 28 Feb 2013 09:33:41 -0800
Subject: [PATCH] Improve perf of GLSL uniform lookups by name

---
 indra/llcommon/llstringtable.h        |  480 ++++----
 indra/llrender/llglslshader.cpp       |   92 +-
 indra/llrender/llglslshader.h         |   37 +-
 indra/llrender/llpostprocess.cpp      |   59 +-
 indra/llrender/llpostprocess.h        |  532 ++++-----
 indra/newview/lldrawpoolavatar.cpp    |  135 +--
 indra/newview/lldrawpoolbump.cpp      |   11 +-
 indra/newview/lldrawpoolterrain.cpp   |   11 +-
 indra/newview/lldrawpoolwater.cpp     | 1461 +++++++++++++------------
 indra/newview/lldrawpoolwlsky.cpp     |    6 +-
 indra/newview/llface.cpp              |   11 +-
 indra/newview/llmaniptranslate.cpp    |    3 +-
 indra/newview/llviewershadermgr.cpp   |   93 +-
 indra/newview/llviewershadermgr.h     |   16 +-
 indra/newview/llwaterparammanager.cpp |   22 +-
 indra/newview/llwlparammanager.cpp    |    7 +-
 indra/newview/pipeline.cpp            |   83 +-
 17 files changed, 1570 insertions(+), 1489 deletions(-)

diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index 59d7372ed49..4f6417328c2 100644
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -1,217 +1,263 @@
-/** 
- * @file llstringtable.h
- * @brief The LLStringTable class provides a _fast_ method for finding
- * unique copies of strings.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_STRING_TABLE_H
-#define LL_STRING_TABLE_H
-
-#include "lldefs.h"
-#include "llformat.h"
-#include "llstl.h"
-#include <list>
-#include <set>
-
-#if LL_WINDOWS
-# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
-#  define STRING_TABLE_HASH_MAP 1
-# endif
-#else
-//# define STRING_TABLE_HASH_MAP 1
-#endif
-
-#if STRING_TABLE_HASH_MAP
-# if LL_WINDOWS
-#  include <hash_map>
-# else
-#  include <ext/hash_map>
-# endif
-#endif
-
-const U32 MAX_STRINGS_LENGTH = 256;
-
-class LL_COMMON_API LLStringTableEntry
-{
-public:
-	LLStringTableEntry(const char *str);
-	~LLStringTableEntry();
-
-	void incCount()		{ mCount++; }
-	BOOL decCount()		{ return --mCount; }
-
-	char *mString;
-	S32  mCount;
-};
-
-class LL_COMMON_API LLStringTable
-{
-public:
-	LLStringTable(int tablesize);
-	~LLStringTable();
-
-	char *checkString(const char *str);
-	char *checkString(const std::string& str);
-	LLStringTableEntry *checkStringEntry(const char *str);
-	LLStringTableEntry *checkStringEntry(const std::string& str);
-
-	char *addString(const char *str);
-	char *addString(const std::string& str);
-	LLStringTableEntry *addStringEntry(const char *str);
-	LLStringTableEntry *addStringEntry(const std::string& str);
-	void  removeString(const char *str);
-
-	S32 mMaxEntries;
-	S32 mUniqueEntries;
-	
-#if STRING_TABLE_HASH_MAP
-#if LL_WINDOWS
-	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#else
-	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#endif
-	string_hash_t mStringHash;
-#else
-	typedef std::list<LLStringTableEntry *> string_list_t;
-	typedef string_list_t * string_list_ptr_t;
-	string_list_ptr_t	*mStringList;
-#endif	
-};
-
-extern LL_COMMON_API LLStringTable gStringTable;
-
-//============================================================================
-
-// This class is designed to be used locally,
-// e.g. as a member of an LLXmlTree
-// Strings can be inserted only, then quickly looked up
-
-typedef const std::string* LLStdStringHandle;
-
-class LL_COMMON_API LLStdStringTable
-{
-public:
-	LLStdStringTable(S32 tablesize = 0)
-	{
-		if (tablesize == 0)
-		{
-			tablesize = 256; // default
-		}
-		// Make sure tablesize is power of 2
-		for (S32 i = 31; i>0; i--)
-		{
-			if (tablesize & (1<<i))
-			{
-				if (tablesize >= (3<<(i-1)))
-					tablesize = (1<<(i+1));
-				else
-					tablesize = (1<<i);
-				break;
-			}
-		}
-		mTableSize = tablesize;
-		mStringList = new string_set_t[tablesize];
-	}
-	~LLStdStringTable()
-	{
-		cleanup();
-		delete[] mStringList;
-	}
-	void cleanup()
-	{
-		// remove strings
-		for (S32 i = 0; i<mTableSize; i++)
-		{
-			string_set_t& stringset = mStringList[i];
-			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
-			{
-				delete *iter;
-			}
-			stringset.clear();
-		}
-	}
-
-	LLStdStringHandle lookup(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-	
-	LLStdStringHandle checkString(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-
-	LLStdStringHandle insert(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		LLStdStringHandle result = lookup(hashval, s);
-		if (result == NULL)
-		{
-			result = new std::string(s);
-			mStringList[hashval].insert(result);
-		}
-		return result;
-	}
-	LLStdStringHandle addString(const std::string& s)
-	{
-		return insert(s);
-	}
-	
-private:
-	U32 makehash(const std::string& s)
-	{
-		S32 len = (S32)s.size();
-		const char* c = s.c_str();
-		U32 hashval = 0;
-		for (S32 i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval & (mTableSize-1);
-	}
-	LLStdStringHandle lookup(U32 hashval, const std::string& s)
-	{
-		string_set_t& stringset = mStringList[hashval];
-		LLStdStringHandle handle = &s;
-		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
-		if (iter != stringset.end())
-		{
-			return *iter;
-		}
-		else
-		{
-			return NULL;
-		}
-	}
-	
-private:
-	S32 mTableSize;
-	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
-	string_set_t* mStringList; // [mTableSize]
-};
-
-
-#endif
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_STRING_TABLE_H
+#define LL_STRING_TABLE_H
+
+#include "lldefs.h"
+#include "llformat.h"
+#include "llstl.h"
+#include <list>
+#include <set>
+#include <hash_map>
+
+#if LL_WINDOWS
+# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
+#  define STRING_TABLE_HASH_MAP 1
+# endif
+#else
+//# define STRING_TABLE_HASH_MAP 1
+#endif
+
+#if STRING_TABLE_HASH_MAP
+# if LL_WINDOWS
+#  include <hash_map>
+# else
+#  include <ext/hash_map>
+# endif
+#endif
+
+class LLStaticHashedString
+{
+public:
+
+	LLStaticHashedString(const std::string& s)
+	{
+		string_hash = makehash(s);
+		string		= s;
+	}
+
+	const std::string&	String() const { return string;		}
+	size_t				Hash()	 const { return string_hash;  }
+
+protected:
+
+	size_t makehash(const std::string& s)
+	{
+		size_t len = s.size();
+		const char* c = s.c_str();
+		size_t hashval = 0;
+		for (size_t i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval;
+	}
+
+	std::string string;
+	size_t		string_hash;
+};
+
+template<class T>
+struct LLStaticStringHasher
+{
+	enum { bucket_size = 8 };
+	size_t operator()(const T& key_value)		   const { return key_value.Hash();			  }
+	bool operator()(const T& left, const T& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+	: public std::hash_map< LLStaticHashedString , MappedObject, LLStaticStringHasher< LLStaticHashedString > >
+{
+};
+
+const U32 MAX_STRINGS_LENGTH = 256;
+
+class LL_COMMON_API LLStringTableEntry
+{
+public:
+	LLStringTableEntry(const char *str);
+	~LLStringTableEntry();
+
+	void incCount()		{ mCount++; }
+	BOOL decCount()		{ return --mCount; }
+
+	char *mString;
+	S32  mCount;
+};
+
+class LL_COMMON_API LLStringTable
+{
+public:
+	LLStringTable(int tablesize);
+	~LLStringTable();
+
+	char *checkString(const char *str);
+	char *checkString(const std::string& str);
+	LLStringTableEntry *checkStringEntry(const char *str);
+	LLStringTableEntry *checkStringEntry(const std::string& str);
+
+	char *addString(const char *str);
+	char *addString(const std::string& str);
+	LLStringTableEntry *addStringEntry(const char *str);
+	LLStringTableEntry *addStringEntry(const std::string& str);
+	void  removeString(const char *str);
+
+	S32 mMaxEntries;
+	S32 mUniqueEntries;
+	
+#if STRING_TABLE_HASH_MAP
+#if LL_WINDOWS
+	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#else
+	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#endif
+	string_hash_t mStringHash;
+#else
+	typedef std::list<LLStringTableEntry *> string_list_t;
+	typedef string_list_t * string_list_ptr_t;
+	string_list_ptr_t	*mStringList;
+#endif	
+};
+
+extern LL_COMMON_API LLStringTable gStringTable;
+
+//============================================================================
+
+// This class is designed to be used locally,
+// e.g. as a member of an LLXmlTree
+// Strings can be inserted only, then quickly looked up
+
+typedef const std::string* LLStdStringHandle;
+
+class LL_COMMON_API LLStdStringTable
+{
+public:
+	LLStdStringTable(S32 tablesize = 0)
+	{
+		if (tablesize == 0)
+		{
+			tablesize = 256; // default
+		}
+		// Make sure tablesize is power of 2
+		for (S32 i = 31; i>0; i--)
+		{
+			if (tablesize & (1<<i))
+			{
+				if (tablesize >= (3<<(i-1)))
+					tablesize = (1<<(i+1));
+				else
+					tablesize = (1<<i);
+				break;
+			}
+		}
+		mTableSize = tablesize;
+		mStringList = new string_set_t[tablesize];
+	}
+	~LLStdStringTable()
+	{
+		cleanup();
+		delete[] mStringList;
+	}
+	void cleanup()
+	{
+		// remove strings
+		for (S32 i = 0; i<mTableSize; i++)
+		{
+			string_set_t& stringset = mStringList[i];
+			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
+			{
+				delete *iter;
+			}
+			stringset.clear();
+		}
+	}
+
+	LLStdStringHandle lookup(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+	
+	LLStdStringHandle checkString(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+
+	LLStdStringHandle insert(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		LLStdStringHandle result = lookup(hashval, s);
+		if (result == NULL)
+		{
+			result = new std::string(s);
+			mStringList[hashval].insert(result);
+		}
+		return result;
+	}
+	LLStdStringHandle addString(const std::string& s)
+	{
+		return insert(s);
+	}
+	
+private:
+	U32 makehash(const std::string& s)
+	{
+		S32 len = (S32)s.size();
+		const char* c = s.c_str();
+		U32 hashval = 0;
+		for (S32 i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval & (mTableSize-1);
+	}
+	LLStdStringHandle lookup(U32 hashval, const std::string& s)
+	{
+		string_set_t& stringset = mStringList[hashval];
+		LLStdStringHandle handle = &s;
+		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
+		if (iter != stringset.end())
+		{
+			return *iter;
+		}
+		else
+		{
+			return NULL;
+		}
+	}
+	
+private:
+	S32 mTableSize;
+	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
+	string_set_t* mStringList; // [mTableSize]
+};
+
+
+#endif
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7cbf39096ec..298a03f32aa 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -128,8 +128,8 @@ void LLGLSLShader::unload()
 	stop_glerror();
 }
 
-BOOL LLGLSLShader::createShader(vector<string> * attributes,
-								vector<string> * uniforms,
+BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
+								std::vector<LLStaticHashedString> * uniforms,
 								U32 varying_count,
 								const char** varyings)
 {
@@ -209,7 +209,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
 
 		for (S32 i = 0; i < channel_count; i++)
 		{
-			uniform1i(llformat("tex%d", i), i);
+			LLStaticHashedString uniName(llformat("tex%d", i));
+			uniform1i(uniName, i);
 		}
 
 		S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
@@ -266,7 +267,7 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
 	}
 }
 
-BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
+BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
 {
 	//before linking, make sure reserved attributes always have consistent locations
 	for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
@@ -300,7 +301,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
 		{
 			for (U32 i = 0; i < numAttributes; i++)
 			{
-				const char* name = (*attributes)[i].c_str();
+				const char* name = (*attributes)[i].String().c_str();
 				S32 index = glGetAttribLocationARB(mProgramObject, name);
 				if (index != -1)
 				{
@@ -316,7 +317,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
 	return FALSE;
 }
 
-void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
+void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
 {
 	if (index == -1)
 	{
@@ -341,7 +342,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
 			is_array[0] = 0;
 		}
 
-		mUniformMap[name] = location;
+		LLStaticHashedString hashedName(name);
+		mUniformMap[hashedName] = location;
 		LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
 	
 		//find the index of this uniform
@@ -362,7 +364,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
 			for (U32 i = 0; i < uniforms->size(); i++)
 			{
 				if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
-					&& ((*uniforms)[i] == name))
+					&& ((*uniforms)[i].String() == name))
 				{
 					//found it
 					mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
@@ -386,7 +388,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
 	return -1;
 }
 
-BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
+BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
 {
 	BOOL res = TRUE;
 	
@@ -793,18 +795,18 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
 	}
 }
 
-GLint LLGLSLShader::getUniformLocation(const string& uniform)
+GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
 {
 	GLint ret = -1;
 	if (mProgramObject > 0)
 	{
-		std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
+		LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
 		if (iter != mUniformMap.end())
 		{
 			if (gDebugGL)
 			{
 				stop_glerror();
-				if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
+				if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
 				{
 					llerrs << "Uniform does not match." << llendl;
 				}
@@ -841,10 +843,10 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
 	}
 }
 
-void LLGLSLShader::uniform1i(const string& uniform, GLint v)
+void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -857,10 +859,10 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
 	}
 }
 
-void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
+void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -873,10 +875,10 @@ void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
 	}
 }
 
-void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
+void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -890,10 +892,10 @@ void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
 
 }
 
-void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
+void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -906,23 +908,7 @@ void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloa
 	}
 }
 
-void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	GLint location = getUniformLocation(uniform);
-
-	if (location >= 0)
-	{
-		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
-		LLVector4 vec(x,y,z,w);
-		if (iter == mValue.end() || shouldChange(iter->second,vec))
-		{
-			glUniform4fARB(location, x,y,z,w);
-			mValue[location] = vec;
-		}
-	}
-}
-
-void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
 {
 	GLint location = getUniformLocation(uniform);
 
@@ -938,10 +924,10 @@ void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v
 	}
 }
 
-void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -954,10 +940,10 @@ void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v
 	}
 }
 
-void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
 {
 	GLint location = getUniformLocation(uniform);
-				
+
 	if (location >= 0)
 	{
 		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@@ -970,7 +956,7 @@ void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v
 	}
 }
 
-void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
 {
 	GLint location = getUniformLocation(uniform);
 
@@ -988,27 +974,7 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
 	}
 }
 
-void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
-	GLint location = getUniformLocation(uniform);
-				
-	if (location >= 0)
-	{
-		glUniformMatrix2fvARB(location, count, transpose, v);
-	}
-}
-
-void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
-	GLint location = getUniformLocation(uniform);
-				
-	if (location >= 0)
-	{
-		glUniformMatrix3fvARB(location, count, transpose, v);
-	}
-}
-
-void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
+void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
 {
 	GLint location = getUniformLocation(uniform);
 				
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 5c68cb46eb3..bac9af69596 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -75,16 +75,16 @@ class LLGLSLShader
 	static bool sNoFixedFunction;
 
 	void unload();
-	BOOL createShader(std::vector<std::string> * attributes,
-						std::vector<std::string> * uniforms,
+	BOOL createShader(std::vector<LLStaticHashedString> * attributes,
+						std::vector<LLStaticHashedString> * uniforms,
 						U32 varying_count = 0,
 						const char** varyings = NULL);
 	BOOL attachObject(std::string object);
 	void attachObject(GLhandleARB object);
 	void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
-	BOOL mapAttributes(const std::vector<std::string> * attributes);
-	BOOL mapUniforms(const std::vector<std::string> * uniforms);
-	void mapUniform(GLint index, const std::vector<std::string> * uniforms);
+	BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
+	BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
+	void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
 	void uniform1i(U32 index, GLint i);
 	void uniform1f(U32 index, GLfloat v);
 	void uniform2f(U32 index, GLfloat x, GLfloat y);
@@ -95,29 +95,26 @@ class LLGLSLShader
 	void uniform2fv(U32 index, U32 count, const GLfloat* v);
 	void uniform3fv(U32 index, U32 count, const GLfloat* v);
 	void uniform4fv(U32 index, U32 count, const GLfloat* v);
-	void uniform1i(const std::string& uniform, GLint i);
-	void uniform1f(const std::string& uniform, GLfloat v);
-	void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
-	void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
-	void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-	void uniform1iv(const std::string& uniform, U32 count, const GLint* i);
-	void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v);
-	void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v);
-	void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v);
-	void uniform4fv(const std::string& uniform, U32 count, const GLfloat* v);
 	void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
 	void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
 	void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
-	void uniformMatrix2fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
-	void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
-	void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
+	void uniform1i(const LLStaticHashedString& uniform, GLint i);
+	void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
+	void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
+	void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
+	void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+	void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+	void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+	void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+	void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
 
 	void setMinimumAlpha(F32 minimum);
 
 	void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 	void vertexAttrib4fv(U32 index, GLfloat* v);
 	
-	GLint getUniformLocation(const std::string& uniform);
+	//GLint getUniformLocation(const std::string& uniform);
+	GLint getUniformLocation(const LLStaticHashedString& uniform);	
 	GLint getUniformLocation(U32 index);
 
 	GLint getAttribLocation(U32 attrib);
@@ -143,7 +140,7 @@ class LLGLSLShader
 	GLhandleARB mProgramObject;
 	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
 	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location
-	std::map<std::string, GLint> mUniformMap;  //lookup map of uniform name to uniform location
+	LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
 	std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
 	std::vector<GLint> mTexture;
 	S32 mActiveTextureChannels;
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index c0045c80447..21a28e386fa 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -31,6 +31,21 @@
 #include "llsdserialize.h"
 #include "llrender.h"
 
+static LLStaticHashedString sRenderTexture("RenderTexture");
+static LLStaticHashedString sBrightness("brightness");
+static LLStaticHashedString sContrast("contrast");
+static LLStaticHashedString sContrastBase("contrastBase");
+static LLStaticHashedString sSaturation("saturation");
+static LLStaticHashedString sLumWeights("lumWeights");
+static LLStaticHashedString sNoiseTexture("NoiseTexture");
+static LLStaticHashedString sBrightMult("brightMult");
+static LLStaticHashedString sNoiseStrength("noiseStrength");
+static LLStaticHashedString sExtractLow("extractLow");
+static LLStaticHashedString sExtractHigh("extractHigh");
+static LLStaticHashedString sBloomStrength("bloomStrength");
+static LLStaticHashedString sTexelSize("texelSize");
+static LLStaticHashedString sBlurDirection("blurDirection");
+static LLStaticHashedString sBlurWidth("blurWidth");
 
 LLPostProcess * gPostProcess = NULL;
 
@@ -258,12 +273,12 @@ void LLPostProcess::applyColorFilterShader(void)
 void LLPostProcess::createColorFilterShader(void)
 {
 	/// Define uniform names
-	colorFilterUniforms["RenderTexture"] = 0;
-	colorFilterUniforms["brightness"] = 0;
-	colorFilterUniforms["contrast"] = 0;
-	colorFilterUniforms["contrastBase"] = 0;
-	colorFilterUniforms["saturation"] = 0;
-	colorFilterUniforms["lumWeights"] = 0;
+	colorFilterUniforms[sRenderTexture] = 0;
+	colorFilterUniforms[sBrightness] = 0;
+	colorFilterUniforms[sContrast] = 0;
+	colorFilterUniforms[sContrastBase] = 0;
+	colorFilterUniforms[sSaturation] = 0;
+	colorFilterUniforms[sLumWeights] = 0;
 }
 
 void LLPostProcess::applyNightVisionShader(void)
@@ -307,11 +322,11 @@ void LLPostProcess::applyNightVisionShader(void)
 void LLPostProcess::createNightVisionShader(void)
 {
 	/// Define uniform names
-	nightVisionUniforms["RenderTexture"] = 0;
-	nightVisionUniforms["NoiseTexture"] = 0;
-	nightVisionUniforms["brightMult"] = 0;	
-	nightVisionUniforms["noiseStrength"] = 0;
-	nightVisionUniforms["lumWeights"] = 0;	
+	nightVisionUniforms[sRenderTexture] = 0;
+	nightVisionUniforms[sNoiseTexture] = 0;
+	nightVisionUniforms[sBrightMult] = 0;	
+	nightVisionUniforms[sNoiseStrength] = 0;
+	nightVisionUniforms[sLumWeights] = 0;	
 
 	createNoiseTexture(mNoiseTexture);
 }
@@ -326,25 +341,25 @@ void LLPostProcess::createBloomShader(void)
 	createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
 
 	/// Create Bloom Extract Shader
-	bloomExtractUniforms["RenderTexture"] = 0;
-	bloomExtractUniforms["extractLow"] = 0;
-	bloomExtractUniforms["extractHigh"] = 0;	
-	bloomExtractUniforms["lumWeights"] = 0;	
+	bloomExtractUniforms[sRenderTexture] = 0;
+	bloomExtractUniforms[sExtractLow] = 0;
+	bloomExtractUniforms[sExtractHigh] = 0;	
+	bloomExtractUniforms[sLumWeights] = 0;	
 	
 	/// Create Bloom Blur Shader
-	bloomBlurUniforms["RenderTexture"] = 0;
-	bloomBlurUniforms["bloomStrength"] = 0;	
-	bloomBlurUniforms["texelSize"] = 0;
-	bloomBlurUniforms["blurDirection"] = 0;
-	bloomBlurUniforms["blurWidth"] = 0;
+	bloomBlurUniforms[sRenderTexture] = 0;
+	bloomBlurUniforms[sBloomStrength] = 0;	
+	bloomBlurUniforms[sTexelSize] = 0;
+	bloomBlurUniforms[sBlurDirection] = 0;
+	bloomBlurUniforms[sBlurWidth] = 0;
 }
 
 void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog)
 {
 	/// Find uniform locations and insert into map	
-	std::map<const char *, GLuint>::iterator i;
+	glslUniforms::iterator i;
 	for (i  = uniforms.begin(); i != uniforms.end(); ++i){
-		i->second = glGetUniformLocationARB(prog, i->first);
+		i->second = glGetUniformLocationARB(prog, i->first.String().c_str());
 	}
 }
 
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index e19de44c608..c380413ec9d 100644
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -1,266 +1,266 @@
-/** 
- * @file llpostprocess.h
- * @brief LLPostProcess class definition
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_POSTPROCESS_H
-#define LL_POSTPROCESS_H
-
-#include <map>
-#include <fstream>
-#include "llgl.h"
-#include "llglheaders.h"
-
-class LLPostProcess 
-{
-public:
-
-	typedef enum _QuadType {
-		QUAD_NORMAL,
-		QUAD_NOISE,
-		QUAD_BLOOM_EXTRACT,
-		QUAD_BLOOM_COMBINE
-	} QuadType;
-
-	/// GLSL Shader Encapsulation Struct
-	typedef std::map<const char *, GLuint> glslUniforms;
-
-	struct PostProcessTweaks : public LLSD {
-		inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
-		{
-		}
-
-		inline LLSD & brightMult() {
-			return (*this)["brightness_multiplier"];
-		}
-
-		inline LLSD & noiseStrength() {
-			return (*this)["noise_strength"];
-		}
-
-		inline LLSD & noiseSize() {
-			return (*this)["noise_size"];
-		}
-
-		inline LLSD & extractLow() {
-			return (*this)["extract_low"];
-		}
-
-		inline LLSD & extractHigh() {
-			return (*this)["extract_high"];
-		}
-
-		inline LLSD & bloomWidth() {
-			return (*this)["bloom_width"];
-		}
-
-		inline LLSD & bloomStrength() {
-			return (*this)["bloom_strength"];
-		}
-
-		inline LLSD & brightness() {
-			return (*this)["brightness"];
-		}
-
-		inline LLSD & contrast() {
-			return (*this)["contrast"];
-		}
-
-		inline LLSD & contrastBaseR() {
-			return (*this)["contrast_base"][0];
-		}
-
-		inline LLSD & contrastBaseG() {
-			return (*this)["contrast_base"][1];
-		}
-
-		inline LLSD & contrastBaseB() {
-			return (*this)["contrast_base"][2];
-		}
-
-		inline LLSD & contrastBaseIntensity() {
-			return (*this)["contrast_base"][3];
-		}
-
-		inline LLSD & saturation() {
-			return (*this)["saturation"];
-		}
-
-		inline LLSD & useNightVisionShader() {
-			return (*this)["enable_night_vision"];
-		}
-
-		inline LLSD & useBloomShader() {
-			return (*this)["enable_bloom"];
-		}
-
-		inline LLSD & useColorFilter() {
-			return (*this)["enable_color_filter"];
-		}
-
-
-		inline F32 getBrightMult() const {
-			return F32((*this)["brightness_multiplier"].asReal());
-		}
-
-		inline F32 getNoiseStrength() const {
-			return F32((*this)["noise_strength"].asReal());
-		}
-
-		inline F32 getNoiseSize() const {
-			return F32((*this)["noise_size"].asReal());
-		}
-
-		inline F32 getExtractLow() const {
-			return F32((*this)["extract_low"].asReal());
-		}
-
-		inline F32 getExtractHigh() const {
-			return F32((*this)["extract_high"].asReal());
-		}
-
-		inline F32 getBloomWidth() const {
-			return F32((*this)["bloom_width"].asReal());
-		}
-
-		inline F32 getBloomStrength() const {
-			return F32((*this)["bloom_strength"].asReal());
-		}
-
-		inline F32 getBrightness() const {
-			return F32((*this)["brightness"].asReal());
-		}
-
-		inline F32 getContrast() const {
-			return F32((*this)["contrast"].asReal());
-		}
-
-		inline F32 getContrastBaseR() const {
-			return F32((*this)["contrast_base"][0].asReal());
-		}
-
-		inline F32 getContrastBaseG() const {
-			return F32((*this)["contrast_base"][1].asReal());
-		}
-
-		inline F32 getContrastBaseB() const {
-			return F32((*this)["contrast_base"][2].asReal());
-		}
-
-		inline F32 getContrastBaseIntensity() const {
-			return F32((*this)["contrast_base"][3].asReal());
-		}
-
-		inline F32 getSaturation() const {
-			return F32((*this)["saturation"].asReal());
-		}
-
-	};
-	
-	bool initialized;
-	PostProcessTweaks tweaks;
-
-	// the map of all availible effects
-	LLSD mAllEffects;
-
-private:
-	LLPointer<LLImageGL> mSceneRenderTexture ;
-	LLPointer<LLImageGL> mNoiseTexture ;
-	LLPointer<LLImageGL> mTempBloomTexture ;
-
-public:
-	LLPostProcess(void);
-
-	~LLPostProcess(void);
-
-	void apply(unsigned int width, unsigned int height);
-	void invalidate() ;
-
-	/// Perform global initialization for this class.
-	static void initClass(void);
-
-	// Cleanup of global data that's only inited once per class.
-	static void cleanupClass();
-
-	void setSelectedEffect(std::string const & effectName);
-
-	inline std::string const & getSelectedEffect(void) const {
-		return mSelectedEffectName;
-	}
-
-	void saveEffect(std::string const & effectName);
-
-private:
-		/// read in from file
-	std::string mShaderErrorString;
-	unsigned int screenW;
-	unsigned int screenH;
-
-	float noiseTextureScale;
-	
-	/// Shader Uniforms
-	glslUniforms nightVisionUniforms;
-	glslUniforms bloomExtractUniforms;
-	glslUniforms bloomBlurUniforms;
-	glslUniforms colorFilterUniforms;
-
-	// the name of currently selected effect in mAllEffects
-	// invariant: tweaks == mAllEffects[mSelectedEffectName]
-	std::string mSelectedEffectName;
-
-	/// General functions
-	void initialize(unsigned int width, unsigned int height);
-	void doEffects(void);
-	void applyShaders(void);
-	bool shadersEnabled(void);
-
-	/// Night Vision Functions
-	void createNightVisionShader(void);
-	void applyNightVisionShader(void);
-
-	/// Bloom Functions
-	void createBloomShader(void);
-	void applyBloomShader(void);
-
-	/// Color Filter Functions
-	void createColorFilterShader(void);
-	void applyColorFilterShader(void);
-
-	/// OpenGL Helper Functions
-	void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog);
-	void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
-	void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
-	void createNoiseTexture(LLPointer<LLImageGL>& texture);
-	bool checkError(void);
-	void checkShaderError(GLhandleARB shader);
-	void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
-	void viewOrthogonal(unsigned int width, unsigned int height);
-	void changeOrthogonal(unsigned int width, unsigned int height);
-	void viewPerspective(void);
-};
-
-extern LLPostProcess * gPostProcess;
-
-
-#endif // LL_POSTPROCESS_H
+/** 
+ * @file llpostprocess.h
+ * @brief LLPostProcess class definition
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_POSTPROCESS_H
+#define LL_POSTPROCESS_H
+
+#include <map>
+#include <fstream>
+#include "llgl.h"
+#include "llglheaders.h"
+
+class LLPostProcess 
+{
+public:
+
+	typedef enum _QuadType {
+		QUAD_NORMAL,
+		QUAD_NOISE,
+		QUAD_BLOOM_EXTRACT,
+		QUAD_BLOOM_COMBINE
+	} QuadType;
+
+	/// GLSL Shader Encapsulation Struct
+	typedef LLStaticStringTable<GLuint> glslUniforms;
+
+	struct PostProcessTweaks : public LLSD {
+		inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
+		{
+		}
+
+		inline LLSD & brightMult() {
+			return (*this)["brightness_multiplier"];
+		}
+
+		inline LLSD & noiseStrength() {
+			return (*this)["noise_strength"];
+		}
+
+		inline LLSD & noiseSize() {
+			return (*this)["noise_size"];
+		}
+
+		inline LLSD & extractLow() {
+			return (*this)["extract_low"];
+		}
+
+		inline LLSD & extractHigh() {
+			return (*this)["extract_high"];
+		}
+
+		inline LLSD & bloomWidth() {
+			return (*this)["bloom_width"];
+		}
+
+		inline LLSD & bloomStrength() {
+			return (*this)["bloom_strength"];
+		}
+
+		inline LLSD & brightness() {
+			return (*this)["brightness"];
+		}
+
+		inline LLSD & contrast() {
+			return (*this)["contrast"];
+		}
+
+		inline LLSD & contrastBaseR() {
+			return (*this)["contrast_base"][0];
+		}
+
+		inline LLSD & contrastBaseG() {
+			return (*this)["contrast_base"][1];
+		}
+
+		inline LLSD & contrastBaseB() {
+			return (*this)["contrast_base"][2];
+		}
+
+		inline LLSD & contrastBaseIntensity() {
+			return (*this)["contrast_base"][3];
+		}
+
+		inline LLSD & saturation() {
+			return (*this)["saturation"];
+		}
+
+		inline LLSD & useNightVisionShader() {
+			return (*this)["enable_night_vision"];
+		}
+
+		inline LLSD & useBloomShader() {
+			return (*this)["enable_bloom"];
+		}
+
+		inline LLSD & useColorFilter() {
+			return (*this)["enable_color_filter"];
+		}
+
+
+		inline F32 getBrightMult() const {
+			return F32((*this)["brightness_multiplier"].asReal());
+		}
+
+		inline F32 getNoiseStrength() const {
+			return F32((*this)["noise_strength"].asReal());
+		}
+
+		inline F32 getNoiseSize() const {
+			return F32((*this)["noise_size"].asReal());
+		}
+
+		inline F32 getExtractLow() const {
+			return F32((*this)["extract_low"].asReal());
+		}
+
+		inline F32 getExtractHigh() const {
+			return F32((*this)["extract_high"].asReal());
+		}
+
+		inline F32 getBloomWidth() const {
+			return F32((*this)["bloom_width"].asReal());
+		}
+
+		inline F32 getBloomStrength() const {
+			return F32((*this)["bloom_strength"].asReal());
+		}
+
+		inline F32 getBrightness() const {
+			return F32((*this)["brightness"].asReal());
+		}
+
+		inline F32 getContrast() const {
+			return F32((*this)["contrast"].asReal());
+		}
+
+		inline F32 getContrastBaseR() const {
+			return F32((*this)["contrast_base"][0].asReal());
+		}
+
+		inline F32 getContrastBaseG() const {
+			return F32((*this)["contrast_base"][1].asReal());
+		}
+
+		inline F32 getContrastBaseB() const {
+			return F32((*this)["contrast_base"][2].asReal());
+		}
+
+		inline F32 getContrastBaseIntensity() const {
+			return F32((*this)["contrast_base"][3].asReal());
+		}
+
+		inline F32 getSaturation() const {
+			return F32((*this)["saturation"].asReal());
+		}
+
+	};
+	
+	bool initialized;
+	PostProcessTweaks tweaks;
+
+	// the map of all availible effects
+	LLSD mAllEffects;
+
+private:
+	LLPointer<LLImageGL> mSceneRenderTexture ;
+	LLPointer<LLImageGL> mNoiseTexture ;
+	LLPointer<LLImageGL> mTempBloomTexture ;
+
+public:
+	LLPostProcess(void);
+
+	~LLPostProcess(void);
+
+	void apply(unsigned int width, unsigned int height);
+	void invalidate() ;
+
+	/// Perform global initialization for this class.
+	static void initClass(void);
+
+	// Cleanup of global data that's only inited once per class.
+	static void cleanupClass();
+
+	void setSelectedEffect(std::string const & effectName);
+
+	inline std::string const & getSelectedEffect(void) const {
+		return mSelectedEffectName;
+	}
+
+	void saveEffect(std::string const & effectName);
+
+private:
+		/// read in from file
+	std::string mShaderErrorString;
+	unsigned int screenW;
+	unsigned int screenH;
+
+	float noiseTextureScale;
+	
+	/// Shader Uniforms
+	glslUniforms nightVisionUniforms;
+	glslUniforms bloomExtractUniforms;
+	glslUniforms bloomBlurUniforms;
+	glslUniforms colorFilterUniforms;
+
+	// the name of currently selected effect in mAllEffects
+	// invariant: tweaks == mAllEffects[mSelectedEffectName]
+	std::string mSelectedEffectName;
+
+	/// General functions
+	void initialize(unsigned int width, unsigned int height);
+	void doEffects(void);
+	void applyShaders(void);
+	bool shadersEnabled(void);
+
+	/// Night Vision Functions
+	void createNightVisionShader(void);
+	void applyNightVisionShader(void);
+
+	/// Bloom Functions
+	void createBloomShader(void);
+	void applyBloomShader(void);
+
+	/// Color Filter Functions
+	void createColorFilterShader(void);
+	void applyColorFilterShader(void);
+
+	/// OpenGL Helper Functions
+	void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog);
+	void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
+	void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
+	void createNoiseTexture(LLPointer<LLImageGL>& texture);
+	bool checkError(void);
+	void checkShaderError(GLhandleARB shader);
+	void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
+	void viewOrthogonal(unsigned int width, unsigned int height);
+	void changeOrthogonal(unsigned int width, unsigned int height);
+	void viewPerspective(void);
+};
+
+extern LLPostProcess * gPostProcess;
+
+
+#endif // LL_POSTPROCESS_H
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 6d02ad2b967..3cf96a90545 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1165,85 +1165,85 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	{ //render rigged attachments
 		if (!avatarp->isVisuallyMuted())
 		{
-			if (pass == 3)
-			{
-				if (is_deferred_render)
-				{
-					renderDeferredRiggedSimple(avatarp);
-				}
-				else
-				{
-					renderRiggedSimple(avatarp);
-				}
-			}
+	if (pass == 3)
+	{
+		if (is_deferred_render)
+		{
+			renderDeferredRiggedSimple(avatarp);
+		}
+		else
+		{
+			renderRiggedSimple(avatarp);
+		}
+	}
 			else if (pass == 4)
-			{
-				if (is_deferred_render)
-				{
-					renderDeferredRiggedBump(avatarp);
-				}
-				else
-				{
-					renderRiggedFullbright(avatarp);
-				}
-			}
+	{
+		if (is_deferred_render)
+		{
+			renderDeferredRiggedBump(avatarp);
+		}
+		else
+		{
+			renderRiggedFullbright(avatarp);
+		}
+	}
 			else if (pass == 5)
-			{
-				renderRiggedShinySimple(avatarp);
-			}
+	{
+		renderRiggedShinySimple(avatarp);
+	}
 			else if (pass == 6)
-			{
-				renderRiggedFullbrightShiny(avatarp);
-			}
+	{
+		renderRiggedFullbrightShiny(avatarp);
+	}
 			else if (pass >= 7 && pass < 9)
-			{
-				if (pass == 7)
-				{
-					renderRiggedAlpha(avatarp);
-				}
+	{
+		if (pass == 7)
+		{
+			renderRiggedAlpha(avatarp);
+		}
 				else if (pass == 8)
-				{
-					renderRiggedFullbrightAlpha(avatarp);
-				}
-			}
+		{
+			renderRiggedFullbrightAlpha(avatarp);
+		}
+	}
 			else if (pass == 9)
-			{
-				renderRiggedGlow(avatarp);
-			}
+	{
+		renderRiggedGlow(avatarp);
+	}
 		}
 	}
 	else
 	{
-		if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
-		{
-			LLMatrix4 rot_mat;
-			LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat);
-			LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
-			rot_mat *= cfr;
+	if ((sShaderLevel >= SHADER_LEVEL_CLOTH))
+	{
+		LLMatrix4 rot_mat;
+		LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat);
+		LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
+		rot_mat *= cfr;
 		
-			LLVector4 wind;
-			wind.setVec(avatarp->mWindVec);
-			wind.mV[VW] = 0;
-			wind = wind * rot_mat;
-			wind.mV[VW] = avatarp->mWindVec.mV[VW];
-
-			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV);
-			F32 phase = -1.f * (avatarp->mRipplePhase);
-
-			F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f);
-			LLVector4 sin_params(freq, freq, freq, phase);
-			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV);
-
-			LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f);
-			gravity = gravity * rot_mat;
-			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV);
-		}
+		LLVector4 wind;
+		wind.setVec(avatarp->mWindVec);
+		wind.mV[VW] = 0;
+		wind = wind * rot_mat;
+		wind.mV[VW] = avatarp->mWindVec.mV[VW];
 
-		if( !single_avatar || (avatarp == single_avatar) )
-		{
-			avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
-		}
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV);
+		F32 phase = -1.f * (avatarp->mRipplePhase);
+
+		F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f);
+		LLVector4 sin_params(freq, freq, freq, phase);
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV);
+
+		LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f);
+		gravity = gravity * rot_mat;
+		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV);
 	}
+
+	if( !single_avatar || (avatarp == single_avatar) )
+	{
+		avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
+	}
+}
 }
 
 void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
@@ -1505,7 +1505,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 				
 				stop_glerror();
 
-				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette", 
+				static LLStaticHashedString sMatPalette("matrixPalette");
+				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(sMatPalette, 
 					skin->mJointNames.size(),
 					FALSE,
 					(GLfloat*) mat[0].mMatrix);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 8d1db7b9ad6..4137084ebe1 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -1368,9 +1368,14 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
 					LLGLDisable blend(GL_BLEND);
 					gGL.setColorMask(TRUE, TRUE);
 					gNormalMapGenProgram.bind();
-					gNormalMapGenProgram.uniform1f("norm_scale", gSavedSettings.getF32("RenderNormalMapScale"));
-					gNormalMapGenProgram.uniform1f("stepX", 1.f/bump->getWidth());
-					gNormalMapGenProgram.uniform1f("stepY", 1.f/bump->getHeight());
+
+					static LLStaticHashedString sNormScale("norm_scale");
+					static LLStaticHashedString sStepX("stepX");
+					static LLStaticHashedString sStepY("stepY");
+
+					gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
+					gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
+					gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
 
 					LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
 								(F32) bump->getHeight()/gPipeline.mScreen.getHeight());
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 9bc32fddbdb..3805348b6bf 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -49,6 +49,9 @@
 #include "llviewershadermgr.h"
 #include "llrender.h"
 
+static LLStaticHashedString sObjectPlaneS("object_plane_s");
+static LLStaticHashedString sObjectPlaneT("object_plane_t");
+
 const F32 DETAIL_SCALE = 1.f/16.f;
 int DebugDetailMap = 0;
 
@@ -352,8 +355,8 @@ void LLDrawPoolTerrain::renderFullShader()
 	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
 	llassert(shader);
 		
-	shader->uniform4fv("object_plane_s", 1, tp0.mV);
-	shader->uniform4fv("object_plane_t", 1, tp1.mV);
+	shader->uniform4fv(sObjectPlaneS, 1, tp0.mV);
+	shader->uniform4fv(sObjectPlaneT, 1, tp1.mV);
 
 	gGL.matrixMode(LLRender::MM_TEXTURE);
 	gGL.loadIdentity();
@@ -862,8 +865,8 @@ void LLDrawPoolTerrain::renderSimple()
 	
 	if (LLGLSLShader::sNoFixedFunction)
 	{
-		sShader->uniform4fv("object_plane_s", 1, tp0.mV);
-		sShader->uniform4fv("object_plane_t", 1, tp1.mV);
+		sShader->uniform4fv(sObjectPlaneS, 1, tp0.mV);
+		sShader->uniform4fv(sObjectPlaneT, 1, tp1.mV);
 	}
 	else
 	{
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4f6eaa5a5b7..ffe438eb273 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -1,725 +1,736 @@
-/** 
- * @file lldrawpoolwater.cpp
- * @brief LLDrawPoolWater class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llfeaturemanager.h"
-#include "lldrawpoolwater.h"
-
-#include "llviewercontrol.h"
-#include "lldir.h"
-#include "llerror.h"
-#include "m3math.h"
-#include "llrender.h"
-
-#include "llagent.h"		// for gAgent for getRegion for getWaterHeight
-#include "llcubemap.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llsky.h"
-#include "llviewertexturelist.h"
-#include "llviewerregion.h"
-#include "llvosky.h"
-#include "llvowater.h"
-#include "llworld.h"
-#include "pipeline.h"
-#include "llviewershadermgr.h"
-#include "llwaterparammanager.h"
-
-const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
-const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
-
-static float sTime;
-
-BOOL deferred_render = FALSE;
-
-BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
-BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
-BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
-LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
-F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
-
-LLVector3 LLDrawPoolWater::sLightDir;
-
-LLDrawPoolWater::LLDrawPoolWater() :
-	LLFacePool(POOL_WATER)
-{
-	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
-	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
-	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
-	gGL.getTexUnit(0)->bind(mHBTex[1]);
-	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
-
-
-	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
-	llassert(mWaterImagep);
-	mWaterImagep->setNoDelete();
-	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
-	llassert(mOpaqueWaterImagep);
-	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
-	mWaterNormp->setNoDelete();
-
-	restoreGL();
-}
-
-LLDrawPoolWater::~LLDrawPoolWater()
-{
-}
-
-//static
-void LLDrawPoolWater::restoreGL()
-{
-	
-}
-
-LLDrawPool *LLDrawPoolWater::instancePool()
-{
-	llerrs << "Should never be calling instancePool on a water pool!" << llendl;
-	return NULL;
-}
-
-
-void LLDrawPoolWater::prerender()
-{
-	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
-		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
-
-	// got rid of modulation by light color since it got a little too
-	// green at sunset and sl-57047 (underwater turns black at 8:00)
-	sWaterFogColor = LLWaterParamManager::instance().getFogColor();
-	sWaterFogColor.mV[3] = 0;
-
-}
-
-S32 LLDrawPoolWater::getNumPasses()
-{
-	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
-	{
-		return 1;
-	}
-
-	return 0;
-}
-
-void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
-{
-	beginRenderPass(pass);
-	deferred_render = TRUE;
-}
-
-void LLDrawPoolWater::endPostDeferredPass(S32 pass)
-{
-	endRenderPass(pass);
-	deferred_render = FALSE;
-}
-
-//===============================
-//DEFERRED IMPLEMENTATION
-//===============================
-void LLDrawPoolWater::renderDeferred(S32 pass)
-{
-	LLFastTimer t(FTM_RENDER_WATER);
-	deferred_render = TRUE;
-	shade();
-	deferred_render = FALSE;
-}
-
-//=========================================
-
-void LLDrawPoolWater::render(S32 pass)
-{
-	LLFastTimer ftm(FTM_RENDER_WATER);
-	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
-	{
-		return;
-	}
-
-	//do a quick 'n dirty depth sort
-	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
-			 iter != mDrawFace.end(); iter++)
-	{
-		LLFace* facep = *iter;
-		facep->mDistance = -facep->mCenterLocal.mV[2];
-	}
-
-	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
-
-	// See if we are rendering water as opaque or not
-	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
-	{
-		// render water for low end hardware
-		renderOpaqueLegacyWater();
-		return;
-	}
-
-	LLGLEnable blend(GL_BLEND);
-
-	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
-	{
-		shade();
-		return;
-	}
-
-	LLVOSky *voskyp = gSky.mVOSkyp;
-
-	stop_glerror();
-
-	if (!gGLManager.mHasMultitexture)
-	{
-		// Ack!  No multitexture!  Bail!
-		return;
-	}
-
-	LLFace* refl_face = voskyp->getReflFace();
-
-	gPipeline.disableLights();
-	
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
-	LLGLDisable cullFace(GL_CULL_FACE);
-	
-	// Set up second pass first
-	mWaterImagep->addTextureStats(1024.f*1024.f);
-	gGL.getTexUnit(1)->activate();
-	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
-	gGL.getTexUnit(1)->bind(mWaterImagep) ;
-
-	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
-	F32 up_dot = camera_up * LLVector3::z_axis;
-
-	LLColor4 water_color;
-	if (LLViewerCamera::getInstance()->cameraUnderWater())
-	{
-		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
-	}
-	else
-	{
-		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
-	}
-
-	gGL.diffuseColor4fv(water_color.mV);
-
-	// Automatically generate texture coords for detail map
-	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
-	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
-	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-
-	// Slowly move over time.
-	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
-	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
-	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
-	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
-	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
-
-	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
-	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
-	gGL.getTexUnit(0)->activate();
-	
-	glClearStencil(1);
-	glClear(GL_STENCIL_BUFFER_BIT);
-	LLGLEnable gls_stencil(GL_STENCIL_TEST);
-	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
-	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
-
-	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
-		 iter != mDrawFace.end(); iter++)
-	{
-		LLFace *face = *iter;
-		if (voskyp->isReflFace(face))
-		{
-			continue;
-		}
-		gGL.getTexUnit(0)->bind(face->getTexture());
-		face->renderIndexed();
-	}
-
-	// Now, disable texture coord generation on texture state 1
-	gGL.getTexUnit(1)->activate();
-	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.getTexUnit(1)->disable();
-	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
-	glDisable(GL_TEXTURE_GEN_T); //texture unit 1
-
-	// Disable texture coordinate and color arrays
-	gGL.getTexUnit(0)->activate();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	stop_glerror();
-	
-	if (gSky.mVOSkyp->getCubeMap())
-	{
-		gSky.mVOSkyp->getCubeMap()->enable(0);
-		gSky.mVOSkyp->getCubeMap()->bind();
-
-		gGL.matrixMode(LLRender::MM_TEXTURE);
-		gGL.loadIdentity();
-		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
-		LLMatrix4 camera_rot(camera_mat.getMat3());
-		camera_rot.invert();
-
-		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
-
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
-
-		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
-		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
-			 iter != mDrawFace.end(); iter++)
-		{
-			LLFace *face = *iter;
-			if (voskyp->isReflFace(face))
-			{
-				//refl_face = face;
-				continue;
-			}
-
-			if (face->getGeomCount() > 0)
-			{					
-				face->renderIndexed();
-			}
-		}
-
-		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
-		gSky.mVOSkyp->getCubeMap()->disable();
-		
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-		gGL.matrixMode(LLRender::MM_TEXTURE);
-		gGL.loadIdentity();
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		
-	}
-
-	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
-    if (refl_face)
-	{
-		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
-		renderReflection(refl_face);
-	}
-
-	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-}
-
-// for low end hardware
-void LLDrawPoolWater::renderOpaqueLegacyWater()
-{
-	LLVOSky *voskyp = gSky.mVOSkyp;
-
-	LLGLSLShader* shader = NULL;
-	if (LLGLSLShader::sNoFixedFunction)
-	{
-		if (LLPipeline::sUnderWaterRender)
-		{
-			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
-		}
-		else
-		{
-			shader = &gObjectSimpleNonIndexedTexGenProgram;
-		}
-
-		shader->bind();
-	}
-
-	stop_glerror();
-
-	// Depth sorting and write to depth buffer
-	// since this is opaque, we should see nothing
-	// behind the water.  No blending because
-	// of no transparency.  And no face culling so
-	// that the underside of the water is also opaque.
-	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
-	LLGLDisable no_cull(GL_CULL_FACE);
-	LLGLDisable no_blend(GL_BLEND);
-
-	gPipeline.disableLights();
-
-	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
-
-	// Activate the texture binding and bind one
-	// texture since all images will have the same texture
-	gGL.getTexUnit(0)->activate();
-	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
-
-	// Automatically generate texture coords for water texture
-	if (!shader)
-	{
-		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
-		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
-		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
-	}
-
-	// Use the fact that we know all water faces are the same size
-	// to save some computation
-
-	// Slowly move texture coordinates over time so the watter appears
-	// to be moving.
-	F32 movement_period_secs = 50.f;
-
-	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
-
-	if (movement_period_secs != 0)
-	{
-	 	offset /= movement_period_secs;
-	}
-	else
-	{
-		offset = 0;
-	}
-
-	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
-	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
-
-	if (!shader)
-	{
-		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
-		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
-	}
-	else
-	{
-		shader->uniform4fv("object_plane_s", 1, tp0);
-		shader->uniform4fv("object_plane_t", 1, tp1);
-	}
-
-	gGL.diffuseColor3f(1.f, 1.f, 1.f);
-
-	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
-		 iter != mDrawFace.end(); iter++)
-	{
-		LLFace *face = *iter;
-		if (voskyp->isReflFace(face))
-		{
-			continue;
-		}
-
-		face->renderIndexed();
-	}
-
-	stop_glerror();
-
-	if (!shader)
-	{
-		// Reset the settings back to expected values
-		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
-		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-}
-
-
-void LLDrawPoolWater::renderReflection(LLFace* face)
-{
-	LLVOSky *voskyp = gSky.mVOSkyp;
-
-	if (!voskyp)
-	{
-		return;
-	}
-
-	if (!face->getGeomCount())
-	{
-		return;
-	}
-	
-	S8 dr = voskyp->getDrawRefl();
-	if (dr < 0)
-	{
-		return;
-	}
-
-	LLGLSNoFog noFog;
-
-	gGL.getTexUnit(0)->bind(mHBTex[dr]);
-
-	LLOverrideFaceColor override(this, face->getFaceColor().mV);
-	face->renderIndexed();
-}
-
-void LLDrawPoolWater::shade()
-{
-	if (!deferred_render)
-	{
-		gGL.setColorMask(true, true);
-	}
-
-	LLVOSky *voskyp = gSky.mVOSkyp;
-
-	if(voskyp == NULL) 
-	{
-		return;
-	}
-
-	LLGLDisable blend(GL_BLEND);
-
-	LLColor3 light_diffuse(0,0,0);
-	F32 light_exp = 0.0f;
-	LLVector3 light_dir;
-	LLColor3 light_color;
-
-	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
-    { 	 
-        light_dir  = gSky.getSunDirection(); 	 
-        light_dir.normVec(); 	
-		light_color = gSky.getSunDiffuseColor();
-		if(gSky.mVOSkyp) {
-	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	 
-			light_diffuse.normVec(); 	 
-		}
-        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
-        light_diffuse *= light_exp + 0.25f; 	 
-    } 	 
-    else  	 
-    { 	 
-        light_dir       = gSky.getMoonDirection(); 	 
-        light_dir.normVec(); 	 
-		light_color = gSky.getMoonDiffuseColor();
-        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	 
-        light_diffuse.normVec(); 	 
-        light_diffuse *= 0.5f; 	 
-        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
-    }
-
-	light_exp *= light_exp;
-	light_exp *= light_exp;
-	light_exp *= light_exp;
-	light_exp *= light_exp;
-	light_exp *= 256.f;
-	light_exp = light_exp > 32.f ? light_exp : 32.f;
-
-	LLGLSLShader* shader;
-
-	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
-	
-	if (deferred_render)
-	{
-		shader = &gDeferredWaterProgram;
-	}
-	else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
-	{
-		shader = &gUnderWaterProgram;
-	}
-	else
-	{
-		shader = &gWaterProgram;
-	}
-
-	if (deferred_render)
-	{
-		gPipeline.bindDeferredShader(*shader);
-	}
-	else
-	{
-		shader->bind();
-	}
-
-	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
-	
-	S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
-		
-	if (reftex > -1)
-	{
-		gGL.getTexUnit(reftex)->activate();
-		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
-		gGL.getTexUnit(0)->activate();
-	}	
-
-	//bind normal map
-	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
-
-	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
-
-	// change mWaterNormp if needed
-	if (mWaterNormp->getID() != param_mgr->getNormalMapID())
-	{
-		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
-	}
-
-	mWaterNormp->addTextureStats(1024.f*1024.f);
-	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
-	if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
-	{
-		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-	}
-	else 
-	{
-		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
-	}
-	
-	S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
-		
-	if (screentex > -1)
-	{
-		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
-		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
-			param_mgr->getFogDensity());
-		gPipeline.mWaterDis.bindTexture(0, screentex);
-	}
-	
-	stop_glerror();
-	
-	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
-
-	if (mVertexShaderLevel == 1)
-	{
-		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
-		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
-	}
-
-	F32 screenRes[] = 
-	{
-		1.f/gGLViewport[2],
-		1.f/gGLViewport[3]
-	};
-	shader->uniform2fv("screenRes", 1, screenRes);
-	stop_glerror();
-	
-	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	stop_glerror();
-	
-	light_dir.normVec();
-	sLightDir = light_dir;
-	
-	light_diffuse *= 6.f;
-
-	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
-	shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
-	shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
-	shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
-	shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
-	shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
-	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
-	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
-	shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
-
-	shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV);
-	shader->uniform1f("fresnelScale", param_mgr->getFresnelScale());
-	shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset());
-	shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier());
-
-	F32 sunAngle = llmax(0.f, light_dir.mV[2]);
-	F32 scaledAngle = 1.f - sunAngle;
-
-	shader->uniform1f("sunAngle", sunAngle);
-	shader->uniform1f("scaledAngle", scaledAngle);
-	shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle);
-
-	LLColor4 water_color;
-	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
-	F32 up_dot = camera_up * LLVector3::z_axis;
-	if (LLViewerCamera::getInstance()->cameraUnderWater())
-	{
-		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
-		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
-	}
-	else
-	{
-		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
-		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
-	}
-
-	if (water_color.mV[3] > 0.9f)
-	{
-		water_color.mV[3] = 0.9f;
-	}
-
-	{
-		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
-		LLGLDisable cullface(GL_CULL_FACE);
-		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
-			iter != mDrawFace.end(); iter++)
-		{
-			LLFace *face = *iter;
-
-			if (voskyp->isReflFace(face))
-			{
-				continue;
-			}
-
-			LLVOWater* water = (LLVOWater*) face->getViewerObject();
-			gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
-			sNeedsReflectionUpdate = TRUE;
-			
-			if (water->getUseTexture() || !water->getIsEdgePatch())
-			{
-				sNeedsDistortionUpdate = TRUE;
-				face->renderIndexed();
-			}
-			else if (gGLManager.mHasDepthClamp || deferred_render)
-			{
-				face->renderIndexed();
-			}
-			else
-			{
-				LLGLSquashToFarClip far_clip(glh_get_current_projection());
-				face->renderIndexed();
-			}
-		}
-	}
-	
-	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
-	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
-	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
-	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-	shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
-	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
-
-	if (deferred_render)
-	{
-		gPipeline.unbindDeferredShader(*shader);
-	}
-	else
-	{
-		shader->unbind();
-	}
-
-	gGL.getTexUnit(0)->activate();
-	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-	if (!deferred_render)
-	{
-		gGL.setColorMask(true, false);
-	}
-
-}
-
-LLViewerTexture *LLDrawPoolWater::getDebugTexture()
-{
-	return LLViewerFetchedTexture::sSmokeImagep;
-}
-
-LLColor3 LLDrawPoolWater::getDebugColor() const
-{
-	return LLColor3(0.f, 1.f, 1.f);
-}
+/** 
+ * @file lldrawpoolwater.cpp
+ * @brief LLDrawPoolWater class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfeaturemanager.h"
+#include "lldrawpoolwater.h"
+
+#include "llviewercontrol.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "m3math.h"
+#include "llrender.h"
+
+#include "llagent.h"		// for gAgent for getRegion for getWaterHeight
+#include "llcubemap.h"
+#include "lldrawable.h"
+#include "llface.h"
+#include "llsky.h"
+#include "llviewertexturelist.h"
+#include "llviewerregion.h"
+#include "llvosky.h"
+#include "llvowater.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llwaterparammanager.h"
+
+const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
+const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
+
+static LLStaticHashedString sObjectPlaneS("object_plane_s");
+static LLStaticHashedString sObjectPlaneT("object_plane_t");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sNormScale("normScale");
+static LLStaticHashedString sFresnelScale("fresnelScale");
+static LLStaticHashedString sFresnelOffset("fresnelOffset");
+static LLStaticHashedString sBlurMultiplier("blurMultiplier");
+static LLStaticHashedString sSunAngle("sunAngle");
+static LLStaticHashedString sScaledAngle("scaledAngle");
+static LLStaticHashedString sSunAngle2("sunAngle2");
+
+static float sTime;
+
+BOOL deferred_render = FALSE;
+
+BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
+BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
+BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
+LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
+F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
+
+LLVector3 LLDrawPoolWater::sLightDir;
+
+LLDrawPoolWater::LLDrawPoolWater() :
+	LLFacePool(POOL_WATER)
+{
+	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
+	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	gGL.getTexUnit(0)->bind(mHBTex[1]);
+	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
+
+
+	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
+	llassert(mWaterImagep);
+	mWaterImagep->setNoDelete();
+	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
+	llassert(mOpaqueWaterImagep);
+	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
+	mWaterNormp->setNoDelete();
+
+	restoreGL();
+}
+
+LLDrawPoolWater::~LLDrawPoolWater()
+{
+}
+
+//static
+void LLDrawPoolWater::restoreGL()
+{
+	
+}
+
+LLDrawPool *LLDrawPoolWater::instancePool()
+{
+	llerrs << "Should never be calling instancePool on a water pool!" << llendl;
+	return NULL;
+}
+
+
+void LLDrawPoolWater::prerender()
+{
+	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
+		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
+
+	// got rid of modulation by light color since it got a little too
+	// green at sunset and sl-57047 (underwater turns black at 8:00)
+	sWaterFogColor = LLWaterParamManager::instance().getFogColor();
+	sWaterFogColor.mV[3] = 0;
+
+}
+
+S32 LLDrawPoolWater::getNumPasses()
+{
+	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
+	{
+		return 1;
+	}
+
+	return 0;
+}
+
+void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
+{
+	beginRenderPass(pass);
+	deferred_render = TRUE;
+}
+
+void LLDrawPoolWater::endPostDeferredPass(S32 pass)
+{
+	endRenderPass(pass);
+	deferred_render = FALSE;
+}
+
+//===============================
+//DEFERRED IMPLEMENTATION
+//===============================
+void LLDrawPoolWater::renderDeferred(S32 pass)
+{
+	LLFastTimer t(FTM_RENDER_WATER);
+	deferred_render = TRUE;
+	shade();
+	deferred_render = FALSE;
+}
+
+//=========================================
+
+void LLDrawPoolWater::render(S32 pass)
+{
+	LLFastTimer ftm(FTM_RENDER_WATER);
+	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
+	{
+		return;
+	}
+
+	//do a quick 'n dirty depth sort
+	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+			 iter != mDrawFace.end(); iter++)
+	{
+		LLFace* facep = *iter;
+		facep->mDistance = -facep->mCenterLocal.mV[2];
+	}
+
+	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
+
+	// See if we are rendering water as opaque or not
+	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
+	{
+		// render water for low end hardware
+		renderOpaqueLegacyWater();
+		return;
+	}
+
+	LLGLEnable blend(GL_BLEND);
+
+	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
+	{
+		shade();
+		return;
+	}
+
+	LLVOSky *voskyp = gSky.mVOSkyp;
+
+	stop_glerror();
+
+	if (!gGLManager.mHasMultitexture)
+	{
+		// Ack!  No multitexture!  Bail!
+		return;
+	}
+
+	LLFace* refl_face = voskyp->getReflFace();
+
+	gPipeline.disableLights();
+	
+	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+
+	LLGLDisable cullFace(GL_CULL_FACE);
+	
+	// Set up second pass first
+	mWaterImagep->addTextureStats(1024.f*1024.f);
+	gGL.getTexUnit(1)->activate();
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->bind(mWaterImagep) ;
+
+	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
+	F32 up_dot = camera_up * LLVector3::z_axis;
+
+	LLColor4 water_color;
+	if (LLViewerCamera::getInstance()->cameraUnderWater())
+	{
+		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
+	}
+	else
+	{
+		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
+	}
+
+	gGL.diffuseColor4fv(water_color.mV);
+
+	// Automatically generate texture coords for detail map
+	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
+	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
+	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+
+	// Slowly move over time.
+	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
+	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
+	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
+	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
+	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
+
+	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
+	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
+
+	gGL.getTexUnit(0)->activate();
+	
+	glClearStencil(1);
+	glClear(GL_STENCIL_BUFFER_BIT);
+	LLGLEnable gls_stencil(GL_STENCIL_TEST);
+	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
+	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
+
+	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+		 iter != mDrawFace.end(); iter++)
+	{
+		LLFace *face = *iter;
+		if (voskyp->isReflFace(face))
+		{
+			continue;
+		}
+		gGL.getTexUnit(0)->bind(face->getTexture());
+		face->renderIndexed();
+	}
+
+	// Now, disable texture coord generation on texture state 1
+	gGL.getTexUnit(1)->activate();
+	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->disable();
+	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
+	glDisable(GL_TEXTURE_GEN_T); //texture unit 1
+
+	// Disable texture coordinate and color arrays
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	stop_glerror();
+	
+	if (gSky.mVOSkyp->getCubeMap())
+	{
+		gSky.mVOSkyp->getCubeMap()->enable(0);
+		gSky.mVOSkyp->getCubeMap()->bind();
+
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.loadIdentity();
+		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
+		LLMatrix4 camera_rot(camera_mat.getMat3());
+		camera_rot.invert();
+
+		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
+
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
+
+		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+			 iter != mDrawFace.end(); iter++)
+		{
+			LLFace *face = *iter;
+			if (voskyp->isReflFace(face))
+			{
+				//refl_face = face;
+				continue;
+			}
+
+			if (face->getGeomCount() > 0)
+			{					
+				face->renderIndexed();
+			}
+		}
+
+		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+		gSky.mVOSkyp->getCubeMap()->disable();
+		
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+		gGL.matrixMode(LLRender::MM_TEXTURE);
+		gGL.loadIdentity();
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		
+	}
+
+	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+    if (refl_face)
+	{
+		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
+		renderReflection(refl_face);
+	}
+
+	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+}
+
+// for low end hardware
+void LLDrawPoolWater::renderOpaqueLegacyWater()
+{
+	LLVOSky *voskyp = gSky.mVOSkyp;
+
+	LLGLSLShader* shader = NULL;
+	if (LLGLSLShader::sNoFixedFunction)
+	{
+		if (LLPipeline::sUnderWaterRender)
+		{
+			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
+		}
+		else
+		{
+			shader = &gObjectSimpleNonIndexedTexGenProgram;
+		}
+
+		shader->bind();
+	}
+
+	stop_glerror();
+
+	// Depth sorting and write to depth buffer
+	// since this is opaque, we should see nothing
+	// behind the water.  No blending because
+	// of no transparency.  And no face culling so
+	// that the underside of the water is also opaque.
+	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
+	LLGLDisable no_cull(GL_CULL_FACE);
+	LLGLDisable no_blend(GL_BLEND);
+
+	gPipeline.disableLights();
+
+	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
+
+	// Activate the texture binding and bind one
+	// texture since all images will have the same texture
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
+
+	// Automatically generate texture coords for water texture
+	if (!shader)
+	{
+		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
+		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
+		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	}
+
+	// Use the fact that we know all water faces are the same size
+	// to save some computation
+
+	// Slowly move texture coordinates over time so the watter appears
+	// to be moving.
+	F32 movement_period_secs = 50.f;
+
+	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
+
+	if (movement_period_secs != 0)
+	{
+	 	offset /= movement_period_secs;
+	}
+	else
+	{
+		offset = 0;
+	}
+
+	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
+	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
+
+	if (!shader)
+	{
+		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
+		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
+	}
+	else
+	{
+		shader->uniform4fv(sObjectPlaneS, 1, tp0);
+		shader->uniform4fv(sObjectPlaneT, 1, tp1);
+	}
+
+	gGL.diffuseColor3f(1.f, 1.f, 1.f);
+
+	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+		 iter != mDrawFace.end(); iter++)
+	{
+		LLFace *face = *iter;
+		if (voskyp->isReflFace(face))
+		{
+			continue;
+		}
+
+		face->renderIndexed();
+	}
+
+	stop_glerror();
+
+	if (!shader)
+	{
+		// Reset the settings back to expected values
+		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
+		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+}
+
+
+void LLDrawPoolWater::renderReflection(LLFace* face)
+{
+	LLVOSky *voskyp = gSky.mVOSkyp;
+
+	if (!voskyp)
+	{
+		return;
+	}
+
+	if (!face->getGeomCount())
+	{
+		return;
+	}
+	
+	S8 dr = voskyp->getDrawRefl();
+	if (dr < 0)
+	{
+		return;
+	}
+
+	LLGLSNoFog noFog;
+
+	gGL.getTexUnit(0)->bind(mHBTex[dr]);
+
+	LLOverrideFaceColor override(this, face->getFaceColor().mV);
+	face->renderIndexed();
+}
+
+void LLDrawPoolWater::shade()
+{
+	if (!deferred_render)
+	{
+		gGL.setColorMask(true, true);
+	}
+
+	LLVOSky *voskyp = gSky.mVOSkyp;
+
+	if(voskyp == NULL) 
+	{
+		return;
+	}
+
+	LLGLDisable blend(GL_BLEND);
+
+	LLColor3 light_diffuse(0,0,0);
+	F32 light_exp = 0.0f;
+	LLVector3 light_dir;
+	LLColor3 light_color;
+
+	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
+    { 	 
+        light_dir  = gSky.getSunDirection(); 	 
+        light_dir.normVec(); 	
+		light_color = gSky.getSunDiffuseColor();
+		if(gSky.mVOSkyp) {
+	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	 
+			light_diffuse.normVec(); 	 
+		}
+        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
+        light_diffuse *= light_exp + 0.25f; 	 
+    } 	 
+    else  	 
+    { 	 
+        light_dir       = gSky.getMoonDirection(); 	 
+        light_dir.normVec(); 	 
+		light_color = gSky.getMoonDiffuseColor();
+        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	 
+        light_diffuse.normVec(); 	 
+        light_diffuse *= 0.5f; 	 
+        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
+    }
+
+	light_exp *= light_exp;
+	light_exp *= light_exp;
+	light_exp *= light_exp;
+	light_exp *= light_exp;
+	light_exp *= 256.f;
+	light_exp = light_exp > 32.f ? light_exp : 32.f;
+
+	LLGLSLShader* shader;
+
+	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
+	
+	if (deferred_render)
+	{
+		shader = &gDeferredWaterProgram;
+	}
+	else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
+	{
+		shader = &gUnderWaterProgram;
+	}
+	else
+	{
+		shader = &gWaterProgram;
+	}
+
+	if (deferred_render)
+	{
+		gPipeline.bindDeferredShader(*shader);
+	}
+	else
+	{
+		shader->bind();
+	}
+
+	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
+	
+	S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
+		
+	if (reftex > -1)
+	{
+		gGL.getTexUnit(reftex)->activate();
+		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
+		gGL.getTexUnit(0)->activate();
+	}	
+
+	//bind normal map
+	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+
+	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
+
+	// change mWaterNormp if needed
+	if (mWaterNormp->getID() != param_mgr->getNormalMapID())
+	{
+		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
+	}
+
+	mWaterNormp->addTextureStats(1024.f*1024.f);
+	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
+	if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
+	{
+		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+	}
+	else 
+	{
+		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
+	}
+	
+	S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
+		
+	if (screentex > -1)
+	{
+		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
+		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
+			param_mgr->getFogDensity());
+		gPipeline.mWaterDis.bindTexture(0, screentex);
+	}
+	
+	stop_glerror();
+	
+	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
+
+	if (mVertexShaderLevel == 1)
+	{
+		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
+		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
+	}
+
+	F32 screenRes[] = 
+	{
+		1.f/gGLViewport[2],
+		1.f/gGLViewport[3]
+	};
+	shader->uniform2fv(sScreenRes, 1, screenRes);
+	stop_glerror();
+	
+	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+	stop_glerror();
+	
+	light_dir.normVec();
+	sLightDir = light_dir;
+	
+	light_diffuse *= 6.f;
+
+	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
+	shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
+	shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
+	shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+	shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+	shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
+	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
+	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
+	shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+
+	shader->uniform3fv(sNormScale, 1, param_mgr->getNormalScale().mV);
+	shader->uniform1f(sFresnelScale, param_mgr->getFresnelScale());
+	shader->uniform1f(sFresnelOffset, param_mgr->getFresnelOffset());
+	shader->uniform1f(sBlurMultiplier, param_mgr->getBlurMultiplier());
+
+	F32 sunAngle = llmax(0.f, light_dir.mV[2]);
+	F32 scaledAngle = 1.f - sunAngle;
+
+	shader->uniform1f(sSunAngle, sunAngle);
+	shader->uniform1f(sScaledAngle, scaledAngle);
+	shader->uniform1f(sSunAngle2, 0.1f + 0.2f*sunAngle);
+
+	LLColor4 water_color;
+	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
+	F32 up_dot = camera_up * LLVector3::z_axis;
+	if (LLViewerCamera::getInstance()->cameraUnderWater())
+	{
+		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
+		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
+	}
+	else
+	{
+		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
+		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
+	}
+
+	if (water_color.mV[3] > 0.9f)
+	{
+		water_color.mV[3] = 0.9f;
+	}
+
+	{
+		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+		LLGLDisable cullface(GL_CULL_FACE);
+		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+			iter != mDrawFace.end(); iter++)
+		{
+			LLFace *face = *iter;
+
+			if (voskyp->isReflFace(face))
+			{
+				continue;
+			}
+
+			LLVOWater* water = (LLVOWater*) face->getViewerObject();
+			gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+			sNeedsReflectionUpdate = TRUE;
+			
+			if (water->getUseTexture() || !water->getIsEdgePatch())
+			{
+				sNeedsDistortionUpdate = TRUE;
+				face->renderIndexed();
+			}
+			else if (gGLManager.mHasDepthClamp || deferred_render)
+			{
+				face->renderIndexed();
+			}
+			else
+			{
+				LLGLSquashToFarClip far_clip(glh_get_current_projection());
+				face->renderIndexed();
+			}
+		}
+	}
+	
+	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
+	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
+	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+	shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
+	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
+
+	if (deferred_render)
+	{
+		gPipeline.unbindDeferredShader(*shader);
+	}
+	else
+	{
+		shader->unbind();
+	}
+
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	if (!deferred_render)
+	{
+		gGL.setColorMask(true, false);
+	}
+
+}
+
+LLViewerTexture *LLDrawPoolWater::getDebugTexture()
+{
+	return LLViewerFetchedTexture::sSmokeImagep;
+}
+
+LLColor3 LLDrawPoolWater::getDebugColor() const
+{
+	return LLColor3(0.f, 1.f, 1.f);
+}
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index b5faff79682..b0e69aa9b54 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -152,7 +152,8 @@ void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) cons
 	gGL.translatef(0.f,-camHeightLocal, 0.f);
 	
 	// Draw WL Sky	
-	shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f);
+	static LLStaticHashedString sCamPosLocal("camPosLocal");
+	shader->uniform3f(sCamPosLocal, 0.f, camHeightLocal, 0.f);
 
 	gSky.mVOWLSkyp->drawDome();
 
@@ -207,7 +208,8 @@ void LLDrawPoolWLSky::renderStars(void) const
 	if (LLGLSLShader::sNoFixedFunction)
 	{
 		gCustomAlphaProgram.bind();
-		gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]);
+		static LLStaticHashedString sCustomAlpha("custom_alpha");
+		gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
 	}
 	else
 	{
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 28e4b327930..3c7a49d5cef 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -55,6 +55,9 @@
 
 #define LL_MAX_INDICES_COUNT 1000000
 
+static LLStaticHashedString sTextureIndexIn("texture_index_in");
+static LLStaticHashedString sColorIn("color_in");
+
 BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
 
 #define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
@@ -1417,8 +1420,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 			vp[1] = 0;
 			vp[2] = 0;
 			vp[3] = 0;
-			
-			gTransformPositionProgram.uniform1i("texture_index_in", val);
+						
+			gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
 			glBeginTransformFeedback(GL_POINTS);
 			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
@@ -1436,7 +1439,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 
 			S32 val = *((S32*) color.mV);
 
-			gTransformColorProgram.uniform1i("color_in", val);
+			gTransformColorProgram.uniform1i(sColorIn, val);
 			glBeginTransformFeedback(GL_POINTS);
 			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
 			push_for_transform(buff, vf.mNumVertices, mGeomCount);
@@ -1457,7 +1460,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 						 (glow << 16) |
 						 (glow << 24);
 
-			gTransformColorProgram.uniform1i("color_in", glow32);
+			gTransformColorProgram.uniform1i(sColorIn, glow32);
 			glBeginTransformFeedback(GL_POINTS);
 			buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
 			push_for_transform(buff, vf.mNumVertices, mGeomCount);
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 362308c1765..0228807dc88 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1698,7 +1698,8 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 
 		gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
 
-		gClipProgram.uniform4fv("clip_plane", 1, plane.v);
+		static LLStaticHashedString sClipPlane("clip_plane");
+		gClipProgram.uniform4fv(sClipPlane, 1, plane.v);
 		
 		BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
 		BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ba9818946cb..fc7e51d06c2 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -52,6 +52,13 @@
 #define UNIFORM_ERRS LL_ERRS("Shader")
 #endif
 
+static LLStaticHashedString sTexture0("texture0");
+static LLStaticHashedString sTexture1("texture1");
+static LLStaticHashedString sTex0("tex0");
+static LLStaticHashedString sTex1("tex1");
+static LLStaticHashedString sGlowMap("glowMap");
+static LLStaticHashedString sScreenMap("screenMap");
+
 // Lots of STL stuff in here, using namespace std to keep things more readable
 using std::vector;
 using std::pair;
@@ -305,46 +312,46 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
 	{
 		LLShaderMgr::initAttribsAndUniforms();
 
-		mAvatarUniforms.push_back("matrixPalette");
-		mAvatarUniforms.push_back("gWindDir");
-		mAvatarUniforms.push_back("gSinWaveParams");
-		mAvatarUniforms.push_back("gGravity");
+		mAvatarUniforms.push_back(LLStaticHashedString("matrixPalette"));
+		mAvatarUniforms.push_back(LLStaticHashedString("gWindDir"));
+		mAvatarUniforms.push_back(LLStaticHashedString("gSinWaveParams"));
+		mAvatarUniforms.push_back(LLStaticHashedString("gGravity"));
 
-		mWLUniforms.push_back("camPosLocal");
+		mWLUniforms.push_back(LLStaticHashedString("camPosLocal"));
 
 		mTerrainUniforms.reserve(5);
-		mTerrainUniforms.push_back("detail_0");
-		mTerrainUniforms.push_back("detail_1");
-		mTerrainUniforms.push_back("detail_2");
-		mTerrainUniforms.push_back("detail_3");
-		mTerrainUniforms.push_back("alpha_ramp");
+		mTerrainUniforms.push_back(LLStaticHashedString("detail_0"));
+		mTerrainUniforms.push_back(LLStaticHashedString("detail_1"));
+		mTerrainUniforms.push_back(LLStaticHashedString("detail_2"));
+		mTerrainUniforms.push_back(LLStaticHashedString("detail_3"));
+		mTerrainUniforms.push_back(LLStaticHashedString("alpha_ramp"));
 
-		mGlowUniforms.push_back("glowDelta");
-		mGlowUniforms.push_back("glowStrength");
+		mGlowUniforms.push_back(LLStaticHashedString("glowDelta"));
+		mGlowUniforms.push_back(LLStaticHashedString("glowStrength"));
 
-		mGlowExtractUniforms.push_back("minLuminance");
-		mGlowExtractUniforms.push_back("maxExtractAlpha");
-		mGlowExtractUniforms.push_back("lumWeights");
-		mGlowExtractUniforms.push_back("warmthWeights");
-		mGlowExtractUniforms.push_back("warmthAmount");
+		mGlowExtractUniforms.push_back(LLStaticHashedString("minLuminance"));
+		mGlowExtractUniforms.push_back(LLStaticHashedString("maxExtractAlpha"));
+		mGlowExtractUniforms.push_back(LLStaticHashedString("lumWeights"));
+		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthWeights"));
+		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthAmount"));
 
-		mShinyUniforms.push_back("origin");
+		mShinyUniforms.push_back(LLStaticHashedString("origin"));
 
 		mWaterUniforms.reserve(12);
-		mWaterUniforms.push_back("screenTex");
-		mWaterUniforms.push_back("screenDepth");
-		mWaterUniforms.push_back("refTex");
-		mWaterUniforms.push_back("eyeVec");
-		mWaterUniforms.push_back("time");
-		mWaterUniforms.push_back("d1");
-		mWaterUniforms.push_back("d2");
-		mWaterUniforms.push_back("lightDir");
-		mWaterUniforms.push_back("specular");
-		mWaterUniforms.push_back("lightExp");
-		mWaterUniforms.push_back("fogCol");
-		mWaterUniforms.push_back("kd");
-		mWaterUniforms.push_back("refScale");
-		mWaterUniforms.push_back("waterHeight");
+		mWaterUniforms.push_back(LLStaticHashedString("screenTex"));
+		mWaterUniforms.push_back(LLStaticHashedString("screenDepth"));
+		mWaterUniforms.push_back(LLStaticHashedString("refTex"));
+		mWaterUniforms.push_back(LLStaticHashedString("eyeVec"));
+		mWaterUniforms.push_back(LLStaticHashedString("time"));
+		mWaterUniforms.push_back(LLStaticHashedString("d1"));
+		mWaterUniforms.push_back(LLStaticHashedString("d2"));
+		mWaterUniforms.push_back(LLStaticHashedString("lightDir"));
+		mWaterUniforms.push_back(LLStaticHashedString("specular"));
+		mWaterUniforms.push_back(LLStaticHashedString("lightExp"));
+		mWaterUniforms.push_back(LLStaticHashedString("fogCol"));
+		mWaterUniforms.push_back(LLStaticHashedString("kd"));
+		mWaterUniforms.push_back(LLStaticHashedString("refScale"));
+		mWaterUniforms.push_back(LLStaticHashedString("waterHeight"));
 	}	
 }
 	
@@ -2091,8 +2098,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
 		if (success)
 		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
 			gObjectBumpProgram.bind();
-			gObjectBumpProgram.uniform1i("texture0", 0);
-			gObjectBumpProgram.uniform1i("texture1", 1);
+			gObjectBumpProgram.uniform1i(sTexture0, 0);
+			gObjectBumpProgram.uniform1i(sTexture1, 1);
 			gObjectBumpProgram.unbind();
 		}
 	}
@@ -2651,7 +2658,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gSplatTextureRectProgram.bind();
-			gSplatTextureRectProgram.uniform1i("screenMap", 0);
+			gSplatTextureRectProgram.uniform1i(sScreenMap, 0);
 			gSplatTextureRectProgram.unbind();
 		}
 	}
@@ -2667,8 +2674,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gGlowCombineProgram.bind();
-			gGlowCombineProgram.uniform1i("glowMap", 0);
-			gGlowCombineProgram.uniform1i("screenMap", 1);
+			gGlowCombineProgram.uniform1i(sGlowMap, 0);
+			gGlowCombineProgram.uniform1i(sScreenMap, 1);
 			gGlowCombineProgram.unbind();
 		}
 	}
@@ -2684,8 +2691,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gGlowCombineFXAAProgram.bind();
-			gGlowCombineFXAAProgram.uniform1i("glowMap", 0);
-			gGlowCombineFXAAProgram.uniform1i("screenMap", 1);
+			gGlowCombineFXAAProgram.uniform1i(sGlowMap, 0);
+			gGlowCombineFXAAProgram.uniform1i(sScreenMap, 1);
 			gGlowCombineFXAAProgram.unbind();
 		}
 	}
@@ -2702,8 +2709,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gTwoTextureAddProgram.bind();
-			gTwoTextureAddProgram.uniform1i("tex0", 0);
-			gTwoTextureAddProgram.uniform1i("tex1", 1);
+			gTwoTextureAddProgram.uniform1i(sTex0, 0);
+			gTwoTextureAddProgram.uniform1i(sTex1, 1);
 		}
 	}
 
@@ -2718,7 +2725,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gOneTextureNoColorProgram.bind();
-			gOneTextureNoColorProgram.uniform1i("tex0", 0);
+			gOneTextureNoColorProgram.uniform1i(sTex0, 0);
 		}
 	}
 
@@ -2733,7 +2740,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
 		if (success)
 		{
 			gSolidColorProgram.bind();
-			gSolidColorProgram.uniform1i("tex0", 0);
+			gSolidColorProgram.uniform1i(sTex0, 0);
 			gSolidColorProgram.unbind();
 		}
 	}
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d6dd645e8cc..999baa0ad09 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -177,22 +177,24 @@ class LLViewerShaderMgr: public LLShaderMgr
 
 private:
 	
-	std::vector<std::string> mShinyUniforms;
+	typedef std::vector< LLStaticHashedString > UniformVec;
+
+	UniformVec mShinyUniforms;
 
 	//water parameters
-	std::vector<std::string> mWaterUniforms;
+	UniformVec mWaterUniforms;
 
-	std::vector<std::string> mWLUniforms;
+	UniformVec mWLUniforms;
 
 	//terrain parameters
-	std::vector<std::string> mTerrainUniforms;
+	UniformVec mTerrainUniforms;
 
 	//glow parameters
-	std::vector<std::string> mGlowUniforms;
+	UniformVec mGlowUniforms;
 
-	std::vector<std::string> mGlowExtractUniforms;
+	UniformVec mGlowExtractUniforms;
 
-	std::vector<std::string> mAvatarUniforms;
+	UniformVec mAvatarUniforms;
 
 	// the list of shaders we need to propagate parameters to.
 	std::vector<LLGLSLShader *> mShaderList;
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 4f52ff97782..376715a2d62 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -57,6 +57,14 @@
 
 #include "curl/curl.h"
 
+static LLStaticHashedString sCamPosLocal("camPosLocal");
+static LLStaticHashedString sWaterFogColor("waterFogColor");
+static LLStaticHashedString sWaterFogEnd("waterFogEnd");
+static LLStaticHashedString sWaterPlane("waterPlane");
+static LLStaticHashedString sWaterFogDensity("waterFogDensity");
+static LLStaticHashedString sWaterFogKS("waterFogKS");
+static LLStaticHashedString sDistanceMultiplier("distance_multiplier");
+
 LLWaterParamManager::LLWaterParamManager() :
 	mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"),
 	mFogDensity(4, "waterFogDensity", 2),
@@ -188,13 +196,13 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
 	if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
 	{
 		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV);
-		shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
-		shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV);
-		shader->uniform1f("waterFogEnd", LLDrawPoolWater::sWaterFogEnd);
-		shader->uniform4fv("waterPlane", 1, mWaterPlane.mV);
-		shader->uniform1f("waterFogDensity", getFogDensity());
-		shader->uniform1f("waterFogKS", mWaterFogKS);
-		shader->uniform1f("distance_multiplier", 0);
+		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+		shader->uniform4fv(sWaterFogColor, 1, LLDrawPoolWater::sWaterFogColor.mV);
+		shader->uniform1f(sWaterFogEnd, LLDrawPoolWater::sWaterFogEnd);
+		shader->uniform4fv(sWaterPlane, 1, mWaterPlane.mV);
+		shader->uniform1f(sWaterFogDensity, getFogDensity());
+		shader->uniform1f(sWaterFogKS, mWaterFogKS);
+		shader->uniform1f(sDistanceMultiplier, 0);
 	}
 }
 
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 6077208799a..65cb80c3e7d 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -61,6 +61,9 @@
 #include "curl/curl.h"
 #include "llstreamtools.h"
 
+static LLStaticHashedString sCamPosLocal("camPosLocal");
+static LLStaticHashedString sSceneLightStrength("scene_light_strength");
+
 LLWLParamManager::LLWLParamManager() :
 
 	//set the defaults for the controls
@@ -352,7 +355,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
 	if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
 	{
 		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
-		shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
+		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 	} 
 
 	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
@@ -360,7 +363,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
 		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
 	}
 
-	shader->uniform1f("scene_light_strength", mSceneLightStrength);
+	shader->uniform1f(sSceneLightStrength, mSceneLightStrength);
 	
 }
 
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 4306b3da12f..92c5ac8583e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -253,6 +253,17 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
 static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
 static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
 
+static LLStaticHashedString sTint("tint");
+static LLStaticHashedString sAmbiance("ambiance");
+static LLStaticHashedString sAlphaScale("alpha_scale");
+static LLStaticHashedString sNormMat("norm_mat");
+static LLStaticHashedString sOffset("offset");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sDelta("delta");
+static LLStaticHashedString sDistFactor("dist_factor");
+static LLStaticHashedString sKern("kern");
+static LLStaticHashedString sKernScale("kern_scale");
+
 //----------------------------------------
 std::string gPoolNames[] = 
 {
@@ -4621,9 +4632,9 @@ void LLPipeline::renderDebug()
 					if (LLGLSLShader::sNoFixedFunction)
 					{					
 						gPathfindingProgram.bind();			
-						gPathfindingProgram.uniform1f("tint", 1.f);
-						gPathfindingProgram.uniform1f("ambiance", 1.f);
-						gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+						gPathfindingProgram.uniform1f(sTint, 1.f);
+						gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+						gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
 					}
 
 					//Requried character physics capsule render parameters
@@ -4640,7 +4651,7 @@ void LLPipeline::renderDebug()
 							llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );				
 							gGL.setColorMask(true, false);
 							LLGLEnable blend(GL_BLEND);
-							gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+							gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
 							llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
 							gPathfindingProgram.bind();
 						}
@@ -4667,9 +4678,9 @@ void LLPipeline::renderDebug()
 					{					
 						gPathfindingProgram.bind();
 			
-						gPathfindingProgram.uniform1f("tint", 1.f);
-						gPathfindingProgram.uniform1f("ambiance", ambiance);
-						gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+						gPathfindingProgram.uniform1f(sTint, 1.f);
+						gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+						gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
 					}
 
 					if ( !pathfindingConsole->isRenderWorld() )
@@ -4693,7 +4704,7 @@ void LLPipeline::renderDebug()
 						if ( pathfindingConsole->isRenderWorld() )
 						{					
 							LLGLEnable blend(GL_BLEND);
-							gPathfindingProgram.uniform1f("alpha_scale", 0.66f);
+							gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
 							llPathingLibInstance->renderNavMesh();
 						}
 						else
@@ -4705,8 +4716,8 @@ void LLPipeline::renderDebug()
 						if (LLGLSLShader::sNoFixedFunction)
 						{
 							gPathfindingNoNormalsProgram.bind();
-							gPathfindingNoNormalsProgram.uniform1f("tint", 1.f);
-							gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 1.f);
+							gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+							gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
 							llPathingLibInstance->renderNavMeshEdges();
 							gPathfindingProgram.bind();
 						}
@@ -4746,7 +4757,7 @@ void LLPipeline::renderDebug()
 							gGL.setColorMask(true, false);
 							//render the bookends
 							LLGLEnable blend(GL_BLEND);
-							gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+							gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
 							llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
 							llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
 							gPathfindingProgram.bind();
@@ -4764,7 +4775,7 @@ void LLPipeline::renderDebug()
 						if (LLGLSLShader::sNoFixedFunction)
 						{
 							LLGLEnable blend(GL_BLEND);
-							gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+							gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
 							llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
 						}
 						else
@@ -4812,7 +4823,7 @@ void LLPipeline::renderDebug()
 							LLGLEnable blend(GL_BLEND);
 				
 							{
-								gPathfindingProgram.uniform1f("ambiance", ambiance);
+								gPathfindingProgram.uniform1f(sAmbiance, ambiance);
 
 								{ //draw solid overlay
 									LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
@@ -4827,8 +4838,8 @@ void LLPipeline::renderDebug()
 
 								if (pathfindingConsole->isRenderXRay())
 								{
-									gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
-									gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+									gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+									gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
 									LLGLEnable blend(GL_BLEND);
 									LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
 								
@@ -4836,13 +4847,13 @@ void LLPipeline::renderDebug()
 								
 									if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
 									{ //draw hidden wireframe as darker and less opaque
-										gPathfindingProgram.uniform1f("ambiance", 1.f);
+										gPathfindingProgram.uniform1f(sAmbiance, 1.f);
 										llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );				
 									}
 									else
 									{
 										glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );	
-										gPathfindingProgram.uniform1f("ambiance", ambiance);
+										gPathfindingProgram.uniform1f(sAmbiance, ambiance);
 										llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );				
 										glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 									}
@@ -4850,9 +4861,9 @@ void LLPipeline::renderDebug()
 
 								{ //draw visible wireframe as brighter, thicker and more opaque
 									glPolygonOffset(offset, offset);
-									gPathfindingProgram.uniform1f("ambiance", 1.f);
-									gPathfindingProgram.uniform1f("tint", 1.f);
-									gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+									gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+									gPathfindingProgram.uniform1f(sTint, 1.f);
+									gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
 
 									glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
 									LLGLDisable blendOut(GL_BLEND);
@@ -4884,19 +4895,19 @@ void LLPipeline::renderDebug()
 						glLineWidth(2.0f);	
 						LLGLEnable cull(GL_CULL_FACE);
 																		
-						gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
-						gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+						gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+						gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
 								
 						if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
 						{ //draw hidden wireframe as darker and less opaque
 							glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );	
-							gPathfindingProgram.uniform1f("ambiance", 1.f);
+							gPathfindingProgram.uniform1f(sAmbiance, 1.f);
 							llPathingLibInstance->renderNavMesh();
 							glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );	
 						}	
 						else
 						{
-							gPathfindingProgram.uniform1f("ambiance", ambiance);
+							gPathfindingProgram.uniform1f(sAmbiance, ambiance);
 							llPathingLibInstance->renderNavMesh();
 						}
 
@@ -4904,8 +4915,8 @@ void LLPipeline::renderDebug()
 						if (LLGLSLShader::sNoFixedFunction)
 						{
 							gPathfindingNoNormalsProgram.bind();
-							gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
-							gPathfindingNoNormalsProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+							gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+							gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
 							llPathingLibInstance->renderNavMeshEdges();
 							gPathfindingProgram.bind();
 						}
@@ -7858,11 +7869,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
 	shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
 	shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
 	
-
-	if (shader.getUniformLocation("norm_mat") >= 0)
+	static LLStaticHashedString sNormMat("norm_mat");
+	if (shader.getUniformLocation(sNormMat) >= 0)
 	{
 		glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
-		shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
+		shader.uniformMatrix4fv(sNormMat, 1, FALSE, norm_mat.m);
 	}
 }
 
@@ -7972,8 +7983,8 @@ void LLPipeline::renderDeferredLighting()
 					}
 				}
 
-				gDeferredSunProgram.uniform3fv("offset", slice, offset);
-				gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
+				gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+				gDeferredSunProgram.uniform2f(sScreenRes, mDeferredLight.getWidth(), mDeferredLight.getHeight());
 				
 				{
 					LLGLDisable blend(GL_BLEND);
@@ -8017,10 +8028,10 @@ void LLPipeline::renderDeferredLighting()
 				x += 1.f;
 			}
 
-			gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
-			gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
-			gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
-			gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+			gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+			gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+			gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+			gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f));
 		
 			{
 				LLGLDisable blend(GL_BLEND);
@@ -8037,7 +8048,7 @@ void LLPipeline::renderDeferredLighting()
 			mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
 			mDeferredLight.bindTarget();
 
-			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+			gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
 
 			{
 				LLGLDisable blend(GL_BLEND);
-- 
GitLab