diff --git a/doc/contributions.txt b/doc/contributions.txt
index a71ee8816606f106d89284fe4034749ee720375a..9a7ce924481d8caddf07f6dc7ccb3da22cb81bec 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -86,6 +86,7 @@ Aleric Inglewood
 	VWR-24320
     VWR-24321
  	VWR-24354
+	VWR-24366
 	VWR-24519
 	SNOW-84
 	SNOW-477
diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake
index ca5a8034ba442082c5881ec4c046ebe4b7a777e9..06d6d847a05b82bb96b6ef3a0bf859d9b89fa0cb 100644
--- a/indra/cmake/GoogleMock.cmake
+++ b/indra/cmake/GoogleMock.cmake
@@ -8,9 +8,10 @@ set(GOOGLEMOCK_INCLUDE_DIRS
     ${LIBS_PREBUILT_DIR}/include)
 
 if (LINUX)
+	# VWR-24366: gmock is underlinked, it needs gtest.
     set(GOOGLEMOCK_LIBRARIES 
-        gmock  
-        gtest)
+        gmock -Wl,--no-as-needed
+        gtest -Wl,--as-needed)
 elseif(WINDOWS)
     set(GOOGLEMOCK_LIBRARIES 
         gmock)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 05f0492234f059146f38ef586295707ef3456cff..cd0eada2d0dbddc0fa804cfe04731cd2bdff1b45 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -57,11 +57,6 @@ INCLUDE(GoogleMock)
     ${CMAKE_SOURCE_DIR}/test/test.h
     )
 
-  # Use the default flags
-  if (LINUX)
-    SET(CMAKE_EXE_LINKER_FLAGS "")
-  endif (LINUX)
-
   # start the source test executable definitions
   SET(${project}_TEST_OUTPUT "")
   FOREACH (source ${sources})
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py
index 37aa75e364663c675a33f2fa109102c964d7f3d2..320a9be8abb9aaeaadaaa6a4491913211aafcad5 100644
--- a/indra/cmake/run_build_test.py
+++ b/indra/cmake/run_build_test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   run_build_test.py
 @author Nat Goodspeed
diff --git a/indra/copy_win_scripts/start-client.py b/indra/copy_win_scripts/start-client.py
index 5f7ff2f293fa4618a832b498a0b6dae73c9720aa..5699f5273f4b88b337d15139262a753bd3c3a151 100644
--- a/indra/copy_win_scripts/start-client.py
+++ b/indra/copy_win_scripts/start-client.py
@@ -1,4 +1,28 @@
 #!/usr/bin/env python
+"""\
+@file   start-client.py
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, 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$
+"""
 import sys, getopt
 import os
 import llstart
diff --git a/indra/develop.py b/indra/develop.py
index 36c947327aefd933e120baa76cc843a9d403e5bd..d9a66352f339f6b03e450da20fcf1af4048c6998 100755
--- a/indra/develop.py
+++ b/indra/develop.py
@@ -1,29 +1,30 @@
 #!/usr/bin/env python
-#
-# @file develop.py
-# @authors Bryan O'Sullivan, Mark Palange, Aaron Brashears
-# @brief Fire and forget script to appropriately configure cmake for SL.
-#
-# $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$
+"""\
+@file develop.py
+@authors Bryan O'Sullivan, Mark Palange, Aaron Brashears
+@brief Fire and forget script to appropriately configure cmake for SL.
+
+$LicenseInfo:firstyear=2007&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2007-2011, 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$
+"""
 
 
 import errno
diff --git a/indra/lib/python/indra/util/llperformance.py b/indra/lib/python/indra/util/llperformance.py
index 7c52730b5e049f40596cbdc21e6a2fc5acab9158..57dd64de3fa04706eb69793361180cf52dee0fe3 100755
--- a/indra/lib/python/indra/util/llperformance.py
+++ b/indra/lib/python/indra/util/llperformance.py
@@ -1,4 +1,28 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+"""\
+@file   llperformance.py
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, 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$
+"""
 
 # ------------------------------------------------
 # Sim metrics utility functions.
diff --git a/indra/lib/python/indra/util/llversion.py b/indra/lib/python/indra/util/llversion.py
index 2718a85f414cb958db30e8035bf21742583a084b..ba6f567b607f43792231d18a19857068d587f408 100644
--- a/indra/lib/python/indra/util/llversion.py
+++ b/indra/lib/python/indra/util/llversion.py
@@ -1,7 +1,9 @@
-"""@file llversion.py
-@brief Utility for parsing llcommon/llversion${server}.h
-       for the version string and channel string
-       Utility that parses hg or svn info for branch and revision
+#!/usr/bin/env python
+"""\
+@file  llversion.py
+@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h
+       for the version string and channel string.
+       Parses hg info for branch and revision.
 
 $LicenseInfo:firstyear=2006&license=mit$
 
@@ -27,7 +29,7 @@
 $/LicenseInfo$
 """
 
-import re, sys, os, commands
+import re, sys, os, subprocess
 
 # Methods for gathering version information from
 # llversionviewer.h and llversionserver.h
@@ -73,29 +75,13 @@ def get_viewer_channel():
 def get_server_channel():
     return get_channel('server')
 
-# Methods for gathering subversion information
-def get_svn_status_matching(regular_expression):
-    # Get the subversion info from the working source tree
-    status, output = commands.getstatusoutput('svn info %s' % get_src_root())
-    m = regular_expression.search(output)
-    if not m:
-        print >> sys.stderr, "Failed to parse svn info output, result follows:"
-        print >> sys.stderr, output
-        raise Exception, "No matching svn status in "+src_root
-    return m.group(1)
-
-def get_svn_branch():
-    branch_re = re.compile('URL: (\S+)')
-    return get_svn_status_matching(branch_re)
-
-def get_svn_revision():
-    last_rev_re = re.compile('Last Changed Rev: (\d+)')
-    return get_svn_status_matching(last_rev_re)
-
+# Methods for gathering hg information
 def get_hg_repo():
-    status, output = commands.getstatusoutput('hg showconfig paths.default')
+    child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE)
+    output, error = child.communicate()
+    status = child.returncode
     if status:
-        print >> sys.stderr, output
+        print >> sys.stderr, error
         sys.exit(1)
     if not output:
         print >> sys.stderr, 'ERROR: cannot find repo we cloned from'
@@ -103,24 +89,19 @@ def get_hg_repo():
     return output
 
 def get_hg_changeset():
-    # The right thing to do:
-    # status, output = commands.getstatusoutput('hg id -i')
-    # if status:
-    #     print >> sys.stderr, output
-    #    sys.exit(1)
-
-    # The temporary hack:
-    status, output = commands.getstatusoutput('hg parents --template "{rev}"')
+    # The right thing to do would be to use the *global* revision id:
+    #     "hg id -i"
+    # For the moment though, we use the parent revision:
+    child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE)
+    output, error = child.communicate()
+    status = child.returncode
     if status:
-        print >> sys.stderr, output
+        print >> sys.stderr, error
         sys.exit(1)
     lines = output.splitlines()
     if len(lines) > 1:
         print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines)
     return lines[0]
 
-def using_svn():
-    return os.path.isdir(os.path.join(get_src_root(), '.svn'))
-
 def using_hg():
     return os.path.isdir(os.path.join(get_src_root(), '.hg'))
diff --git a/indra/lib/python/indra/util/simperf_proc_interface.py b/indra/lib/python/indra/util/simperf_proc_interface.py
index da6304a2742435dc30bb8da49452053d9f38b734..de061f68ccfda36277b0bb2f558d464c03b3bcc7 100755
--- a/indra/lib/python/indra/util/simperf_proc_interface.py
+++ b/indra/lib/python/indra/util/simperf_proc_interface.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file simperf_proc_interface.py
 @brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.
diff --git a/indra/lib/python/indra/util/test_win32_manifest.py b/indra/lib/python/indra/util/test_win32_manifest.py
index da8ee6c545741a56a43d849f0f68420b4f3d2df9..0532cb006537df4af76d63a521bcd223f8d31b2c 100644
--- a/indra/lib/python/indra/util/test_win32_manifest.py
+++ b/indra/lib/python/indra/util/test_win32_manifest.py
@@ -1,28 +1,29 @@
 #!/usr/bin/env python
-# @file test_win32_manifest.py
-# @brief Test an assembly binding version and uniqueness in a windows dll or exe.  
-#
-# $LicenseInfo:firstyear=2009&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$
-
+"""\
+@file test_win32_manifest.py
+@brief Test an assembly binding version and uniqueness in a windows dll or exe.  
+
+$LicenseInfo:firstyear=2009&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2009-2011, 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$
+"""
 import sys, os
 import tempfile
 from xml.dom.minidom import parse
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h
index 10c88464e50da32bc59d962020d739a4670fc932..3588f36758c75f8858eeb8377baf0bed311804e7 100644
--- a/indra/llmath/m4math.h
+++ b/indra/llmath/m4math.h
@@ -132,6 +132,7 @@ class LLMatrix4
 
 	// various useful matrix functions
 	const LLMatrix4& setIdentity();					// Load identity matrix
+	bool isIdentity() const;
 	const LLMatrix4& setZero();						// Clears matrix to all zeros.
 
 	const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z);	// Calculate rotation matrix by rotating angle radians about (x, y, z)
@@ -262,6 +263,30 @@ inline const LLMatrix4&	LLMatrix4::setIdentity()
 	return (*this);
 }
 
+inline bool LLMatrix4::isIdentity() const
+{
+	return
+		mMatrix[0][0] == 1.f &&
+		mMatrix[0][1] == 0.f &&
+		mMatrix[0][2] == 0.f &&
+		mMatrix[0][3] == 0.f &&
+
+		mMatrix[1][0] == 0.f &&
+		mMatrix[1][1] == 1.f &&
+		mMatrix[1][2] == 0.f &&
+		mMatrix[1][3] == 0.f &&
+
+		mMatrix[2][0] == 0.f &&
+		mMatrix[2][1] == 0.f &&
+		mMatrix[2][2] == 1.f &&
+		mMatrix[2][3] == 0.f &&
+
+		mMatrix[3][0] == 0.f &&
+		mMatrix[3][1] == 0.f &&
+		mMatrix[3][2] == 0.f &&
+		mMatrix[3][3] == 1.f;
+}
+
 
 /*
 inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index 7eb198bb34f47ac729e320bec64801f7d4444969..580ee7f8b44cb7ece17ee60077238883dce8bd78 100644
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   test_llsdmessage_peer.py
 @author Nat Goodspeed
diff --git a/indra/llmessage/tests/testrunner.py b/indra/llmessage/tests/testrunner.py
index 4d58ef71301b9db5aea8d991053d1004361aa1ff..b70ce91ee7beecc1e68471c6e51e380a4a352b3f 100644
--- a/indra/llmessage/tests/testrunner.py
+++ b/indra/llmessage/tests/testrunner.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   testrunner.py
 @author Nat Goodspeed
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index d5a29dcd0ce495f408f3902db7c3b56eb41f16f7..e26aead676fe6520cb0256a501387bd37c62c1d4 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -238,9 +238,11 @@ class LLGLSTracker
 class LLGLSSpecular
 {
 public:
+	F32 mShininess;
 	LLGLSSpecular(const LLColor4& color, F32 shininess)
 	{
-		if (shininess > 0.0f)
+		mShininess = shininess;
+		if (mShininess > 0.0f)
 		{
 			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV);
 			S32 shiny = (S32)(shininess*128.f);
@@ -250,32 +252,14 @@ class LLGLSSpecular
 	}
 	~LLGLSSpecular()
 	{
-		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV);
-		glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+		if (mShininess > 0.f)
+		{
+			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV);
+			glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+		}
 	}
 };
 
 //----------------------------------------------------------------------------
 
-
-class LLGLSBlendFunc : public LLGLSPipeline {
-protected:
-	GLint mSavedSrc, mSavedDst;
-	LLGLEnable mBlend;
-
-public:
-	LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) :
-		mBlend(GL_BLEND)
-	{
-		glGetIntegerv(GL_BLEND_SRC, &mSavedSrc);
-		glGetIntegerv(GL_BLEND_DST, &mSavedDst);
-		glBlendFunc(srcFunc, dstFunc);
-	}
-
-	~LLGLSBlendFunc(void) {
-		glBlendFunc(mSavedSrc, mSavedDst);
-	}
-};
-
-
 #endif
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index fb2d0bc7a7fca385e29a786a1ee1d5239b6ceb5f..49e10c47902911dc082f79f96bbf16df966dbe63 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -47,6 +47,7 @@ U32 LLRender::sUICalls = 0;
 U32 LLRender::sUIVerts = 0;
 
 static const U32 LL_NUM_TEXTURE_LAYERS = 16; 
+static const U32 LL_NUM_LIGHT_UNITS = 8;
 
 static GLenum sGLTextureType[] =
 {
@@ -747,6 +748,130 @@ void LLTexUnit::debugTextureUnit(void)
 	}
 }
 
+LLLightState::LLLightState(S32 index)
+: mIndex(index),
+  mEnabled(false),
+  mConstantAtten(1.f),
+  mLinearAtten(0.f),
+  mQuadraticAtten(0.f),
+  mSpotExponent(0.f),
+  mSpotCutoff(180.f)
+{
+	if (mIndex == 0)
+	{
+		mDiffuse.set(1,1,1,1);
+		mSpecular.set(1,1,1,1);
+	}
+
+	mAmbient.set(0,0,0,1);
+	mPosition.set(0,0,1,0);
+	mSpotDirection.set(0,0,-1);
+
+}
+
+void LLLightState::enable()
+{
+	if (!mEnabled)
+	{
+		glEnable(GL_LIGHT0+mIndex);
+		mEnabled = true;
+	}
+}
+
+void LLLightState::disable()
+{
+	if (mEnabled)
+	{
+		glDisable(GL_LIGHT0+mIndex);
+		mEnabled = false;
+	}
+}
+
+void LLLightState::setDiffuse(const LLColor4& diffuse)
+{
+	if (mDiffuse != diffuse)
+	{
+		mDiffuse = diffuse;
+		glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
+	}
+}
+
+void LLLightState::setAmbient(const LLColor4& ambient)
+{
+	if (mAmbient != ambient)
+	{
+		mAmbient = ambient;
+		glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
+	}
+}
+
+void LLLightState::setSpecular(const LLColor4& specular)
+{
+	if (mSpecular != specular)
+	{
+		mSpecular = specular;
+		glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
+	}
+}
+
+void LLLightState::setPosition(const LLVector4& position)
+{
+	//always set position because modelview matrix may have changed
+	mPosition = position;
+	glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
+}
+
+void LLLightState::setConstantAttenuation(const F32& atten)
+{
+	if (mConstantAtten != atten)
+	{
+		mConstantAtten = atten;
+		glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
+	}
+}
+
+void LLLightState::setLinearAttenuation(const F32& atten)
+{
+	if (mLinearAtten != atten)
+	{
+		mLinearAtten = atten;
+		glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
+	}
+}
+
+void LLLightState::setQuadraticAttenuation(const F32& atten)
+{
+	if (mQuadraticAtten != atten)
+	{
+		mQuadraticAtten = atten;
+		glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
+	}
+}
+
+void LLLightState::setSpotExponent(const F32& exponent)
+{
+	if (mSpotExponent != exponent)
+	{
+		mSpotExponent = exponent;
+		glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
+	}
+}
+
+void LLLightState::setSpotCutoff(const F32& cutoff)
+{
+	if (mSpotCutoff != cutoff)
+	{
+		mSpotCutoff = cutoff;
+		glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
+	}
+}
+
+void LLLightState::setSpotDirection(const LLVector3& direction)
+{
+	//always set direction because modelview matrix may have changed
+	mSpotDirection = direction;
+	glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
+}
 
 LLRender::LLRender()
   : mDirty(false),
@@ -768,6 +893,11 @@ LLRender::LLRender()
 	}
 	mDummyTexUnit = new LLTexUnit(-1);
 
+	for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i)
+	{
+		mLightState.push_back(new LLLightState(i));
+	}
+
 	for (U32 i = 0; i < 4; i++)
 	{
 		mCurrColorMask[i] = true;
@@ -795,6 +925,12 @@ void LLRender::shutdown()
 	mTexUnits.clear();
 	delete mDummyTexUnit;
 	mDummyTexUnit = NULL;
+
+	for (U32 i = 0; i < mLightState.size(); ++i)
+	{
+		delete mLightState[i];
+	}
+	mLightState.clear();
 }
 
 void LLRender::refreshState(void)
@@ -932,15 +1068,21 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB
 {
 	flush();
 
-	mCurrColorMask[0] = writeColorR;
-	mCurrColorMask[1] = writeColorG;
-	mCurrColorMask[2] = writeColorB;
-	mCurrColorMask[3] = writeAlpha;
+	if (mCurrColorMask[0] != writeColorR ||
+		mCurrColorMask[1] != writeColorG ||
+		mCurrColorMask[2] != writeColorB ||
+		mCurrColorMask[3] != writeAlpha)
+	{
+		mCurrColorMask[0] = writeColorR;
+		mCurrColorMask[1] = writeColorG;
+		mCurrColorMask[2] = writeColorB;
+		mCurrColorMask[3] = writeAlpha;
 
-	glColorMask(writeColorR ? GL_TRUE : GL_FALSE, 
-				writeColorG ? GL_TRUE : GL_FALSE,
-				writeColorB ? GL_TRUE : GL_FALSE,
-				writeAlpha ? GL_TRUE : GL_FALSE);
+		glColorMask(writeColorR ? GL_TRUE : GL_FALSE, 
+					writeColorG ? GL_TRUE : GL_FALSE,
+					writeColorB ? GL_TRUE : GL_FALSE,
+					writeAlpha ? GL_TRUE : GL_FALSE);
+	}
 }
 
 void LLRender::setSceneBlendType(eBlendType type)
@@ -978,15 +1120,19 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
 {
 	flush();
 
-	mCurrAlphaFunc = func;
-	mCurrAlphaFuncVal = value;
-	if (func == CF_DEFAULT)
-	{
-		glAlphaFunc(GL_GREATER, 0.01f);
-	} 
-	else
+	if (mCurrAlphaFunc != func ||
+		mCurrAlphaFuncVal != value)
 	{
-		glAlphaFunc(sGLCompareFunc[func], value);
+		mCurrAlphaFunc = func;
+		mCurrAlphaFuncVal = value;
+		if (func == CF_DEFAULT)
+		{
+			glAlphaFunc(GL_GREATER, 0.01f);
+		} 
+		else
+		{
+			glAlphaFunc(sGLCompareFunc[func], value);
+		}
 	}
 }
 
@@ -1045,6 +1191,16 @@ LLTexUnit* LLRender::getTexUnit(U32 index)
 	}
 }
 
+LLLightState* LLRender::getLight(U32 index)
+{
+	if (index < mLightState.size())
+	{
+		return mLightState[index];
+	}
+	
+	return NULL;
+}
+
 bool LLRender::verifyTexUnitActive(U32 unitToVerify)
 {
 	if (mCurrTextureUnitIndex == unitToVerify)
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 2767aa64a8a675bf891e11a4b1ee3928f2938e98..7ba14f7b405376f77060bfb331ca18b0bb31b27a 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -37,6 +37,7 @@
 #include "v2math.h"
 #include "v3math.h"
 #include "v4coloru.h"
+#include "v4math.h"
 #include "llstrider.h"
 #include "llpointer.h"
 #include "llglheaders.h"
@@ -212,6 +213,41 @@ class LLTexUnit
 	void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false);
 };
 
+class LLLightState
+{
+public:
+	LLLightState(S32 index);
+
+	void enable();
+	void disable();
+	void setDiffuse(const LLColor4& diffuse);
+	void setAmbient(const LLColor4& ambient);
+	void setSpecular(const LLColor4& specular);
+	void setPosition(const LLVector4& position);
+	void setConstantAttenuation(const F32& atten);
+	void setLinearAttenuation(const F32& atten);
+	void setQuadraticAttenuation(const F32& atten);
+	void setSpotExponent(const F32& exponent);
+	void setSpotCutoff(const F32& cutoff);
+	void setSpotDirection(const LLVector3& direction);
+
+protected:
+	S32 mIndex;
+	bool mEnabled;
+	LLColor4 mDiffuse;
+	LLColor4 mAmbient;
+	LLColor4 mSpecular;
+	LLVector4 mPosition;
+	LLVector3 mSpotDirection;
+
+	F32 mConstantAtten;
+	F32 mLinearAtten;
+	F32 mQuadraticAtten;
+
+	F32 mSpotExponent;
+	F32 mSpotCutoff;
+};
+
 class LLRender
 {
 	friend class LLTexUnit;
@@ -327,6 +363,8 @@ class LLRender
 	void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
 		       eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
 
+	LLLightState* getLight(U32 index);
+
 	LLTexUnit* getTexUnit(U32 index);
 
 	U32	getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
@@ -363,6 +401,7 @@ class LLRender
 	LLStrider<LLColor4U>		mColorsp;
 	std::vector<LLTexUnit*>		mTexUnits;
 	LLTexUnit*			mDummyTexUnit;
+	std::vector<LLLightState*> mLightState;
 
 	eBlendFactor mCurrBlendColorSFactor;
 	eBlendFactor mCurrBlendColorDFactor;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 07ec31dbd5c5a3f25c89ad0d37cae3b696ebeb31..f5e85aecda460f518eb9b61e0ceacd4c0706886c 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -58,6 +58,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE;
 U32 LLVertexBuffer::sAllocatedBytes = 0;
 BOOL LLVertexBuffer::sMapped = FALSE;
 BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
+BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
 S32	LLVertexBuffer::sWeight4Loc = -1;
 
 std::vector<U32> LLVertexBuffer::sDeleteList;
@@ -143,11 +144,11 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 			}
 			else 
 			{	//was disabled
-				if (data_mask & mask[i])
+				if (data_mask & mask[i] && i > 0)
 				{ //needs to be enabled
 					glEnableClientState(array[i]);
 				}
-				else if (gDebugGL && glIsEnabled(array[i]))
+				else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
 				{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 					if (gDebugSession)
 					{
@@ -427,9 +428,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 		mUsage = 0;
 	}
 	
-	if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+	if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
 	{
-		mUsage = 0;
+		mUsage = GL_STREAM_DRAW_ARB;
 	}
 
 	//zero out offsets
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index f40f013306b6c1dd851b20ee9c466b2e3ca57722..77c9da2d6c8a42894481f6425b5510710c641cf8 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -92,6 +92,7 @@ class LLVertexBuffer : public LLRefCount
 	static S32	sWeight4Loc;
 
 	static BOOL	sUseStreamDraw;
+	static BOOL	sPreferStreamDraw;
 
 	static void initClass(bool use_vbo);
 	static void cleanupClass();
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d71b84739c97c24acc253df57bfbe4bee9dfc76d..ec6b942e3e0b5b1fb861b0d0d6f13e7aec762a97 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8810,7 +8810,18 @@
     <key>Value</key>
     <integer>1</integer>
   </map>
-    <key>RenderVolumeLODFactor</key>
+	<key>RenderPreferStreamDraw</key>
+	<map>
+		<key>Comment</key>
+		<string>Use GL_STREAM_DRAW in place of GL_DYNAMIC_DRAW</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>Boolean</string>
+		<key>Value</key>
+		<integer>0</integer>
+	</map>
+	<key>RenderVolumeLODFactor</key>
     <map>
       <key>Comment</key>
       <string>Controls level of detail of primitives (multiplier for current screen area when calculated level of detail)</string>
diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 4fd04d780eb0a8b926797d7623d26b1b04ab611e..5ebec1563e915b5914be63fc2d1dc4f1ecb6bcae 100644
--- a/indra/newview/generate_breakpad_symbols.py
+++ b/indra/newview/generate_breakpad_symbols.py
@@ -1,29 +1,31 @@
 #!/usr/bin/env python
-# @file generate_breakpad_symbols.py
-# @author Brad Kittenbrink <brad@lindenlab.com>
-# @brief Simple tool for generating google_breakpad symbol information
-#        for the crash reporter.
-#
-# $LicenseInfo:firstyear=2010&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$
+"""\
+@file generate_breakpad_symbols.py
+@author Brad Kittenbrink <brad@lindenlab.com>
+@brief Simple tool for generating google_breakpad symbol information
+       for the crash reporter.
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, 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$
+"""
 
 
 import collections
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index cbee800acbfe0f02c6643bdcfae3dd1b05caf990..d370c72a04be37ab366c1fe674717d4210f564e0 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -1052,7 +1052,7 @@ BOOL LLDrawable::isVisible() const
 //=======================================
 
 LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
-: LLSpatialPartition(data_mask, render_by_group, FALSE)
+: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
 {
 	mDrawable = root;
 	root->setSpatialBridge(this);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index ae3421a019f99a45cd71618205c2fdcfeba43512..b044a89af8e144ace2485bcd9d5158c899148693 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -507,6 +507,11 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
 	//reset vertex buffer mappings
 	LLVertexBuffer::unbind();
 
+	if (pass == 0)
+	{ //make sure no stale colors are left over from a previous render
+		glColor4f(1,1,1,1);
+	}
+
 	if (LLPipeline::sImpostorRender)
 	{ //impostor render does not have impostors or rigid rendering
 		pass += 2;
@@ -1030,6 +1035,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
 
 	sVertexProgram->bind();
 	
+	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 	enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 
 	gGL.getTexUnit(0)->activate();
@@ -1042,6 +1048,8 @@ void LLDrawPoolAvatar::endDeferredSkinned()
 	disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
 	sVertexProgram->unbind();
 
+	sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
 	sShaderLevel = mVertexShaderLevel;
 
 	gGL.getTexUnit(0)->activate();
@@ -1126,8 +1134,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 
-    LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f);
-
 	if (pass == 0)
 	{
 		if (!LLPipeline::sReflectionRender)
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index eaa6aa7e37cbacc6199f5f31736e0b2661912a14..696c2d1abdcf3533f291c2193fdbaa4921d222b6 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -192,7 +192,7 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
 				&gWLCloudProgram;
 
 		LLGLEnable blend(GL_BLEND);
-		LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+		gGL.setSceneBlendType(LLRender::BT_ALPHA);
 		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 
 		gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 689fa7295861c0bfb597b462e2bcf164c8a7435d..bd939d8636e64012d792e05ecaec5377a696068b 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -366,7 +366,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 	LLFastTimer ftm(FTM_DO_FLEXIBLE_UPDATE);
 	LLVolume* volume = mVO->getVolume();
 	LLPath *path = &volume->getPath();
-	if (mSimulateRes == 0 && mVO->mDrawable->isVisible())
+	if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
 	{
 		mVO->markForUpdate(TRUE);
 		if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
@@ -375,6 +375,11 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 		}
 	}
 
+	if (!mVO->mDrawable->isVisible())
+	{
+		return;
+	}
+
 	llassert_always(mInitialized);
 	
 	S32 num_sections = 1 << mSimulateRes;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7d42c842e8262476ca463c56783bbcb55373ef0d..42c93a91a5a5ec8332517b402caf1d61df5bb926 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1653,7 +1653,7 @@ void LLModelLoader::run()
 									
 									std::vector<LLImportMaterial> materials;
 									materials.resize(model->getNumVolumeFaces());
-									mScene[transformation].push_back(LLModelInstance(model, transformation, materials));
+									mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
 									stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
 								}
 							}
@@ -1944,7 +1944,8 @@ void LLModelLoader::processElement(daeElement* element)
 					mesh_scale *= transformation;
 					transformation = mesh_scale;
 
-					mScene[transformation].push_back(LLModelInstance(model, transformation, materials));
+					std::string label = getElementLabel(instance_geo);
+					mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials));
 
 					stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform);
 				}
@@ -2615,188 +2616,6 @@ void LLModelPreview::generateNormals()
 
 }
 
-void LLModelPreview::consolidate()
-{
-	std::map<LLImportMaterial, std::vector<LLModelInstance> > composite;
-
-	LLMatrix4 identity;
-
-	//bake out each node in current scene to composite
-	for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
-	{ //for each transform in current scene
-		LLMatrix4 mat = iter->first;
-		glh::matrix4f inv_trans = glh::matrix4f((F32*) mat.mMatrix).inverse().transpose();
-		LLMatrix4 norm_mat(inv_trans.m);
-
-		for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
-		{ //for each instance with that transform
-			LLModelInstance& source_instance = *model_iter;
-			LLModel* source = source_instance.mModel;
-
-			if (!validate_model(source))
-			{
-				llerrs << "Invalid model found!" << llendl;
-			}
-
-			for (S32 i = 0; i < source->getNumVolumeFaces(); ++i)
-			{ //for each face in instance
-				const LLVolumeFace& src_face = source->getVolumeFace(i);
-				LLImportMaterial& source_material = source_instance.mMaterial[i];
-
-				//get model in composite that is composite for this material
-				LLModel* model = NULL;
-
-				if (composite.find(source_material) != composite.end())
-				{
-					model = composite[source_material].rbegin()->mModel;
-					if (model->getVolumeFace(0).mNumVertices + src_face.mNumVertices > 65535)
-					{
-						model = NULL;
-					}
-				}
-
-				if (model == NULL)
-				{  //no model found, make new model
-					std::vector<LLImportMaterial> materials;
-					materials.push_back(source_material);
-					LLVolumeParams volume_params;
-					volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-					model = new LLModel(volume_params, 0.f);
-					model->mLabel = source->mLabel;
-					model->setNumVolumeFaces(0);
-					composite[source_material].push_back(LLModelInstance(model, identity, materials));
-				}
-
-				model->appendFace(src_face, source->mMaterialList[i], mat, norm_mat);
-			}
-		}
-	}
-
-
-	//condense composite into as few LLModel instances as possible
-	LLModelLoader::model_list new_model;
-	std::vector<LLModelInstance> instance_list;
-
-	LLVolumeParams volume_params;
-	volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-
-	std::vector<LLImportMaterial> empty_material;
-	LLModelInstance cur_instance(new LLModel(volume_params, 0.f), identity, empty_material);
-	cur_instance.mModel->setNumVolumeFaces(0);
-
-	BOOL first_transform = TRUE;
-
-	LLModelLoader::scene new_scene;
-	LLVector3 min,max;
-
-	for (std::map<LLImportMaterial, std::vector<LLModelInstance> >::iterator iter = composite.begin();
-		 iter != composite.end();
-		 ++iter)
-	{
-		std::map<LLImportMaterial, std::vector<LLModelInstance> >::iterator next_iter = iter; ++next_iter;
-
-		for (std::vector<LLModelInstance>::iterator instance_iter = iter->second.begin();
-			 instance_iter != iter->second.end();
-			 ++instance_iter)
-		{
-			LLModel* source = instance_iter->mModel;
-
-			if (instance_iter->mMaterial.size() != 1)
-			{
-				llerrs << "WTF?" << llendl;
-			}
-
-			if (source->getNumVolumeFaces() != 1)
-			{
-				llerrs << "WTF?" << llendl;
-			}
-
-			if (source->mMaterialList.size() != 1)
-			{
-				llerrs << "WTF?" << llendl;
-			}
-
-			cur_instance.mModel->addFace(source->getVolumeFace(0));
-			cur_instance.mMaterial.push_back(instance_iter->mMaterial[0]);
-			cur_instance.mModel->mMaterialList.push_back(source->mMaterialList[0]);
-
-			BOOL last_model = FALSE;
-
-			std::vector<LLModelInstance>::iterator next_instance = instance_iter; ++next_instance;
-
-			if (next_iter == composite.end() &&
-				next_instance == iter->second.end())
-			{
-				last_model = TRUE;
-			}
-
-			if (last_model || cur_instance.mModel->getNumVolumeFaces() >= MAX_MODEL_FACES)
-			{
-				cur_instance.mModel->mLabel = source->mLabel;
-
-				cur_instance.mModel->optimizeVolumeFaces();
-				cur_instance.mModel->normalizeVolumeFaces();
-
-				if (!validate_model(cur_instance.mModel))
-				{
-					llerrs << "Invalid model detected." << llendl;
-				}
-
-				new_model.push_back(cur_instance.mModel);
-
-				LLMatrix4 transformation = LLMatrix4();
-
-				// adjust the transformation to compensate for mesh normalization
-				LLVector3 mesh_scale_vector;
-				LLVector3 mesh_translation_vector;
-				cur_instance.mModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector);
-
-				LLMatrix4 mesh_translation;
-				mesh_translation.setTranslation(mesh_translation_vector);
-				mesh_translation *= transformation;
-				transformation = mesh_translation;
-
-				LLMatrix4 mesh_scale;
-				mesh_scale.initScale(mesh_scale_vector);
-				mesh_scale *= transformation;
-				transformation = mesh_scale;
-
-				cur_instance.mTransform = transformation;
-
-				new_scene[transformation].push_back(cur_instance);
-				stretch_extents(cur_instance.mModel, transformation, min, max, first_transform);
-
-				if (!last_model)
-				{
-					cur_instance = LLModelInstance(new LLModel(volume_params, 0.f), identity, empty_material);
-					cur_instance.mModel->setNumVolumeFaces(0);
-				}
-			}
-		}
-	}
-
-	mScene[mPreviewLOD] = new_scene;
-	mModel[mPreviewLOD] = new_model;
-	mVertexBuffer[mPreviewLOD].clear();
-
-	if (mPreviewLOD == LLModel::LOD_HIGH)
-	{
-		mBaseScene = new_scene;
-		mBaseModel = new_model;
-		clearGLODGroup();
-		mVertexBuffer[5].clear();
-	}
-
-	mPreviewTarget = (min+max)*0.5f;
-	mPreviewScale = (max-min)*0.5f;
-	setPreviewTarget(mPreviewScale.magVec()*2.f);
-
-	clearIncompatible(mPreviewLOD);
-
-	mResourceCost = calcResourceCost();
-	refresh();
-}
-
 void LLModelPreview::clearMaterials()
 {
 	for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 8fc85cebb947602a3a79b8220a661784383c5482..e1c520134b7d8f8896eb96b06c324f98b018ce1c 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -279,7 +279,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	void loadModelCallback(S32 lod);
 	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
 	void generateNormals();
-	void consolidate();
+	
 	void clearMaterials();
 	U32 calcResourceCost();
 	void rebuildUploadData();
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a2b0ac09af2d31a391bf75ff0fd6d9938cddb30f..b6e3626cbad6bc80ceaa8f1e68281c9a5bdc41d8 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2981,7 +2981,7 @@ LLSD LLMeshUploadThread::createObject(LLModelInstance& instance)
 	object_params["pos"] = ll_sd_from_vector3(position + mOrigin);
 	object_params["rotation"] = ll_sd_from_quaternion(quat_rotation);
 	object_params["scale"] = ll_sd_from_vector3(scale);
-	object_params["name"] = instance.mModel->getName();
+	object_params["name"] = instance.mLabel;
 
 	// load material from dae file
 	object_params["facelist"] = LLSD::emptyArray();
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index b642a89192a17083e2e440f51aecc69001b322fc..0fcb2213de78920ac38ea7777bf5e965af9ff227 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -108,14 +108,16 @@ class LLModelInstance
 public:
 	LLPointer<LLModel> mModel;
 	LLPointer<LLModel> mLOD[5];
-	 
+	
+	std::string mLabel;
+
 	LLUUID mMeshID;
 
 	LLMatrix4 mTransform;
 	std::vector<LLImportMaterial> mMaterial;
 
-	LLModelInstance(LLModel* model, LLMatrix4& transform, std::vector<LLImportMaterial>& materials)
-		: mModel(model), mTransform(transform), mMaterial(materials)
+	LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::vector<LLImportMaterial>& materials)
+		: mModel(model), mLabel(label), mTransform(transform), mMaterial(materials)
 	{
 	}
 };
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 42da966b929f7b6688019f0a7e8bdd74fc60d7d8..0300ea0c928e276d75bbd63b9b1d7796cbcbe198 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1178,13 +1178,13 @@ void LLPanelObject::getState( )
 			if (mCtrlSculptMirror)
 			{
 				mCtrlSculptMirror->set(sculpt_mirror);
-				mCtrlSculptMirror->setEnabled(editable && (sculpt_stitching != LL_SCULPT_TYPE_MESH));
+				mCtrlSculptMirror->setEnabled(editable);
 			}
 
 			if (mCtrlSculptInvert)
 			{
 				mCtrlSculptInvert->set(sculpt_invert);
-				mCtrlSculptInvert->setEnabled(editable && (!isMesh));
+				mCtrlSculptInvert->setEnabled(editable);
 			}
 
 			if (mLabelSculptType)
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5dd1b5ba7e64f08c0b1c3019c5c8aa052f252df2..14775f0f21353a2bb88940d5dd10fd5d33db4449 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -252,11 +252,15 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
 }
 
 
+static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
+
 void LLSpatialGroup::buildOcclusion()
 {
 	if (mOcclusionVerts.isNull())
 	{
-		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_DYNAMIC_DRAW_ARB);
+
+		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 
+			LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
 		mOcclusionVerts->allocateBuffer(8, 64, true);
 	
 		LLStrider<U16> idx;
@@ -275,40 +279,47 @@ void LLSpatialGroup::buildOcclusion()
 
 	LLStrider<LLVector3> pos;
 	
-	mOcclusionVerts->getVertexStrider(pos);
-
-	LLVector4a* v = (LLVector4a*) pos.get();
-
-	const LLVector4a& c = mBounds[0];
-	const LLVector4a& s = r;
-	
-	static const LLVector4a octant[] =
 	{
-		LLVector4a(-1.f, -1.f, -1.f),
-		LLVector4a(-1.f, -1.f, 1.f),
-		LLVector4a(-1.f, 1.f, -1.f),
-		LLVector4a(-1.f, 1.f, 1.f),
+		LLFastTimer t(FTM_BUILD_OCCLUSION);
+		mOcclusionVerts->getVertexStrider(pos);
+	}
 
-		LLVector4a(1.f, -1.f, -1.f),
-		LLVector4a(1.f, -1.f, 1.f),
-		LLVector4a(1.f, 1.f, -1.f),
-		LLVector4a(1.f, 1.f, 1.f),
-	};
+	{
+		LLVector4a* v = (LLVector4a*) pos.get();
 
-	//vertex positions are encoded so the 3 bits of their vertex index 
-	//correspond to their axis facing, with bit position 3,2,1 matching
-	//axis facing x,y,z, bit set meaning positive facing, bit clear 
-	//meaning negative facing
+		const LLVector4a& c = mBounds[0];
+		const LLVector4a& s = r;
+		
+		static const LLVector4a octant[] =
+		{
+			LLVector4a(-1.f, -1.f, -1.f),
+			LLVector4a(-1.f, -1.f, 1.f),
+			LLVector4a(-1.f, 1.f, -1.f),
+			LLVector4a(-1.f, 1.f, 1.f),
+
+			LLVector4a(1.f, -1.f, -1.f),
+			LLVector4a(1.f, -1.f, 1.f),
+			LLVector4a(1.f, 1.f, -1.f),
+			LLVector4a(1.f, 1.f, 1.f),
+		};
+
+		//vertex positions are encoded so the 3 bits of their vertex index 
+		//correspond to their axis facing, with bit position 3,2,1 matching
+		//axis facing x,y,z, bit set meaning positive facing, bit clear 
+		//meaning negative facing
+		
+		for (S32 i = 0; i < 8; ++i)
+		{
+			LLVector4a p;
+			p.setMul(s, octant[i]);
+			p.add(c);
+			v[i] = p;
+		}
+	}
 	
-	for (S32 i = 0; i < 8; ++i)
 	{
-		LLVector4a p;
-		p.setMul(s, octant[i]);
-		p.add(c);
-		v[i] = p;
+		mOcclusionVerts->setBuffer(0);
 	}
-	
-	mOcclusionVerts->setBuffer(0);
 
 	clearState(LLSpatialGroup::OCCLUSION_DIRTY);
 }
@@ -1189,7 +1200,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
 	mOctreeNode(node),
 	mSpatialPartition(part),
 	mVertexBuffer(NULL), 
-	mBufferUsage(GL_STATIC_DRAW_ARB),
+	mBufferUsage(part->mBufferUsage),
 	mDistance(0.f),
 	mDepth(0.f),
 	mLastUpdateDistance(-1.f), 
@@ -1616,6 +1627,10 @@ void LLSpatialGroup::checkOcclusion()
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
+static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
+
 void LLSpatialGroup::doOcclusion(LLCamera* camera)
 {
 	if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
@@ -1623,6 +1638,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 		// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
 		if (earlyFail(camera, this))
 		{
+			LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL);
 			setOcclusionState(LLSpatialGroup::DISCARD_QUERY);
 			assert_states_valid(this);
 			clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
@@ -1664,41 +1680,47 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
 					sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
 #endif
 
-					glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					
+					{
+						LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
+						glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					
 					
-					mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
+						mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
 
-					if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
-					{
-						LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
-						if (camera->getOrigin().isExactlyZero())
-						{ //origin is invalid, draw entire box
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
-						}
-						else
+						if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
 						{
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
-						}
-					}
-					else
-					{
-						if (camera->getOrigin().isExactlyZero())
-						{ //origin is invalid, draw entire box
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
+							LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
+							if (camera->getOrigin().isExactlyZero())
+							{ //origin is invalid, draw entire box
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
+							}
+							else
+							{
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+							}
 						}
 						else
 						{
-							mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+							if (camera->getOrigin().isExactlyZero())
+							{ //origin is invalid, draw entire box
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				
+							}
+							else
+							{
+								mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+							}
 						}
-					}
 
-					glEndQueryARB(mode);
+						glEndQueryARB(mode);
+					}
 				}
 
-				setOcclusionState(LLSpatialGroup::QUERY_PENDING);
-				clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
+				{
+					LLFastTimer t(FTM_SET_OCCLUSION_STATE);
+					setOcclusionState(LLSpatialGroup::QUERY_PENDING);
+					clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
+				}
 			}
 		}
 	}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 664d957e498b3ce5480afbd363837cfb9e964a3f..0d9cad914a55755344cc062719da89ec364a05d7 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -148,6 +148,17 @@ class LLDrawInfo : public LLRefCount
 
 	};
 
+	struct CompareMatrixTexturePtr
+	{
+		bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)	
+		{
+			return lhs.get() != rhs.get() 
+				&& (lhs.isNull() || (rhs.notNull() && (lhs->mModelMatrix > rhs->mModelMatrix ||
+													   (lhs->mModelMatrix == rhs->mModelMatrix && lhs->mTexture.get() > rhs->mTexture.get()))));
+		}
+
+	};
+
 	struct CompareBump
 	{
 		bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) 
@@ -532,6 +543,7 @@ class LLCullResult
 	sg_list_t::iterator beginAlphaGroups();
 	sg_list_t::iterator endAlphaGroups();
 
+	bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
 	sg_list_t::iterator beginOcclusionGroups();
 	sg_list_t::iterator endOcclusionGroups();
 
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 414036c597eb19986070952ba7fc2214f6760fd9..46aa44b2bb07853e1491e0218a462e9a1364d3ed 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -339,15 +339,6 @@ static bool handleNumpadControlChanged(const LLSD& newvalue)
 	return true;
 }
 
-static bool handleRenderUseVBOChanged(const LLSD& newvalue)
-{
-	if (gPipeline.isInit())
-	{
-		gPipeline.setUseVBO(newvalue.asBoolean());
-	}
-	return true;
-}
-
 static bool handleWLSkyDetailChanged(const LLSD&)
 {
 	if (gSky.mVOWLSkyp.notNull())
@@ -636,8 +627,9 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
-	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
+	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+	gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
 	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
 	gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 97d6a222c54477016f4a3c6cbb497833d3004067..b45d1aa3a6d3c81223fc34d3ef720f58f983978f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -616,10 +616,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				&& gSavedSettings.getBOOL("UseOcclusion") 
 				&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
 
-		if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
-		{ //force occlusion on for all render types if doing deferred render
+		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
+		{ //force occlusion on for all render types if doing deferred render (tighter shadow frustum)
 			LLPipeline::sUseOcclusion = 3;
-		}
+		}*/
 
 		LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
 		LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 14b9a03fd5a6a47010dd6182e64441471cae066e..aa6da5c9f39af4984def83876f7a618a0592db23 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -533,7 +533,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 
 	stop_glerror();
 	
-	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0));
+	LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), mFace->getPool()->getVertexShaderLevel() > 0 ? 0.f : mShiny);
 
 	//----------------------------------------------------------------
 	// setup current texture
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 439584c7e8e2794cb2555942537e5a8598987dab..e982df1c92e6a23a342a7d05ccc3518649c89f4c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1332,20 +1332,7 @@ const LLVector3 LLVOAvatar::getRenderPosition() const
 	}
 	else if (isRoot())
 	{
-		if ( mHasPelvisOffset )
-		{
-			LLVector3 returnVec( mDrawable->getPositionAgent() );	
-			//1. Move the pelvis down by the old amount
-			returnVec[VZ] -= (mLastPelvisToFoot);
-			//2. Now move the pelvis up by the new amount
-			returnVec[VZ] += mPelvisToFoot;
-			//3. Return the fixed up pelvis position
-			return returnVec;
-		}
-		else
-		{
-			return mDrawable->getPositionAgent();
-		}
+		return mDrawable->getPositionAgent();
 	}
 	else
 	{
@@ -3486,15 +3473,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 		// correct for the fact that the pelvis is not necessarily the center 
 		// of the agent's physical representation
-		if ( !mHasPelvisOffset )
-		{
-			root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
-		}
-		else
-		{
-			root_pos.mdV[VZ] -= (0.65f * mBodySize.mV[VZ]) - mPelvisToFoot;		
-		}
-	
+		root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
+		
 		LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
 
 		if (newPosition != mRoot.getXform()->getWorldPosition())
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index d966bd161462e821cbd2fceb3e32eea6b72ee97a..f762f04d8e050be6d952164bf5cf7f41565ffe99 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -360,7 +360,7 @@ U32 LLVOPartGroup::getPartitionType() const
 }
 
 LLParticlePartition::LLParticlePartition()
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB)
 {
 	mRenderPass = LLRenderPass::PASS_ALPHA;
 	mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 20ca02efda10d527f6da6d0d46470b7dcaca5cfb..1b5aed804f3072a31d7bf10eaa57b4ebfe39f2ea 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -1330,7 +1330,7 @@ U32 LLVOTree::getPartitionType() const
 }
 
 LLTreePartition::LLTreePartition()
-: LLSpatialPartition(0, FALSE, 0)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
 {
 	mDrawableType = LLPipeline::RENDER_TYPE_TREE;
 	mPartitionType = LLViewerRegion::PARTITION_TREE;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 1b7cd801da8bc27064a788ae4cfddad1952dca00..e3cc2f25890139a47d968c53a914f3e848dec45a 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1204,10 +1204,23 @@ BOOL LLVOVolume::calcLOD()
 
 	S32 cur_detail = 0;
 	
-	F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
-	F32 distance = mDrawable->mDistanceWRTCamera; //llmin(mDrawable->mDistanceWRTCamera, MAX_LOD_DISTANCE);
-	distance *= sDistanceFactor;
+	F32 radius;
+	F32 distance;
+
+	if (mDrawable->isState(LLDrawable::RIGGED))
+	{
+		LLVOAvatar* avatar = getAvatar(); 
+		distance = avatar->mDrawable->mDistanceWRTCamera;
+		radius = avatar->getBinRadius();
+	}
+	else
+	{
+		distance = mDrawable->mDistanceWRTCamera;
+		radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
+	}
 			
+	distance *= sDistanceFactor;
+
 	F32 rampDist = LLVOVolume::sLODFactor * 2;
 	
 	if (distance < rampDist)
@@ -3691,6 +3704,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	else
 	{
 		model_mat = &(drawable->getRegion()->mRenderMatrix);
+		if (model_mat->isIdentity())
+		{
+			model_mat = NULL;
+		}
 	}
 
 	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 9f3ec9cadc5e92358820542731047ed291b21a3e..77875859e99e92924aa24dbfba3d7690b1cb87db 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -289,7 +289,7 @@ U32 LLVOVoidWater::getPartitionType() const
 }
 
 LLWaterPartition::LLWaterPartition()
-: LLSpatialPartition(0, FALSE, 0)
+: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
 {
 	mInfiniteFarClip = TRUE;
 	mDrawableType = LLPipeline::RENDER_TYPE_WATER;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9d7af4aace2678965c622a7e2bb91e6ec5797783..a8e36df29415d96deb4b8c6cc47f909575913b59 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -383,6 +383,7 @@ void LLPipeline::init()
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
+	LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
 	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 
@@ -2079,33 +2080,34 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
 
 void LLPipeline::doOcclusion(LLCamera& camera)
 {
-	LLVertexBuffer::unbind();
-
-	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
-	{
-		gGL.setColorMask(true, false, false, false);
-	}
-	else
+	if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
 	{
-		gGL.setColorMask(false, false);
-	}
-	LLGLDisable blend(GL_BLEND);
-	LLGLDisable test(GL_ALPHA_TEST);
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+		LLVertexBuffer::unbind();
 
-	LLGLDisable cull(GL_CULL_FACE);
-	if (LLPipeline::sUseOcclusion > 1)
-	{
+		if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
+		{
+			gGL.setColorMask(true, false, false, false);
+		}
+		else
+		{
+			gGL.setColorMask(false, false);
+		}
+		LLGLDisable blend(GL_BLEND);
+		LLGLDisable test(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+		LLGLDisable cull(GL_CULL_FACE);
+		
 		for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
 		{
 			LLSpatialGroup* group = *iter;
 			group->doOcclusion(&camera);
 			group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
 		}
+	
+		gGL.setColorMask(true, false);
 	}
-
-	gGL.setColorMask(true, false);
 }
 	
 BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
@@ -2941,21 +2943,6 @@ void LLPipeline::postSort(LLCamera& camera)
 	//rebuild groups
 	sCull->assertDrawMapsEmpty();
 
-	/*LLSpatialGroup::sNoDelete = FALSE;
-	for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
-	{
-		LLSpatialGroup* group = *i;
-		if (sUseOcclusion && 
-			group->isState(LLSpatialGroup::OCCLUDED))
-		{
-			continue;
-		}
-		
-		group->rebuildGeom();
-	}
-	LLSpatialGroup::sNoDelete = TRUE;*/
-
-
 	rebuildPriorityGroups();
 	llpushcallstacks ;
 
@@ -4625,16 +4612,19 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
 		
 		light_pos.normalize();
 
+		LLLightState* light = gGL.getLight(1);
+
 		mHWLightColors[1] = diffuse;
-		glLightfv(GL_LIGHT1, GL_DIFFUSE,  diffuse.mV);
-		glLightfv(GL_LIGHT1, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
-		glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); 
-		glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION,  1.0f);
-		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 	 0.0f);
-		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
-		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 		 0.0f);
-		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 			 180.0f);
+
+		light->setDiffuse(diffuse);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
+		light->setPosition(light_pos);
+		light->setConstantAttenuation(1.f);
+		light->setLinearAttenuation(0.f);
+		light->setQuadraticAttenuation(0.f);
+		light->setSpotExponent(0.f);
+		light->setSpotCutoff(180.f);
 	}
 	else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
 	{
@@ -4665,22 +4655,28 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
 		backlight_diffuse *= backlight_mag / max_component;
 
 		mHWLightColors[1] = backlight_diffuse;
-		glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction
-		glLightfv(GL_LIGHT1, GL_DIFFUSE,  backlight_diffuse.mV);
-		glLightfv(GL_LIGHT1, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
-		glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION,  1.0f);
-		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION,    0.0f);
-		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
-		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT,         0.0f);
-		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,           180.0f);
+
+		LLLightState* light = gGL.getLight(1);
+
+		light->setPosition(backlight_pos);
+		light->setDiffuse(backlight_diffuse);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
+		light->setConstantAttenuation(1.f);
+		light->setLinearAttenuation(0.f);
+		light->setQuadraticAttenuation(0.f);
+		light->setSpotExponent(0.f);
+		light->setSpotCutoff(180.f);
 	}
 	else
 	{
+		LLLightState* light = gGL.getLight(1);
+
 		mHWLightColors[1] = LLColor4::black;
-		glLightfv(GL_LIGHT1, GL_DIFFUSE,  LLColor4::black.mV);
-		glLightfv(GL_LIGHT1, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
+
+		light->setDiffuse(LLColor4::black);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
 	}
 }
 
@@ -4861,15 +4857,17 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		LLVector4 light_pos(mSunDir, 0.0f);
 		LLColor4 light_diffuse = mSunDiffuse;
 		mHWLightColors[0] = light_diffuse;
-		glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction
-		glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse.mV);
-		glLightfv(GL_LIGHT0, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV);
-		glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION,  1.0f);
-		glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION,    0.0f);
-		glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);
-		glLightf (GL_LIGHT0, GL_SPOT_EXPONENT,         0.0f);
-		glLightf (GL_LIGHT0, GL_SPOT_CUTOFF,           180.0f);
+
+		LLLightState* light = gGL.getLight(0);
+		light->setPosition(light_pos);
+		light->setDiffuse(light_diffuse);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
+		light->setConstantAttenuation(1.f);
+		light->setLinearAttenuation(0.f);
+		light->setQuadraticAttenuation(0.f);
+		light->setSpotExponent(0.f);
+		light->setSpotCutoff(180.f);
 	}
 	
 	// Light 1 = Backlight (for avatars)
@@ -4927,13 +4925,15 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			float linatten = x / (light_radius); // % of brightness at radius
 
 			mHWLightColors[cur_light] = light_color;
-			S32 gllight = GL_LIGHT0+cur_light;
-			glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
-			glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
-			glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
-			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
-			glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten);
-			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);
+			LLLightState* light_state = gGL.getLight(cur_light);
+			
+			light_state->setPosition(light_pos_gl);
+			light_state->setDiffuse(light_color);
+			light_state->setAmbient(LLColor4::black);
+			light_state->setConstantAttenuation(0.f);
+			light_state->setLinearAttenuation(linatten);
+			light_state->setQuadraticAttenuation(0.f);
+
 			if (light->isLightSpotlight() // directional (spot-)light
 			    && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
 			{
@@ -4941,22 +4941,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 				LLQuaternion quat = light->getRenderRotation();
 				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
 				at_axis *= quat;
-				//llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
-				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
-				glLightf (gllight, GL_SPOT_EXPONENT,  2.0f); // 2.0 = good old dot product ^ 2
-				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere
-				const float specular[] = {0.f, 0.f, 0.f, 0.f};
-				glLightfv(gllight, GL_SPECULAR, specular);
+
+				light_state->setSpotDirection(at_axis);
+				light_state->setSpotCutoff(90.f);
+				light_state->setSpotExponent(2.f);
+	
+				light_state->setSpecular(LLColor4::black);
 			}
 			else // omnidirectional (point) light
 			{
-			glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
-			glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
-
+				light_state->setSpotExponent(0.f);
+				light_state->setSpotCutoff(180.f);
+				
 				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
-				const float specular[] = {0.f, 0.f, 0.f, 1.f};
-				glLightfv(gllight, GL_SPECULAR, specular);
-				//llinfos << "boring light" << llendl;
+				const LLColor4 specular(0.f, 0.f, 0.f, 1.f);
+				light_state->setSpecular(specular);				
 			}
 			cur_light++;
 			if (cur_light >= 8)
@@ -4968,10 +4967,11 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 	for ( ; cur_light < 8 ; cur_light++)
 	{
 		mHWLightColors[cur_light] = LLColor4::black;
-		S32 gllight = GL_LIGHT0+cur_light;
-		glLightfv(gllight, GL_DIFFUSE,  LLColor4::black.mV);
-		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
+		LLLightState* light = gGL.getLight(cur_light);
+
+		light->setDiffuse(LLColor4::black);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
 	}
 	if (gAgentAvatarp &&
 		gAgentAvatarp->mSpecialRenderMode == 3)
@@ -4988,23 +4988,24 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 		float linatten = x / (light_radius); // % of brightness at radius
 
 		mHWLightColors[2] = light_color;
-		S32 gllight = GL_LIGHT2;
-		glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
-		glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
-		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
-		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
-		glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
-		glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten);
-		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);
-		glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
-		glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
+		LLLightState* light = gGL.getLight(2);
+
+		light->setPosition(light_pos_gl);
+		light->setDiffuse(light_color);
+		light->setAmbient(LLColor4::black);
+		light->setSpecular(LLColor4::black);
+		light->setQuadraticAttenuation(0.f);
+		light->setConstantAttenuation(0.f);
+		light->setLinearAttenuation(linatten);
+		light->setSpotExponent(0.f);
+		light->setSpotCutoff(180.f);
 	}
 
 	// Init GL state
 	glDisable(GL_LIGHTING);
-	for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++)
+	for (S32 i = 0; i < 8; ++i)
 	{
-		glDisable(gllight);
+		gGL.getLight(i)->disable();
 	}
 	mLightMask = 0;
 }
@@ -5029,15 +5030,16 @@ void LLPipeline::enableLights(U32 mask)
 			stop_glerror();
 			for (S32 i=0; i<8; i++)
 			{
+				LLLightState* light = gGL.getLight(i);
 				if (mask & (1<<i))
 				{
-					glEnable(GL_LIGHT0 + i);
-					glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  mHWLightColors[i].mV);
+					light->enable();
+					light->setDiffuse(mHWLightColors[i]);
 				}
 				else
 				{
-					glDisable(GL_LIGHT0 + i);
-					glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  LLColor4::black.mV);
+					light->disable();
+					light->setDiffuse(LLColor4::black);
 				}
 			}
 			stop_glerror();
@@ -5061,7 +5063,6 @@ void LLPipeline::enableLightsStatic()
 	if (mLightingDetail >= 2)
 	{
 		mask |= mLightMovingMask; // Hardware moving lights
-		glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default
 	}
 	else
 	{
@@ -5075,11 +5076,7 @@ void LLPipeline::enableLightsDynamic()
 	assertInitialized();
 	U32 mask = 0xff & (~2); // Local lights
 	enableLights(mask);
-	if (mLightingDetail >= 2)
-	{
-		glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
-	}
-
+	
 	if (isAgentAvatarValid() && getLightingDetail() <= 0)
 	{
 		if (gAgentAvatarp->mSpecialRenderMode == 0) // normal
@@ -5125,33 +5122,37 @@ void LLPipeline::enableLightsPreview()
 	dir2.normVec();
 	
 	LLVector4 light_pos(dir0, 0.0f);
-	glEnable(GL_LIGHT0);
-	glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); 
-	glLightfv(GL_LIGHT0, GL_DIFFUSE,  diffuse0.mV);
-	glLightfv(GL_LIGHT0, GL_AMBIENT,  LLColor4::black.mV);
-	glLightfv(GL_LIGHT0, GL_SPECULAR, specular0.mV);
-	glLightf (GL_LIGHT0, GL_SPOT_EXPONENT,         0.0f);
-	glLightf (GL_LIGHT0, GL_SPOT_CUTOFF,           180.0f);
 
-	light_pos = LLVector4(dir1, 0.f);
-	glEnable(GL_LIGHT1);
-	glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); 
-	glLightfv(GL_LIGHT1, GL_DIFFUSE,  diffuse1.mV);
-	glLightfv(GL_LIGHT1, GL_AMBIENT,  LLColor4::black.mV);
-	glLightfv(GL_LIGHT1, GL_SPECULAR, specular1.mV);
-	glLightf (GL_LIGHT1, GL_SPOT_EXPONENT,         0.0f);
-	glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,           180.0f);
+	LLLightState* light = gGL.getLight(0);
 
-	light_pos = LLVector4(dir2, 0.f);
-	glEnable(GL_LIGHT2);
-	glLightfv(GL_LIGHT2, GL_POSITION, light_pos.mV); 
-	glLightfv(GL_LIGHT2, GL_DIFFUSE,  diffuse2.mV);
-	glLightfv(GL_LIGHT2, GL_AMBIENT,  LLColor4::black.mV);
-	glLightfv(GL_LIGHT2, GL_SPECULAR, specular2.mV);
-	glLightf (GL_LIGHT2, GL_SPOT_EXPONENT,         0.0f);
-	glLightf (GL_LIGHT2, GL_SPOT_CUTOFF,           180.0f);
+	light->enable();
+	light->setPosition(light_pos);
+	light->setDiffuse(diffuse0);
+	light->setAmbient(LLColor4::black);
+	light->setSpecular(specular0);
+	light->setSpotExponent(0.f);
+	light->setSpotCutoff(180.f);
 
+	light_pos = LLVector4(dir1, 0.f);
 
+	light = gGL.getLight(1);
+	light->enable();
+	light->setPosition(light_pos);
+	light->setDiffuse(diffuse1);
+	light->setAmbient(LLColor4::black);
+	light->setSpecular(specular1);
+	light->setSpotExponent(0.f);
+	light->setSpotCutoff(180.f);
+
+	light_pos = LLVector4(dir2, 0.f);
+	light = gGL.getLight(2);
+	light->enable();
+	light->setPosition(light_pos);
+	light->setDiffuse(diffuse2);
+	light->setAmbient(LLColor4::black);
+	light->setSpecular(specular2);
+	light->setSpotExponent(0.f);
+	light->setSpotCutoff(180.f);
 }
 
 
@@ -5171,16 +5172,11 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)
 	enableLights(mask);
 
 	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
-	/*if (mLightingDetail >= 2)
-	{
-		glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
-	}*/
 }
 
 void LLPipeline::disableLights()
 {
 	enableLights(0); // no lighting (full bright)
-	glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
 }
 
 //============================================================================
@@ -5800,6 +5796,8 @@ void LLPipeline::resetVertexBuffers()
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
 	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
+	LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
+	LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable");
 	sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
 	sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
 
@@ -5858,24 +5856,6 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
 	gGLLastMatrix = NULL;		
 }
 
-void LLPipeline::setUseVBO(BOOL use_vbo)
-{
-	if (use_vbo != LLVertexBuffer::sEnableVBOs)
-	{
-		if (use_vbo)
-		{
-			llinfos << "Enabling VBO." << llendl;
-		}
-		else
-		{ 
-			llinfos << "Disabling VBO." << llendl;
-		}
-		
-		resetVertexBuffers();
-		LLVertexBuffer::initClass(use_vbo);
-	}
-}
-
 void apply_cube_face_rotation(U32 face)
 {
 	switch (face)
@@ -5969,8 +5949,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 		tc2 /= (F32) res_mod;
 	}
 
-	gGL.setColorMask(true, true);
-		
 	LLFastTimer ftm(FTM_RENDER_BLOOM);
 	gGL.color4f(1,1,1,1);
 	LLGLDepthTest depth(GL_FALSE);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 0eb020605e1e6cba80021c09f468face27a44b96..32ac93388d9c2db5c9ab391124144fee87da1d49 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -119,7 +119,6 @@ class LLPipeline
 	void allocatePhysicsBuffer();
 	
 	void resetVertexBuffers(LLDrawable* drawable);
-	void setUseVBO(BOOL use_vbo);
 	void generateImpostor(LLVOAvatar* avatar);
 	void bindScreenToTexture();
 	void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
diff --git a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
index cf95257b0a508d9d5a1e937f4c6ff4a7894cc68e..7c7ee2df4cba54d28e78a7e4bd927cdb58f0d25c 100644
--- a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
@@ -2,6 +2,7 @@
 <floater
   name="region_debug_console"
   title="Region Debug"
+  can_resize="true"
   layout="topleft"
   min_height="300"
   min_width="300"
@@ -12,7 +13,7 @@
   left="10"
    type="string"
    length="1"
-   follows="left|top|right|bottom"
+   follows="left|right|bottom"
    font="Monospace"
    height="366"
    width="576"
diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py
index aeebb0cfd18b758c6e449c77f986de9a7684a184..1c7204a6b639cad20ee9761709be0095f632f1fe 100644
--- a/indra/newview/tests/test_llxmlrpc_peer.py
+++ b/indra/newview/tests/test_llxmlrpc_peer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   test_llxmlrpc_peer.py
 @author Nat Goodspeed
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index adf7e4af9bfc765e8abef0a3cb14dce5de45af56..1653a01b4a8291bd75eddd5480c7ce7b91e0bfa1 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1,29 +1,31 @@
-#!/usr/bin/python
-# @file viewer_manifest.py
-# @author Ryan Williams
-# @brief Description of all installer viewer files, and methods for packaging
-#        them into installers for all supported platforms.
-#
-# $LicenseInfo:firstyear=2006&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$
+#!/usr/bin/env python
+"""\
+@file viewer_manifest.py
+@author Ryan Williams
+@brief Description of all installer viewer files, and methods for packaging
+       them into installers for all supported platforms.
+
+$LicenseInfo:firstyear=2006&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2006-2011, 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$
+"""
 import sys
 import os.path
 import re
diff --git a/indra/test/test_llmanifest.py b/indra/test/test_llmanifest.py
index 89c36f95ddaf40cdf1c1db5f85aa1680f6073664..a97abbc6eed3292fad3af64d5ac746ec2cfb20fd 100644
--- a/indra/test/test_llmanifest.py
+++ b/indra/test/test_llmanifest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """
 @file test_llmanifest.py
 @author Ryan Williams
diff --git a/install.xml b/install.xml
index 88a6a7ce905097e246f7da563f15213572816fee..bae3ff707b0fd2e91fb1743c1dce1183995eb6a1 100755
--- a/install.xml
+++ b/install.xml
@@ -280,9 +280,9 @@
           <key>windows</key>
           <map>
             <key>md5sum</key>
-            <string>041ac5d31331eb7358af71f7390f5dce</string>
+            <string>c1e79c9d3084727be35ce140db87717e</string>
             <key>url</key>
-            <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/colladadom-2.1-windows-20101119.tar.bz2</uri>
+            <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/colladadom-2.1-windows-20110223.tar.bz2</uri>
           </map>
         </map>
       </map>
diff --git a/scripts/build_version.py b/scripts/build_version.py
index 4bef290b7dd0c932a6b709ef05587d563436850b..203d76fe9ee904d0f8ffe73f04da66d251bda019 100755
--- a/scripts/build_version.py
+++ b/scripts/build_version.py
@@ -1,16 +1,39 @@
 #!/usr/bin/env python
-#
-# Print the build information embedded in a header file.
-#
-# Expects to be invoked from the command line with a file name and a
-# list of directories to search.  The file name will be one of the
-# following:
-#
-#   llversionserver.h
-#   llversionviewer.h
-#
-# The directory list that follows will include indra/llcommon, where
-# these files live.
+"""\
+@file   build_version.py
+@brief Print the build information embedded in a header file.
+
+  Expects to be invoked from the command line with a file name and a
+  list of directories to search.  The file name will be one of the
+  following:
+
+    llversionserver.h
+    llversionviewer.h
+
+  The directory list that follows will include indra/llcommon, where
+  these files live.
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, 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$
+"""
 
 import errno, os, re
 
diff --git a/scripts/md5check.py b/scripts/md5check.py
index 951fe0105ca8a7106c0ac9649b6f4d050b016402..1a54a2844c395e037a321a789f7015e642a0faa6 100644
--- a/scripts/md5check.py
+++ b/scripts/md5check.py
@@ -1,32 +1,27 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file md5check.py
 @brief Replacement for message template compatibility verifier.
 
-$LicenseInfo:firstyear=20i10&license=viewergpl$
-Copyright (c) 2010, Linden Research, Inc.
-
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
 Second Life Viewer Source Code
-The source code in this file ("Source Code") is provided by Linden Lab
-to you under the terms of the GNU General Public License, version 2.0
-("GPL"), unless you have obtained a separate licensing agreement
-("Other License"), formally executed by you and Linden Lab.  Terms of
-the GPL can be found in doc/GPL-license.txt in this distribution, or
-online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-
-There are special exceptions to the terms and conditions of the GPL as
-it is applied to this Source Code. View the full text of the exception
-in the file doc/FLOSS-exception.txt in this software distribution, or
-online at
-http://secondlifegrid.net/programs/open_source/licensing/flossexception
-
-By copying, modifying or distributing this software, you acknowledge
-that you have read and understood your obligations described above,
-and agree to abide by those obligations.
-
-ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-COMPLETENESS OR PERFORMANCE.
+Copyright (C) 2010-2011, 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$
 """
 
diff --git a/scripts/setup-path.py b/scripts/setup-path.py
index 55e0f1a85f91665048ee46c475fbf5a496ed4d41..ce83d815bf8d0ac3c743d8848e715da48d2b29bb 100644
--- a/scripts/setup-path.py
+++ b/scripts/setup-path.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file setup-path.py
 @brief Get the python library directory in the path, so we don't have
diff --git a/scripts/template_verifier.py b/scripts/template_verifier.py
index ddb050fbbbb604626d3f3a89d6831b54e990a901..7f3fed88a92bc1ce2cb72e8f9159ad3f4288ec28 100644
--- a/scripts/template_verifier.py
+++ b/scripts/template_verifier.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file template_verifier.py
 @brief Message template compatibility verifier.
diff --git a/scripts/update_version_files.py b/scripts/update_version_files.py
index da60fd105a93e35059e62a63107481f20bdcfec1..87036dc1c05e2a0f632c768e827fc27894a16418 100755
--- a/scripts/update_version_files.py
+++ b/scripts/update_version_files.py
@@ -1,8 +1,30 @@
-#!/usr/bin/python
-#
-# Update all of the various files in the repository to a new version number,
-# instead of having to figure it out by hand
-#
+#!/usr/bin/env python
+"""\
+@file   update_version_files.py
+@brief  Update all of the various files in the repository to a new version number,
+instead of having to figure it out by hand
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, 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$
+"""
 
 import sys
 import os.path
@@ -37,9 +59,6 @@ def add_indra_lib_path():
 import getopt, os, re, commands
 from indra.util import llversion
 
-svn = os.path.expandvars("${SVN}")
-if not svn or svn == "${SVN}": svn = "svn"
-
 def usage():
     print "Usage:"
     print sys.argv[0] + """ [options]
@@ -68,7 +87,7 @@ def usage():
    Print this message and exit.
 
 Common Uses:
-   # Update server and viewer build numbers to the current SVN revision:
+   # Update server and viewer build numbers to the current hg revision:
    update_version_files.py
 
    # Update build numbers unless we are on a release branch:
@@ -80,7 +99,7 @@ def usage():
    # Update just the viewer version number explicitly:
    update_version_files.py --viewer --version=1.18.1.6     
 
-   # Update just the server build number to the current SVN revision:
+   # Update just the server build number to the current hg revision:
    update_version_files.py --server
                                
    # Update the viewer channel
@@ -152,9 +171,7 @@ def _getstatusoutput(cmd):
       'CFBundleGetInfoString = "Second Life version %(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s'))
 
 
-version_re      = re.compile('(\d+).(\d+).(\d+).(\d+)')
-svn_branch_re   = re.compile('^URL:\s+\S+/([^/\s]+)$', re.MULTILINE)
-svn_revision_re = re.compile('^Last Changed Rev: (\d+)$', re.MULTILINE)
+version_re = re.compile('(\d+).(\d+).(\d+).(\d+)')
 
 def main():
     script_path = os.path.dirname(__file__)
@@ -249,13 +266,7 @@ def main():
             server_version = new_version
     else:
 
-        if llversion.using_svn():
-            if new_revision:
-                revision = new_revision
-            else:
-                revision = llversion.get_svn_revision()
-            branch = llversion.get_svn_branch()
-        elif llversion.using_hg():
+        if llversion.using_hg():
             if new_revision:
                 revision = new_revision
             else:
@@ -327,5 +338,6 @@ def main():
             print "File %(filename)s not present, skipping..." % locals()
     return 0
 
-main()
+if __name__ == '__main__':
+    sys.exit(main())