From f89f19990cbb9f3f2e7473ac6c159098bdfabec7 Mon Sep 17 00:00:00 2001
From: Mark Palange <palange@lindenlab.com>
Date: Fri, 7 Nov 2008 17:51:03 +0000
Subject: [PATCH] QAR-992 Merging revisions 101012-101170,101686-101687 of
 svn+ssh://svn.lindenlab.com/svn/linden/qa/viewer_combo_1-22-merge into
 linden/release

---
 doc/contributions.txt                         |   9 +-
 indra/llcommon/llfasttimer.h                  |   1 +
 indra/llcommon/llversionviewer.h              |   4 +-
 indra/llinventory/llparcel.cpp                |   2 +-
 indra/llmessage/llpartdata.h                  |   1 +
 indra/llmessage/message.cpp                   |  17 +-
 indra/llmessage/message.h                     |  13 +-
 indra/llrender/llcubemap.cpp                  |  54 +--
 indra/llrender/llcubemap.h                    |   2 +
 indra/llrender/llfontgl.cpp                   |  20 +-
 indra/llrender/llgl.cpp                       |  29 +-
 indra/llrender/llglslshader.cpp               |   8 +-
 indra/llrender/llglslshader.h                 |   5 +-
 indra/llrender/llglstates.h                   |  22 +-
 indra/llrender/llimagegl.cpp                  | 266 +++++++------
 indra/llrender/llimagegl.h                    |  26 +-
 indra/llrender/llpostprocess.cpp              |  18 +-
 indra/llrender/llrender.cpp                   | 364 +++++++++++++++---
 indra/llrender/llrender.h                     | 122 ++++--
 indra/llrender/llrendertarget.cpp             |  56 ++-
 indra/llrender/llrendertarget.h               |  15 +-
 indra/llrender/llshadermgr.cpp                |   2 +-
 indra/llrender/llvertexbuffer.cpp             |   8 +-
 indra/llrender/llvertexbuffer.h               |  16 +-
 indra/llui/llfloater.cpp                      |  22 ++
 indra/llui/lllineeditor.cpp                   |   2 +-
 indra/llui/llmenugl.cpp                       |   3 +
 indra/llui/llmultislider.cpp                  |   2 +-
 indra/llui/llscrollcontainer.cpp              |   2 +-
 indra/llui/llscrolllistctrl.cpp               |   4 +-
 indra/llui/llslider.cpp                       |   2 +-
 indra/llui/lltexteditor.cpp                   |   4 +-
 indra/llui/llui.cpp                           |  86 ++---
 indra/llui/llview.cpp                         |   4 +-
 indra/llui/llviewborder.cpp                   |   8 +-
 indra/llvfs/lldir.cpp                         |  23 ++
 indra/llvfs/lldir.h                           |  14 +-
 indra/newview/CMakeLists.txt                  |   3 +
 indra/newview/app_settings/settings.xml       | 108 ++++--
 .../shaders/class1/objects/simpleV.glsl       |   2 +-
 indra/newview/featuretable.txt                |  15 +-
 indra/newview/featuretable_linux.txt          |  15 +-
 indra/newview/featuretable_mac.txt            |  15 +-
 indra/newview/gpu_table.txt                   |  23 +-
 indra/newview/llagent.cpp                     |  42 +-
 indra/newview/llagent.h                       |   4 +-
 indra/newview/llbox.cpp                       |   2 +-
 indra/newview/llchatbar.cpp                   |  10 +-
 indra/newview/lldrawable.cpp                  |   6 +-
 indra/newview/lldrawpool.cpp                  |   9 +-
 indra/newview/lldrawpoolalpha.cpp             |   8 +-
 indra/newview/lldrawpoolavatar.cpp            |  14 +-
 indra/newview/lldrawpoolbump.cpp              |  54 +--
 indra/newview/lldrawpoolground.cpp            |   5 +-
 indra/newview/lldrawpoolsky.cpp               |   4 +-
 indra/newview/lldrawpoolterrain.cpp           | 124 +++---
 indra/newview/lldrawpooltree.cpp              |   5 +-
 indra/newview/lldrawpoolwater.cpp             |  38 +-
 indra/newview/lldrawpoolwlsky.cpp             |  13 +-
 indra/newview/lldynamictexture.cpp            |  19 +-
 indra/newview/lldynamictexture.h              |   4 +-
 indra/newview/llface.cpp                      |  16 +-
 indra/newview/llface.h                        |   2 +-
 indra/newview/llface.inl                      |   1 +
 indra/newview/llfasttimerview.cpp             |  13 +-
 indra/newview/llfeaturemanager.cpp            |   2 -
 indra/newview/llfloateranimpreview.cpp        |   9 +-
 indra/newview/llfloaterauction.cpp            |   4 +-
 indra/newview/llfloaterbeacons.cpp            | 150 ++++++++
 indra/newview/llfloaterbeacons.h              |  56 +++
 indra/newview/llfloaterbuy.cpp                |  12 +-
 indra/newview/llfloaterbuy.h                  |   3 +-
 indra/newview/llfloatercolorpicker.cpp        |   6 +-
 indra/newview/llfloaterimagepreview.cpp       |  28 +-
 indra/newview/llfloaterjoystick.cpp           |   2 +-
 indra/newview/llfloaterland.cpp               |   2 +-
 indra/newview/llfloaterpostcard.cpp           |  12 +-
 indra/newview/llfloaterpreference.cpp         |   4 +-
 indra/newview/llfloatersnapshot.cpp           | 285 +++++++-------
 indra/newview/llfloatertopobjects.cpp         |   2 +-
 indra/newview/llfolderview.cpp                |   4 +-
 indra/newview/llglsandbox.cpp                 |  59 +--
 indra/newview/llhudeffectbeam.cpp             |   2 +-
 indra/newview/llhudeffectlookat.cpp           |   4 +-
 indra/newview/llhudeffectpointat.cpp          |   4 +-
 indra/newview/llhudicon.cpp                   |   6 +-
 indra/newview/llhudtext.cpp                   | 127 +++++-
 indra/newview/llhudtext.h                     |   2 +
 indra/newview/lljoystickbutton.cpp            |   4 +-
 indra/newview/llmanip.cpp                     |   8 +-
 indra/newview/llmaniprotate.cpp               |  12 +-
 indra/newview/llmanipscale.cpp                |  14 +-
 indra/newview/llmaniptranslate.cpp            |  44 +--
 indra/newview/llmemoryview.cpp                |   2 +-
 indra/newview/llnetmap.cpp                    |  20 +-
 indra/newview/llpanellogin.cpp                |   7 +-
 indra/newview/llpanelobject.cpp               |  14 +-
 indra/newview/llpolymesh.h                    |   2 +-
 indra/newview/llpreviewtexture.cpp            |  26 +-
 indra/newview/llprogressview.cpp              |   6 +-
 indra/newview/llselectmgr.cpp                 |   8 +-
 indra/newview/llsky.cpp                       |   6 +-
 indra/newview/llspatialpartition.cpp          |  77 ++--
 indra/newview/llspatialpartition.h            |   7 +
 indra/newview/llstartup.cpp                   |  20 +
 indra/newview/llsurface.cpp                   |   6 +-
 indra/newview/lltexlayer.cpp                  | 131 +++----
 indra/newview/lltexlayer.h                    |   4 +-
 indra/newview/lltexturectrl.cpp               |   4 +-
 indra/newview/lltextureview.cpp               |   4 +-
 indra/newview/lltool.cpp                      |   6 +
 indra/newview/lltoolbrush.cpp                 |   4 +-
 indra/newview/lltoolmorph.cpp                 |   7 +-
 indra/newview/lltoolselectrect.cpp            |   2 +-
 indra/newview/lltracker.cpp                   |   7 +-
 indra/newview/llviewerdisplay.cpp             |  24 +-
 indra/newview/llviewerjoint.cpp               |  71 +++-
 indra/newview/llviewerjointattachment.cpp     |   2 +-
 indra/newview/llviewerjointmesh.cpp           |  18 +-
 indra/newview/llviewermenu.cpp                | 189 +--------
 indra/newview/llviewermessage.cpp             |   4 +-
 indra/newview/llviewerobject.cpp              |  70 +++-
 indra/newview/llviewerobject.h                |  10 +-
 indra/newview/llviewerobjectlist.cpp          |  21 +-
 indra/newview/llviewerparcelmedia.cpp         |   2 +-
 indra/newview/llviewerparceloverlay.cpp       |   8 +-
 indra/newview/llviewerpartsim.cpp             |  22 +-
 indra/newview/llviewerpartsim.h               |   6 +-
 indra/newview/llviewerpartsource.cpp          |   9 +-
 indra/newview/llviewerregion.cpp              |  11 +
 indra/newview/llviewerregion.h                |   1 +
 indra/newview/llviewershadermgr.cpp           |  38 +-
 indra/newview/llviewerwindow.cpp              | 240 ++++++++----
 indra/newview/llviewerwindow.h                |   9 +
 indra/newview/llvoavatar.cpp                  | 138 +++++--
 indra/newview/llvoavatar.h                    |  10 +
 indra/newview/llvograss.cpp                   | 143 +++++++
 indra/newview/llvograss.h                     |  10 +
 indra/newview/llvoground.cpp                  |   2 +-
 indra/newview/llvoicevisualizer.cpp           |  17 +-
 indra/newview/llvopartgroup.cpp               |  45 ++-
 indra/newview/llvopartgroup.h                 |  17 +
 indra/newview/llvosky.cpp                     |   4 +-
 indra/newview/llvosurfacepatch.cpp            |  81 ++++
 indra/newview/llvosurfacepatch.h              |  10 +
 indra/newview/llvotree.cpp                    |  44 ++-
 indra/newview/llvotree.h                      |  11 +
 indra/newview/llvovolume.cpp                  | 109 ++++--
 indra/newview/llvovolume.h                    |   1 +
 indra/newview/llvowlsky.cpp                   |   6 +-
 indra/newview/llwaterparammanager.cpp         |  85 ++--
 indra/newview/llwaterparammanager.h           |   3 +-
 indra/newview/llwlparammanager.cpp            | 128 +++---
 indra/newview/llwlparammanager.h              |   3 +-
 indra/newview/llworld.cpp                     |   3 +-
 indra/newview/llworldmap.cpp                  |   5 +-
 indra/newview/llworldmapview.cpp              |  40 +-
 indra/newview/pipeline.cpp                    | 167 +++++---
 indra/newview/pipeline.h                      |   2 +
 .../default/xui/de/panel_preferences_chat.xml |   2 +-
 .../default/xui/fr/panel_preferences_chat.xml |   2 +-
 .../default/xui/ja/panel_preferences_chat.xml |   2 +-
 162 files changed, 3185 insertions(+), 1727 deletions(-)
 create mode 100644 indra/newview/llfloaterbeacons.cpp
 create mode 100644 indra/newview/llfloaterbeacons.h

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 488bacc8ed6..54aad6e1b19 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1,3 +1,4 @@
+
 Linden Lab would like to acknowledge source code contributions from the
 following residents.   The Second Life resident name is given below,
 along with the issue identifier corresponding to the patches we've
@@ -12,6 +13,7 @@ Able Whitman
 Adam Marker
 	VWR-2755
 Aimee Trescothick
+  VWR-3336
 	VWR-3903
 	VWR-4083
 	VWR-9255
@@ -59,6 +61,8 @@ Angus Boyd
 	VWR-592
 Argent Stonecutter
 	VWR-68
+Asuka Neely
+  VWR-3434
 Balp Allen
     VWR-4157
 Benja Kepler
@@ -191,6 +195,7 @@ Jacek Antonelli
 	VWR-3605
 JB Kraft
   VWR-5283
+  VWR-7802
 Joghert LeSabre
 	VWR-64
 Kage Pixel
@@ -208,13 +213,15 @@ Matthew Dowd
 	VWR-1761
 McCabe Maxsted
 	VWR-1318
-        VWR-7893
+	VWR-7893
+	VWR-8689
 Michelle2 Zenovka
 	VWR-2652
 	VWR-2834
 	VWR-3749
 	VWR-4022
 	VWR-4506
+	VWR-4981
 	VWR-7831
 	VWR-8889
 	VWR-8310
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index e92f04441c0..3538ad88ed0 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -165,6 +165,7 @@ class LLFastTimer
 		FTM_FILTER,
 		FTM_REFRESH,
 		FTM_SORT,
+		FTM_PICK,
 		
 		// Temp
 		FTM_TEMP1,
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 092eadd3034..27d69c453d7 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -33,8 +33,8 @@
 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 1;
-const S32 LL_VERSION_MINOR = 21;
-const S32 LL_VERSION_PATCH = 6;
+const S32 LL_VERSION_MINOR = 22;
+const S32 LL_VERSION_PATCH = 0;
 const S32 LL_VERSION_BUILD = 100000;
 
 const char * const LL_CHANNEL = "Second Life Release";
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 3607318d7f4..cd05350f831 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1398,7 +1398,7 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
 
 	// New Media Data
 	// Note: the message has been converted to TCP
-	if(msg->getNumberOfBlocks("MediaData") > 0)
+	if(msg->has("MediaData"))
 	{
 		msg->getString("MediaData", "MediaDesc", buffer);
 		setMediaDesc(buffer);
diff --git a/indra/llmessage/llpartdata.h b/indra/llmessage/llpartdata.h
index b16cdc5141c..b7fcb7429b9 100644
--- a/indra/llmessage/llpartdata.h
+++ b/indra/llmessage/llpartdata.h
@@ -114,6 +114,7 @@ class LLPartData
 		//LL_PART_TRAIL_MASK =			0x400,		// Particles have historical "trails"
 
 		// Viewer side use only!
+		LL_PART_HUD =					0x40000000,
 		LL_PART_DEAD_MASK =				0x80000000,
 	};
 
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index dd7818c4709..0e2a5cbf7fb 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -3956,22 +3956,27 @@ void LLMessageSystem::getString(const char *block, const char *var,
 				  blocknum);
 }
 
-S32	LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
+BOOL	LLMessageSystem::has(const char *blockname) const
+{
+	return getNumberOfBlocks(blockname) > 0;
+}
+
+S32	LLMessageSystem::getNumberOfBlocksFast(const char *blockname) const
 {
 	return mMessageReader->getNumberOfBlocks(blockname);
 }
 
-S32	LLMessageSystem::getNumberOfBlocks(const char *blockname)
+S32	LLMessageSystem::getNumberOfBlocks(const char *blockname) const
 {
 	return getNumberOfBlocksFast(LLMessageStringTable::getInstance()->getString(blockname));
 }
 	
-S32	LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
+S32	LLMessageSystem::getSizeFast(const char *blockname, const char *varname) const
 {
 	return mMessageReader->getSize(blockname, varname);
 }
 
-S32	LLMessageSystem::getSize(const char *blockname, const char *varname)
+S32	LLMessageSystem::getSize(const char *blockname, const char *varname) const
 {
 	return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), 
 					   LLMessageStringTable::getInstance()->getString(varname));
@@ -3979,13 +3984,13 @@ S32	LLMessageSystem::getSize(const char *blockname, const char *varname)
 	
 // size in bytes of variable length data
 S32	LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, 
-								 const char *varname)
+								 const char *varname) const
 {
 	return mMessageReader->getSize(blockname, blocknum, varname);
 }
 		
 S32	LLMessageSystem::getSize(const char *blockname, S32 blocknum, 
-							 const char *varname)
+							 const char *varname) const
 {
 	return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), blocknum, 
 					   LLMessageStringTable::getInstance()->getString(varname));
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index f4f3927f66b..46fa3251dee 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -594,13 +594,14 @@ class LLMessageSystem
 	LLHost	findHost(const U32 circuit_code);
 	void	sanityCheck();
 
-	S32		getNumberOfBlocksFast(const char *blockname);
-	S32		getNumberOfBlocks(const char *blockname);
-	S32		getSizeFast(const char *blockname, const char *varname);
-	S32		getSize(const char *blockname, const char *varname);
+	BOOL	has(const char *blockname) const;
+	S32		getNumberOfBlocksFast(const char *blockname) const;
+	S32		getNumberOfBlocks(const char *blockname) const;
+	S32		getSizeFast(const char *blockname, const char *varname) const;
+	S32		getSize(const char *blockname, const char *varname) const;
 	S32		getSizeFast(const char *blockname, S32 blocknum, 
-						const char *varname); // size in bytes of data
-	S32		getSize(const char *blockname, S32 blocknum, const char *varname);
+						const char *varname) const; // size in bytes of data
+	S32		getSize(const char *blockname, S32 blocknum, const char *varname) const;
 
 	void	resetReceiveCounts();				// resets receive counts for all message types to 0
 	void	dumpReceiveCounts();				// dumps receive count for each message type to llinfos
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index f19992eeabe..ba2846202fe 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -92,11 +92,11 @@ void LLCubeMap::initGL()
 			for (int i = 0; i < 6; i++)
 			{
 				mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
-				mImages[i]->setTarget(mTargets[i], GL_TEXTURE_CUBE_MAP_ARB);
+				mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
 				mRawImages[i] = new LLImageRaw(64, 64, 4);
 				mImages[i]->createGLTexture(0, mRawImages[i], texname);
 				
-				glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texname);
+				gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); 
 				mImages[i]->setClampCubemap (TRUE, TRUE, TRUE);
 				stop_glerror();
 			}
@@ -180,26 +180,7 @@ GLuint LLCubeMap::getGLName()
 
 void LLCubeMap::bind()
 {
-	if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
-	{
-		// We assume that if they have cube mapping, they have multitexturing.
-		if (mTextureStage > 0)
-		{
-			gGL.getTexUnit(mTextureStage)->activate();
-		}
-		glEnable(GL_TEXTURE_CUBE_MAP_ARB);
-		glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mImages[0]->getTexName());
-
-		mImages[0]->setMipFilterNearest (FALSE, FALSE);
-		if (mTextureStage > 0)
-		{
-			gGL.getTexUnit(0)->activate();
-		}
-	}
-	else
-	{
-		llwarns << "Using cube map without extension!" << llendl
-	}
+	gGL.getTexUnit(mTextureStage)->bind(this);
 }
 
 void LLCubeMap::enable(S32 stage)
@@ -213,17 +194,7 @@ void LLCubeMap::enableTexture(S32 stage)
 	mTextureStage = stage;
 	if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
-		if (stage > 0)
-		{
-			gGL.getTexUnit(stage)->activate();
-		}
-		
-		glEnable(GL_TEXTURE_CUBE_MAP_ARB);
-		
-		if (stage > 0)
-		{
-			gGL.getTexUnit(0)->activate();
-		}
+		gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
 	}
 }
 
@@ -262,15 +233,10 @@ void LLCubeMap::disableTexture(void)
 {
 	if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
 	{
-		if (mTextureStage > 0)
+		gGL.getTexUnit(mTextureStage)->disable();
+		if (mTextureStage == 0)
 		{
-			gGL.getTexUnit(mTextureStage)->activate();
-		}
-		glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
-		glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-		if (mTextureStage > 0)
-		{
-			gGL.getTexUnit(0)->activate();
+			gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 		}
 	}
 }
@@ -297,6 +263,8 @@ void LLCubeMap::setMatrix(S32 stage)
 {
 	mMatrixStage = stage;
 	
+	if (mMatrixStage < 0) return;
+	
 	if (stage > 0)
 	{
 		gGL.getTexUnit(stage)->activate();
@@ -324,6 +292,8 @@ void LLCubeMap::setMatrix(S32 stage)
 
 void LLCubeMap::restoreMatrix()
 {
+	if (mMatrixStage < 0) return;
+
 	if (mMatrixStage > 0)
 	{
 		gGL.getTexUnit(mMatrixStage)->activate();
@@ -340,7 +310,7 @@ void LLCubeMap::restoreMatrix()
 
 void LLCubeMap::setReflection (void)
 {
-	glBindTexture (GL_TEXTURE_CUBE_MAP_ARB, getGLName());
+	gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
 	mImages[0]->setMipFilterNearest (FALSE, FALSE);
 	mImages[0]->setClampCubemap (TRUE, TRUE);
 }
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index c273ab40ec7..2fc0f01b9a3 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -53,6 +53,7 @@ class LLCubeMap : public LLRefCount
 	
 	void enableTexture(S32 stage);
 	void enableTextureCoords(S32 stage);
+	S32	 getStage(void) { return mTextureStage; }
 	
 	void disable(void);
 	void disableTexture(void);
@@ -77,6 +78,7 @@ class LLCubeMap : public LLRefCount
 	static bool sUseCubeMaps;
 
 protected:
+	friend class LLTexUnit;
 	~LLCubeMap();
 	LLGLenum mTargets[6];
 	LLPointer<LLImageGL> mImages[6];
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 02e1663513d..bc4fc172aae 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -148,7 +148,7 @@ void LLFontGL::init()
 	{
 		mImageGLp = new LLImageGL(FALSE);
 		//RN: use nearest mipmap filtering to obviate the need to do pixel-accurate positioning
-		mImageGLp->bind();
+		gGL.getTexUnit(0)->bind(mImageGLp);
 		// we allow bilinear filtering to get sub-pixel positioning for drop shadows
 		//mImageGLp->setMipFilterNearest(TRUE, TRUE);
 	}
@@ -533,7 +533,7 @@ BOOL LLFontGL::loadFace(const std::string& filename,
 		return FALSE;
 	}
 	mImageGLp->createGLTexture(0, mRawImageGLp);
-	mImageGLp->bind();
+	gGL.getTexUnit(0)->bind(mImageGLp);
 	mImageGLp->setMipFilterNearest(TRUE, TRUE);
 	return TRUE;
 }
@@ -547,7 +547,7 @@ BOOL LLFontGL::addChar(const llwchar wch)
 
 	stop_glerror();
 	mImageGLp->setSubImage(mRawImageGLp, 0, 0, mImageGLp->getWidth(), mImageGLp->getHeight());
-	mImageGLp->bind();
+	gGL.getTexUnit(0)->bind(mImageGLp);
 	mImageGLp->setMipFilterNearest(TRUE, TRUE);
 	stop_glerror();
 	return TRUE;
@@ -583,7 +583,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 		return wstr.length() ;
 	}
 
-	LLGLEnable tex(GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 	if (wstr.empty())
 	{
@@ -663,7 +663,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 
 	// Bind the font texture
 	
-	mImageGLp->bind(0);
+	gGL.getTexUnit(0)->bind(mImageGLp);
 	
  	// Not guaranteed to be set correctly
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -761,7 +761,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 				break;
 			}
 
-			ext_image->bind();
+			gGL.getTexUnit(0)->bind(ext_image);
 			const F32 ext_x = cur_render_x + (EXT_X_BEARING * sScaleX);
 			const F32 ext_y = cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight);
 
@@ -795,7 +795,7 @@ S32 LLFontGL::render(const LLWString &wstr,
 			cur_render_x = cur_x;
 
 			// Bind the font texture
-			mImageGLp->bind();
+			gGL.getTexUnit(0)->bind(mImageGLp);
 		}
 		else
 		{
@@ -863,8 +863,8 @@ S32 LLFontGL::render(const LLWString &wstr,
 
 	if (style & UNDERLINE)
 	{
-		LLGLSNoTexture no_texture;
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.begin(LLRender::LINES);
 		gGL.vertex2f(start_x, cur_y - (mDescender));
 		gGL.vertex2f(cur_x, cur_y - (mDescender));
 		gGL.end();
@@ -1359,7 +1359,7 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con
 	F32 slant_offset;
 	slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		//FIXME: bold and drop shadow are mutually exclusive only for convenience
 		//Allow both when we need them.
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 570a0cbed1b..fa763bf2f85 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -960,7 +960,8 @@ void assert_glerror()
 		GLubyte const * gl_error_msg = gluErrorString(error);
 		if (NULL != gl_error_msg)
 		{
-			LL_WARNS("RenderState") << "GL Error:" << gl_error_msg << LL_ENDL;
+			LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
+			LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
 		}
 		else
 		{
@@ -1001,7 +1002,7 @@ GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
 void LLGLState::initClass() 
 {
 	sStateMap[GL_DITHER] = GL_TRUE;
-	sStateMap[GL_TEXTURE_2D] = GL_TRUE;
+	// sStateMap[GL_TEXTURE_2D] = GL_TRUE;
 
 	//make sure multisample defaults to disabled
 	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
@@ -1030,7 +1031,7 @@ void LLGLState::resetTextureStates()
 	{
 		gGL.getTexUnit(j)->activate();
 		glClientActiveTextureARB(GL_TEXTURE0_ARB+j);
-		j == 0 ? glEnable(GL_TEXTURE_2D) : glDisable(GL_TEXTURE_2D);
+		j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
 	}
 }
 
@@ -1053,14 +1054,6 @@ void LLGLState::checkStates(const std::string& msg)
 
 	stop_glerror();
 
-	GLint activeTexture;
-	glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
-	
-	if (activeTexture != GL_TEXTURE0_ARB)
-	{
-		LL_GL_ERRS << "Texture channel corrupted. " << LL_ENDL;
-	}
-	
 	GLint src;
 	GLint dst;
 	glGetIntegerv(GL_BLEND_SRC, &src);
@@ -1099,17 +1092,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
 	
 	BOOL error = FALSE;
 
-	if (activeTexture != GL_TEXTURE0_ARB)
-	{
-		error = TRUE;
- 		LL_WARNS("RenderState") << "Active texture channel corrupted. " << LL_ENDL;
-	}
-	else if (!glIsEnabled(GL_TEXTURE_2D))
-	{
-		error = TRUE;
-		LL_WARNS("RenderState") << "GL_TEXTURE_2D not enabled on texture channel 0." << LL_ENDL;
-	}
-	else 
+	if (activeTexture == GL_TEXTURE0_ARB)
 	{
 		GLint tex_env_mode = 0;
 
@@ -1152,7 +1135,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
 	LLMatrix4 identity;
 	LLMatrix4 matrix;
 
-	for (GLint i = 0; i < maxTextureUnits; i++)
+	for (GLint i = 1; i < maxTextureUnits; i++)
 	{
 		gGL.getTexUnit(i)->activate();
 		glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 7b039449188..1c0fbf477d0 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -365,7 +365,7 @@ void LLGLSLShader::bindNoShader(void)
 	glUseProgramObjectARB(0);
 }
 
-S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
+S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
 {
 	if (uniform < 0 || uniform >= (S32)mTexture.size())
 	{
@@ -376,12 +376,12 @@ S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
 	if (index != -1)
 	{
 		gGL.getTexUnit(index)->activate();
-		glEnable(mode);
+		gGL.getTexUnit(index)->enable(mode);
 	}
 	return index;
 }
 
-S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
+S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
 {
 	if (uniform < 0 || uniform >= (S32)mTexture.size())
 	{
@@ -392,7 +392,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
 	if (index != -1)
 	{
 		gGL.getTexUnit(index)->activate();
-		glDisable(mode);
+		gGL.getTexUnit(index)->disable();
 	}
 	return index;
 }
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index c78188ba871..75448191bfc 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -33,6 +33,7 @@
 #define LL_LLGLSLSHADER_H
 
 #include "llgl.h"
+#include "llrender.h"
 
 class LLShaderFeatures
 {
@@ -111,8 +112,8 @@ class LLGLSLShader
 	//if given texture uniform is active in the shader, 
 	//the corresponding channel will be active upon return
 	//returns channel texture is enabled in from [0-MAX)
-	S32 enableTexture(S32 uniform, S32 mode = GL_TEXTURE_2D);
-	S32 disableTexture(S32 uniform, S32 mode = GL_TEXTURE_2D); 
+	S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+	S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE); 
 	
     BOOL link(BOOL suppress_errors = FALSE);
 	void bind();
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 907e4ee2e69..88b4e914256 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -87,13 +87,6 @@ class LLGLSDefault
 	{ }
 };
 
-class LLGLSNoTexture 
-{
-public:
-	LLGLSNoTexture()
-	{ LLImageGL::unbindTexture(0); }
-};
-
 class LLGLSObjectSelect
 { 
 protected:
@@ -104,7 +97,7 @@ class LLGLSObjectSelect
 		: mBlend(GL_BLEND), mFog(GL_FOG), 
 		  mAlphaTest(GL_ALPHA_TEST),
 		  mCullFace(GL_CULL_FACE)
-	{ LLImageGL::unbindTexture(0); }
+	{ }
 };
 
 class LLGLSObjectSelectAlpha
@@ -143,17 +136,6 @@ class LLGLSNoAlphaTest // : public LLGLSUIDefault
 	{}
 };
 
-class LLGLSNoTextureNoAlphaTest // : public LLGLSUIDefault
-{
-protected:
-	LLGLDisable mAlphaTest;
-public:
-	LLGLSNoTextureNoAlphaTest()
-		: mAlphaTest(GL_ALPHA_TEST)
-		  
-	{ LLImageGL::unbindTexture(0); }
-};
-
 //----------------------------------------------------------------------------
 
 class LLGLSFog
@@ -251,7 +233,7 @@ class LLGLSTracker
 		mBlend(GL_BLEND),
 		mAlphaTest(GL_ALPHA_TEST)
 		
-	{ LLImageGL::unbindTexture(0); }
+	{ }
 };
 
 //----------------------------------------------------------------------------
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 1c9b4d96939..2ef2bae1ab1 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -124,49 +124,6 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
 
 //----------------------------------------------------------------------------
 
-// static
-void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_target )
-{
-	gGL.flush();
-	if (stage > 0)
-	{
-		gGL.getTexUnit(stage)->activate();
-	}
-	glBindTexture(bind_target, gl_name);
-	sCurrentBoundTextures[stage] = gl_name;
-	if (stage > 0)
-	{
-		gGL.getTexUnit(0)->activate();
-	}
-}
-
-// static
-void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target)
-{
-	// LLGLSLShader can return -1
-	if (stage >= 0)
-	{
-		gGL.flush();
-		if (stage > 0)
-		{
-			gGL.getTexUnit(stage)->activate();
-			glBindTexture(GL_TEXTURE_2D, 0);
-			gGL.getTexUnit(0)->activate();
-		}
-		else
-		{
-			glBindTexture(GL_TEXTURE_2D, 0);
-		}
-		sCurrentBoundTextures[stage] = 0;
-	}
-}
-
-// static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency)
-void LLImageGL::unbindTexture(S32 stage)
-{
-	unbindTexture(stage, GL_TEXTURE_2D);
-}
-
 // static
 void LLImageGL::updateStats(F32 current_time)
 {
@@ -189,7 +146,7 @@ void LLImageGL::destroyGL(BOOL save_state)
 {
 	for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++)
 	{
-		LLImageGL::unbindTexture(stage, GL_TEXTURE_2D);
+		gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 	for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
 		 iter != sImageList.end(); iter++)
@@ -284,6 +241,8 @@ LLImageGL::~LLImageGL()
 {
 	LLImageGL::cleanup();
 	sImageList.erase(this);
+	delete [] mPickMask;
+	mPickMask = NULL;
 	sCount--;
 }
 
@@ -293,11 +252,12 @@ void LLImageGL::init(BOOL usemipmaps)
 	mMissed				= FALSE;
 #endif
 
+	mPickMask		  = NULL;
 	mTextureMemory    = 0;
 	mLastBindTime     = 0.f;
 
 	mTarget			  = GL_TEXTURE_2D;
-	mBindTarget		  = GL_TEXTURE_2D;
+	mBindTarget		  = LLTexUnit::TT_TEXTURE;
 	mUseMipMaps		  = usemipmaps;
 	mHasMipMaps		  = FALSE;
 	mAutoGenMips	  = FALSE;
@@ -321,6 +281,8 @@ void LLImageGL::init(BOOL usemipmaps)
 	mFormatType = GL_UNSIGNED_BYTE;
 	mFormatSwapBytes = FALSE;
 	mHasExplicitFormat = FALSE;
+
+	mInitialized = true;
 }
 
 void LLImageGL::cleanup()
@@ -421,41 +383,14 @@ void LLImageGL::dump()
 
 //----------------------------------------------------------------------------
 
-BOOL LLImageGL::bindTextureInternal(const S32 stage) const
+void LLImageGL::updateBindStats(void) const
 {	
-	if (gGLManager.mIsDisabled)
-	{
-		llwarns << "Trying to bind a texture while GL is disabled!" << llendl;
-	}
-
-
-	if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName)
-	{
-		// already set!
-		return TRUE;
-	}
-
 	if (mTexName != 0)
 	{
 #ifdef DEBUG_MISS
 		mMissed = ! getIsResident(TRUE);
 #endif
-
-		gGL.flush();
-		if (stage > 0)
-		{
-			gGL.getTexUnit(stage)->activate();
-		}
-	
-		glBindTexture(mBindTarget, mTexName);
-		sCurrentBoundTextures[stage] = mTexName;
 		sBindCount++;
-
-		if (stage > 0)
-		{
-			gGL.getTexUnit(0)->activate();
-		}
-		
 		if (mLastBindTime != sLastFrameTime)
 		{
 			// we haven't accounted for this texture yet this frame
@@ -463,38 +398,22 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
 			updateBoundTexMem(mTextureMemory);
 			mLastBindTime = sLastFrameTime;
 		}
-		
-		return TRUE;
-	}
-	else
-	{
-		gGL.flush();
-		if (stage > 0)
-		{
-			gGL.getTexUnit(stage)->activate();
-		}
-		glBindTexture(mBindTarget, 0);
-		if (stage > 0)
-		{
-			gGL.getTexUnit(0)->activate();
-		}
-		sCurrentBoundTextures[stage] = 0;
-		return FALSE;
 	}
 }
 
 //virtual
-BOOL LLImageGL::bind(const S32 stage) const
+bool LLImageGL::bindError(const S32 stage) const
 {
-	if (stage == -1)
-	{
-		return FALSE;
-	}
-	BOOL res = bindTextureInternal(stage);
-	//llassert(res);
-	return res;
+	return false;
+}
+
+//virtual
+bool LLImageGL::bindDefaultImage(const S32 stage) const
+{
+	return false;
 }
 
+
 void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
 {
 	// Note: must be called before createTexture()
@@ -532,7 +451,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 
 	{
 // 		LLFastTimer t2(LLFastTimer::FTM_TEMP2);
-		llverify(bindTextureInternal(0));
+		llverify(gGL.getTexUnit(0)->bind(this));
 	}
 	
 	if (mUseMipMaps)
@@ -569,7 +488,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 					}
 						
 					glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
-					
+					updatePickMask(w, h, data_in);
+
 					if(mFormatSwapBytes)
 					{
 						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
@@ -585,7 +505,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		{
 			if (mAutoGenMips)
 			{
-				glTexParameteri(mBindTarget, GL_GENERATE_MIPMAP_SGIS, TRUE);
+				glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
 				stop_glerror();
 				{
 // 					LLFastTimer t2(LLFastTimer::FTM_TEMP4);
@@ -596,12 +516,17 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						stop_glerror();
 					}
 
+					S32 w = getWidth(mCurrentDiscardLevel);
+					S32 h = getHeight(mCurrentDiscardLevel);
+
 					glTexImage2D(mTarget, 0, mFormatInternal,
-								 getWidth(mCurrentDiscardLevel), getHeight(mCurrentDiscardLevel), 0,
+								 w, h, 0,
 								 mFormatPrimary, mFormatType,
 								 data_in);
 					stop_glerror();
 
+					updatePickMask(w, h, data_in);
+
 					if(mFormatSwapBytes)
 					{
 						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
@@ -651,6 +576,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 
 						glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data);
 						stop_glerror();
+						if (m == 0)
+						{
+							updatePickMask(w, h, cur_mip_data);
+						}
 
 						if(mFormatSwapBytes)
 						{
@@ -701,6 +630,8 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 
 			glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0,
 						 mFormatPrimary, mFormatType, (GLvoid *)data_in);
+			updatePickMask(w, h, data_in);
+
 			stop_glerror();
 
 			if(mFormatSwapBytes)
@@ -713,6 +644,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 		mHasMipMaps = FALSE;
 	}
 	stop_glerror();
+	mInitialized = true;
 }
 
 BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
@@ -786,12 +718,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
 
 		datap += (y_pos * data_width + x_pos) * getComponents();
 		// Update the GL texture
-		BOOL res = bindTextureInternal(0);
+		BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
 		if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
 		stop_glerror();
 
-		LLGLEnable tex( GL_TEXTURE_2D ); 
-
 		glTexSubImage2D(mTarget, 0, x_pos, y_pos, 
 						width, height, mFormatPrimary, mFormatType, datap);
 		stop_glerror();
@@ -804,6 +734,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
 
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 		stop_glerror();
+		mInitialized = true;
 	}
 	
 	return TRUE;
@@ -817,9 +748,10 @@ BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S3
 // Copy sub image from frame buffer
 BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
 {
-	if (bindTextureInternal(0))
+	if (gGL.getTexUnit(0)->bind(this))
 	{
 		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
+		mInitialized = true;
 		stop_glerror();
 		return TRUE;
 	}
@@ -919,9 +851,9 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 		stop_glerror();
 		{
 // 			LLFastTimer t1(LLFastTimer::FTM_TEMP6);
-			llverify(bindTextureInternal(0));
-			glTexParameteri(mBindTarget, GL_TEXTURE_BASE_LEVEL, 0);
-			glTexParameteri(mBindTarget, GL_TEXTURE_MAX_LEVEL,  mMaxDiscardLevel-discard_level);
+			llverify(gGL.getTexUnit(0)->bind(this));
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL,  mMaxDiscardLevel-discard_level);
 		}
 	}
 	if (!mTexName)
@@ -949,7 +881,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 	setMipFilterNearest(mMagFilterNearest);
 	
 	// things will break if we don't unbind after creation
-	unbindTexture(0, mBindTarget);
+	gGL.getTexUnit(0)->unbind(mBindTarget);
 	stop_glerror();
 
 	if (old_name != 0)
@@ -1050,8 +982,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
 	S32 gl_discard = discard_level - mCurrentDiscardLevel;
 
 	//explicitly unbind texture 
-	LLImageGL::unbindTexture(0, mTarget);
-	llverify(bindTextureInternal(0));	
+	gGL.getTexUnit(0)->unbind(mBindTarget);
+	llverify(gGL.getTexUnit(0)->bind(this));	
 
 	if (gDebugGL)
 	{
@@ -1148,15 +1080,15 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
 
 void LLImageGL::destroyGLTexture()
 {
-	stop_glerror();
-
 	if (mTexName != 0)
 	{
+		stop_glerror();
+
 		for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
 		{
 			if (sCurrentBoundTextures[i] == mTexName)
 			{
-				unbindTexture(i, GL_TEXTURE_2D);
+				gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
 				stop_glerror();
 			}
 		}
@@ -1184,8 +1116,8 @@ void LLImageGL::glClamp (BOOL clamps, BOOL clampt)
 {
 	if (mTexName != 0)
 	{
-		glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
-		glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT);
+		glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
+		glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT);
 	}
 }
 
@@ -1223,23 +1155,23 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
 	{
 		if (mMinFilterNearest)
 		{
-			glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 		}
 		else if (mHasMipMaps)
 		{
-			glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 		}
 		else
 		{
-			glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		}
 		if (mMagFilterNearest)
 		{
-			glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 		}
 		else 
 		{
-			glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+			glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 		}
 		if (gGLManager.mHasAnisotropic)
 		{
@@ -1247,16 +1179,15 @@ void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest)
 			{
 				F32 largest_anisotropy;
 				glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy);
-				glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy);
+				glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy);
 			}
 			else
 			{
-				glTexParameterf(mBindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
+				glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
 			}
 		}
-	}
-	
-	stop_glerror();
+		stop_glerror();
+	}	
 }
 
 BOOL LLImageGL::getIsResident(BOOL test_now)
@@ -1337,14 +1268,93 @@ BOOL LLImageGL::getBoundRecently() const
 	return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
 }
 
-void LLImageGL::setTarget(const LLGLenum target, const LLGLenum bind_target)
+void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
 {
 	mTarget = target;
 	mBindTarget = bind_target;
 }
 
+void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
+{
+	if (mFormatType != GL_UNSIGNED_BYTE ||
+		mFormatPrimary != GL_RGBA)
+	{
+		//cannot generate a pick mask for this texture
+		delete [] mPickMask;
+		mPickMask = NULL;
+		return;
+	}
+
+	U32 pick_width = width/2;
+	U32 pick_height = height/2;
+
+	U32 size = llmax(pick_width, (U32) 1) * llmax(pick_height, (U32) 1);
+
+	size = size/8 + 1;
+
+	delete[] mPickMask;
+	mPickMask = new U8[size];
+
+	memset(mPickMask, 0, sizeof(U8) * size);
+
+	U32 pick_bit = 0;
+	
+	for (S32 y = 0; y < height; y += 2)
+	{
+		for (S32 x = 0; x < width; x += 2)
+		{
+			U8 alpha = data_in[(y*width+x)*4+3];
+
+			if (alpha > 32)
+			{
+				U32 pick_idx = pick_bit/8;
+				U32 pick_offset = pick_bit%8;
+				if (pick_idx >= size)
+				{
+					llerrs << "WTF?" << llendl;
+				}
+
+				mPickMask[pick_idx] |= 1 << pick_offset;
+			}
+			
+			++pick_bit;
+		}
+	}
+}
+
+BOOL LLImageGL::getMask(const LLVector2 &tc)
+{
+	BOOL res = TRUE;
+
+	if (mPickMask)
+	{
+		S32 width = getWidth()/2;
+		S32 height = getHeight()/2;
+
+		F32 u = tc.mV[0] - floorf(tc.mV[0]);
+		F32 v = tc.mV[1] - floorf(tc.mV[1]);
+
+		if (u < 0.f || u > 1.f ||
+		    v < 0.f || v > 1.f)
+		{
+			llerrs << "WTF?" << llendl;
+		}
+		
+		S32 x = (S32)(u * width);
+		S32 y = (S32)(v * height);
+
+		S32 idx = y*width+x;
+		S32 offset = idx%8;
+
+		res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
+	}
+	
+	return res;
+}
+
 //----------------------------------------------------------------------------
 
+
 // Manual Mip Generation
 /*
 		S32 width = getWidth(discard_level);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 8aeecb36278..35a98b88fab 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -37,6 +37,9 @@
 
 #include "llgltypes.h"
 #include "llmemory.h"
+#include "v2math.h"
+
+#include "llrender.h"
 
 //============================================================================
 
@@ -48,11 +51,7 @@ class LLImageGL : public LLRefCount
 	static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
 	static S32 dataFormatComponents(S32 dataformat);
 
-	// Wrapper for glBindTexture that keeps LLImageGL in sync.
-	// Usually you want stage = 0 and bind_target = GL_TEXTURE_2D
-	static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target);
-	static void unbindTexture(S32 stage, LLGLenum target);
-	static void unbindTexture(S32 stage); // Uses GL_TEXTURE_2D (not a default arg to avoid gl.h dependency)
+	void updateBindStats(void) const;
 
 	// needs to be called every frame
 	static void updateStats(F32 current_time);
@@ -79,7 +78,6 @@ class LLImageGL : public LLRefCount
 	
 protected:
 	virtual ~LLImageGL();
-	BOOL bindTextureInternal(const S32 stage = 0) const;
 
 private:
 	void glClamp (BOOL clamps, BOOL clampt);
@@ -87,7 +85,8 @@ class LLImageGL : public LLRefCount
 
 public:
 	virtual void dump();	// debugging info to llinfos
-	virtual BOOL bind(const S32 stage = 0) const;
+	virtual bool bindError(const S32 stage = 0) const;
+	virtual bool bindDefaultImage(const S32 stage = 0) const;
 
 	void setSize(S32 width, S32 height, S32 ncomponents);
 
@@ -132,7 +131,11 @@ class LLImageGL : public LLRefCount
 
 	BOOL getIsResident(BOOL test_now = FALSE); // not const
 
-	void setTarget(const LLGLenum target, const LLGLenum bind_target);
+	void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
+
+	LLTexUnit::eTextureType getTarget(void) const { return mBindTarget; }
+	bool isInitialized(void) const { return mInitialized; }
+	void setInitialized (bool initialized) { mInitialized = initialized; }
 
 	BOOL getUseMipMaps() const { return mUseMipMaps; }
 	void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
@@ -141,6 +144,9 @@ class LLImageGL : public LLRefCount
 
 	BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
 
+	void updatePickMask(S32 width, S32 height, const U8* data_in);
+	BOOL getMask(const LLVector2 &tc);
+
 protected:
 	void init(BOOL usemipmaps);
 	virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized.  Be careful when using this in derived class destructors
@@ -152,6 +158,7 @@ class LLImageGL : public LLRefCount
 
 private:
 	LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
+	U8* mPickMask;  //downsampled bitmap approximation of alpha channel.  NULL if no alpha channel
 	S8 mUseMipMaps;
 	S8 mHasMipMaps;
 	S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
@@ -159,7 +166,8 @@ class LLImageGL : public LLRefCount
 	
 protected:
 	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
-	LLGLenum mBindTarget;	// NOrmally GL_TEXTURE2D, sometimes something else (ex. cube maps)
+	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps)
+	bool mInitialized;
 
 	LLGLuint mTexName;
 
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index 7c14b57fff8..3c1d8d3f173 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -220,9 +220,9 @@ void LLPostProcess::applyColorFilterShader(void)
 	gPostColorFilterProgram.bind();
 
 	gGL.getTexUnit(0)->activate();
-	glEnable(GL_TEXTURE_RECTANGLE_ARB);	
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
 
-	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
 
 	getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject);
 	glUniform1iARB(colorFilterUniforms["RenderTexture"], 0);
@@ -264,16 +264,16 @@ void LLPostProcess::applyNightVisionShader(void)
 	gPostNightVisionProgram.bind();
 
 	gGL.getTexUnit(0)->activate();
-	glEnable(GL_TEXTURE_RECTANGLE_ARB);	
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
 
 	getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject);
-	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, sceneRenderTexture);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture);
 	glUniform1iARB(nightVisionUniforms["RenderTexture"], 0);
 
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D);	
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);	
 
-	glBindTexture(GL_TEXTURE_2D, noiseTexture);
+	gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture);
 	glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1);
 
 	
@@ -373,7 +373,7 @@ void LLPostProcess::doEffects(void)
 
 void LLPostProcess::copyFrameBuffer(GLuint & texture, unsigned int width, unsigned int height)
 {
-	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
 	glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0);
 }
 
@@ -487,7 +487,7 @@ void LLPostProcess::createTexture(GLuint & texture, unsigned int width, unsigned
 	std::vector<GLubyte> data(width * height * 4, 0);
 
 	glGenTextures(1, &texture);
-	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture);
 	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0,
 		GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
 	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
@@ -509,7 +509,7 @@ void LLPostProcess::createNoiseTexture(GLuint & texture)
 			buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
 		}
 	}
-	glBindTexture(GL_TEXTURE_2D, texture);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture);
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 9b116d6410d..969bfe608ee 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -32,7 +32,11 @@
 #include "linden_common.h"
 
 #include "llrender.h"
+
 #include "llvertexbuffer.h"
+#include "llcubemap.h"
+#include "llimagegl.h"
+#include "llrendertarget.h"
 
 LLRender gGL;
 
@@ -44,6 +48,20 @@ S32	gGLViewport[4];
 
 static const U32 LL_NUM_TEXTURE_LAYERS = 8; 
 
+static GLenum sGLTextureType[] =
+{
+	GL_TEXTURE_2D,
+	GL_TEXTURE_RECTANGLE_ARB,
+	GL_TEXTURE_CUBE_MAP_ARB
+};
+
+static GLint sGLAddressMode[] =
+{	
+	GL_REPEAT,
+	GL_MIRRORED_REPEAT,
+	GL_CLAMP_TO_EDGE
+};
+
 static GLenum sGLCompareFunc[] =
 {
 	GL_NEVER,
@@ -72,82 +90,217 @@ static GLenum sGLBlendFactor[] =
 	GL_ONE_MINUS_SRC_ALPHA
 };
 
-LLTexUnit::LLTexUnit(U32 index)
-: mIsEnabled(false), mCurrBlendType(TB_MULT), 
+LLTexUnit::LLTexUnit(S32 index)
+: mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT), 
 mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
 mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
 mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
-mCurrColorScale(1), mCurrAlphaScale(1)
+mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0)
 {
 	llassert_always(index < LL_NUM_TEXTURE_LAYERS);
 	mIndex = index;
 }
 
-U32 LLTexUnit::getIndex(void)
+//static
+U32 LLTexUnit::getInternalType(eTextureType type)
 {
-	return mIndex;
+	return sGLTextureType[type];
 }
 
-void LLTexUnit::enable(void)
+void LLTexUnit::refreshState(void)
 {
-	if (!mIsEnabled)
+	// We set dirty to true so that the tex unit knows to ignore caching
+	// and we reset the cached tex unit state
+
+	glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+	if (mCurrTexType != TT_NONE)
 	{
-		activate();
-		glEnable(GL_TEXTURE_2D);
-		mIsEnabled = true;
+		glEnable(sGLTextureType[mCurrTexType]);
+		glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
 	}
-}
-
-void LLTexUnit::disable(void)
-{
-	if (mIsEnabled)
+	else
 	{
-		activate();
 		glDisable(GL_TEXTURE_2D);
-		mIsEnabled = false;
+		glBindTexture(GL_TEXTURE_2D, 0);	
+	}
+
+	if (mCurrBlendType != TB_COMBINE)
+	{
+		setTextureBlendType(mCurrBlendType);
+	}
+	else
+	{
+		setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
+		setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
 	}
 }
 
 void LLTexUnit::activate(void)
 {
-	//if (gGL.mCurrTextureUnitIndex != mIndex)
+	if (mIndex < 0) return;
+
+	if (gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
 	{
 		glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
 		gGL.mCurrTextureUnitIndex = mIndex;
 	}
 }
 
-// Useful for debugging that you've manually assigned a texture operation to the correct 
-// texture unit based on the currently set active texture in opengl.
-void LLTexUnit::debugTextureUnit(void)
+void LLTexUnit::enable(eTextureType type)
 {
-	GLint activeTexture;
-	glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
-	if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
+	if (mIndex < 0) return;
+
+	if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
+	{
+		activate();
+		if (mCurrTexType != TT_NONE && !gGL.mDirty)
+		{
+			disable(); // Force a disable of a previous texture type if it's enabled.
+		}
+		mCurrTexType = type;
+		glEnable(sGLTextureType[type]);
+	}
+}
+
+void LLTexUnit::disable(void)
+{
+	if (mIndex < 0) return;
+
+	if (mCurrTexType != TT_NONE)
 	{
-		llerrs << "Incorrect Texture Unit!  Expected: " << (activeTexture - GL_TEXTURE0_ARB) << " Actual: " << mIndex << llendl;
+		activate();
+		unbind(mCurrTexType);
+		glDisable(sGLTextureType[mCurrTexType]);
+		mCurrTexType = TT_NONE;
 	}
 }
 
-void LLTexUnit::bindTexture(const LLImageGL* texture)
+bool LLTexUnit::bind(const LLImageGL* texture)
 {
+	if (mIndex < 0) return false;
+
+	gGL.flush();
+
+	if (texture == NULL)
+	{
+		return texture->bindError(mIndex);
+	}
+
+	if (!texture->isInitialized())
+	{
+		return texture->bindDefaultImage(mIndex);
+	}
+
+	// Disabled caching of binding state.
 	if (texture != NULL)
 	{
 		activate();
-		texture->bind(mIndex);
+		enable(texture->getTarget());
+		mCurrTexture = texture->getTexName();
+		glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
+		texture->updateBindStats();
+		return true;
 	}
+	return false;
 }
 
-void LLTexUnit::unbindTexture(void)
+bool LLTexUnit::bind(LLCubeMap* cubeMap)
 {
+	if (mIndex < 0) return false;
+
+	gGL.flush();
+
+	// Disabled caching of binding state.
+	if (cubeMap != NULL)
+	{
+		if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+		{
+			activate();
+			enable(LLTexUnit::TT_CUBE_MAP);
+			mCurrTexture = cubeMap->mImages[0]->getTexName();
+			glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
+			cubeMap->mImages[0]->updateBindStats();
+			cubeMap->mImages[0]->setMipFilterNearest (FALSE, FALSE);
+			return true;
+		}
+		else
+		{
+			llwarns << "Using cube map without extension!" << llendl
+		}
+	}
+	return false;
+}
+
+bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
+{
+	if (mIndex < 0) return false;
+
+	gGL.flush();
+
+	if (bindDepth)
+	{
+		bindManual(renderTarget->getUsage(), renderTarget->getDepth());
+	}
+	else
+	{
+		bindManual(renderTarget->getUsage(), renderTarget->getTexture());
+	}
+
+	return true;
+}
+
+bool LLTexUnit::bindManual(eTextureType type, U32 texture)
+{
+	if (mIndex < 0) return false;
+
+	// Disabled caching of binding state.
+	gGL.flush();
+	
 	activate();
-	glBindTexture(GL_TEXTURE_2D, 0);
+	enable(type);
+	mCurrTexture = texture;
+	glBindTexture(sGLTextureType[type], texture);
+	return true;
+}
+
+void LLTexUnit::unbind(eTextureType type)
+{
+	if (mIndex < 0) return;
+
+	// Disabled caching of binding state.
+	if (mCurrTexType == type)
+	{
+		gGL.flush();
+
+		activate();
+		mCurrTexture = 0;
+		glBindTexture(sGLTextureType[type], 0);
+	}
+}
+
+void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
+{
+	if (mIndex < 0) return;
+
+	if (true)
+	{
+		activate();
+
+		glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
+		glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
+		if (mCurrTexType == TT_CUBE_MAP)
+		{
+			glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
+		}
+	}
 }
 
 void LLTexUnit::setTextureBlendType(eTextureBlendType type)
 {
+	if (mIndex < 0) return;
+
 	// Do nothing if it's already correctly set.
-	if (mCurrBlendType == type)
+	if (mCurrBlendType == type && !gGL.mDirty)
 	{
 		return;
 	}
@@ -262,16 +415,18 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
 
 void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
 {
+	if (mIndex < 0) return;
+
 	activate();
-	if (mCurrBlendType != TB_COMBINE)
+	if (mCurrBlendType != TB_COMBINE || gGL.mDirty)
 	{
 		mCurrBlendType = TB_COMBINE;
 		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
 	}
 
 	// We want an early out, because this function does a LOT of stuff.
-	if ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2) )
-		|| (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2) ))
+	if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
+			|| (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
 	{
 		return;
 	}
@@ -304,7 +459,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
 	}
 	else 
 	{
-		// Set enums to ALPHA ones
+		// Set enums to RGB ones
 		comb_enum = GL_COMBINE_RGB_ARB;
 		src0_enum = GL_SOURCE0_RGB_ARB;
 		src1_enum = GL_SOURCE1_RGB_ARB;
@@ -405,7 +560,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
 
 void LLTexUnit::setColorScale(S32 scale)
 {
-	if (mCurrColorScale != scale)
+	if (mCurrColorScale != scale || gGL.mDirty)
 	{
 		mCurrColorScale = scale;
 		glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
@@ -414,27 +569,52 @@ void LLTexUnit::setColorScale(S32 scale)
 
 void LLTexUnit::setAlphaScale(S32 scale)
 {
-	if (mCurrAlphaScale != scale)
+	if (mCurrAlphaScale != scale || gGL.mDirty)
 	{
 		mCurrAlphaScale = scale;
 		glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
 	}
 }
 
+// Useful for debugging that you've manually assigned a texture operation to the correct 
+// texture unit based on the currently set active texture in opengl.
+void LLTexUnit::debugTextureUnit(void)
+{
+	if (mIndex < 0) return;
+
+	GLint activeTexture;
+	glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
+	if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
+	{
+		U32 set_unit = (activeTexture - GL_TEXTURE0_ARB);
+		llwarns << "Incorrect Texture Unit!  Expected: " << set_unit << " Actual: " << mIndex << llendl;
+	}
+}
+
+
 LLRender::LLRender()
+: mDirty(false), mCount(0), mMode(LLRender::TRIANGLES)
 {
-	mCount = 0;
-	mMode = LLVertexBuffer::TRIANGLES;
 	mBuffer = new LLVertexBuffer(immediate_mask, 0);
 	mBuffer->allocateBuffer(4096, 0, TRUE);
 	mBuffer->getVertexStrider(mVerticesp);
 	mBuffer->getTexCoordStrider(mTexcoordsp);
 	mBuffer->getColorStrider(mColorsp);
-
-	for (unsigned int i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
+	
+	mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
+	for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
 	{
 		mTexUnits.push_back(new LLTexUnit(i));
 	}
+	mDummyTexUnit = new LLTexUnit(-1);
+
+	for (U32 i = 0; i < 4; i++)
+	{
+		mCurrColorMask[i] = true;
+	}
+
+	mCurrAlphaFunc = CF_DEFAULT;
+	mCurrAlphaFuncVal = 0.01f;
 }
 
 LLRender::~LLRender()
@@ -449,6 +629,28 @@ void LLRender::shutdown()
 		delete mTexUnits[i];
 	}
 	mTexUnits.clear();
+	delete mDummyTexUnit;
+	mDummyTexUnit = NULL;
+}
+
+void LLRender::refreshState(void)
+{
+	mDirty = true;
+
+	U32 active_unit = mCurrTextureUnitIndex;
+
+	for (U32 i = 0; i < mTexUnits.size(); i++)
+	{
+		mTexUnits[i]->refreshState();
+	}
+	
+	mTexUnits[active_unit]->activate();
+
+	setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
+	
+	setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
+
+	mDirty = false;
 }
 
 void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -483,6 +685,12 @@ void LLRender::setColorMask(bool writeColor, bool writeAlpha)
 void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
 {
 	flush();
+
+	mCurrColorMask[0] = writeColorR;
+	mCurrColorMask[1] = writeColorG;
+	mCurrColorMask[2] = writeColorB;
+	mCurrColorMask[3] = writeAlpha;
+
 	glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha);
 }
 
@@ -518,6 +726,9 @@ void LLRender::setSceneBlendType(eBlendType type)
 void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
 {
 	flush();
+
+	mCurrAlphaFunc = func;
+	mCurrAlphaFuncVal = value;
 	if (func == CF_DEFAULT)
 	{
 		glAlphaFunc(GL_GREATER, 0.01f);
@@ -536,22 +747,38 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
 
 LLTexUnit* LLRender::getTexUnit(U32 index)
 {
-	if (index < mTexUnits.size())
+	if ((index >= 0) && (index < mTexUnits.size()))
 	{
 		return mTexUnits[index];
 	}
-	llerrs << "Non-existing texture unit layer requested: " << index << llendl;
-	return NULL;
+	else 
+	{
+		lldebugs << "Non-existing texture unit layer requested: " << index << llendl;
+		return mDummyTexUnit;
+	}
+}
+
+bool LLRender::verifyTexUnitActive(U32 unitToVerify)
+{
+	if (mCurrTextureUnitIndex == unitToVerify)
+	{
+		return true;
+	}
+	else 
+	{
+		llwarns << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << llendl;
+		return false;
+	}
 }
 
 void LLRender::begin(const GLuint& mode)
 {
 	if (mode != mMode)
 	{
-		if (mMode == LLVertexBuffer::QUADS ||
-			mMode == LLVertexBuffer::LINES ||
-			mMode == LLVertexBuffer::TRIANGLES ||
-			mMode == LLVertexBuffer::POINTS)
+		if (mMode == LLRender::QUADS ||
+			mMode == LLRender::LINES ||
+			mMode == LLRender::TRIANGLES ||
+			mMode == LLRender::POINTS)
 		{
 			flush();
 		}
@@ -572,10 +799,10 @@ void LLRender::end()
 		//IMM_ERRS << "GL begin and end called with no vertices specified." << llendl;
 	}
 
-	if ((mMode != LLVertexBuffer::QUADS && 
-		mMode != LLVertexBuffer::LINES &&
-		mMode != LLVertexBuffer::TRIANGLES &&
-		mMode != LLVertexBuffer::POINTS) ||
+	if ((mMode != LLRender::QUADS && 
+		mMode != LLRender::LINES &&
+		mMode != LLRender::TRIANGLES &&
+		mMode != LLRender::POINTS) ||
 		mCount > 2048)
 	{
 		flush();
@@ -638,7 +865,8 @@ void LLRender::flush()
 }
 void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
 { 
-	if (mCount >= 4096)
+	//the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
+	if (mCount > 4094)
 	{
 	//	llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl;
 		return;
@@ -720,3 +948,35 @@ void LLRender::color3fv(const GLfloat* c)
 	color4f(c[0],c[1],c[2],1);
 }
 
+void LLRender::debugTexUnits(void)
+{
+	LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
+	std::string active_enabled = "false";
+	for (U32 i = 0; i < mTexUnits.size(); i++)
+	{
+		if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
+		{
+			if (i == mCurrTextureUnitIndex) active_enabled = "true";
+			LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
+			LL_INFOS("TextureUnit") << "Enabled As: " ;
+			switch (getTexUnit(i)->mCurrTexType)
+			{
+				case LLTexUnit::TT_TEXTURE:
+					LL_CONT << "Texture 2D";
+					break;
+				case LLTexUnit::TT_RECT_TEXTURE:
+					LL_CONT << "Texture Rectangle";
+					break;
+				case LLTexUnit::TT_CUBE_MAP:
+					LL_CONT << "Cube Map";
+					break;
+				default:
+					LL_CONT << "ARGH!!! NONE!";
+					break;
+			}
+			LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
+		}
+	}
+	LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
+}
+
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 5133f2804eb..e604bbb84c6 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -37,14 +37,39 @@
 #ifndef LL_LLGLRENDER_H
 #define LL_LLGLRENDER_H
 
-#include "stdtypes.h"
-#include "llgltypes.h"
+//#include "linden_common.h"
+
+#include "v2math.h"
+#include "v3math.h"
+#include "v4coloru.h"
+#include "llstrider.h"
+#include "llmemory.h"
 #include "llglheaders.h"
-#include "llvertexbuffer.h"
+
+class LLVertexBuffer;
+class LLCubeMap;
+class LLImageGL;
+class LLRenderTarget;
 
 class LLTexUnit
 {
+	friend class LLRender;
 public:
+	typedef enum
+	{
+		TT_TEXTURE = 0,			// Standard 2D Texture
+		TT_RECT_TEXTURE,	// Non power of 2 texture
+		TT_CUBE_MAP,		// 6-sided cube map texture
+		TT_NONE 		// No texture type is currently enabled
+	} eTextureType;
+
+	typedef enum
+	{
+		TAM_WRAP = 0,			// Standard 2D Texture
+		TAM_MIRROR,				// Non power of 2 texture
+		TAM_CLAMP 				// No texture type is currently enabled
+	} eTextureAddressMode;
+
 	typedef enum 
 	{
 		TB_REPLACE = 0,
@@ -93,15 +118,36 @@ class LLTexUnit
 		TBS_ONE_MINUS_CONST_ALPHA
 	} eTextureBlendSrc;
 
-	LLTexUnit(U32 index);
-	U32 getIndex(void);
+	LLTexUnit(S32 index);
+
+	// Refreshes renderer state of the texture unit to the cached values
+	// Needed when the render context has changed and invalidated the current state
+	void refreshState(void);
+
+	// returns the index of this texture unit
+	S32 getIndex(void) const { return mIndex; }
 
-	void enable(void);
-	void disable(void);
-	void activate(void);
+	// Sets this tex unit to be the currently active one
+	void activate(void); 
+
+	// Enables this texture unit for the given texture type (automatically disables any previously enabled texture type)
+	void enable(eTextureType type); 
+	// Disables the current texture unit
+	void disable(void);	
+	
+	// Binds the LLImageGL to this texture unit (automatically enables the unit for the LLImageGL's texture type)
+	bool bind(const LLImageGL* texture);
+	// Binds a cubemap to this texture unit (automatically enables the texture unit for cubemaps)
+	bool bind(LLCubeMap* cubeMap);
+	// Binds a render target to this texture unit (automatically enables the texture unit for the RT's texture type)
+	bool bind(LLRenderTarget * renderTarget, bool bindDepth = false);
+	// Manually binds a texture to the texture unit (automatically enables the tex unit for the given texture type)
+	bool bindManual(eTextureType type, U32 texture);
+	
+	// Unbinds the currently bound texture of the given type (only if there's a texture of the given type currently bound)
+	void unbind(eTextureType type);
 
-	void bindTexture(const LLImageGL* texture);
-	void unbindTexture(void);
+	void setTextureAddressMode(eTextureAddressMode mode);
 
 	void setTextureBlendType(eTextureBlendType type);
 
@@ -110,11 +156,14 @@ class LLTexUnit
 
 	// NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead.
 	inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA)
-	{ setTextureCombiner(op, src1, src2, true); }	
+	{ setTextureCombiner(op, src1, src2, true); }
 
-private:
-	U32					mIndex;
-	bool				mIsEnabled;
+	static U32 getInternalType(eTextureType type);
+
+protected:
+	S32					mIndex;
+	U32					mCurrTexture;
+	eTextureType		mCurrTexType;
 	eTextureBlendType	mCurrBlendType;
 	eTextureBlendOp		mCurrColorOp;
 	eTextureBlendSrc	mCurrColorSrc1;
@@ -137,6 +186,19 @@ class LLRender
 {
 	friend class LLTexUnit;
 public:
+
+	typedef enum {
+		TRIANGLES = 0,
+		TRIANGLE_STRIP,
+		TRIANGLE_FAN,
+		POINTS,
+		LINES,
+		LINE_STRIP,
+		QUADS,
+		LINE_LOOP,
+		NUM_MODES
+	} eGeomModes;
+
 	typedef enum 
 	{
 		CF_NEVER = 0,
@@ -178,6 +240,10 @@ class LLRender
 	~LLRender();
 	void shutdown();
 	
+	// Refreshes renderer state to the cached values
+	// Needed when the render context has changed and invalidated the current state
+	void refreshState(void);
+
 	void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
 	void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
 	void pushMatrix();
@@ -214,6 +280,12 @@ class LLRender
 
 	LLTexUnit* getTexUnit(U32 index);
 
+	U32	getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
+
+	bool verifyTexUnitActive(U32 unitToVerify);
+
+	void debugTexUnits(void);
+
 	struct Vertex
 	{
 		GLfloat v[3];
@@ -224,14 +296,20 @@ class LLRender
 public:
 
 private:
-	U32 mCount;
-	U32 mMode;
-	U32 mCurrTextureUnitIndex;
-	LLPointer<LLVertexBuffer> mBuffer;
-	LLStrider<LLVector3> mVerticesp;
-	LLStrider<LLVector2> mTexcoordsp;
-	LLStrider<LLColor4U> mColorsp;
-	std::vector<LLTexUnit*> mTexUnits;
+	bool				mDirty;
+	U32				mCount;
+	U32				mMode;
+	U32				mCurrTextureUnitIndex;
+	bool				mCurrColorMask[4];
+	eCompareFunc			mCurrAlphaFunc;
+	F32				mCurrAlphaFuncVal;
+
+	LLPointer<LLVertexBuffer>	mBuffer;
+	LLStrider<LLVector3>		mVerticesp;
+	LLStrider<LLVector2>		mTexcoordsp;
+	LLStrider<LLColor4U>		mColorsp;
+	std::vector<LLTexUnit*>		mTexUnits;
+	LLTexUnit*			mDummyTexUnit;
 };
 
 extern F64 gGLModelView[16];
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index cfb7496795c..1b57e43f075 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -47,7 +47,7 @@ LLRenderTarget::LLRenderTarget() :
 	mStencil(0),
 	mUseDepth(FALSE),
 	mRenderDepth(FALSE),
-	mUsage(GL_TEXTURE_2D)
+	mUsage(LLTexUnit::TT_TEXTURE)
 {
 }
 
@@ -56,7 +56,7 @@ LLRenderTarget::~LLRenderTarget()
 	release();
 }
 
-void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL use_fbo)
+void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage, BOOL use_fbo)
 {
 	stop_glerror();
 	mResX = resx;
@@ -67,22 +67,22 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
 	release();
 
 	glGenTextures(1, (GLuint *) &mTex);
-	glBindTexture(mUsage, mTex);
-	glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL);
+	gGL.getTexUnit(0)->bindManual(mUsage, mTex);
+	glTexImage2D(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL);
 
-	glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
-	if (mUsage != GL_TEXTURE_RECTANGLE_ARB)
+	if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
 	{
-		glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
-		glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
+		glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
+		glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
 	}
 	else
 	{
 		// ATI doesn't support mirrored repeat for rectangular textures.
-		glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 	}
 
 	stop_glerror();
@@ -107,14 +107,14 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
 
 		if (mDepth)
 		{
-			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0);
+			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
 			stop_glerror();
-			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0);
+			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
 			stop_glerror();
 		}
 
 		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-						mUsage, mTex, 0);
+						LLTexUnit::getInternalType(mUsage), mTex, 0);
 		stop_glerror();
 
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
@@ -125,10 +125,11 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32
 void LLRenderTarget::allocateDepth()
 {
 	glGenTextures(1, (GLuint *) &mDepth);
-	glBindTexture(mUsage, mDepth);
-	glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
+	gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
+	U32 internal_type = LLTexUnit::getInternalType(mUsage);
+	glTexParameteri(internal_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(internal_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexImage2D(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
 }
 
 void LLRenderTarget::release()
@@ -191,24 +192,13 @@ void LLRenderTarget::clear()
 	}
 }
 
-void LLRenderTarget::bindTexture()
-{
-	glBindTexture(mUsage, mTex);
-}
-
-void LLRenderTarget::bindDepth()
-{
-	glBindTexture(mUsage, mDepth);
-}
-
-
 void LLRenderTarget::flush(BOOL fetch_depth)
 {
 	gGL.flush();
 	if (!mFBO)
 	{
-		bindTexture();
-		glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY);
+		gGL.getTexUnit(0)->bind(this);
+		glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY);
 
 		if (fetch_depth)
 		{
@@ -217,8 +207,8 @@ void LLRenderTarget::flush(BOOL fetch_depth)
 				allocateDepth();
 			}
 
-			bindDepth();
-			glCopyTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0);
+			gGL.getTexUnit(0)->bind(this, true);
+			glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0);
 		}
 	}
 	else
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index df886409704..bb6131741c0 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -33,6 +33,7 @@
 #define LL_LLRENDERTARGET_H
 
 #include "llgl.h"
+#include "llrender.h"
 
 /*
  SAMPLE USAGE:
@@ -53,7 +54,7 @@
 	...
 
 	//use target as a texture
-	target.bindTexture();
+	gGL.getTexUnit(INDEX)->bind(&target);
 	... <issue drawing commands> ...
 
 */
@@ -71,7 +72,7 @@ class LLRenderTarget
 	//allocate resources for rendering
 	//must be called before use
 	//multiple calls will release previously allocated resources
-	void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = FALSE);
+	void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE);
 
 	//allocate a depth texture
 	void allocateDepth();
@@ -100,11 +101,11 @@ class LLRenderTarget
 	//get Y resolution
 	U32 getHeight() const { return mResY; }
 
-	//bind results of render for sampling
-	void bindTexture();
+	LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
 
-	//bind results of render for sampling depth buffer
-	void bindDepth();
+	U32 getTexture(void) const { return mTex; }
+
+	U32 getDepth(void) const { return mDepth; }
 
 	//flush rendering operations
 	//must be called when rendering is complete
@@ -128,7 +129,7 @@ class LLRenderTarget
 	U32 mStencil;
 	BOOL mUseDepth;
 	BOOL mRenderDepth;
-	U32 mUsage;
+	LLTexUnit::eTextureType mUsage;
 	
 };
 
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 3bdc36c6773..7a3bcafaf01 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -307,7 +307,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
 		{
 			LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
 		}
-}
+	}
 }
 
 GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type)
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2414d2adff4..0bb0ea81a2b 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -76,7 +76,7 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
 	sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
 };
 
-U32 LLVertexBuffer::sGLMode[LLVertexBuffer::NUM_MODES] = 
+U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
 {
 	GL_TRIANGLES,
 	GL_TRIANGLE_STRIP,
@@ -187,7 +187,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 		llerrs << "Wrong vertex buffer bound." << llendl;
 	}
 
-	if (mode > NUM_MODES)
+	if (mode > LLRender::NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
 		return;
@@ -216,7 +216,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 		llerrs << "Wrong vertex buffer bound." << llendl;
 	}
 
-	if (mode > NUM_MODES)
+	if (mode > LLRender::NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
 		return;
@@ -240,7 +240,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 		llerrs << "Wrong vertex buffer bound." << llendl;
 	}
 
-	if (mode > NUM_MODES)
+	if (mode > LLRender::NUM_MODES)
 	{
 		llerrs << "Invalid draw mode: " << mode << llendl;
 		return;
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 45f501fe1e7..e11eb437021 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -39,6 +39,7 @@
 #include "v4coloru.h"
 #include "llstrider.h"
 #include "llmemory.h"
+#include "llrender.h"
 #include <set>
 #include <vector>
 #include <list>
@@ -123,19 +124,8 @@ class LLVertexBuffer : public LLRefCount
 		MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
 	};
 	
-	enum {
-		TRIANGLES = 0,
-		TRIANGLE_STRIP,
-		TRIANGLE_FAN,
-		POINTS,
-		LINES,
-		LINE_STRIP,
-		QUADS,
-		LINE_LOOP,
-		NUM_MODES
-	};
 protected:
-	friend class LLGLImmediate;
+	friend class LLRender;
 
 	virtual ~LLVertexBuffer(); // use unref()
 
@@ -255,7 +245,7 @@ class LLVertexBuffer : public LLRefCount
 		
 	static BOOL sEnableVBOs;
 	static S32 sTypeOffsets[TYPE_MAX];
-	static U32 sGLMode[NUM_MODES];
+	static U32 sGLMode[LLRender::NUM_MODES];
 	static U32 sGLRenderBuffer;
 	static U32 sGLRenderIndices;
 	static BOOL sVBOActive;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 78a43626187..ffdca840016 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -127,6 +127,7 @@ LLFloaterView* gFloaterView = NULL;
 
 LLFloater::LLFloater() :
 	//FIXME: we should initialize *all* member variables here
+	LLPanel(), mAutoFocus(TRUE),
 	mResizable(FALSE),
 	mDragOnLeft(FALSE),
 	mMinWidth(0),
@@ -139,6 +140,11 @@ LLFloater::LLFloater() :
 		mButtonsEnabled[i] = FALSE;
 		mButtons[i] = NULL;
 	}
+	for (S32 i = 0; i < 4; i++) 
+	{
+		mResizeBar[i] = NULL; 
+		mResizeHandle[i] = NULL;
+	}
 	mDragHandle = NULL;
 	mHandle.bind(this);
 }
@@ -151,6 +157,11 @@ LLFloater::LLFloater(const std::string& name)
 		mButtonsEnabled[i] = FALSE;
 		mButtons[i] = NULL;
 	}
+	for (S32 i = 0; i < 4; i++) 
+	{
+		mResizeBar[i] = NULL; 
+		mResizeHandle[i] = NULL;
+	}
 	std::string title; // null string
 	initFloater(title, FALSE, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, FALSE, TRUE, TRUE); // defaults
 }
@@ -171,6 +182,11 @@ LLFloater::LLFloater(const std::string& name, const LLRect& rect, const std::str
 		mButtonsEnabled[i] = FALSE;
 		mButtons[i] = NULL;
 	}
+	for (S32 i = 0; i < 4; i++) 
+	{
+		mResizeBar[i] = NULL; 
+		mResizeHandle[i] = NULL;
+	}
 	initFloater( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn);
 }
 
@@ -189,6 +205,11 @@ LLFloater::LLFloater(const std::string& name, const std::string& rect_control, c
 		mButtonsEnabled[i] = FALSE;
 		mButtons[i] = NULL;
 	}
+	for (S32 i = 0; i < 4; i++) 
+	{
+		mResizeBar[i] = NULL; 
+		mResizeHandle[i] = NULL;
+	}
 	initFloater( title, resizable, min_width, min_height, drag_on_left, minimizable, close_btn);
 }
 
@@ -1580,6 +1601,7 @@ void LLFloater::updateButtons()
 	S32 button_count = 0;
 	for (S32 i = 0; i < BUTTON_COUNT; i++)
 	{
+		if(!mButtons[i]) continue;
 		mButtons[i]->setEnabled(mButtonsEnabled[i]);
 
 		if (mButtonsEnabled[i] 
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index a8ed555a450..c3bbce60556 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -1423,7 +1423,7 @@ void LLLineEditor::draw()
 #else // the old programmer art.
 	// drawing solids requires texturing be disabled
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		// draw background for text
 		if( !mReadOnly )
 		{
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 03edaf69d34..b4619d2738a 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1309,6 +1309,7 @@ void LLMenuItemBranchGL::openMenu()
 		}
 		mBranch->translate( delta_x, delta_y );
 		mBranch->setVisible( TRUE );
+		mBranch->getParent()->sendChildToFront(mBranch);
 	}
 }
 
@@ -1427,6 +1428,7 @@ void LLMenuItemBranchDownGL::openMenu( void )
 
 			setHighlight(TRUE);
 			branch->setVisible( TRUE );
+			branch->getParent()->sendChildToFront(branch);
 		}
 	}
 }
@@ -2958,6 +2960,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	}
 	menu->translate( delta_x, delta_y );
 	menu->setVisible( TRUE );
+	menu->getParent()->sendChildToFront(menu);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index 1663312c6f7..eedf4986679 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -431,7 +431,7 @@ void LLMultiSlider::draw()
 	// Draw background and thumb.
 
 	// drawing solids requires texturing be disabled
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	LLRect rect(mDragStartThumbRect);
 
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 8bb051f3f5c..f1169f1cdba 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -425,7 +425,7 @@ void LLScrollableContainerView::draw()
 	// Draw background
 	if( mIsOpaque )
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( mBackgroundColor.mV );
 		gl_rect_2d( mInnerRect );
 	}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index ebfdda30273..c0f21ba9e56 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -435,7 +435,7 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const
 	// draw background rect
 	LLRect bg_rect = rect;
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv(bg_color.mV);
 		gl_rect_2d( bg_rect );
 	}
@@ -1758,7 +1758,7 @@ void LLScrollListCtrl::draw()
 	// Draw background
 	if (mBackgroundVisible)
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( getEnabled() ? mBgWriteableColor.mV : mBgReadOnlyColor.mV );
 		gl_rect_2d(background);
 	}
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index 28058d0005c..1c0ce08d98a 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -253,7 +253,7 @@ void LLSlider::draw()
 	// Draw background and thumb.
 
 	// drawing solids requires texturing be disabled
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	F32 opacity = getEnabled() ? 1.f : 0.3f;
 	LLColor4 center_color = (mThumbCenterColor % opacity);
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 0440d4c68b2..f935432e57c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2594,7 +2594,7 @@ void LLTextEditor::drawSelectionBackground()
 		BOOL selection_visible = (left_visible_pos <= selection_right) && (selection_left <= right_visible_pos);
 		if( selection_visible )
 		{
-			LLGLSNoTexture no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			const LLColor4& color = mReadOnly ? mReadOnlyBgColor : mWriteableBgColor;
 			F32 alpha = hasFocus() ? 1.f : 0.5f;
 			gGL.color4f( 1.f - color.mV[0], 1.f - color.mV[1], 1.f - color.mV[2], alpha );
@@ -2729,7 +2729,7 @@ void LLTextEditor::drawCursor()
 					}
 				}
 				
-				LLGLSNoTexture no_texture;
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 				gGL.color4fv( mCursorColor.mV );
 				
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 43898f57efe..472f8606b16 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -143,11 +143,11 @@ void gl_state_for_2d(S32 width, S32 height)
 
 void gl_draw_x(const LLRect& rect, const LLColor4& color)
 {
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	gGL.color4fv( color.mV );
 
-	gGL.begin( LLVertexBuffer::LINES );
+	gGL.begin( LLRender::LINES );
 		gGL.vertex2i( rect.mLeft,		rect.mTop );
 		gGL.vertex2i( rect.mRight,	rect.mBottom );
 		gGL.vertex2i( rect.mLeft,		rect.mBottom );
@@ -183,12 +183,12 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
 void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
 {
 	stop_glerror();
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// Counterclockwise quad will face the viewer
 	if( filled )
 	{
-		gGL.begin( LLVertexBuffer::QUADS );
+		gGL.begin( LLRender::QUADS );
 			gGL.vertex2i(left, top);
 			gGL.vertex2i(left, bottom);
 			gGL.vertex2i(right, bottom);
@@ -200,7 +200,7 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
 		if( gGLManager.mATIOffsetVerticalLines )
 		{
 			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-			gGL.begin( LLVertexBuffer::LINES );
+			gGL.begin( LLRender::LINES );
 
 				// Verticals 
 				gGL.vertex2i(left + 1, top);
@@ -223,7 +223,7 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
 		{
 			top--;
 			right--;
-			gGL.begin( LLVertexBuffer::LINE_STRIP );
+			gGL.begin( LLRender::LINE_STRIP );
 				gGL.vertex2i(left, top);
 				gGL.vertex2i(left, bottom);
 				gGL.vertex2i(right, bottom);
@@ -254,7 +254,7 @@ void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
 void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
 {
 	stop_glerror();
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 	// HACK: Overlap with the rectangle by a single pixel.
 	right--;
@@ -264,7 +264,7 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st
 	LLColor4 end_color = start_color;
 	end_color.mV[VALPHA] = 0.f;
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 
 	// Right edge, CCW faces screen
 	gGL.color4fv(start_color.mV);
@@ -324,9 +324,9 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
 		y2++;
 	}
 
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 		gGL.vertex2i(x1, y1);
 		gGL.vertex2i(x2, y2);
 	gGL.end();
@@ -343,11 +343,11 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
 		y2++;
 	}
 
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	gGL.color4fv( color.mV );
 
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 		gGL.vertex2i(x1, y1);
 		gGL.vertex2i(x2, y2);
 	gGL.end();
@@ -355,17 +355,17 @@ void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
 
 void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
 {
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	gGL.color4fv(color.mV);
 
 	if (filled)
 	{
-		gGL.begin(LLVertexBuffer::TRIANGLES);
+		gGL.begin(LLRender::TRIANGLES);
 	}
 	else
 	{
-		gGL.begin(LLVertexBuffer::LINE_LOOP);
+		gGL.begin(LLRender::LINE_LOOP);
 	}
 	gGL.vertex2i(x1, y1);
 	gGL.vertex2i(x2, y2);
@@ -375,11 +375,11 @@ void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColo
 
 void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
 {
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	length = llmin((S32)(max_frac*(right - left)), length);
 	length = llmin((S32)(max_frac*(top - bottom)), length);
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 	gGL.vertex2i(left, top);
 	gGL.vertex2i(left + length, top);
 	
@@ -496,11 +496,11 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLIma
 	{
 		gGL.translatef((F32)x, (F32)y, 0.f);
 
-		image->bind();
+		gGL.getTexUnit(0)->bind(image);
 
 		gGL.color4fv(color.mV);
 		
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			// draw bottom left
 			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
@@ -656,11 +656,11 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
 			gGL.translatef( -offset_x, -offset_y, 0.f );
 		}
 
-		image->bind();
+		gGL.getTexUnit(0)->bind(image);
 
 		gGL.color4fv(color.mV);
 		
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
 			gGL.vertex2i(width, height );
@@ -694,11 +694,11 @@ void gl_draw_scaled_image_inverted(S32 x, S32 y, S32 width, S32 height, LLImageG
 	{
 		gGL.translatef((F32)x, (F32)y, 0.f);
 
-		image->bind();
+		gGL.getTexUnit(0)->bind(image);
 
 		gGL.color4fv(color.mV);
 		
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
 			gGL.vertex2i(width, height );
@@ -733,7 +733,7 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
 	glLineWidth(2.5f);
 	glLineStipple(2, 0x3333 << shift);
 
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv( start.mV );
 		gGL.vertex3fv( end.mV );
@@ -750,7 +750,7 @@ void gl_rect_2d_xor(S32 left, S32 top, S32 right, S32 bottom)
 	glLogicOp( GL_XOR );
 	stop_glerror();
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 		gGL.vertex2i(left, top);
 		gGL.vertex2i(left, bottom);
 		gGL.vertex2i(right, bottom);
@@ -782,14 +782,14 @@ void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F
 
 		if (filled)
 		{
-			gGL.begin(LLVertexBuffer::TRIANGLE_FAN);
+			gGL.begin(LLRender::TRIANGLE_FAN);
 			gGL.vertex2f(0.f, 0.f);
 			// make sure circle is complete
 			steps += 1;
 		}
 		else
 		{
-			gGL.begin(LLVertexBuffer::LINE_STRIP);
+			gGL.begin(LLRender::LINE_STRIP);
 		}
 
 		while( steps-- )
@@ -809,7 +809,7 @@ void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled
 {
 	gGL.pushMatrix();
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.translatef(center_x, center_y, 0.f);
 
 		// Inexact, but reasonably fast.
@@ -821,14 +821,14 @@ void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled
 
 		if (filled)
 		{
-			gGL.begin(LLVertexBuffer::TRIANGLE_FAN);
+			gGL.begin(LLRender::TRIANGLE_FAN);
 			gGL.vertex2f(0.f, 0.f);
 			// make sure circle is complete
 			steps += 1;
 		}
 		else
 		{
-			gGL.begin(LLVertexBuffer::LINE_LOOP);
+			gGL.begin(LLRender::LINE_LOOP);
 		}
 
 		while( steps-- )
@@ -850,7 +850,7 @@ void gl_deep_circle( F32 radius, F32 depth, S32 steps )
 	F32 x = radius;
 	F32 y = 0.f;
 	F32 angle_delta = F_TWO_PI / (F32)steps;
-	gGL.begin( LLVertexBuffer::TRIANGLE_STRIP  );
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
 	{
 		S32 step = steps + 1; // An extra step to close the circle.
 		while( step-- )
@@ -905,7 +905,7 @@ void gl_rect_2d_checkerboard(const LLRect& rect)
 		first = FALSE;
 	}
 	
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// ...white squares
 	gGL.color3f( 1.f, 1.f, 1.f );
@@ -935,9 +935,9 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&
 	F32 x2 = inner_radius;
 	F32 y2 = 0.f;
 
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-	gGL.begin( LLVertexBuffer::TRIANGLE_STRIP  );
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
 	{
 		steps += 1; // An extra step to close the circle.
 		while( steps-- )
@@ -972,8 +972,8 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians,
 	F32 x2 = inner_radius * cos( start_radians );
 	F32 y2 = inner_radius * sin( start_radians );
 
-	LLGLSNoTexture gls_no_texture;
-	gGL.begin( LLVertexBuffer::TRIANGLE_STRIP  );
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
 	{
 		steps += 1; // An extra step to close the circle.
 		while( steps-- )
@@ -1008,9 +1008,9 @@ void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LL
 	F32 x2 = inner_radius * cos( HALF_DELTA );
 	F32 y2 = inner_radius * sin( HALF_DELTA );
 
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-	gGL.begin( LLVertexBuffer::LINES  );
+	gGL.begin( LLRender::LINES  );
 	{
 		while( count-- )
 		{
@@ -1033,7 +1033,7 @@ void gl_washer_spokes_2d(F32 outer_radius, F32 inner_radius, S32 count, const LL
 
 void gl_rect_2d_simple_tex( S32 width, S32 height )
 {
-	gGL.begin( LLVertexBuffer::QUADS );
+	gGL.begin( LLRender::QUADS );
 
 		gGL.texCoord2f(1.f, 1.f);
 		gGL.vertex2i(width, height);
@@ -1052,7 +1052,7 @@ void gl_rect_2d_simple_tex( S32 width, S32 height )
 
 void gl_rect_2d_simple( S32 width, S32 height )
 {
-	gGL.begin( LLVertexBuffer::QUADS );
+	gGL.begin( LLRender::QUADS );
 		gGL.vertex2i(width, height);
 		gGL.vertex2i(0, height);
 		gGL.vertex2i(0, 0);
@@ -1094,7 +1094,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
 	LLVector2 width_vec((F32)width, 0.f);
 	LLVector2 height_vec(0.f, (F32)height);
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		// draw bottom left
 		gGL.texCoord2f(0.f, 0.f);
@@ -1262,7 +1262,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
 	LLVector2 x_min;
 	LLVector2 x_max;
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		if (start_fragment < middle_start)
 		{
@@ -1419,7 +1419,7 @@ void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& bo
 	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
 
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		// draw bottom left
 		gGL.texCoord2f(0.f, 0.f);
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 3bce976c8a1..5b71851520e 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1281,7 +1281,7 @@ void LLView::drawDebugRect()
 	LLUI::pushMatrix();
 	{
 		// drawing solids requires texturing be disabled
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		if (mUseBoundingRect)
 		{
@@ -1303,7 +1303,7 @@ void LLView::drawDebugRect()
 
 		gGL.color4fv( border_color.mV );
 
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 			gGL.vertex2i(0, debug_rect.getHeight() - 1);
 			gGL.vertex2i(0, 0);
 
diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp
index a4cec9a53f2..0fc557a4d36 100644
--- a/indra/llui/llviewborder.cpp
+++ b/indra/llui/llviewborder.cpp
@@ -111,7 +111,7 @@ void LLViewBorder::draw()
 
 void LLViewBorder::drawOnePixelLines()
 {
-	LLGLSNoTexture uiNoTexture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	LLColor4 top_color = mHighlightLight;
 	LLColor4 bottom_color = mHighlightLight;
@@ -158,7 +158,7 @@ void LLViewBorder::drawOnePixelLines()
 
 void LLViewBorder::drawTwoPixelLines()
 {
-	LLGLSNoTexture no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 	LLColor4 focus_color = gFocusMgr.getFocusColor();
 
@@ -230,7 +230,7 @@ void LLViewBorder::drawTextures()
 
 	//gGL.color4fv(UI_VERTEX_COLOR.mV);
 
-	//mTexture->bind();
+	//gGL.getTexUnit(0)->bind(mTexture);
 	//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
 	//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
 
@@ -248,7 +248,7 @@ void LLViewBorder::drawTextureTrapezoid( F32 degrees, S32 width, S32 length, F32
 		gGL.translatef(start_x, start_y, 0.f);
 		glRotatef( degrees, 0, 0, 1 );
 
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			//      width, width   /---------\ length-width, width		//
 			//	   			      /           \							//
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index ff7bfde521c..8acf7d88ca7 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -497,6 +497,29 @@ std::string LLDir::getTempFilename() const
 	return temp_filename;
 }
 
+// static
+std::string LLDir::getScrubbedFileName(const std::string uncleanFileName)
+{
+	std::string name(uncleanFileName);
+	const std::string illegalChars(getForbiddenFileChars());
+	// replace any illegal file chars with and underscore '_'
+	for( unsigned int i = 0; i < illegalChars.length(); i++ )
+	{
+		int j = -1;
+		while((j = name.find(illegalChars[i])) > -1)
+		{
+			name[j] = '_';
+		}
+	}
+	return name;
+}
+
+// static
+std::string LLDir::getForbiddenFileChars()
+{
+	return "\\/:*?\"<>|";
+}
+
 void LLDir::setLindenUserDir(const std::string &first, const std::string &last)
 {
 	// if both first and last aren't set, assume we're grabbing the cached dir
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index b0255b4d00a..a884ea7c763 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -64,12 +64,12 @@ class LLDir
 
 	virtual void initAppDirs(const std::string &app_name) = 0;
  public:	
-	 virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
+	virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
 
 // pure virtual functions
-	 virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
-	 virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) = 0;
-	 virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) = 0;
+	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) = 0;
+	virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) = 0;
 	virtual std::string getCurPath() = 0;
 	virtual BOOL fileExists(const std::string &filename) const = 0;
 
@@ -104,7 +104,7 @@ class LLDir
 	std::string getBaseFileName(const std::string& filepath, bool strip_exten = false) const;
 	std::string getDirName(const std::string& filepath) const;
 	std::string getExtension(const std::string& filepath) const; // Excludes '.', e.g getExtension("foo.wav") == "wav"
-	
+
 	// these methods search the various skin paths for the specified file in the following order:
 	// getUserSkinDir(), getSkinDir(), getDefaultSkinDir()
 	std::string findSkinnedFilename(const std::string &filename) const;
@@ -114,6 +114,10 @@ class LLDir
 	// random filename in common temporary directory
 	std::string getTempFilename() const;
 
+	// For producing safe download file names from potentially unsafe ones
+	static std::string getScrubbedFileName(const std::string uncleanFileName);
+	static std::string getForbiddenFileChars();
+
 	virtual void setChatLogsDir(const std::string &path);		// Set the chat logs dir to this user's dir
 	virtual void setPerAccountChatLogsDir(const std::string &first, const std::string &last);		// Set the per user chat log directory.
 	virtual void setLindenUserDir(const std::string &first, const std::string &last);		// Set the linden user dir to this user's dir
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d2730c5a950..4dd4c74ea38 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -124,6 +124,7 @@ set(viewer_SOURCE_FILES
     llfloateravatarinfo.cpp
     llfloateravatarpicker.cpp
     llfloateravatartextures.cpp
+    llfloaterbeacons.cpp
     llfloaterbuildoptions.cpp
     llfloaterbump.cpp
     llfloaterbuycontents.cpp
@@ -518,6 +519,7 @@ set(viewer_HEADER_FILES
     llfloateravatarinfo.h
     llfloateravatarpicker.h
     llfloateravatartextures.h
+    llfloaterbeacons.h
     llfloaterbuildoptions.h
     llfloaterbump.h
     llfloaterbuy.h
@@ -1025,6 +1027,7 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/floater_audio_volume.xml
     skins/default/xui/en-us/floater_avatar_picker.xml
     skins/default/xui/en-us/floater_avatar_textures.xml
+    skins/default/xui/en-us/floater_beacons.xml
     skins/default/xui/en-us/floater_build_options.xml
     skins/default/xui/en-us/floater_bumps.xml
     skins/default/xui/en-us/floater_buy_contents.xml
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 72e16ea70ca..4d4ce6c326f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1838,17 +1838,6 @@
         <integer>0</integer>
       </array>
     </map>
-    <key>CompressSnapshotsToDisk</key>
-    <map>
-      <key>Comment</key>
-      <string>Compress snapshots saved to disk (Using JPEG 2000)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>ConnectAsGod</key>
     <map>
       <key>Comment</key>
@@ -2660,6 +2649,22 @@
         <integer>0</integer>
       </array>
     </map>
+    <key>FloaterBeaconsRect</key>
+    <map>
+        <key>Comment</key>
+        <string>Rectangle for beacon and highlight controls</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Rect</string>
+        <key>Value</key>
+        <array>
+            <integer>200</integer>
+            <integer>250</integer>
+            <integer>250</integer>
+            <integer>200</integer>
+    </array>
+  </map>
     <key>FloaterBuildOptionsRect</key>
     <map>
       <key>Comment</key>
@@ -4279,10 +4284,11 @@
       <key>Value</key>
       <string>0.0.0</string>
     </map>
-    <key>LastSnapshotHeight</key>
+  
+    <key>LastSnapshotToEmailHeight</key>
     <map>
       <key>Comment</key>
-      <string>The height of the last snapshot, in px</string>
+      <string>The height of the last email snapshot, in px</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -4290,21 +4296,32 @@
       <key>Value</key>
       <integer>768</integer>
     </map>
-    <key>LastSnapshotType</key>
+    <key>LastSnapshotToEmailWidth</key>
     <map>
       <key>Comment</key>
-      <string>Select this as next type of snapshot to take (0 = postcard, 1 = texture, 2 = local image)</string>
+      <string>The width of the last email snapshot, in px</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1024</integer>
     </map>
-    <key>LastSnapshotWidth</key>
+    <key>LastSnapshotToDiskHeight</key>
     <map>
       <key>Comment</key>
-      <string>The width of the last snapshot, in px</string>
+      <string>The height of the last disk snapshot, in px</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>768</integer>
+    </map>
+    <key>LastSnapshotToDiskWidth</key>
+    <map>
+      <key>Comment</key>
+      <string>The width of the last disk snapshot, in px</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -4312,6 +4329,39 @@
       <key>Value</key>
       <integer>1024</integer>
     </map>
+    <key>LastSnapshotToInventoryHeight</key>
+    <map>
+      <key>Comment</key>
+      <string>The height of the last texture snapshot, in px</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>512</integer>
+    </map>
+    <key>LastSnapshotToInventoryWidth</key>
+    <map>
+      <key>Comment</key>
+      <string>The width of the last texture snapshot, in px</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>512</integer>
+    </map>
+    <key>LastSnapshotType</key>
+    <map>
+      <key>Comment</key>
+      <string>Select this as next type of snapshot to take (0 = postcard, 1 = texture, 2 = local image)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LeftClickShowMenu</key>
     <map>
       <key>Comment</key>
@@ -4488,17 +4538,6 @@
       <key>Value</key>
       <real>20.0</real>
     </map>
-    <key>MainloopTimeoutDefault</key>
-        <map>
-        <key>Comment</key>
-            <string>Timeout duration for mainloop lock detection, in seconds.</string>
-        <key>Persist</key>
-            <integer>1</integer>
-        <key>Type</key>
-            <string>F32</string>
-        <key>Value</key>
-            <real>10.0</real>
-        </map>
     <key>MapOverlayIndex</key>
     <map>
       <key>Comment</key>
@@ -6066,6 +6105,17 @@
       <key>Value</key>
       <real>1.3</real>
     </map>
+    <key>RenderGround</key>
+    <map>
+      <key>Comment</key>
+	  <string>Determines whether we can render the ground pool or not</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>RenderHUDInSnapshot</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
index 0df89c8fc37..78b96b30252 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
@@ -11,7 +11,7 @@ void calcAtmospherics(vec3 inPositionEye);
 void main()
 {
 	//transform vertex
-	gl_Position = ftransform(); //gl_ModelViewProjectionMatrix * gl_Vertex;
+	gl_Position = ftransform();
 	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
 	
 	vec4 pos = (gl_ModelViewMatrix * gl_Vertex);
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index b2270434132..8a8ef0deac6 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -33,6 +33,7 @@ RenderFlexTimeFactor		1	1.0
 RenderFogRatio				1	4.0
 RenderGamma					1	0
 RenderGlowResolutionPow		1	9
+RenderGround				1	1
 RenderLightingDetail		1	1
 RenderMaxPartCount			1	8192
 RenderNightBrightness		1	1.0
@@ -347,21 +348,7 @@ RenderVBOEnable				0	0
 list ATI_All-in-Wonder_7500
 RenderVBOEnable				0	0
 
-
-list ATI_Mobility_Radeon_9800
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
-list ATI_Mobility_Radeon_9700
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
 list ATI_Mobility_Radeon_9600
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
 Disregard96DefaultDrawDistance	1	0
 
 
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 3eaa781206d..08a9794c61b 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -33,6 +33,7 @@ RenderFlexTimeFactor		1	1.0
 RenderFogRatio				1	4.0
 RenderGamma					1	0
 RenderGlowResolutionPow		1	9
+RenderGround				1	1
 RenderLightingDetail		1	1
 RenderMaxPartCount			1	8192
 RenderNightBrightness		1	1.0
@@ -343,21 +344,7 @@ RenderVBOEnable				0	0
 list ATI_All-in-Wonder_7500
 RenderVBOEnable				0	0
 
-
-list ATI_Mobility_Radeon_9800
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
-list ATI_Mobility_Radeon_9700
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
 list ATI_Mobility_Radeon_9600
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
 Disregard96DefaultDrawDistance	1	0
 
 
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index fab8ea9173e..323683462a9 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -33,6 +33,7 @@ RenderFlexTimeFactor			1	1.0
 RenderFogRatio					1	4.0
 RenderGamma						1	0
 RenderGlowResolutionPow			1	9
+RenderGround					1	1
 RenderLightingDetail			1	1
 RenderMaxPartCount				1	8192
 RenderNightBrightness			1	1.0
@@ -291,6 +292,7 @@ RenderVBOEnable				1	0
 list Intel_950
 RenderTerrainDetail			1	0
 RenderVBOEnable				1	0
+RenderGround				1	0
 
 list Intel_965
 RenderTerrainDetail			1	0
@@ -324,20 +326,7 @@ list Intel_Springdale
 RenderTerrainDetail			1	0
 RenderVBOEnable				1	0
 
-list ATI_Mobility_Radeon_9800
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
-list ATI_Mobility_Radeon_9700
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
-
 list ATI_Mobility_Radeon_9600
-RenderAvatarCloth			0	0
-VertexShaderEnable			0	0
-WindLightUseAtmosShaders	0	0
 Disregard96DefaultDrawDistance	1	0
 
 list NVIDIA_GeForce_8600
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 48af543aa4f..44d66a606b0 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -36,6 +36,7 @@ ATI ASUS A9xxx					.*ATI.*ASUS.*A9.*					1		1
 ATI ASUS AH24xx					.*ATI.*ASUS.*AH24.*					1		1
 ATI ASUS AH26xx					.*ATI.*ASUS.*AH26.*					3		1
 ATI ASUS AH36xx					.*ATI.*ASUS.*AH36.*					3		1
+ATI ASUS AH46xx					.*ATI.*ASUS.*AH46.*					3		1
 ATI ASUS AX3xx					.*ATI.*ASUS.*AX3.*					1		1
 ATI ASUS AX5xx					.*ATI.*ASUS.*AX5.*					1		1
 ATI ASUS AX8xx					.*ATI.*ASUS.*AX8.* 					2		1
@@ -51,6 +52,7 @@ ATI Diamond X550				.*ATI.*Diamond X550.*				1		1
 ATI Diamond X13xx				.*ATI.*Diamond X13.*				1		1
 ATI Diamond X16xx				.*ATI.*Diamond X16.*				1		1
 ATI Diamond X19xx				.*ATI.*Diamond X19.*				1		1
+ATI Display Adapter				.*ATI.*display adapter.*			0		1
 ATI FireGL 5200					.*ATI.*FireGL V52.*					0		1
 ATI FireGL 5xxx					.*ATI.*FireGL V5.*					1		1
 ATI FireGL						.*ATI.*Fire.*GL.*					0		1
@@ -104,13 +106,14 @@ ATI Radeon RV250				.*ATI.*RV250.*						0		1
 ATI Radeon RV600				.*ATI.*RV6.*						1		1
 ATI Radeon RX700				.*ATI.*RX70.*						1		1
 ATI Radeon RX800				.*ATI.*Radeon *RX80.*				2		1
+ATI Radeon RX9550				.*ATI.*RX9550.*						1		1
 ATI Radeon VE					.*ATI.*Radeon.*VE.*					0		0
 ATI Radeon X1000				.*ATI.*Radeon *X10.*				0		1
 ATI Radeon X1200				.*ATI.*Radeon *X12.*				0		1
 ATI Radeon X1300				.*ATI.*Radeon *X13.*				1		1
 ATI Radeon X1400				.*ATI.*Radeon X14.*					1		1
 ATI Radeon X1500				.*ATI.*Radeon X15.*					1		1
-ATI Radeon X1600				.*ATI.*Radeon X16.*					1		1
+ATI Radeon X1600				.*ATI.*Radeon *X16.*				1		1
 ATI Radeon X1700				.*ATI.*Radeon X17.*					1		1
 ATI Radeon X1800				.*ATI.*Radeon X18.*					3		1
 ATI Radeon X1900				.*ATI.*Radeon X19.*					3		1
@@ -143,15 +146,20 @@ Intel G45						.*Intel.*G45.*						0		1
 Intel Bear Lake					.*Intel.*Bear Lake.*				0		0
 Intel Broadwater 				.*Intel.*Broadwater.*				0		0
 Intel Brookdale					.*Intel.*Brookdale.*				0		0
-Intel Eaglelake					.*Intel.*Eaglelake.*				0		1
+Intel Cantiga					.*Intel.*Cantiga.*					0		0
+Intel Eaglelake					.*Intel.*Eaglelake.*				0		0
 Intel Montara					.*Intel.*Montara.*					0		0
 Intel Springdale				.*Intel.*Springdale.*				0		0
 Matrox							.*Matrox.*							0		0
 Mesa							.*Mesa.*							0		0
 NVIDIA GTX 260					.*NVIDIA.*GeForce.*GTX.*260.*		3		1
 NVIDIA GTX 280					.*NVIDIA.*GeForce.*GTX.*280.*		3		1
+NVIDIA C51						.*NVIDIA.*C51.*						0		1
 NVIDIA G72						.*NVIDIA.*G72.*						1		1
 NVIDIA G73						.*NVIDIA.*G73.*						1		1
+NVIDIA G84						.*NVIDIA.*G84.*						3		1
+NVIDIA G86						.*NVIDIA.*G86.*						3		1
+NVIDIA G92						.*NVIDIA.*G92.*						3		1
 NVIDIA GeForce					.*GeForce 256.*						0		0
 NVIDIA GeForce 2				.*GeForce2.*						0		1
 NVIDIA GeForce 3				.*GeForce3.*						0		1
@@ -170,7 +178,7 @@ NVIDIA GeForce 7200				.*NVIDIA.*GeForce 72.*				1		1
 NVIDIA GeForce 7300				.*NVIDIA.*GeForce 73.*				1		1
 NVIDIA GeForce 7500				.*NVIDIA.*GeForce 75.*				1		1
 NVIDIA GeForce 7600				.*NVIDIA.*GeForce 76.*				2		1
-NVIDIA GeForce 7800				.*NVIDIA.*GeForce 78.*				2		1
+NVIDIA GeForce 7800				.*NVIDIA.*GeForce.*78.*				2		1
 NVIDIA GeForce 7900				.*NVIDIA.*GeForce 79.*				2		1
 NVIDIA GeForce 8200				.*NVIDIA.*GeForce 82.*				1		1
 NVIDIA GeForce 8300				.*NVIDIA.*GeForce 83.*				1		1
@@ -181,6 +189,9 @@ NVIDIA GeForce 8700				.*NVIDIA.*GeForce 87.*				3		1
 NVIDIA GeForce 8800				.*NVIDIA.*GeForce 88.*				3		1
 NVIDIA GeForce 9300M			.*NVIDIA.*GeForce 9300M.*			1		1
 NVIDIA GeForce 9500M			.*NVIDIA.*GeForce 9500M.*			2		1
+NVIDIA GeForce 9700M			.*NVIDIA.*GeForce 9700M.*			2		1
+NVIDIA GeForce 9300				.*NVIDIA.*GeForce 93.*				1		1
+NVIDIA GeForce 9500				.*NVIDIA.*GeForce 95.*				2		1
 NVIDIA GeForce 9600				.*NVIDIA.*GeForce 96.*				3		1
 NVIDIA GeForce 9800				.*NVIDIA.*GeForce 98.*				3		1
 NVIDIA GeForce FX 5100			.*NVIDIA.*GeForce FX 51.*			0		1
@@ -212,10 +223,16 @@ NVIDIA GeForce Go 7600			.*NVIDIA.*GeForce Go 76.*			2		1
 NVIDIA GeForce Go 7700			.*NVIDIA.*GeForce Go 77.*			2		1
 NVIDIA GeForce Go 7800			.*NVIDIA.*GeForce Go 78.*			2		1
 NVIDIA GeForce Go 7900			.*NVIDIA.*GeForce Go 79.*			2		1
+NVIDIA GeForce GTX 260			.*NVIDIA.*GeForce GTX 26.*			3		1
+NVIDIA GeForce GTX 280			.*NVIDIA.*GeForce GTX 28.*			3		1
 NVIDIA GeForce Go 6				.*GeForce Go 6.*					1		1
+NVIDIA NB9M						.*GeForce NB9M.*					1		1
+NVIDIA NB9P						.*GeForce NB9P.*					1		1
 NVIDIA GeForce PCX				.*GeForce PCX.*						0		1
 NVIDIA Generic					.*NVIDIA.*Unknown.*					0		0
+NVIDIA NV17						.*GeForce NV17.*					0		1
 NVIDIA NV34						.*NVIDIA.*NV34.*					0		1
+NVIDIA NV36						.*GeForce NV36.*					1		1
 NVIDIA NV43						.*NVIDIA.*NV43.*					1		1
 NVIDIA MCP78					.*NVIDIA.*MCP78.*					1		1
 NVIDIA Quadro2					.*Quadro2.*							0		1
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 36e4182e375..0fa680e7538 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -492,7 +492,7 @@ LLAgent::~LLAgent()
 //-----------------------------------------------------------------------------
 // resetView()
 //-----------------------------------------------------------------------------
-void LLAgent::resetView(BOOL reset_camera)
+void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
 {
 	if (mAutoPilot)
 	{
@@ -517,6 +517,30 @@ void LLAgent::resetView(BOOL reset_camera)
 		gMenuHolder->hideMenus();
 	}
 
+	if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
+	{
+		changeCameraToDefault();
+		
+		if (LLViewerJoystick::getInstance()->getOverrideCamera())
+		{
+			handle_toggle_flycam();
+		}
+
+		// reset avatar mode from eventual residual motion
+		if (LLToolMgr::getInstance()->inBuildMode())
+		{
+			LLViewerJoystick::getInstance()->moveAvatar(true);
+		}
+
+		gFloaterTools->close();
+		
+		gViewerWindow->showCursor();
+
+		// Switch back to basic toolset
+		LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+	}
+
+
 	if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
 	{
 		if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
@@ -1296,7 +1320,7 @@ LLQuaternion LLAgent::getQuat() const
 //-----------------------------------------------------------------------------
 // calcFocusOffset()
 //-----------------------------------------------------------------------------
-LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)
+LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y)
 {
 	// calculate offset based on view direction
 	BOOL is_avatar = object->isAvatar();
@@ -1399,7 +1423,7 @@ LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)
 	if (!is_avatar) 
 	{
 		//unproject relative clicked coordinate from window coordinate using GL
-		GLint viewport[4];
+		/*GLint viewport[4];
 		GLdouble modelview[16];
 		GLdouble projection[16];
 		GLfloat winX, winY, winZ;
@@ -1421,11 +1445,9 @@ LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)
 		winY = ((F32)y) * gViewerWindow->getDisplayScale().mV[VY];
 		glReadPixels( llfloor(winX), llfloor(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
 
-		gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
+		gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);*/
 
-		LLVector3 obj_rel((F32)posX, (F32)posY, (F32)posZ);
-		obj_rel = obj_rel * object->getRenderMatrix();
-		obj_rel -= object->getRenderPosition();
+		LLVector3 obj_rel = pos_agent - object->getRenderPosition();
 		
 		LLVector3 obj_center = LLVector3(0, 0, 0) * object->getRenderMatrix();
 
@@ -1940,6 +1962,8 @@ void LLAgent::cameraPanIn(F32 meters)
 	mFocusGlobal = mFocusTargetGlobal;
 	// don't enforce zoom constraints as this is the only way for users to get past them easily
 	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
 }
 
 //-----------------------------------------------------------------------------
@@ -1958,6 +1982,8 @@ void LLAgent::cameraPanLeft(F32 meters)
 	
 	cameraZoomIn(1.f);
 	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
 }
 
 //-----------------------------------------------------------------------------
@@ -1976,6 +2002,8 @@ void LLAgent::cameraPanUp(F32 meters)
 
 	cameraZoomIn(1.f);
 	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 851c47cbd5e..f6d983b3a3e 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -139,7 +139,7 @@ class LLAgent : public LLObservable
 
 	// Called whenever the agent moves.  Puts camera back in default position,
 	// deselects items, etc.
-	void			resetView(BOOL reset_camera = TRUE);
+	void			resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE);
 
 	// Called on camera movement, to allow the camera to be unlocked from the 
 	// default position behind the avatar.
@@ -378,7 +378,7 @@ class LLAgent : public LLObservable
 	void			sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
 	void			sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
 
-	LLVector3		calcFocusOffset(LLViewerObject *object, S32 x, S32 y);
+	LLVector3		calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y);
 	BOOL			calcCameraMinDistance(F32 &obj_min_distance);
 
 	void			startCameraAnimation();
diff --git a/indra/newview/llbox.cpp b/indra/newview/llbox.cpp
index 95e16cf8725..77979765eaa 100644
--- a/indra/newview/llbox.cpp
+++ b/indra/newview/llbox.cpp
@@ -81,7 +81,7 @@ void LLBox::renderface(S32 which_face)
 		{7, 4, 0, 3}
 	};
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 		//gGL.normal3fv(&normals[which_face][0]);
 		gGL.texCoord2f(1,0);
 		gGL.vertex3fv(&mVertex[ faces[which_face][0] ][0]);
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index d6b2a9e28ec..9138ad2644b 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -553,15 +553,17 @@ void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userda
 // static
 void LLChatBar::onClickSay( LLUICtrl* ctrl, void* userdata )
 {
-	LLChatBar* self = (LLChatBar*) userdata;
+	e_chat_type chat_type = CHAT_TYPE_NORMAL;
 	if (ctrl->getValue().asString() == "shout")
 	{
-		self->sendChat( CHAT_TYPE_SHOUT );
+		chat_type = CHAT_TYPE_SHOUT;
 	}
-	else
+	else if (ctrl->getValue().asString() == "whisper")
 	{
-		self->sendChat( CHAT_TYPE_NORMAL );
+		chat_type = CHAT_TYPE_WHISPER;
 	}
+	LLChatBar* self = (LLChatBar*) userdata;
+	self->sendChat(chat_type);
 }
 
 void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index b207c44e959..1592cc0a8b7 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -362,6 +362,7 @@ void LLDrawable::makeActive()
 		if (pcode == LLViewerObject::LL_VO_WATER ||
 			pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
 			pcode == LLViewerObject::LL_VO_PART_GROUP ||
+			pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
 			pcode == LLViewerObject::LL_VO_CLOUDS ||
 			pcode == LLViewerObject::LL_VO_GROUND ||
 			pcode == LLViewerObject::LL_VO_SKY)
@@ -1380,7 +1381,10 @@ BOOL LLDrawable::isAnimating() const
 	{
 		return TRUE;
 	}
-
+	if (mVObjp->getPCode() == LLViewerObject::LL_VO_HUD_PART_GROUP)
+	{
+		return TRUE;
+	}
 	if (mVObjp->getPCode() == LLViewerObject::LL_VO_CLOUDS)
 	{
 		return TRUE;
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index b7966f2b209..38a59f67c29 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -194,7 +194,8 @@ S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
 			 iter != face_list.end(); iter++)
 		{
 			LLFace *facep = *iter;
-			facep->bindTexture(stage);
+			gGL.getTexUnit(stage)->bind(facep->getTexture());
+			gGL.getTexUnit(0)->activate();
 			res += facep->renderIndexed();
 		}
 	}
@@ -395,7 +396,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
 	{
 		if (params.mTexture.notNull())
 		{
-			params.mTexture->bind();
+			gGL.getTexUnit(0)->bind(params.mTexture.get());
 			if (params.mTextureMatrix)
 			{
 				glMatrixMode(GL_TEXTURE);
@@ -406,14 +407,14 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
 		}
 		else
 		{
-			LLImageGL::unbindTexture(0);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
 	}
 	
 	if (params.mVertexBuffer.notNull())
 	{
 		params.mVertexBuffer->setBuffer(mask);
-		params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+		params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
 		gPipeline.addTrianglesDrawn(params.mCount/3);
 	}
 
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e7c89035619..f8acb21e5d2 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -129,7 +129,7 @@ void LLDrawPoolAlpha::render(S32 pass)
 		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
 		glColor4f(1,0,0,1);
 		LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f);
-        LLViewerImage::sSmokeImagep->bind();
+		gGL.getTexUnit(0)->bind(LLViewerImage::sSmokeImagep.get());
 		renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
 							LLVertexBuffer::MAP_TEXCOORD);
 	}
@@ -170,7 +170,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
 				LLRenderPass::applyModelMatrix(params);
 
 				params.mVertexBuffer->setBuffer(mask);
-				params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
 				gPipeline.addTrianglesDrawn(params.mCount/3);
 			}
 		}
@@ -231,7 +231,7 @@ void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask
 		if (texture && params.mTexture.notNull())
 		{
 			gGL.getTexUnit(0)->activate();
-			params.mTexture->bind();
+			gGL.getTexUnit(0)->bind(params.mTexture.get());
 			params.mTexture->addTextureStats(params.mVSize);
 			if (params.mTextureMatrix)
 			{
@@ -288,7 +288,7 @@ void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask
 		}
 
 		params.mVertexBuffer->setBuffer(mask);
-		params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+		params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
 		gPipeline.addTrianglesDrawn(params.mCount/3);
 
 		if (params.mTextureMatrix && texture && params.mTexture.notNull())
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index bb4af2268d0..d68afa6632b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -396,7 +396,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	{
 		
 		/* // debug code to draw a cube in place of avatar
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLVector3 pos = avatarp->getPositionAgent();
 
 		gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f);
@@ -495,17 +495,17 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	{
 		if (LLVOAvatar::sShowCollisionVolumes)
 		{
-			LLGLSNoTexture no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			avatarp->renderCollisionVolumes();
 		}
 
 		if (avatarp->mIsSelf && LLAgent::sDebugDisplayTarget)
 		{
-			LLGLSNoTexture gls_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLVector3 pos = avatarp->getPositionAgent();
 
 			gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
 				gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
@@ -517,7 +517,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 
 			pos = avatarp->mDrawable->getPositionAgent();
 			gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
 				gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
@@ -529,7 +529,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 
 			pos = avatarp->mRoot.getWorldPosition();
 			gGL.color4f(1.0f, 1.0f, 1.0f, 0.8f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
 				gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
@@ -541,7 +541,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 
 			pos = avatarp->mPelvisp->getWorldPosition();
 			gGL.color4f(0.0f, 0.0f, 1.0f, 0.8f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV);
 				gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 2556462cb47..ccf130be7a4 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -349,27 +349,29 @@ void LLDrawPoolBump::beginShiny(bool invisible)
 				cube_map->setMatrix(1);
 				// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for 
 				// the cube map in the one pass shiny shaders
-				cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
+				cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 				cube_map->enableTexture(cube_channel);
 				cube_map->enableTextureCoords(1);
 				diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 			}
 			else
 			{
-				cube_channel = 0;
+				cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 				diffuse_channel = -1;
 				cube_map->setMatrix(0);
-				cube_map->enable(shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB));
+				cube_map->enable(cube_channel);
 			}			
-			cube_map->bind();
+			gGL.getTexUnit(cube_channel)->bind(cube_map);
+			gGL.getTexUnit(0)->activate();
 		}
 		else
 		{
 			cube_channel = 0;
 			diffuse_channel = -1;
+			gGL.getTexUnit(0)->disable();
 			cube_map->enable(0);
 			cube_map->setMatrix(0);
-			cube_map->bind();
+			gGL.getTexUnit(0)->bind(cube_map);
 
 			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
 			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_VERT_ALPHA);
@@ -423,7 +425,7 @@ void LLDrawPoolBump::endShiny(bool invisible)
 
 		if (!invisible && mVertexShaderLevel > 1)
 		{
-			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
+			shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 					
 			if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0)
 			{
@@ -435,18 +437,21 @@ void LLDrawPoolBump::endShiny(bool invisible)
 
 			shader->unbind();
 			gGL.getTexUnit(0)->activate();
-			glEnable(GL_TEXTURE_2D);
+			gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 		}
 		if (cube_channel >= 0)
 		{
+			gGL.getTexUnit(cube_channel)->enable(LLTexUnit::TT_TEXTURE);
 			gGL.getTexUnit(cube_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
 		}
 	}
 	
-	gGL.getTexUnit(0)->activate();
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(diffuse_channel)->disable();
+	gGL.getTexUnit(cube_channel)->disable();
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-	
+
 	diffuse_channel = -1;
 	cube_channel = 0;
 	mShiny = FALSE;
@@ -489,12 +494,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
 		cube_map->setMatrix(1);
 		// Make sure that texture coord generation happens for tex unit 1, as that's the one we use for 
 		// the cube map in the one pass shiny shaders
-		cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
+		gGL.getTexUnit(1)->disable();
+		cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 		cube_map->enableTexture(cube_channel);
 		cube_map->enableTextureCoords(1);
 		diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 
-		cube_map->bind();
+		gGL.getTexUnit(cube_channel)->bind(cube_map);
+		gGL.getTexUnit(0)->activate();
 	}
 	mShiny = TRUE;
 }
@@ -535,14 +542,13 @@ void LLDrawPoolBump::endFullbrightShiny()
 			shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 		}
 		gGL.getTexUnit(0)->activate();
-		glEnable(GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 		shader->unbind();
-
 		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 	}
 	
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 
 	diffuse_channel = -1;
@@ -561,7 +567,7 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
 		applyModelMatrix(params);
 
 		params.mVertexBuffer->setBuffer(mask);
-		params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+		params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
 		gPipeline.addTrianglesDrawn(params.mCount/3);
 	}
 }
@@ -599,8 +605,8 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params)
 
 	if (bump)
 	{
-		bump->bind(1);
-		bump->bind(0);
+		gGL.getTexUnit(1)->bind(bump);
+		gGL.getTexUnit(0)->bind(bump);
 		return TRUE;
 	}
 	return FALSE;
@@ -629,7 +635,7 @@ void LLDrawPoolBump::beginBump()
 	// TEXTURE UNIT 1
 	gGL.getTexUnit(1)->activate();
  
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 
 	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD_SIGNED, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_ONE_MINUS_TEX_ALPHA);
 	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
@@ -648,7 +654,7 @@ void LLDrawPoolBump::beginBump()
 	gGL.getTexUnit(0)->activate();
 	stop_glerror();
 
-	LLViewerImage::unbindTexture(1, GL_TEXTURE_2D);
+	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 }
 
 //static
@@ -680,7 +686,7 @@ void LLDrawPoolBump::endBump()
 
 	// Disable texture unit 1
 	gGL.getTexUnit(1)->activate();
-	glDisable(GL_TEXTURE_2D); // Texture unit 1
+	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
 
 	// Disable texture unit 0
@@ -1083,17 +1089,17 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
 	{
 		if (params.mTexture.notNull())
 		{
-			params.mTexture->bind(diffuse_channel);
+			gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
 			params.mTexture->addTextureStats(params.mVSize);
 		}
 		else
 		{
-			LLImageGL::unbindTexture(0);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
 	}
 	
 	params.mVertexBuffer->setBuffer(mask);
-	params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+	params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
 	gPipeline.addTrianglesDrawn(params.mCount/3);
 	if (params.mTextureMatrix)
 	{
diff --git a/indra/newview/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
index c7e8aa32b7f..5c719339b9a 100644
--- a/indra/newview/lldrawpoolground.cpp
+++ b/indra/newview/lldrawpoolground.cpp
@@ -63,13 +63,14 @@ void LLDrawPoolGround::prerender()
 
 void LLDrawPoolGround::render(S32 pass)
 {
-	if (mDrawFace.empty())
+	if (mDrawFace.empty() || !gSavedSettings.getBOOL("RenderGround"))
 	{
 		return;
 	}	
 	
 	LLGLSPipelineSkyBox gls_skybox;
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 
 	LLGLClampToFarClip far_clip(glh_get_current_projection());
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 2687e6d2c0b..1210391360f 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -186,7 +186,7 @@ void LLDrawPoolSky::renderHeavenlyBody(U8 hb, LLFace* face)
 	if (! face->getGeomCount()) return;
 
 	LLImageGL* tex = face->getTexture();
-	tex->bind();
+	gGL.getTexUnit(0)->bind(tex);
 	LLColor4 color(mHB[hb]->getInterpColor());
 	LLOverrideFaceColor override(this, color);
 	face->renderIndexed();
@@ -200,7 +200,7 @@ void LLDrawPoolSky::renderSunHalo(LLFace* face)
 	if (! face->getGeomCount()) return;
 
 	LLImageGL* tex = face->getTexture();
-	tex->bind();
+	gGL.getTexUnit(0)->bind(tex);
 	LLColor4 color(mHB[0]->getInterpColor());
 	color.mV[3] = llclamp(mHB[0]->getHaloBrighness(), 0.f, 1.f);
 
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index e5850a00572..4a27b7f6a7a 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -72,19 +72,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) :
 													TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
 													LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
 
-	mAlphaRampImagep->bind(0);
+	gGL.getTexUnit(0)->bind(mAlphaRampImagep.get());
 	mAlphaRampImagep->setClamp(TRUE, TRUE);
 
 	m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c",
 													TRUE, TRUE, GL_ALPHA8, GL_ALPHA,
 													LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
 
-	m2DAlphaRampImagep->bind(0);
+	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 	m2DAlphaRampImagep->setClamp(TRUE, TRUE);
 	
 	mTexturep->setBoostLevel(LLViewerImage::BOOST_TERRAIN);
 	
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
 
 LLDrawPoolTerrain::~LLDrawPoolTerrain()
@@ -240,7 +240,7 @@ void LLDrawPoolTerrain::renderFullShader()
 	// detail texture 0
 	//
 	S32 detail0 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL0);
-	LLViewerImage::bindTexture(detail_texture0p,detail0);
+	gGL.getTexUnit(detail0)->bind(detail_texture0p);
 	gGL.getTexUnit(0)->activate();
 
 	glEnable(GL_TEXTURE_GEN_S);
@@ -258,7 +258,7 @@ void LLDrawPoolTerrain::renderFullShader()
 	// detail texture 1
 	//
 	S32 detail1 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL1); 
-	LLViewerImage::bindTexture(detail_texture1p,detail1);
+	gGL.getTexUnit(detail1)->bind(detail_texture1p);
 	
 	/// ALPHA TEXTURE COORDS 0:
 	gGL.getTexUnit(1)->activate();
@@ -269,11 +269,11 @@ void LLDrawPoolTerrain::renderFullShader()
 	// detail texture 2
 	//
 	S32 detail2 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
-	LLViewerImage::bindTexture(detail_texture2p,detail2);
-	glEnable(GL_TEXTURE_2D);
+	gGL.getTexUnit(detail2)->bind(detail_texture2p);
+
+	gGL.getTexUnit(2)->activate();
 	
 	/// ALPHA TEXTURE COORDS 1:
-	gGL.getTexUnit(2)->activate();
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glTranslatef(-2.f, 0.f, 0.f);
@@ -283,7 +283,7 @@ void LLDrawPoolTerrain::renderFullShader()
 	// detail texture 3
 	//
 	S32 detail3 = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
-	LLViewerImage::bindTexture(detail_texture3p,detail3);
+	gGL.getTexUnit(detail3)->bind(detail_texture3p);
 	
 	/// ALPHA TEXTURE COORDS 2:
 	gGL.getTexUnit(3)->activate();
@@ -296,7 +296,7 @@ void LLDrawPoolTerrain::renderFullShader()
 	// Alpha Ramp 
 	//
 	S32 alpha_ramp = sShader->enableTexture(LLViewerShaderMgr::TERRAIN_ALPHARAMP);
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,alpha_ramp);
+	gGL.getTexUnit(alpha_ramp)->bind(m2DAlphaRampImagep.get());
 		
 	// GL_BLEND disabled by default
 	drawLoop();
@@ -308,36 +308,36 @@ void LLDrawPoolTerrain::renderFullShader()
 	sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL2);
 	sShader->disableTexture(LLViewerShaderMgr::TERRAIN_DETAIL3);
 
-	LLImageGL::unbindTexture(alpha_ramp, GL_TEXTURE_2D);
+	gGL.getTexUnit(alpha_ramp)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(4)->disable();
 	gGL.getTexUnit(4)->activate();
-	glDisable(GL_TEXTURE_2D); // Texture unit 4
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 
-	LLImageGL::unbindTexture(detail3, GL_TEXTURE_2D);
+	gGL.getTexUnit(detail3)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(3)->disable();
 	gGL.getTexUnit(3)->activate();
-	glDisable(GL_TEXTURE_2D);	
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 
-	LLImageGL::unbindTexture(detail2, GL_TEXTURE_2D);
+	gGL.getTexUnit(detail2)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(2)->disable();
 	gGL.getTexUnit(2)->activate();
-	glDisable(GL_TEXTURE_2D);		
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 
-	LLImageGL::unbindTexture(detail1, GL_TEXTURE_2D);
+	gGL.getTexUnit(detail1)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->activate();
-	glDisable(GL_TEXTURE_2D);		
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
@@ -347,9 +347,9 @@ void LLDrawPoolTerrain::renderFullShader()
 	//----------------------------------------------------------------------------
 	// Restore Texture Unit 0 defaults
 	
-	LLImageGL::unbindTexture(detail0, GL_TEXTURE_2D);
+	gGL.getTexUnit(detail0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(0)->activate();
-	glEnable(GL_TEXTURE_2D);
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
@@ -388,7 +388,7 @@ void LLDrawPoolTerrain::renderFull4TU()
 	// Stage 0: detail texture 0
 	//
 	gGL.getTexUnit(0)->activate();
-	LLViewerImage::bindTexture(detail_texture0p,0);
+	gGL.getTexUnit(0)->bind(detail_texture0p);
 	glClientActiveTextureARB(GL_TEXTURE0_ARB);
 	
 	glEnable(GL_TEXTURE_GEN_S);
@@ -405,9 +405,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	// Stage 1: Generate alpha ramp for detail0/detail1 transition
 	//
 
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,1);
+	gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
 	glClientActiveTextureARB(GL_TEXTURE1_ARB);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
@@ -418,12 +418,13 @@ void LLDrawPoolTerrain::renderFull4TU()
 	//
 	// Stage 2: Interpolate detail1 with existing based on ramp
 	//
-	LLViewerImage::bindTexture(detail_texture1p,2);
+	gGL.getTexUnit(2)->bind(detail_texture1p);
+	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(2)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 2
-	glClientActiveTextureARB(GL_TEXTURE2_ARB);
 
+	glClientActiveTextureARB(GL_TEXTURE2_ARB);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
 	glEnable(GL_TEXTURE_GEN_S);
 	glEnable(GL_TEXTURE_GEN_T);
 	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
@@ -436,9 +437,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	//
 	// Stage 3: Modulate with primary (vertex) color for lighting
 	//
-	LLViewerImage::bindTexture(detail_texture1p,3); // bind any texture
+	gGL.getTexUnit(3)->bind(detail_texture1p);
+	gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(3)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 3
 	glClientActiveTextureARB(GL_TEXTURE3_ARB);
 
 	// Set alpha texture and do lighting modulation
@@ -456,7 +457,7 @@ void LLDrawPoolTerrain::renderFull4TU()
 	// Stage 0: Write detail3 into base
 	//
 	gGL.getTexUnit(0)->activate();
-	LLViewerImage::bindTexture(detail_texture3p,0);
+	gGL.getTexUnit(0)->bind(detail_texture3p);
 	glClientActiveTextureARB(GL_TEXTURE0_ARB);
 
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -472,9 +473,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	//
 	// Stage 1: Generate alpha ramp for detail2/detail3 transition
 	//
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,1);
+	gGL.getTexUnit(1)->bind(m2DAlphaRampImagep.get());
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
 	glClientActiveTextureARB(GL_TEXTURE1_ARB);
 
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -492,9 +493,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	//
 	// Stage 2: Interpolate detail2 with existing based on ramp
 	//
-	LLViewerImage::bindTexture(detail_texture2p,2);
+	gGL.getTexUnit(2)->bind(detail_texture2p);
+	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(2)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 2
 
 	glClientActiveTextureARB(GL_TEXTURE2_ARB);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -511,9 +512,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	//
 	// Stage 3: Generate alpha ramp for detail1/detail2 transition
 	//
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,3);
+	gGL.getTexUnit(3)->bind(m2DAlphaRampImagep.get());
+	gGL.getTexUnit(3)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(3)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 3
 
 	glClientActiveTextureARB(GL_TEXTURE3_ARB);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -536,21 +537,21 @@ void LLDrawPoolTerrain::renderFull4TU()
 
 	LLVertexBuffer::unbind();
 	// Disable multitexture
-	LLImageGL::unbindTexture(3, GL_TEXTURE_2D);
+	gGL.getTexUnit(3)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(3)->disable();
 	gGL.getTexUnit(3)->activate();
 	glClientActiveTextureARB(GL_TEXTURE3_ARB);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisable(GL_TEXTURE_2D); // Texture unit 3
 
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 
-	LLImageGL::unbindTexture(2, GL_TEXTURE_2D);
+	gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(2)->disable();
 	gGL.getTexUnit(2)->activate();
 	glClientActiveTextureARB(GL_TEXTURE2_ARB);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisable(GL_TEXTURE_2D); // Texture unit 2
 
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
@@ -558,11 +559,11 @@ void LLDrawPoolTerrain::renderFull4TU()
 	glLoadIdentity();
 	glMatrixMode(GL_MODELVIEW);
 
-	LLImageGL::unbindTexture(1, GL_TEXTURE_2D);
+	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);	
+	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->activate();
  	glClientActiveTextureARB(GL_TEXTURE1_ARB);
  	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisable(GL_TEXTURE_2D); // Texture unit 1
 
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
@@ -575,9 +576,9 @@ void LLDrawPoolTerrain::renderFull4TU()
 	// Restore Texture Unit 0 defaults
 	
 	gGL.getTexUnit(0)->activate();
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
 	glClientActiveTextureARB(GL_TEXTURE0_ARB);
-	gGL.getTexUnit(0)->activate();
 	glDisableClientState(GL_NORMAL_ARRAY);
 
 	glDisable(GL_TEXTURE_GEN_S);
@@ -616,7 +617,7 @@ void LLDrawPoolTerrain::renderFull2TU()
 	//
 	// Stage 0: Render detail 0 into base
 	//
-	LLViewerImage::bindTexture(detail_texture0p,0);
+	gGL.getTexUnit(0)->bind(detail_texture0p);
 	glEnable(GL_TEXTURE_GEN_S);
 	glEnable(GL_TEXTURE_GEN_T);
 	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
@@ -635,7 +636,7 @@ void LLDrawPoolTerrain::renderFull2TU()
 	//
 	// Stage 0: Generate alpha ramp for detail0/detail1 transition
 	//
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,0);
+	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 	
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
@@ -648,9 +649,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	//
 	// Stage 1: Write detail1
 	//
-	LLViewerImage::bindTexture(detail_texture1p,1); // Texture unit 1
+	gGL.getTexUnit(1)->bind(detail_texture1p);
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D);		// Texture unit 1
 
 	glEnable(GL_TEXTURE_GEN_S);
 	glEnable(GL_TEXTURE_GEN_T);
@@ -673,7 +674,7 @@ void LLDrawPoolTerrain::renderFull2TU()
 	//
 	// Stage 0: Generate alpha ramp for detail1/detail2 transition
 	//
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,0);
+	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 
 	// Set the texture matrix
 	glMatrixMode(GL_TEXTURE);
@@ -687,9 +688,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	//
 	// Stage 1: Write detail2
 	//
-	LLViewerImage::bindTexture(detail_texture2p,1);
+	gGL.getTexUnit(1)->bind(detail_texture2p);
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
 	
 	glEnable(GL_TEXTURE_GEN_S);
 	glEnable(GL_TEXTURE_GEN_T);
@@ -713,7 +714,7 @@ void LLDrawPoolTerrain::renderFull2TU()
 	// Stage 0: Generate alpha ramp for detail2/detail3 transition
 	//
 	gGL.getTexUnit(0)->activate();
-	LLViewerImage::bindTexture(m2DAlphaRampImagep,0);	
+	gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 	// Set the texture matrix
 	glMatrixMode(GL_TEXTURE);
 	glLoadIdentity();
@@ -724,9 +725,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
 
 	// Stage 1: Write detail3
-	LLViewerImage::bindTexture(detail_texture3p,1);
+	gGL.getTexUnit(1)->bind(detail_texture3p);
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.getTexUnit(1)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
 
 	glEnable(GL_TEXTURE_GEN_S);
 	glEnable(GL_TEXTURE_GEN_T);
@@ -749,9 +750,9 @@ void LLDrawPoolTerrain::renderFull2TU()
 	
 	// Disable multitexture
 	
-	LLImageGL::unbindTexture(1, GL_TEXTURE_2D);
+	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->disable();
 	gGL.getTexUnit(1)->activate();
-	glDisable(GL_TEXTURE_2D); // Texture unit 1
 
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
@@ -763,9 +764,8 @@ void LLDrawPoolTerrain::renderFull2TU()
 	// Restore Texture Unit 0 defaults
 	
 	gGL.getTexUnit(0)->activate();
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-	gGL.getTexUnit(0)->activate();
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
@@ -784,10 +784,10 @@ void LLDrawPoolTerrain::renderSimple()
 
 	// Stage 0: Base terrain texture pass
 	mTexturep->addTextureStats(1024.f*1024.f);
-	mTexturep->bind(0);
 
 	gGL.getTexUnit(0)->activate();
-	glEnable(GL_TEXTURE_2D); // Texture unit 2
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->bind(mTexturep.get());
 	
 	LLVector3 origin_agent = mDrawFace[0]->getDrawable()->getVObj()->getRegion()->getOriginAgent();
 	F32 tscale = 1.f/256.f;
@@ -808,8 +808,8 @@ void LLDrawPoolTerrain::renderSimple()
 	//----------------------------------------------------------------------------
 	// Restore Texture Unit 0 defaults
 	
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
 	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	glDisable(GL_TEXTURE_GEN_S);
 	glDisable(GL_TEXTURE_GEN_T);
 	glMatrixMode(GL_TEXTURE);
@@ -839,7 +839,7 @@ void LLDrawPoolTerrain::renderOwnership()
 	LLViewerParcelOverlay	*overlayp			= regionp->getParcelOverlay();
 	LLImageGL				*texturep			= overlayp->getTexture();
 
-	LLViewerImage::bindTexture(texturep);
+	gGL.getTexUnit(0)->bind(texturep);
 
 	// *NOTE: Because the region is 256 meters wide, but has 257 pixels, the 
 	// texture coordinates for pixel 256x256 is not 1,1. This makes the
@@ -872,7 +872,7 @@ void LLDrawPoolTerrain::renderForSelect()
 	}
 
 	
-	LLImageGL::unbindTexture(0);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 		 iter != mDrawFace.end(); iter++)
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 33f23ab6fa3..cb4a0b9fd68 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -50,7 +50,7 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) :
 	LLFacePool(POOL_TREE),
 	mTexturep(texturep)
 {
-	mTexturep->bind(0);
+	gGL.getTexUnit(0)->bind(mTexturep.get());
 	mTexturep->setClamp(FALSE, FALSE);
 }
 
@@ -124,6 +124,7 @@ void LLDrawPoolTree::renderForSelect()
 	LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
 
 	LLGLSObjectSelectAlpha gls_alpha;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	gGL.setSceneBlendType(LLRender::BT_REPLACE);
 	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
@@ -144,7 +145,7 @@ void LLDrawPoolTree::renderTree(BOOL selecting)
 	LLGLState normalize(GL_NORMALIZE, TRUE);
 	
 	// Bind the texture for this tree.
-	LLViewerImage::bindTexture(mTexturep,sDiffTex);
+	gGL.getTexUnit(sDiffTex)->bind(mTexturep.get());
 		
 	U32 indices_drawn = 0;
 
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index f7770f001c6..018092373a0 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -68,11 +68,11 @@ LLDrawPoolWater::LLDrawPoolWater() :
 	LLFacePool(POOL_WATER)
 {
 	mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE);
-	mHBTex[0]->bind();
+	gGL.getTexUnit(0)->bind(mHBTex[0].get());
 	mHBTex[0]->setClamp(TRUE, TRUE);
 
 	mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
-	mHBTex[1]->bind();
+	gGL.getTexUnit(0)->bind(mHBTex[1].get());
 	mHBTex[1]->setClamp(TRUE, TRUE);
 
 	mWaterImagep = gImageList.getImage(WATER_TEST);
@@ -166,10 +166,9 @@ void LLDrawPoolWater::render(S32 pass)
 	
 	// Set up second pass first
 	mWaterImagep->addTextureStats(1024.f*1024.f);
-	mWaterImagep->bind(1);
 	gGL.getTexUnit(1)->activate();
-	
-	glEnable(GL_TEXTURE_2D); // Texture unit 1
+	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(1)->bind(mWaterImagep.get());
 
 	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
 	F32 up_dot = camera_up * LLVector3::z_axis;
@@ -218,20 +217,20 @@ void LLDrawPoolWater::render(S32 pass)
 		{
 			continue;
 		}
-		face->bindTexture();
+		gGL.getTexUnit(0)->bind(face->getTexture());
 		face->renderIndexed();
 	}
 
 	// Now, disable texture coord generation on texture state 1
 	gGL.getTexUnit(1)->activate();
-	glDisable(GL_TEXTURE_2D); // Texture unit 1
+	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
-	LLImageGL::unbindTexture(1, GL_TEXTURE_2D);
 
 	// Disable texture coordinate and color arrays
 	gGL.getTexUnit(0)->activate();
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	stop_glerror();
 	
@@ -275,8 +274,9 @@ void LLDrawPoolWater::render(S32 pass)
 		{
 			gSky.mVOSkyp->getCubeMap()->disable();
 		}
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
-		glEnable(GL_TEXTURE_2D);
+		
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 		glMatrixMode(GL_TEXTURE);
 		glLoadIdentity();
 		glMatrixMode(GL_MODELVIEW);
@@ -316,7 +316,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
 
 	LLGLSNoFog noFog;
 
-	LLViewerImage::bindTexture(mHBTex[dr]);
+	gGL.getTexUnit(0)->bind(mHBTex[dr].get());
 
 	LLOverrideFaceColor override(this, face->getFaceColor().mV);
 	face->renderIndexed();
@@ -390,7 +390,7 @@ void LLDrawPoolWater::shade()
 	if (reftex > -1)
 	{
 		gGL.getTexUnit(reftex)->activate();
-		gPipeline.mWaterRef.bindTexture();
+		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
 		gGL.getTexUnit(0)->activate();
 	}	
 
@@ -406,7 +406,7 @@ void LLDrawPoolWater::shade()
 	}
 
 	mWaterNormp->addTextureStats(1024.f*1024.f);
-	mWaterNormp->bind(bumpTex);
+	gGL.getTexUnit(bumpTex)->bind(mWaterNormp.get());
 	mWaterNormp->setMipFilterNearest (mWaterNormp->getMipFilterNearest(),
 									  !gSavedSettings.getBOOL("RenderWaterMipNormal"));
 	
@@ -421,8 +421,8 @@ void LLDrawPoolWater::shade()
 		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
 			param_mgr->getFogDensity());
 	}
-	
-	gPipeline.mWaterDis.bindTexture();
+
+	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
 
 	if (mVertexShaderLevel == 1)
 	{
@@ -502,7 +502,7 @@ void LLDrawPoolWater::shade()
 			}
 
 			LLVOWater* water = (LLVOWater*) face->getViewerObject();
-			face->bindTexture(diffTex);
+			gGL.getTexUnit(diffTex)->bind(face->getTexture());
 
 			sNeedsReflectionUpdate = TRUE;
 			
@@ -527,7 +527,7 @@ void LLDrawPoolWater::shade()
 		}
 	}
 	
-	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
+	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
 	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
 	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
@@ -536,7 +536,7 @@ void LLDrawPoolWater::shade()
 	shader->unbind();
 
 	gGL.getTexUnit(0)->activate();
-	glEnable(GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	gGL.setColorMask(true, false);
 
 }
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 9f22d2aa0fd..d8aa555752e 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -159,7 +159,7 @@ void LLDrawPoolWLSky::renderStars(void) const
 	// *NOTE: have to have bound the cloud noise texture already since register
 	// combiners blending below requires something to be bound
 	// and we might as well only bind once.
-	//LLGLEnable gl_texture_2d(GL_TEXTURE_2D);
+	//gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	
 	gPipeline.disableLights();
 
@@ -202,7 +202,8 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
 		LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 
-		sCloudNoiseTexture->bind();
+		gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
+
 		shader->bind();
 
 		/// Render the skydome
@@ -223,7 +224,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
 	if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
 	{
 		LLImageGL * tex  = face->getTexture();
-		tex->bind();
+		gGL.getTexUnit(0)->bind(tex);
 		LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
 		LLFacePool::LLOverrideFaceColor color_override(this, color);
 		face->renderIndexed();
@@ -238,7 +239,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
 		// stars register combiners, we bind again here for defensive reasons,
 		// since LLImageGL::bind detects that it's a noop, and optimizes it out.
 		LLImageGL * tex  = face->getTexture();
-		tex->bind();
+		gGL.getTexUnit(0)->bind(tex);
 		LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
 		F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
 		if (a > 0.f)
@@ -280,7 +281,7 @@ void LLDrawPoolWLSky::render(S32 pass)
 		// renderStars() requires something to be bound and we might as well only
 		// bind the moon's texture once.
 		LLImageGL * tex  = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture();
-		tex->bind();
+		gGL.getTexUnit(0)->bind(tex);
 
 		renderHeavenlyBodies();
 
@@ -291,7 +292,7 @@ void LLDrawPoolWLSky::render(S32 pass)
 
 	renderSkyClouds(camHeightLocal);
 
-	LLImageGL::unbindTexture(0);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
 
 void LLDrawPoolWLSky::prerender()
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index d29ac9b43ae..f8ba382a74e 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -32,7 +32,6 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "lldynamictexture.h"
-#include "llimagegl.h"
 #include "llglheaders.h"
 #include "llviewerwindow.h"
 #include "llviewercamera.h"
@@ -105,7 +104,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima
 	}
 	releaseGLTexture();
 	LLPointer<LLImageRaw> raw_image = new LLImageRaw(mWidth, mHeight, mComponents);
-	mTexture = new LLImageGL(mWidth, mHeight, mComponents, FALSE);
+	mTexture = new LLViewerImage(mWidth, mHeight, mComponents, FALSE);
 	if (internal_format >= 0)
 	{
 		mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
@@ -113,6 +112,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima
 // 	llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl;
 	mTexture->createGLTexture(0, raw_image);
 	mTexture->setClamp(mClamp, mClamp);
+	mTexture->setInitialized(false);
 }
 
 //-----------------------------------------------------------------------------
@@ -144,7 +144,7 @@ void LLDynamicTexture::preRender(BOOL clear_depth)
 			mOrigin.mY = llmax(mOrigin.mY, 0) ;
 		}
 
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 	// Set up camera
 	mCamera.setOrigin(*LLViewerCamera::getInstance());
@@ -183,19 +183,6 @@ void LLDynamicTexture::postRender(BOOL success)
 	LLViewerCamera::getInstance()->setNear(mCamera.getNear());
 }
 
-//-----------------------------------------------------------------------------
-// bindTexture()
-//-----------------------------------------------------------------------------
-void LLDynamicTexture::bindTexture()
-{
-	LLViewerImage::bindTexture(mTexture,0);
-}
-
-void LLDynamicTexture::unbindTexture()
-{
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
-}
-
 //-----------------------------------------------------------------------------
 // static
 // updateDynamicTextures()
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 9f647232c58..2e7ba1d4223 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -60,8 +60,8 @@ class LLDynamicTexture
 	virtual void preRender(BOOL clear_depth = TRUE);
 	virtual BOOL render();
 	virtual void postRender(BOOL success);
-	virtual void bindTexture();
-	virtual void unbindTexture();
+
+	LLImageGL* getTexture(void) const { return mTexture; }
 
 	static BOOL	updateAllInstances();
 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 05b873eae46..4f49aa584f3 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -362,10 +362,10 @@ void LLFace::renderForSelect(U32 data_mask)
 			switch (getPoolType())
 			{
 			case LLDrawPool::POOL_ALPHA:
-				getTexture()->bind();
+				gGL.getTexUnit(0)->bind(getTexture());
 				break;
 			default:
-				LLImageGL::unbindTexture(0);
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				break;
 			}
 		}
@@ -390,19 +390,19 @@ void LLFace::renderForSelect(U32 data_mask)
 				{
 					glPushMatrix();
 					glMultMatrixf((float*) mDrawablep->getRegion()->mRenderMatrix.mMatrix);
-					mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex);
+					mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
 					glPopMatrix();
 				}
 				else
 				{
-					mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex);
+					mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
 				}
 			}
 			else
 			{
 				glPushMatrix();
 				glMultMatrixf((float*)getRenderMatrix().mMatrix);
-				mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex);
+				mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
 				glPopMatrix();
 			}
 		}
@@ -419,7 +419,7 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
 
 	if (mGeomCount > 0 && mIndicesCount > 0)
 	{
-		LLViewerImage::bindTexture(imagep);
+		gGL.getTexUnit(0)->bind(imagep);
 	
 		gGL.pushMatrix();
 		if (mDrawablep->isActive())
@@ -438,7 +438,7 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color)
 #if !LL_RELEASE_FOR_DOWNLOAD
 		LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD);
 #endif
-		mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, mIndicesCount, mIndicesIndex);
+		mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
 				
 		unsetFaceColor();
 		gGL.popMatrix();
@@ -1203,7 +1203,7 @@ S32 LLFace::pushVertices(const U16* index_array) const
 {
 	if (mIndicesCount)
 	{
-		mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
+		mVertexBuffer->drawRange(LLRender::TRIANGLES, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
 		gPipeline.addTrianglesDrawn(mIndicesCount/3);
 	}
 
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 9e7a33eb7b5..9253bb46fb7 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -101,7 +101,6 @@ class LLFace
 	void			setPixelArea(F32 area)	{ mPixelArea = area; }
 	F32				getVirtualSize() const { return mVSize; }
 	F32				getPixelArea() const { return mPixelArea; }
-	void			bindTexture(S32 stage = 0)		const	{ LLViewerImage::bindTexture(mTexture, stage); }
 
 	void			renderSetColor() const;
 	S32				renderElements(const U16 *index_array) const;
@@ -120,6 +119,7 @@ class LLFace
 	LLVertexBuffer* getVertexBuffer()	const	{ return mVertexBuffer; }
 	void			setPoolType(U32 type)		{ mPoolType = type; }
 	S32				getTEOffset()				{ return mTEOffset; }
+	LLViewerImage*	getTexture()				{ return mTexture; }
 
 	void			setViewerObject(LLViewerObject* object);
 	void			setPool(LLFacePool *pool, LLViewerImage *texturep);
diff --git a/indra/newview/llface.inl b/indra/newview/llface.inl
index aa944931961..38f38f5466e 100644
--- a/indra/newview/llface.inl
+++ b/indra/newview/llface.inl
@@ -33,6 +33,7 @@
 #define LL_LLFACE_INL
 
 #include "llglheaders.h"
+#include "llrender.h"
 
 inline BOOL LLFace::getDirty() const
 { 
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index e224ee57c09..54730af145e 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -116,6 +116,7 @@ static struct ft_display_info ft_display_table[] =
 	{ LLFastTimer::FTM_VFILE_WAIT,			"  VFile Wait",		&LLColor4::cyan6, 0 },
 //	{ LLFastTimer::FTM_IDLE_CB,				"  Callbacks",		&LLColor4::pink1, 0 },
 	{ LLFastTimer::FTM_RENDER,				" Render",			&green0, 1 },
+	{ LLFastTimer::FTM_PICK,				"  Pick",			&LLColor4::purple, 1 },
 	{ LLFastTimer::FTM_HUD_EFFECTS,			"  HUD Effects",	&LLColor4::orange1, 0 },
 	{ LLFastTimer::FTM_HUD_UPDATE,			"  HUD Update",	&LLColor4::orange2, 0 },
 	{ LLFastTimer::FTM_UPDATE_SKY,			"  Sky Update",		&LLColor4::cyan1, 0 },
@@ -463,7 +464,7 @@ void LLFastTimerView::draw()
 	
 	// Draw the window background
 	{
-		LLGLSNoTexture gls_ui_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
 	}
 	
@@ -755,7 +756,7 @@ void LLFastTimerView::draw()
 		LLRect graph_rect;
 		// Draw borders
 		{
-			LLGLSNoTexture gls_ui_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			gGL.color4f(0.5f,0.5f,0.5f,0.5f);
 
 			S32 by = y + 2;
@@ -792,7 +793,7 @@ void LLFastTimerView::draw()
 		
 		// Draw bars for each history entry
 		// Special: -1 = show running average
-		LLViewerImage::bindTexture(box_imagep->getImage());
+		gGL.getTexUnit(0)->bind(box_imagep->getImage());
 		for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++)
 		{
 			int sublevel_dx[FTV_DISPLAY_NUM+1];
@@ -936,7 +937,7 @@ void LLFastTimerView::draw()
 		
 		//draw line graph history
 		{
-			LLGLSNoTexture no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLLocalClipRect clip(graph_rect);
 			
 			//normalize based on last frame's maximum
@@ -980,7 +981,7 @@ void LLFastTimerView::draw()
 
 					gGL.color4f(0.5f,0.5f,0.5f,1);
 				
-					gGL.begin(LLVertexBuffer::LINES);
+					gGL.begin(LLRender::LINES);
 					gGL.vertex2i((S32)bar, graph_rect.mBottom);
 					gGL.vertex2i((S32)bar, graph_rect.mTop);
 					gGL.end();
@@ -1016,7 +1017,7 @@ void LLFastTimerView::draw()
 				}
 
 				gGL.color4f(col[0], col[1], col[2], alpha);				
-				gGL.begin(LLVertexBuffer::LINE_STRIP);
+				gGL.begin(LLRender::LINE_STRIP);
 				for (U32 j = 0; j < LLFastTimer::FTM_HISTORY_NUM; j++)
 				{
 					U64 ticks = ticks_sum[j+1][idx];
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ecc40aa0940..b43838a3a43 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -447,8 +447,6 @@ void LLFeatureManager::applyRecommendedSettings()
 	{
 		gSavedSettings.setF32("RenderFarClip", 128.0f);
 	}
-
-
 }
 
 void LLFeatureManager::applyFeatures(bool skipFeatures)
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 2d595bc4929..6c42a71fe64 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -384,9 +384,10 @@ void LLFloaterAnimPreview::draw()
 	if (mMotionID.notNull() && mAnimPreview)
 	{
 		gGL.color3f(1.f, 1.f, 1.f);
-		mAnimPreview->bindTexture();
 
-		gGL.begin( LLVertexBuffer::QUADS );
+		gGL.getTexUnit(0)->bind(mAnimPreview->getTexture());
+
+		gGL.begin( LLRender::QUADS );
 		{
 			gGL.texCoord2f(0.f, 1.f);
 			gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
@@ -399,7 +400,7 @@ void LLFloaterAnimPreview::draw()
 		}
 		gGL.end();
 
-		mAnimPreview->unbindTexture();
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
 		if (!avatarp->areAnimationsPaused())
@@ -1068,7 +1069,7 @@ BOOL	LLPreviewAnimation::render()
 	glLoadIdentity();
 
 	LLGLSUIDefault def;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
 
 	gl_rect_2d_simple( mWidth, mHeight );
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 480ef708d60..a90d11f6eaa 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -148,7 +148,7 @@ void LLFloaterAuction::draw()
 		if (childGetRect("snapshot_icon", rect))
 		{
 			{
-				LLGLSNoTexture gls_no_texture;
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
 				rect.stretch(-1);
 			}
@@ -205,7 +205,7 @@ void LLFloaterAuction::onClickSnapshot(void* data)
 		LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE);
 
 		self->mImage = new LLImageGL((LLImageRaw*)raw, FALSE);
-		self->mImage->bind();
+		gGL.getTexUnit(0)->bind(self->mImage);
 		self->mImage->setClamp(TRUE, TRUE);
 	}
 	else
diff --git a/indra/newview/llfloaterbeacons.cpp b/indra/newview/llfloaterbeacons.cpp
new file mode 100644
index 00000000000..a49995adae4
--- /dev/null
+++ b/indra/newview/llfloaterbeacons.cpp
@@ -0,0 +1,150 @@
+/** 
+ * @file llfloaterbeacons.cpp
+ * @brief Front-end to LLPipeline controls for highlighting various kinds of objects.
+ * @author Coco
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2007, Linden Research, Inc.
+ * 
+ * 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterbeacons.h"
+#include "llviewercontrol.h"
+#include "lluictrlfactory.h"
+#include "llcheckboxctrl.h"
+#include "pipeline.h"
+
+
+LLFloaterBeacons::LLFloaterBeacons(const LLSD& seed)
+{
+	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_beacons.xml");
+
+	// Initialize pipeline states from saved settings.
+	// OK to do at floater constructor time because beacons do not display unless the floater is open
+	// therefore it is OK to not initialize the pipeline state before needed.
+	// Note also that we should replace those pipeline statics with direct lookup of the saved settings
+	// eliminating the need to keep these states in sync.
+	LLPipeline::setRenderScriptedTouchBeacons(gSavedSettings.getBOOL("scripttouchbeacon"));
+	LLPipeline::setRenderScriptedBeacons(     gSavedSettings.getBOOL("scriptsbeacon"));
+	LLPipeline::setRenderPhysicalBeacons(     gSavedSettings.getBOOL("physicalbeacon"));
+	LLPipeline::setRenderSoundBeacons(        gSavedSettings.getBOOL("soundsbeacon"));
+	LLPipeline::setRenderParticleBeacons(     gSavedSettings.getBOOL("particlesbeacon"));
+	LLPipeline::setRenderHighlights(          gSavedSettings.getBOOL("renderhighlights"));
+	LLPipeline::setRenderBeacons(             gSavedSettings.getBOOL("renderbeacons"));
+}
+
+BOOL LLFloaterBeacons::postBuild()
+{
+	childSetCommitCallback("touch_only",      onClickUICheck, this);
+	childSetCommitCallback("scripted",        onClickUICheck, this);
+	childSetCommitCallback("physical",        onClickUICheck, this);
+	childSetCommitCallback("sounds",          onClickUICheck, this);
+	childSetCommitCallback("particles",       onClickUICheck, this);
+	childSetCommitCallback("highlights",      onClickUICheck, this);
+	childSetCommitCallback("beacons",         onClickUICheck, this);
+	return TRUE;
+}
+
+// Needed to make the floater visibility toggle the beacons.
+// Too bad we can't just add control_name="BeaconAlwaysOn" to the XML.
+void LLFloaterBeacons::open()
+{
+	LLFloater::open();
+	gSavedSettings.setBOOL( "BeaconAlwaysOn", TRUE);
+}
+void LLFloaterBeacons::close(bool app_quitting)
+{
+	LLFloater::close(app_quitting);
+	if(!app_quitting)
+	{
+		gSavedSettings.setBOOL( "BeaconAlwaysOn", FALSE);
+	}
+}
+
+// Callback attached to each check box control to both affect their main purpose
+// and to implement the couple screwy interdependency rules that some have.
+//static 
+void LLFloaterBeacons::onClickUICheck(LLUICtrl *ctrl, void* data)
+{
+	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
+	std::string name = check->getName();
+	LLFloaterBeacons* view = (LLFloaterBeacons*)data;
+	if(     name == "touch_only")
+	{
+		LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
+		// Don't allow both to be ON at the same time. Toggle the other one off if both now on.
+		if (
+			LLPipeline::getRenderScriptedTouchBeacons(NULL) &&
+			LLPipeline::getRenderScriptedBeacons(NULL) )
+		{
+			LLPipeline::setRenderScriptedBeacons(FALSE);
+			view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(FALSE));
+			view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
+		}
+	}
+	else if(name == "scripted")
+	{
+		LLPipeline::toggleRenderScriptedBeacons(NULL);
+		// Don't allow both to be ON at the same time. Toggle the other one off if both now on.
+		if (
+			LLPipeline::getRenderScriptedTouchBeacons(NULL) &&
+			LLPipeline::getRenderScriptedBeacons(NULL) )
+		{
+			LLPipeline::setRenderScriptedTouchBeacons(FALSE);
+			view->getChild<LLCheckBoxCtrl>("touch_only")->setControlValue(LLSD(FALSE));
+			view->getChild<LLCheckBoxCtrl>("scripted")->setControlValue(LLSD(TRUE)); // just to be sure it's in sync with llpipeline
+		}
+	}
+	else if(name == "physical")       LLPipeline::setRenderPhysicalBeacons(check->get());
+	else if(name == "sounds")         LLPipeline::setRenderSoundBeacons(check->get());
+	else if(name == "particles")      LLPipeline::setRenderParticleBeacons(check->get());
+	else if(name == "highlights")
+	{
+		LLPipeline::toggleRenderHighlights(NULL);
+		// Don't allow both to be OFF at the same time. Toggle the other one on if both now off.
+		if (
+			!LLPipeline::getRenderBeacons(NULL) &&
+			!LLPipeline::getRenderHighlights(NULL) )
+		{
+			LLPipeline::setRenderBeacons(TRUE);
+			view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(TRUE));
+			view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
+		}
+	}
+	else if(name == "beacons")
+	{
+		LLPipeline::toggleRenderBeacons(NULL);
+		// Don't allow both to be OFF at the same time. Toggle the other one on if both now off.
+		if (
+			!LLPipeline::getRenderBeacons(NULL) &&
+			!LLPipeline::getRenderHighlights(NULL) )
+		{
+			LLPipeline::setRenderHighlights(TRUE);
+			view->getChild<LLCheckBoxCtrl>("highlights")->setControlValue(LLSD(TRUE));
+			view->getChild<LLCheckBoxCtrl>("beacons")->setControlValue(LLSD(FALSE)); // just to be sure it's in sync with llpipeline
+		}
+	}
+}
diff --git a/indra/newview/llfloaterbeacons.h b/indra/newview/llfloaterbeacons.h
new file mode 100644
index 00000000000..3ba6783a30a
--- /dev/null
+++ b/indra/newview/llfloaterbeacons.h
@@ -0,0 +1,56 @@
+/** 
+ * @file llfloaterbeacons.h
+ * @brief Front-end to LLPipeline controls for highlighting various kinds of objects.
+ * @author Coco 
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ * 
+ * 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERBEACONS_H
+#define LL_LLFLOATERBEACONS_H
+
+#include "llfloater.h"
+
+class LLFloaterBeacons : public LLFloater, public LLFloaterSingleton<LLFloaterBeacons>
+{
+	friend class LLUISingleton<LLFloaterBeacons, VisibilityPolicy<LLFloater> >;
+	
+public:
+	/*virtual*/ BOOL postBuild();
+	
+	// Needed to make the floater visibility toggle the beacons.
+	// Too bad we can't just add control_name="BeaconAlwaysOn" to the XML.
+	/*virtual*/ void open();
+	/*virtual*/ void close(bool app_quitting);
+
+private:
+	LLFloaterBeacons(const LLSD& seed);
+
+	static void onClickUICheck(LLUICtrl *ctrl, void* data);
+};
+
+#endif
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index ed2cc2b7c37..9edb0afb5c2 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -289,11 +289,6 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
 	removeVOInventoryListener();
 }
 
-void LLFloaterBuy::close(bool app_quitting)
-{
-	LLSelectMgr::getInstance()->deselectAll();
-	LLFloater::close(app_quitting);
-}
 
 // static
 void LLFloaterBuy::onClickBuy(void*)
@@ -325,3 +320,10 @@ void LLFloaterBuy::onClickCancel(void*)
 		sInstance->close();
 	}
 }
+
+void LLFloaterBuy::onClose(bool app_quitting)
+{
+	// drop reference to current selection so selection goes away
+	mObjectSelection = NULL;
+	LLFloater::onClose(app_quitting);
+}
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 1506b465d63..b1678c7c9f2 100644
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
@@ -57,6 +57,7 @@ class LLFloaterBuy
 	LLFloaterBuy();
 	~LLFloaterBuy();
 
+	/*virtual*/ void onClose(bool app_quitting);
 	void reset();
 
 	void requestObjectInventories();
@@ -65,8 +66,6 @@ class LLFloaterBuy
 								 S32 serial_num,
 								 void* data);
 
-	/*virtual*/ void close(bool app_quitting = false);
-
 	static void onClickBuy(void*);
 	static void onClickCancel(void*);
 
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 4218c4c65ac..9790b5a7af9 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -165,7 +165,7 @@ createUI ()
 		}
 	}
 	mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE );
-	mRGBImage->bind();
+	gGL.getTexUnit(0)->bind(mRGBImage);
 	mRGBImage->setClamp(TRUE, TRUE);
 	
 	// create palette
@@ -543,9 +543,9 @@ void LLFloaterColorPicker::draw()
 	LLRect local_rect = getLocalRect();
 	if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLEnable(GL_CULL_FACE);
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 4b0afd6db32..ef27a6d5f44 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -232,14 +232,14 @@ void LLFloaterImagePreview::draw()
 		
 			if (mGLName)
 			{
-				LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D ); 
+				gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mGLName);
 			}
 			else
 			{
 				glGenTextures(1, &mGLName );
 				stop_glerror();
 
-				LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D ); 
+				gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mGLName);
 				stop_glerror();
 
 				glTexImage2D(
@@ -251,8 +251,7 @@ void LLFloaterImagePreview::draw()
 				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 				
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+				gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 				if (mAvatarPreview)
 				{
 					mAvatarPreview->setTexture(mGLName);
@@ -261,7 +260,7 @@ void LLFloaterImagePreview::draw()
 			}
 
 			gGL.color3f(1.f, 1.f, 1.f);
-			gGL.begin( LLVertexBuffer::QUADS );
+			gGL.begin( LLRender::QUADS );
 			{
 				gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
 				gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
@@ -274,7 +273,7 @@ void LLFloaterImagePreview::draw()
 			}
 			gGL.end();
 
-			LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 			stop_glerror();
 		}
@@ -285,11 +284,15 @@ void LLFloaterImagePreview::draw()
 				gGL.color3f(1.f, 1.f, 1.f);
 
 				if (selected == 9)
-					mSculptedPreview->bindTexture();
+				{
+					gGL.getTexUnit(0)->bind(mSculptedPreview->getTexture());
+				}
 				else
-					mAvatarPreview->bindTexture();
+				{
+					gGL.getTexUnit(0)->bind(mAvatarPreview->getTexture());
+				}
 
-				gGL.begin( LLVertexBuffer::QUADS );
+				gGL.begin( LLRender::QUADS );
 				{
 					gGL.texCoord2f(0.f, 1.f);
 					gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
@@ -302,10 +305,7 @@ void LLFloaterImagePreview::draw()
 				}
 				gGL.end();
 
-				if (selected == 9)
-					mSculptedPreview->unbindTexture();
-				else
-					mAvatarPreview->unbindTexture();
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			}
 		}
 	}
@@ -907,7 +907,7 @@ BOOL LLImagePreviewSculpted::render()
 	gGL.scalef(SCALE, SCALE, SCALE);
 	const F32 BRIGHTNESS = 0.9f;
 	gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
-	mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, num_indices, 0);
+	mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
 
 	gGL.popMatrix();
 		
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index e9124313235..9c3463010e5 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -46,7 +46,7 @@
 #include "llviewerjoystick.h"
 
 LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
-	: LLFloater(std::string("floater_joystick"))
+	: LLFloater("floater_joystick")
 {
 	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_joystick.xml");
 	center();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 6ba78285ba6..f4a515e0a04 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1448,7 +1448,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
 		msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned,	is_group_owned,	i);
 		msg->getS32Fast (_PREHASH_Data, _PREHASH_Count,			object_count,	i);
 		msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus,	is_online,		i);
-		if(msg->getNumberOfBlocks("DataExtended"))
+		if(msg->has("DataExtended"))
 		{
 			msg->getU32("DataExtended", "TimeStamp", most_recent_time, i);
 		}
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index d97023e2560..3e12c2e47c8 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -63,6 +63,8 @@
 
 #include "llassetuploadresponders.h"
 
+#include <boost/regex.hpp>  //boost.regex lib
+
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
@@ -180,7 +182,7 @@ void LLFloaterPostcard::draw()
 			rect.mBottom = (S32)((F32)rect.mTop - ((F32)rect.getWidth() / ratio));
 		}
 		{
-			LLGLSNoTexture gls_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
 			rect.stretch(-1);
 		}
@@ -242,14 +244,16 @@ void LLFloaterPostcard::onClickSend(void* data)
 
 		std::string from(self->childGetValue("from_form").asString());
 		std::string to(self->childGetValue("to_form").asString());
-
-		if (to.empty() || to.find('@') == std::string::npos)
+		
+		boost::regex emailFormat("[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}");
+		
+		if (to.empty() || !boost::regex_match(to, emailFormat))
 		{
 			gViewerWindow->alertXml("PromptRecipientEmail");
 			return;
 		}
 
-		if (from.empty() || from.find('@') == std::string::npos)
+		if (from.empty() || !boost::regex_match(from, emailFormat))
 		{
 			gViewerWindow->alertXml("PromptSelfEmail");
 			return;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 37a0fde367d..15d4d302216 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -424,8 +424,6 @@ void LLFloaterPreference::onClickAbout(void*)
 // static 
 void LLFloaterPreference::onBtnOK( void* userdata )
 {
-	LLPanelLogin::refreshLocation( false );
-
 	LLFloaterPreference *fp =(LLFloaterPreference *)userdata;
 	// commit any outstanding text entry
 	if (fp->hasFocus())
@@ -453,6 +451,8 @@ void LLFloaterPreference::onBtnOK( void* userdata )
 		// Show beep, pop up dialog, etc.
 		llinfos << "Can't close preferences!" << llendl;
 	}
+
+	LLPanelLogin::refreshLocation( false );
 }
 
 
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 462f05ff27a..f4843ea1a53 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -151,7 +151,8 @@ class LLSnapshotLivePreview : public LLView
 	void resetThumbnailImage() { mThumbnailImage = NULL ; }
 	void drawPreviewRect(S32 offset_x, S32 offset_y) ;
 
-	static void onIdle( void* snapshot_preview );
+	// Returns TRUE when snapshot generated, FALSE otherwise.
+	static BOOL onIdle( void* snapshot_preview );
 
 private:
 	LLColor4					mColor;
@@ -203,6 +204,8 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
 	mCurImageIndex(0),
 	mPreviewImage(NULL),
 	mThumbnailImage(NULL) ,
+	mThumbnailWidth(0),
+	mThumbnailHeight(0),
 	mPreviewImageEncoded(NULL),
 	mFormattedImage(NULL),
 	mShineCountdown(0),
@@ -342,14 +345,11 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
 		mSnapshotDelayTimer.start();
 		mSnapshotDelayTimer.setTimerExpirySec(delay);
 	}
-	else if(new_thumbnail)
+	if(new_thumbnail)
 	{
 		mThumbnailUpToDate = FALSE ;
 	}
-	else
-	{
-		setThumbnailImageSize() ;
-	}
+	setThumbnailImageSize();
 }
 
 void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
@@ -417,14 +417,14 @@ void LLSnapshotLivePreview::draw()
 
 		LLColor4 image_color(1.f, 1.f, 1.f, 1.f);
 		gGL.color4fv(image_color.mV);
-		LLViewerImage::bindTexture(mViewerImage[mCurImageIndex]);
+		gGL.getTexUnit(0)->bind(mViewerImage[mCurImageIndex]);
 		// calculate UV scale
 		F32 uv_width = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mWidth[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getWidth(), 1.f);
 		F32 uv_height = mImageScaled[mCurImageIndex] ? 1.f : llmin((F32)mHeight[mCurImageIndex] / (F32)mViewerImage[mCurImageIndex]->getHeight(), 1.f);
 		glPushMatrix();
 		{
 			glTranslatef((F32)rect.mLeft, (F32)rect.mBottom, 0.f);
-			gGL.begin(LLVertexBuffer::QUADS);
+			gGL.begin(LLRender::QUADS);
 			{
 				gGL.texCoord2f(uv_width, uv_height);
 				gGL.vertex2i(rect.getWidth(), rect.getHeight() );
@@ -486,8 +486,8 @@ void LLSnapshotLivePreview::draw()
 				S32 y1 = 0;
 				S32 y2 = gViewerWindow->getWindowHeight();
 
-				LLGLSNoTexture no_texture;
-				gGL.begin(LLVertexBuffer::QUADS);
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+				gGL.begin(LLRender::QUADS);
 				{
 					gGL.color4f(1.f, 1.f, 1.f, 0.f);
 					gGL.vertex2i(x1, y1);
@@ -515,10 +515,10 @@ void LLSnapshotLivePreview::draw()
 
 	// draw framing rectangle
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f(1.f, 1.f, 1.f, 1.f);
 		LLRect outline_rect = mImageRect[mCurImageIndex];
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			gGL.vertex2i(outline_rect.mLeft - BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
 			gGL.vertex2i(outline_rect.mRight + BORDER_WIDTH, outline_rect.mTop + BORDER_WIDTH);
@@ -553,7 +553,7 @@ void LLSnapshotLivePreview::draw()
 			F32 alpha = clamp_rescale(fall_interp, 0.f, 1.f, 0.8f, 0.4f);
 			LLColor4 image_color(1.f, 1.f, 1.f, alpha);
 			gGL.color4fv(image_color.mV);
-			LLViewerImage::bindTexture(mViewerImage[old_image_index]);
+			gGL.getTexUnit(0)->bind(mViewerImage[old_image_index]);
 			// calculate UV scale
 			// *FIX get this to work with old image
 			BOOL rescale = !mImageScaled[old_image_index] && mViewerImage[mCurImageIndex].notNull();
@@ -564,7 +564,7 @@ void LLSnapshotLivePreview::draw()
 				LLRect& rect = mImageRect[old_image_index];
 				glTranslatef((F32)rect.mLeft, (F32)rect.mBottom - llround(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f);
 				glRotatef(-45.f * fall_interp, 0.f, 0.f, 1.f);
-				gGL.begin(LLVertexBuffer::QUADS);
+				gGL.begin(LLRender::QUADS);
 				{
 					gGL.texCoord2f(uv_width, uv_height);
 					gGL.vertex2i(rect.getWidth(), rect.getHeight() );
@@ -719,8 +719,11 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
 	mThumbnailUpdateLock = FALSE ;		
 }
 
+
+// Called often. Checks whether it's time to grab a new snapshot and if so, does it.
+// Returns TRUE if new snapshot generated, FALSE otherwise.
 //static 
-void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
+BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 {
 	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)snapshot_preview;	
 
@@ -733,7 +736,10 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 		previewp->mCameraRot = new_camera_rot;
 		// request a new snapshot whenever the camera moves, with a time delay
 		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
-		previewp->updateSnapshot(autosnap, FALSE, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
+		previewp->updateSnapshot(
+			autosnap, // whether a new snapshot is needed or merely invalidate the existing one
+			FALSE, // or if 1st arg is false, whether to produce a new thumbnail image.
+			autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f); // shutter delay if 1st arg is true.
 	}
 
 	// see if it's time yet to snap the shot and bomb out otherwise.
@@ -742,7 +748,7 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 		&& !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
 	if ( ! previewp->mSnapshotActive)
 	{
-		return;
+		return FALSE;
 	}
 
 	// time to produce a snapshot
@@ -819,6 +825,7 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 			}
 			if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
 			{
+				previewp->mDataSize = previewp->mFormattedImage->getDataSize();
 				// special case BMP to copy instead of decode otherwise decode will crash.
 				if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
 				{
@@ -826,7 +833,6 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 				}
 				else
 				{
-					previewp->mDataSize = previewp->mFormattedImage->getDataSize();
 					previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
 				}
 			}
@@ -855,7 +861,7 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 
 			previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
 			previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
-			LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
+			gGL.getTexUnit(0)->bind(previewp->mViewerImage[previewp->mCurImageIndex]);
 			previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
 
 			previewp->mSnapshotUpToDate = TRUE;
@@ -875,6 +881,8 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 	{
 		previewp->generateThumbnailImage() ;
 	}
+
+	return TRUE;
 }
 
 void LLSnapshotLivePreview::setSize(S32 w, S32 h)
@@ -952,7 +960,7 @@ void LLSnapshotLivePreview::saveTexture()
 		llwarns << "Error encoding snapshot" << llendl;
 	}
 
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );	
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
 }
 
 BOOL LLSnapshotLivePreview::saveLocal()
@@ -996,7 +1004,8 @@ class LLFloaterSnapshot::Impl
 	static void onClickKeepOpenCheck(LLUICtrl *ctrl, void* data);
 	static void onClickKeepAspectCheck(LLUICtrl *ctrl, void* data);
 	static void onCommitQuality(LLUICtrl* ctrl, void* data);
-	static void onCommitResolution(LLUICtrl* ctrl, void* data);
+	static void onCommitResolution(LLUICtrl* ctrl, void* data) { updateResolution(ctrl, data); }
+	static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
 	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
 	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
 	static void onCommitSnapshotType(LLUICtrl* ctrl, void* data);
@@ -1093,11 +1102,8 @@ LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSna
 void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname)
 {
 	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
-	if (combo)
-	{
 		combo->setVisible(TRUE);
-		onCommitResolution(combo, floater);
-	}
+	updateResolution(combo, floater, FALSE); // to sync spinners with combo
 }
 
 //static 
@@ -1107,22 +1113,18 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 
 	S32 delta_height = gSavedSettings.getBOOL("AdvanceSnapshot") ? 0 : floaterp->getUIWinHeightShort() - floaterp->getUIWinHeightLong() ;
 
-	LLComboBox* combo;
 	if(!gSavedSettings.getBOOL("AdvanceSnapshot")) //set to original window resolution
 	{
-		previewp->mKeepAspectRatio = TRUE ;
+		previewp->mKeepAspectRatio = TRUE;
 
-		combo = floaterp->getChild<LLComboBox>("postcard_size_combo");
-		combo->setCurrentByIndex(0) ;
-		gSavedSettings.setS32("SnapshotPostcardLastResolution", 0) ;
+		floaterp->getChild<LLComboBox>("postcard_size_combo")->setCurrentByIndex(0);
+		gSavedSettings.setS32("SnapshotPostcardLastResolution", 0);
 
-		combo = floaterp->getChild<LLComboBox>("texture_size_combo");
-		combo->setCurrentByIndex(0) ;
-		gSavedSettings.setS32("SnapshotTextureLastResolution", 0) ;
+		floaterp->getChild<LLComboBox>("texture_size_combo")->setCurrentByIndex(0);
+		gSavedSettings.setS32("SnapshotTextureLastResolution", 0);
 
-		combo = floaterp->getChild<LLComboBox>("local_size_combo");
-		combo->setCurrentByIndex(0) ;
-		gSavedSettings.setS32("SnapshotLocalLastResolution", 0) ;
+		floaterp->getChild<LLComboBox>("local_size_combo")->setCurrentByIndex(0);
+		gSavedSettings.setS32("SnapshotLocalLastResolution", 0);
 
 		LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
 		previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
@@ -1187,7 +1189,11 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 	}
 }
 
-
+// This is the main function that keeps all the GUI controls in sync with the saved settings.
+// It should be called anytime a setting is changed that could affect the controls.
+// No other methods should be changing any of the controls directly except for helpers called by this method.
+// The basic pattern for programmatically changing the GUI settings is to first set the
+// appropriate saved settings and then call this method to sync the GUI with them.
 // static
 void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 {
@@ -1201,15 +1207,10 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 	floater->childSetVisible("texture_size_combo", FALSE);
 	floater->childSetVisible("local_size_combo", FALSE);
 
-	LLComboBox* combo;
-	combo = floater->getChild<LLComboBox>("postcard_size_combo");
-	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
-	combo = floater->getChild<LLComboBox>("texture_size_combo");
-	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
-	combo = floater->getChild<LLComboBox>("local_size_combo");
-	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
-	combo = floater->getChild<LLComboBox>("local_format_combo");
-	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
+	floater->getChild<LLComboBox>("postcard_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotPostcardLastResolution"));
+	floater->getChild<LLComboBox>("texture_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
+	floater->getChild<LLComboBox>("local_size_combo")->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
+	floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
 
 	floater->childSetVisible("upload_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE);
 	floater->childSetVisible("send_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
@@ -1240,6 +1241,23 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 	floater->childSetVisible("auto_snapshot_check",		is_advance);
 	floater->childSetVisible("image_quality_slider",	is_advance && show_slider);
 
+	LLSnapshotLivePreview* previewp = getPreviewView(floater);
+	BOOL got_bytes = previewp && previewp->getDataSize() > 0;
+	BOOL got_snap = previewp->getSnapshotUpToDate();
+
+	floater->childSetEnabled("send_btn",   shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && got_bytes && got_snap && previewp->getDataSize() <= MAX_POSTCARD_DATASIZE);
+	floater->childSetEnabled("upload_btn", shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE  && got_bytes && got_snap);
+	floater->childSetEnabled("save_btn",   shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL    && got_bytes && got_snap);
+
+	LLLocale locale(LLLocale::USER_LOCALE);
+	std::string bytes_string;
+	LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
+	floater->childSetTextArg("file_size_label", "[SIZE]", got_snap ? bytes_string : got_bytes ? floater->getString("unknown") : std::string("???"));
+	floater->childSetColor("file_size_label", 
+		shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD 
+		&& got_bytes
+		&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLColor4::red : gColors.getColor( "LabelTextColor" ));
+
 	switch(shot_type)
 	{
 	  case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
@@ -1270,7 +1288,6 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 
 	updateResolutionTextEntry(floater);
 
-	LLSnapshotLivePreview* previewp = getPreviewView(floater);
 	if (previewp)
 	{
 		previewp->setSnapshotType(shot_type);
@@ -1389,6 +1406,7 @@ void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
 	if (view)
 	{
 		checkAutoSnapshot(getPreviewView(view));
+		updateControls(view);
 	}
 }
 
@@ -1401,9 +1419,12 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data)
 	{
 		view->translate( 0, view->getUIWinHeightShort() - view->getUIWinHeightLong() );
 		view->reshape(view->getRect().getWidth(), view->getUIWinHeightLong());
-
 		updateControls(view) ;
 		updateLayout(view) ;
+		if(getPreviewView(view))
+		{
+			getPreviewView(view)->setThumbnailImageSize() ;
+	}
 	}
 }
 void LLFloaterSnapshot::Impl::onClickLess(void* data)
@@ -1415,10 +1436,8 @@ void LLFloaterSnapshot::Impl::onClickLess(void* data)
 	{
 		view->translate( 0, view->getUIWinHeightLong() - view->getUIWinHeightShort() );
 		view->reshape(view->getRect().getWidth(), view->getUIWinHeightShort());
-
 		updateControls(view) ;
 		updateLayout(view) ;
-
 		if(getPreviewView(view))
 		{
 			getPreviewView(view)->setThumbnailImageSize() ;
@@ -1436,6 +1455,7 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
 	if (view)
 	{
 		checkAutoSnapshot(getPreviewView(view), TRUE);
+		updateControls(view);
 	}
 }
 
@@ -1449,6 +1469,7 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
 	if (view)
 	{
 		checkAutoSnapshot(getPreviewView(view), TRUE);
+		updateControls(view);
 	}
 }
 
@@ -1482,6 +1503,7 @@ void LLFloaterSnapshot::Impl::onClickKeepAspectCheck(LLUICtrl* ctrl, void* data)
 			}
 
 			previewp->setSize(w, h) ;
+			previewp->updateSnapshot(FALSE, TRUE);
 			checkAutoSnapshot(previewp, TRUE);
 		}
 	}
@@ -1531,7 +1553,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
 	}
 #endif
 	
-	if(!index) //current window size
+	if(0 == index) //current window size
 	{
 		sAspectRatioCheckOff = TRUE ;
 		view->childSetEnabled("keep_aspect_check", FALSE) ;
@@ -1568,8 +1590,27 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
 	return ;
 }
 
+static std::string lastSnapshotWidthName()
+{
+	switch(gSavedSettings.getS32("LastSnapshotType"))
+	{
+	case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailWidth";
+	case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:  return "LastSnapshotToInventoryWidth";
+	default:                                       return "LastSnapshotToDiskWidth";
+	}
+}
+static std::string lastSnapshotHeightName()
+{
+	switch(gSavedSettings.getS32("LastSnapshotType"))
+	{
+	case LLSnapshotLivePreview::SNAPSHOT_POSTCARD: return "LastSnapshotToEmailHeight";
+	case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:  return "LastSnapshotToInventoryHeight";
+	default:                                       return "LastSnapshotToDiskHeight";
+	}
+}
+
 // static
-void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
+void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update)
 {
 	LLComboBox* combobox = (LLComboBox*)ctrl;
 	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
@@ -1580,13 +1621,9 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
 	}
 
 	// save off all selected resolution values
-	LLComboBox* combo;
-	combo = view->getChild<LLComboBox>("postcard_size_combo");
-	gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex());
-	combo = view->getChild<LLComboBox>("texture_size_combo");
-	gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex());
-	combo = view->getChild<LLComboBox>("local_size_combo");
-	gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex());
+	gSavedSettings.setS32("SnapshotPostcardLastResolution", view->getChild<LLComboBox>("postcard_size_combo")->getCurrentIndex());
+	gSavedSettings.setS32("SnapshotTextureLastResolution",  view->getChild<LLComboBox>("texture_size_combo")->getCurrentIndex());
+	gSavedSettings.setS32("SnapshotLocalLastResolution",    view->getChild<LLComboBox>("local_size_combo")->getCurrentIndex());
 
 	std::string sdstring = combobox->getSelectedValue();
 	LLSD sdres;
@@ -1601,15 +1638,17 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
 	{
 		if (width == 0 || height == 0)
 		{
+			// take resolution from current window size
 			previewp->setSize(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
 		}
 		else if (width == -1 || height == -1)
 		{
 			// load last custom value
-			previewp->setSize(gSavedSettings.getS32("LastSnapshotWidth"), gSavedSettings.getS32("LastSnapshotHeight"));
+			previewp->setSize(gSavedSettings.getS32(lastSnapshotWidthName()), gSavedSettings.getS32(lastSnapshotHeightName()));
 		}
 		else
 		{
+			// use the resolution from the selected pre-canned drop-down choice
 			previewp->setSize(width, height);
 		}
 
@@ -1623,10 +1662,18 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
 		}
 		previewp->setSize(width, height);
 
+		if(view->childGetValue("snapshot_width").asInteger() != width || view->childGetValue("snapshot_height").asInteger() != height)
+		{
 		view->childSetValue("snapshot_width", width);
 		view->childSetValue("snapshot_height", height);
 		// hide old preview as the aspect ratio could be wrong
 		checkAutoSnapshot(previewp, FALSE);
+			getPreviewView(view)->updateSnapshot(FALSE, TRUE);
+			if(do_update)
+			{
+				updateControls(view);
+	}
+		}
 	}
 }
 
@@ -1675,17 +1722,28 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data)
 
 
 
-
+// Sets the named size combo to "custom" mode.
 // static
 void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
 {
 	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
-	if (combo)
-	{
-		combo->setCurrentByIndex(combo->getItemCount() - 1);
 
-		checkAspectRatio(floater, -1);//combo->getCurrentIndex()) ;
+	combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
+
+	if(comboname == "postcard_size_combo") 
+	{
+		gSavedSettings.setS32("SnapshotPostcardLastResolution", combo->getCurrentIndex());
+	}
+	else if(comboname == "texture_size_combo") 
+	{
+		gSavedSettings.setS32("SnapshotTextureLastResolution", combo->getCurrentIndex());
 	}
+	else if(comboname == "local_size_combo") 
+	{
+		gSavedSettings.setS32("SnapshotLocalLastResolution", combo->getCurrentIndex());
+	}
+
+	checkAspectRatio(floater, -1); // -1 means custom
 }
 
 
@@ -1711,8 +1769,8 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3
 
 		//round to nearest power of 2 based on the direction of movement
 		// i.e. higher power of two if increasing texture resolution
-		if(gSavedSettings.getS32("LastSnapshotWidth") < width ||
-			gSavedSettings.getS32("LastSnapshotHeight") < height)
+		if(gSavedSettings.getS32("LastSnapshotToInventoryWidth") < width ||
+			gSavedSettings.getS32("LastSnapshotToInventoryHeight") < height)
 		{
 			// Up arrow pressed
 			width = get_next_power_two(width, MAX_TEXTURE_SIZE) ;
@@ -1772,20 +1830,10 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3
 //static
 void LLFloaterSnapshot::Impl::resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height)
 {
-	LLSpinCtrl *sctrl = view->getChild<LLSpinCtrl>("snapshot_width") ;
-	if(sctrl)
-	{
-		sctrl->forceSetValue(width) ;
-	}
-
-	sctrl = view->getChild<LLSpinCtrl>("snapshot_height") ;
-	if(sctrl)
-	{
-		sctrl->forceSetValue(height) ;
-	}
-
-	gSavedSettings.setS32("LastSnapshotWidth", width);
-	gSavedSettings.setS32("LastSnapshotHeight", height);
+	view->getChild<LLSpinCtrl>("snapshot_width")->forceSetValue(width);
+	view->getChild<LLSpinCtrl>("snapshot_height")->forceSetValue(height);
+	gSavedSettings.setS32(lastSnapshotWidthName(), width);
+	gSavedSettings.setS32(lastSnapshotHeightName(), height);
 }
 
 //static
@@ -1839,15 +1887,17 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
 
 				previewp->setSize(w,h);
 				checkAutoSnapshot(previewp, FALSE);
+				previewp->updateSnapshot(FALSE, TRUE);
 				comboSetCustom(view, "postcard_size_combo");
 				comboSetCustom(view, "texture_size_combo");
 				comboSetCustom(view, "local_size_combo");
 			}
 		}
 
-		gSavedSettings.setS32("LastSnapshotWidth", w);
-		gSavedSettings.setS32("LastSnapshotHeight", h);
+		gSavedSettings.setS32(lastSnapshotWidthName(), w);
+		gSavedSettings.setS32(lastSnapshotHeightName(), h);
 
+		updateControls(view);
 	}
 }
 
@@ -1883,6 +1933,7 @@ LLFloaterSnapshot::~LLFloaterSnapshot()
 	delete &impl;
 }
 
+
 BOOL LLFloaterSnapshot::postBuild()
 {
 	childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this);
@@ -1890,11 +1941,6 @@ BOOL LLFloaterSnapshot::postBuild()
 	
 	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
 
-	childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot"));
-	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
-
-	//childSetValue("advance_snapshot_check", gSavedSettings.getBOOL("AdvanceSnapshot"));
-	//childSetCommitCallback("advance_snapshot_check", Impl::onClickAdvanceSnap, this);
 	childSetAction("more_btn", Impl::onClickMore, this);
 	childSetAction("less_btn", Impl::onClickLess, this);
 
@@ -1907,10 +1953,10 @@ BOOL LLFloaterSnapshot::postBuild()
 	childSetValue("image_quality_slider", gSavedSettings.getS32("SnapshotQuality"));
 
 	childSetCommitCallback("snapshot_width", Impl::onCommitCustomResolution, this);
-
 	childSetCommitCallback("snapshot_height", Impl::onCommitCustomResolution, this);
 
 	childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
+	childSetValue("ui_check", gSavedSettings.getBOOL("RenderUIInSnapshot"));
 
 	childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
 	childSetValue("hud_check", gSavedSettings.getBOOL("RenderHUDInSnapshot"));
@@ -1925,12 +1971,15 @@ BOOL LLFloaterSnapshot::postBuild()
 	childSetValue("layer_types", "colors");
 	childSetEnabled("layer_types", FALSE);
 
-	childSetValue("snapshot_width", gSavedSettings.getS32("LastSnapshotWidth"));
-	childSetValue("snapshot_height", gSavedSettings.getS32("LastSnapshotHeight"));
+	childSetValue("snapshot_width", gSavedSettings.getS32(lastSnapshotWidthName()));
+	childSetValue("snapshot_height", gSavedSettings.getS32(lastSnapshotHeightName()));
 
 	childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame"));
 	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
 
+	childSetValue("auto_snapshot_check", gSavedSettings.getBOOL("AutoSnapshot"));
+	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
+
 	childSetCommitCallback("postcard_size_combo", Impl::onCommitResolution, this);
 	childSetCommitCallback("texture_size_combo", Impl::onCommitResolution, this);
 	childSetCommitCallback("local_size_combo", Impl::onCommitResolution, this);
@@ -1960,53 +2009,6 @@ void LLFloaterSnapshot::draw()
 		return;
 	}
 
-	if(!isMinimized())
-	{
-		if (previewp && previewp->getDataSize() > 0)
-		{
-			LLLocale locale(LLLocale::USER_LOCALE);
-
-			std::string bytes_string;
-			if (previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_POSTCARD && 
-				previewp->getDataSize() > MAX_POSTCARD_DATASIZE)
-			{
-				childSetColor("file_size_label", LLColor4::red);
-				childSetEnabled("send_btn", FALSE);
-			}
-			else
-			{
-				childSetColor("file_size_label", gColors.getColor( "LabelTextColor" ));
-				childSetEnabled("send_btn", previewp->getSnapshotUpToDate());
-			}
-			
-			if (previewp->getSnapshotUpToDate())
-			{
-				std::string bytes_string;
-				LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
-				childSetTextArg("file_size_label", "[SIZE]", bytes_string);
-			}
-			else
-			{
-				childSetTextArg("file_size_label", "[SIZE]", getString("unknown"));
-				childSetColor("file_size_label", gColors.getColor( "LabelTextColor" ));
-			}
-			childSetEnabled("upload_btn", previewp->getSnapshotUpToDate());
-			childSetEnabled("save_btn", previewp->getSnapshotUpToDate());
-
-		}
-		else
-		{
-			childSetTextArg("file_size_label", "[SIZE]", std::string("???"));
-			childSetEnabled("upload_btn", FALSE);
-			childSetEnabled("send_btn", FALSE);
-			childSetEnabled("save_btn", FALSE);
-		}
-
-		BOOL ui_in_snapshot = gSavedSettings.getBOOL("RenderUIInSnapshot");
-		childSetValue("ui_check", ui_in_snapshot);
-		childSetToolTip("ui_check", std::string("If selected shows the UI in the snapshot"));
-	}
-
 	LLFloater::draw();
 
 	if (previewp)
@@ -2071,10 +2073,15 @@ void LLFloaterSnapshot::hide(void*)
 //static 
 void LLFloaterSnapshot::update()
 {
+	BOOL changed = FALSE;
 	for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
 		 iter != LLSnapshotLivePreview::sList.end(); ++iter)
 	{
-		LLSnapshotLivePreview::onIdle(*iter);
+		changed |= LLSnapshotLivePreview::onIdle(*iter);
+	}
+	if(changed)
+	{
+		sInstance->impl.updateControls(sInstance);
 	}
 }
 
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 02ea02a2915..617d4d010fe 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -180,7 +180,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
 		msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
 		msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
-		if(msg->getNumberOfBlocks("DataExtended"))
+		if(msg->has("DataExtended"))
 		{
 			have_extended_data = true;
 			msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 4a55e0b8601..c671a70b4a5 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -821,7 +821,7 @@ void LLFolderViewItem::draw()
 	// mShowSingleSelection is FALSE
 	if( mIsSelected )
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLColor4 bg_color = sHighlightBgColor;
 		//const S32 TRAILING_PAD = 5;  // It just looks better with this.
 		if (!mIsCurSelection)
@@ -876,7 +876,7 @@ void LLFolderViewItem::draw()
 	}
 	if (mDragAndDropTarget)
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gl_rect_2d(
 			0, 
 			getRect().getHeight(), 
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index a021a66af2e..d595a223367 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -142,7 +142,7 @@ void LLAgent::renderAutoPilotTarget()
 		gGL.pushMatrix();
 
 		// not textured
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		// lovely green
 		glColor4f(0.f, 1.f, 1.f, 1.f);
@@ -355,10 +355,11 @@ void LLCompass::draw()
 
 	if (mBkgndTexture)
 	{
-		mBkgndTexture->bind();
+		gGL.getTexUnit(0)->bind(mBkgndTexture.get());
+
 		gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
 		
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		
 		gGL.texCoord2f(1.f, 1.f);
 		gGL.vertex2i(width, height);
@@ -381,10 +382,10 @@ void LLCompass::draw()
 	
 	if (mTexture)
 	{
-		mTexture->bind();
+		gGL.getTexUnit(0)->bind(mTexture.get());
 		gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
 		
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		
 		gGL.texCoord2f(1.f, 1.f);
 		gGL.vertex2i(width, height);
@@ -426,9 +427,9 @@ void LLHorizontalCompass::draw()
 		F32 left = center - COMPASS_RANGE;
 		F32 right = center + COMPASS_RANGE;
 
-		mTexture->bind();
+		gGL.getTexUnit(0)->bind(mTexture.get());
 		gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f );
-		gGL.begin( LLVertexBuffer::QUADS );
+		gGL.begin( LLRender::QUADS );
 
 		gGL.texCoord2f(right, 1.f);
 		gGL.vertex2i(width, height);
@@ -447,7 +448,7 @@ void LLHorizontalCompass::draw()
 
 	// Draw the focus line
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( mFocusColor.mV );
 		gl_line_2d( half_width, 0, half_width, height );
 	}
@@ -465,7 +466,7 @@ void LLWind::renderVectors()
 
 	F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
 
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.pushMatrix();
 	LLVector3 origin_agent;
 	origin_agent = gAgent.getPosAgentFromGlobal(mOriginGlobal);
@@ -479,11 +480,11 @@ void LLWind::renderVectors()
 			gGL.pushMatrix();
 			gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0);
 			gGL.color3f(0,1,0);
-			gGL.begin(LLVertexBuffer::POINTS);
+			gGL.begin(LLRender::POINTS);
 				gGL.vertex3f(0,0,0);
 			gGL.end();
 			gGL.color3f(1,0,0);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 				gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f);
 				gGL.vertex3f(x, y, 0.f);
 			gGL.end();
@@ -501,7 +502,7 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global,
 								   const LLVector3d &east_north_top_global )
 {
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE);
 
 	LLVector3 west_south_bottom_agent = gAgent.getPosAgentFromGlobal(west_south_bottom_global);
@@ -532,7 +533,7 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global,
 	gGL.color4f(1.f, 1.f, 0.f, 1.f);
 
 	// Cheat and give this the same pick-name as land
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 
 	gGL.vertex3f(west, north, nw_bottom);
 	gGL.vertex3f(west, north, nw_top);
@@ -549,7 +550,7 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global,
 	gGL.end();
 
 	gGL.color4f(1.f, 1.f, 0.f, 0.2f);
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 
 	gGL.vertex3f(west, north, nw_bottom);
 	gGL.vertex3f(west, north, nw_top);
@@ -609,14 +610,14 @@ void LLViewerParcelMgr::renderParcel(LLParcel* parcel )
 		F32 ne_top = ne_bottom + POST_HEIGHT;
 		F32 nw_top = nw_bottom + POST_HEIGHT;
 
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLDepthTest gls_depth(GL_TRUE);
 
 		LLUI::setLineWidth(2.f);
 		gGL.color4f(0.f, 1.f, 1.f, 1.f);
 
 		// Cheat and give this the same pick-name as land
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 
 		gGL.vertex3f(west, north, nw_bottom);
 		gGL.vertex3f(west, north, nw_top);
@@ -633,7 +634,7 @@ void LLViewerParcelMgr::renderParcel(LLParcel* parcel )
 		gGL.end();
 
 		gGL.color4f(0.f, 1.f, 1.f, 0.2f);
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 
 		gGL.vertex3f(west, north, nw_bottom);
 		gGL.vertex3f(west, north, nw_top);
@@ -759,7 +760,7 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi
 	bool has_segments = false;
 
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE);
 
 	gGL.color4f(1.f, 1.f, 0.f, 0.2f);
@@ -786,7 +787,7 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi
 				if (!has_segments)
 				{
 					has_segments = true;
-					gGL.begin(LLVertexBuffer::QUADS);
+					gGL.begin(LLRender::QUADS);
 				}
 				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp);
 			}
@@ -802,7 +803,7 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi
 				if (!has_segments)
 				{
 					has_segments = true;
-					gGL.begin(LLVertexBuffer::QUADS);
+					gGL.begin(LLRender::QUADS);
 				}
 				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp);
 			}
@@ -850,14 +851,14 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLV
 	
 	if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST))
 	{
-		LLViewerImage::bindTexture(mPassImage);
+		gGL.getTexUnit(0)->bind(mPassImage);
 	}
 	else
 	{
-		LLViewerImage::bindTexture(mBlockedImage);
+		gGL.getTexUnit(0)->bind(mBlockedImage);
 	}
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 
 	for (y = 0; y < STRIDE; y++)
 	{
@@ -1011,10 +1012,10 @@ void LLViewerObjectList::renderObjectBeacons()
 	LLGLSUIDefault gls_ui;
 
 	{
-		LLGLSNoTexture gls_ui_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		S32 last_line_width = -1;
-		// gGL.begin(LLVertexBuffer::LINES); // Always happens in (line_width != last_line_width)
+		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
 		
 		for (S32 i = 0; i < mDebugBeacons.count(); i++)
 		{
@@ -1031,7 +1032,7 @@ void LLViewerObjectList::renderObjectBeacons()
 				}
 				glLineWidth( (F32)line_width );
 				last_line_width = line_width;
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 			}
 
 			const LLVector3 &thisline = debug_beacon.mPositionAgent;
@@ -1049,11 +1050,11 @@ void LLViewerObjectList::renderObjectBeacons()
 	}
 
 	{
-		LLGLSNoTexture gls_ui_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLDepthTest gls_depth(GL_TRUE);
 		
 		S32 last_line_width = -1;
-		// gGL.begin(LLVertexBuffer::LINES); // Always happens in (line_width != last_line_width)
+		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
 		
 		for (S32 i = 0; i < mDebugBeacons.count(); i++)
 		{
@@ -1069,7 +1070,7 @@ void LLViewerObjectList::renderObjectBeacons()
 				}
 				glLineWidth( (F32)line_width );
 				last_line_width = line_width;
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 			}
 
 			const LLVector3 &thisline = debug_beacon.mPositionAgent;
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 9fae0e33872..b8d77c8c06f 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -251,7 +251,7 @@ void LLHUDEffectBeam::render()
 	}
 
 	LLGLSPipelineAlpha gls_pipeline_alpha;
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 
 	// Interpolate the global fade alpha
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 7a1df7e3b2f..fd09f0d94e5 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -499,14 +499,14 @@ void LLHUDEffectLookAt::render()
 {
 	if (sDebugLookAt && mSourceObject.notNull())
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
 		glMatrixMode(GL_MODELVIEW);
 		gGL.pushMatrix();
 		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
 		glScalef(0.3f, 0.3f, 0.3f);
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 		{
 			LLColor3 color = (*mAttentions)[mTargetType].mColor;
 			gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index 310b0331c99..8fc68d1f5c9 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -328,13 +328,13 @@ void LLHUDEffectPointAt::render()
 	update();
 	if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
 		gGL.pushMatrix();
 		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
 		glScalef(0.3f, 0.3f, 0.3f);
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 		{
 			gGL.color3f(1.f, 0.f, 0.f);
 			gGL.vertex3f(-1.f, 0.f, 0.f);
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 4cfd556eade..dd33c05ad17 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -86,7 +86,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
 	LLGLDepthTest gls_depth(GL_TRUE);
 	if (for_select)
 	{
-		LLViewerImage::unbindTexture(0);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 	
 	if (mHidden)
@@ -163,10 +163,10 @@ void LLHUDIcon::renderIcon(BOOL for_select)
 		LLColor4 icon_color = LLColor4::white;
 		icon_color.mV[VALPHA] = alpha_factor;
 		gGL.color4fv(icon_color.mV);
-		LLViewerImage::bindTexture(mImagep);
+		gGL.getTexUnit(0)->bind(mImagep.get());
 	}
 
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		gGL.texCoord2f(0.f, 1.f);
 		gGL.vertex3fv(upper_left.mV);
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 80e62aff8f8..7dafac74ea6 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -120,6 +120,111 @@ LLHUDText::~LLHUDText()
 }
 
 
+BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render)
+{
+	if (!mVisible || mHidden)
+	{
+		return FALSE;
+	}
+
+	// don't pick text that isn't bound to a viewerobject or isn't in a bubble
+	if (!mSourceObject || mSourceObject->mDrawable.isNull() || !mUseBubble)
+	{
+		return FALSE;
+	}
+	
+	F32 alpha_factor = 1.f;
+	LLColor4 text_color = mColor;
+	if (mDoFade)
+	{
+		if (mLastDistance > mFadeDistance)
+		{
+			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange);
+			text_color.mV[3] = text_color.mV[3]*alpha_factor;
+		}
+	}
+	if (text_color.mV[3] < 0.01f)
+	{
+		return FALSE;
+	}
+
+	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
+
+	// scale screen size of borders down
+	//RN: for now, text on hud objects is never occluded
+
+	LLVector3 x_pixel_vec;
+	LLVector3 y_pixel_vec;
+	
+	if (mOnHUDAttachment)
+	{
+		x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWindowWidth();
+		y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWindowHeight();
+	}
+	else
+	{
+		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
+	}
+
+	LLVector3 width_vec = mWidth * x_pixel_vec;
+	LLVector3 height_vec = mHeight * y_pixel_vec;
+	
+	LLCoordGL screen_pos;
+	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
+
+	LLVector2 screen_offset;
+	screen_offset = updateScreenPos(mPositionOffset);
+	
+	LLVector3 render_position = mPositionAgent  
+			+ (x_pixel_vec * screen_offset.mV[VX])
+			+ (y_pixel_vec * screen_offset.mV[VY]);
+
+
+	if (mUseBubble)
+	{
+		LLVector3 bg_pos = render_position
+			+ (F32)mOffsetY * y_pixel_vec
+			- (width_vec / 2.f)
+			- (height_vec);
+		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+
+		LLVector3 v[] = 
+		{
+			bg_pos,
+			bg_pos + width_vec,
+			bg_pos + width_vec + height_vec,
+			bg_pos + height_vec,
+		};
+
+		if (debug_render)
+		{
+			gGL.begin(LLRender::LINE_STRIP);
+			gGL.vertex3fv(v[0].mV);
+			gGL.vertex3fv(v[1].mV);
+			gGL.vertex3fv(v[2].mV);
+			gGL.vertex3fv(v[3].mV);
+			gGL.vertex3fv(v[0].mV);
+			gGL.vertex3fv(v[2].mV);
+			gGL.end();
+		}
+
+		LLVector3 dir = end-start;
+		F32 t = 0.f;
+
+		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) ||
+			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) )
+		{
+			if (t <= 1.f)
+			{
+				intersection = start + dir*t;
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
 void LLHUDText::render()
 {
 	if (!mOnHUDAttachment && sDisplayText)
@@ -152,7 +257,15 @@ void LLHUDText::renderText(BOOL for_select)
 		return;
 	}
 	
-	LLGLState gls_tex(GL_TEXTURE_2D, for_select ? FALSE : TRUE);
+	if (for_select)
+	{
+		gGL.getTexUnit(0)->disable();
+	}
+	else
+	{
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	}
+
 	LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE);
 	LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE);
 	
@@ -261,7 +374,7 @@ void LLHUDText::renderText(BOOL for_select)
 
 			if (for_select)
 			{
-				LLGLSNoTexture no_texture_state;
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				S32 name = mSourceObject->mGLName;
 				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
 				gGL.color4ubv(coloru.mV);
@@ -271,7 +384,7 @@ void LLHUDText::renderText(BOOL for_select)
 			}
 			else
 			{
-				LLViewerImage::bindTexture(imagep->getImage());
+				gGL.getTexUnit(0)->bind(imagep->getImage());
 				
 				gGL.color4fv(bg_color.mV);
 				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
@@ -309,7 +422,7 @@ void LLHUDText::renderText(BOOL for_select)
 				}
 				LLUI::popMatrix();
 
-				LLImageGL::unbindTexture(0);
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
 				
 				LLVector3 box_center_offset;
@@ -317,7 +430,7 @@ void LLHUDText::renderText(BOOL for_select)
 				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
 				gGL.color4fv(bg_color.mV);
 				LLUI::setLineWidth(2.0);
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					if (outside_width)
 					{
@@ -444,6 +557,10 @@ void LLHUDText::renderText(BOOL for_select)
 	}
 	/// Reset the default color to white.  The renderer expects this to be the default. 
 	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+	if (for_select)
+	{
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	}
 }
 
 void LLHUDText::setStringUTF8(const std::string &wtext)
diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h
index b46a1635dd4..e65d1d534d5 100644
--- a/indra/newview/llhudtext.h
+++ b/indra/newview/llhudtext.h
@@ -123,6 +123,8 @@ class LLHUDText : public LLHUDObject
 	void setOnHUDAttachment(BOOL on_hud) { mOnHUDAttachment = on_hud; }
 	void shift(const LLVector3& offset);
 
+	BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE);
+
 	static void shiftAll(const LLVector3& offset);
 	static void renderAllHUD();
 	static void addPickable(std::set<LLViewerObject*> &pick_list);
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 994bf393000..87ec272344a 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -651,11 +651,11 @@ void LLJoystickCameraRotate::drawRotatedImage( const LLImageGL* image, S32 rotat
 		{ 1.f, 0.f }
 	};
 
-	image->bind();
+	gGL.getTexUnit(0)->bind(image);
 
 	gGL.color4fv(UI_VERTEX_COLOR.mV);
 	
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		gGL.texCoord2fv( uv[ (rotations + 0) % 4]);
 		gGL.vertex2i(width, height );
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 891dd69f84d..030237df37f 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -388,13 +388,13 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 
 		const F32 LINE_ALPHA = 0.33f;
 
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLUI::setLineWidth(1.5f);
 
 		if (draw_x)
 		{
 			gGL.color4f(1.f, 0.f, 0.f, LINE_ALPHA);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			gGL.vertex3f( -region_size, 0.f, 0.f );
 			gGL.vertex3f(  region_size, 0.f, 0.f );
 			gGL.end();
@@ -403,7 +403,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 		if (draw_y)
 		{
 			gGL.color4f(0.f, 1.f, 0.f, LINE_ALPHA);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			gGL.vertex3f( 0.f, -region_size, 0.f );
 			gGL.vertex3f( 0.f,  region_size, 0.f );
 			gGL.end();
@@ -412,7 +412,7 @@ void LLManip::renderGuidelines(BOOL draw_x, BOOL draw_y, BOOL draw_z)
 		if (draw_z)
 		{
 			gGL.color4f(0.f, 0.f, 1.f, LINE_ALPHA);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			gGL.vertex3f( 0.f, 0.f, -region_size );
 			gGL.vertex3f( 0.f, 0.f,  region_size );
 			gGL.end();
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index f1a0fd4c676..d3dc2fdd08a 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -115,7 +115,7 @@ void LLManipRotate::handleSelect()
 void LLManipRotate::render()
 {
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE);
 	LLGLEnable gl_blend(GL_BLEND);
 	LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
@@ -838,7 +838,7 @@ void LLManipRotate::renderSnapGuides()
 				LLVector3 outer_point;
 				LLVector3 text_point;
 				LLQuaternion rot(deg * DEG_TO_RAD, constraint_axis);
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					inner_point = (projected_snap_axis * mRadiusMeters * SNAP_GUIDE_INNER_RADIUS * rot) + center;
 					F32 tick_length = 0.f;
@@ -1017,7 +1017,7 @@ void LLManipRotate::renderSnapGuides()
 				object_axis = object_axis * SNAP_GUIDE_INNER_RADIUS * mRadiusMeters + center;
 				LLVector3 line_start = center;
 
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					gGL.vertex3fv(line_start.mV);
 					gGL.vertex3fv(object_axis.mV);
@@ -1025,7 +1025,7 @@ void LLManipRotate::renderSnapGuides()
 				gGL.end();
 
 				// draw snap guide arrow
-				gGL.begin(LLVertexBuffer::TRIANGLES);
+				gGL.begin(LLRender::TRIANGLES);
 				{
 					LLVector3 arrow_dir;
 					LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
@@ -1045,7 +1045,7 @@ void LLManipRotate::renderSnapGuides()
 
 				{
 					LLGLDepthTest gls_depth(GL_TRUE);
-					gGL.begin(LLVertexBuffer::LINES);
+					gGL.begin(LLRender::LINES);
 					{
 						gGL.vertex3fv(line_start.mV);
 						gGL.vertex3fv(object_axis.mV);
@@ -1053,7 +1053,7 @@ void LLManipRotate::renderSnapGuides()
 					gGL.end();
 
 					// draw snap guide arrow
-					gGL.begin(LLVertexBuffer::TRIANGLES);
+					gGL.begin(LLRender::TRIANGLES);
 					{
 						LLVector3 arrow_dir;
 						LLVector3 arrow_span = (object_axis - line_start) % getConstraintAxis();
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 68e59ce9e0d..6539748d30b 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -197,7 +197,7 @@ LLManipScale::~LLManipScale()
 void LLManipScale::render()
 {
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE);
 	LLGLEnable gl_blend(GL_BLEND);
 	LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
@@ -590,7 +590,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
 	{
 		gGL.color4fv( default_normal_color.mV );
 		LLGLDepthTest gls_depth(GL_FALSE);
-		gGL.begin(LLVertexBuffer::QUADS); 
+		gGL.begin(LLRender::QUADS); 
 		{
 			// Face 0
 			gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]);
@@ -751,7 +751,7 @@ void LLManipScale::renderCorners( const LLBBox& bbox )
 
 void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
 {
-	LLImageGL::unbindTexture(0);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_FALSE);
 
 	glPushMatrix();
@@ -1528,7 +1528,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
 	{
 		LLColor4 tick_color = setupSnapGuideRenderPass(pass);
 
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 		LLVector3 line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset);
 		LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f)));
 		LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f));
@@ -1579,7 +1579,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
 		if (mInSnapRegime)
 		{
 			// draw snap guide line
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			LLVector3 snap_line_center = mScaleCenter + (mScaleSnapValue * mScaleDir);
 
 			LLVector3 snap_line_start = snap_line_center + (mSnapGuideDir1 * mSnapRegimeOffset);
@@ -1593,7 +1593,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
 			gGL.end();
 
 			// draw snap guide arrow
-			gGL.begin(LLVertexBuffer::TRIANGLES);
+			gGL.begin(LLRender::TRIANGLES);
 			{
 				//gGLSNoCullFaces.set();
 				gGL.color4f(1.f, 1.f, 1.f, grid_alpha);
@@ -1628,7 +1628,7 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
 			start_tick = -(llmin(ticks_from_scale_center_1, num_ticks_per_side1));
 			stop_tick = llmin(max_ticks1, num_ticks_per_side1);
 
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			// draw first row of ticks
 			for (S32 i = start_tick; i <= stop_tick; i++)
 			{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index ac822950083..d09cb8a8430 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -134,7 +134,7 @@ void LLManipTranslate::restoreGL()
 
 	GLuint* d = new GLuint[rez*rez];
 	glGenTextures(1, &sGridTex);
-	glBindTexture(GL_TEXTURE_2D, sGridTex);
+	gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
@@ -1052,7 +1052,7 @@ void LLManipTranslate::renderSnapGuides()
 	F32 max_subdivisions = sGridMaxSubdivisionLevel;//(F32)gSavedSettings.getS32("GridSubdivision");
 	F32 line_alpha = gSavedSettings.getF32("GridOpacity");
 
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE);
 	LLGLDisable gls_cull(GL_CULL_FACE);
 	LLVector3 translate_axis;
@@ -1223,7 +1223,7 @@ void LLManipTranslate::renderSnapGuides()
 		{
 			LLColor4 line_color = setupSnapGuideRenderPass(pass);
 
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				LLVector3 line_start = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) + (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
 				LLVector3 line_end = selection_center + (mSnapOffsetMeters * mSnapOffsetAxis) - (translate_axis * (guide_size_meters * 0.5f + offset_nearest_grid_unit));
@@ -1299,7 +1299,7 @@ void LLManipTranslate::renderSnapGuides()
 				LLVector3 line_start = selection_center - mSnapOffsetAxis * mSnapOffsetMeters;
 				LLVector3 line_end = selection_center + mSnapOffsetAxis * mSnapOffsetMeters;
 
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
 
@@ -1309,7 +1309,7 @@ void LLManipTranslate::renderSnapGuides()
 				gGL.end();
 
 				// draw snap guide arrow
-				gGL.begin(LLVertexBuffer::TRIANGLES);
+				gGL.begin(LLRender::TRIANGLES);
 				{
 					gGL.color4f(line_color.mV[VX], line_color.mV[VY], line_color.mV[VZ], line_color.mV[VW]);
 
@@ -1463,7 +1463,7 @@ void LLManipTranslate::renderSnapGuides()
 			break;
 		}
 
-		LLImageGL::unbindTexture(0);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		highlightIntersection(normal, selection_center, grid_rotation, inner_color);
 
 		gGL.pushMatrix();
@@ -1503,7 +1503,7 @@ void LLManipTranslate::renderSnapGuides()
 				LLGLDisable stencil(GL_STENCIL_TEST);
 				{
 					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
-					glBindTexture(GL_TEXTURE_2D, sGridTex);
+					gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex);
 					gGL.flush();
 					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
 					renderGrid(u,v,tiles,0.9f, 0.9f, 0.9f,a*0.15f);
@@ -1514,11 +1514,11 @@ void LLManipTranslate::renderSnapGuides()
 				{
 					LLGLDisable alpha_test(GL_ALPHA_TEST);
 					//draw black overlay
-					LLImageGL::unbindTexture(0);
+					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 					renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f);
 
 					//draw grid top
-					glBindTexture(GL_TEXTURE_2D, sGridTex);
+					gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, sGridTex);
 					renderGrid(u,v,tiles,1,1,1,a);
 
 					gGL.popMatrix();
@@ -1564,7 +1564,7 @@ void LLManipTranslate::renderGrid(F32 x, F32 y, F32 size, F32 r, F32 g, F32 b, F
 
 	for (F32 xx = -size-d; xx < size+d; xx += d)
 	{
-		gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+		gGL.begin(LLRender::TRIANGLE_STRIP);
 		for (F32 yy = -size-d; yy < size+d; yy += d)
 		{
 			float dx, dy, da;
@@ -1620,7 +1620,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 		LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
 		glStencilFunc(GL_ALWAYS, 0, stencil_mask);
 		gGL.setColorMask(false, false);
-		LLImageGL::unbindTexture(0);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		glColor4f(1,1,1,1);
 
 		//setup clip plane
@@ -1686,7 +1686,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
 
 	//draw volume/plane intersections
 	{
-		LLImageGL::unbindTexture(0);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLDepthTest depth(GL_FALSE);
 		LLGLEnable stencil(GL_STENCIL_TEST);
 		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
@@ -1834,7 +1834,7 @@ void LLManipTranslate::renderTranslationHandles()
 		relative_camera_dir.normVec();
 
 		{
-			LLGLSNoTexture gls_ui_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLGLDisable cull_face(GL_CULL_FACE);
 
 			LLColor4 color1;
@@ -1877,7 +1877,7 @@ void LLManipTranslate::renderTranslationHandles()
 					color1.setVec(0.f, 1.f, 0.f, 0.6f);
 					color2.setVec(0.f, 0.f, 1.f, 0.6f);
 				}
-				gGL.begin(LLVertexBuffer::TRIANGLES);
+				gGL.begin(LLRender::TRIANGLES);
 				{
 					gGL.color4fv(color1.mV);
 					gGL.vertex3f(0.f, mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f), mPlaneManipOffsetMeters * (-PLANE_TICK_SIZE * 0.25f));
@@ -1892,7 +1892,7 @@ void LLManipTranslate::renderTranslationHandles()
 				gGL.end();
 
 				LLUI::setLineWidth(3.0f);
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					gGL.color4f(0.f, 0.f, 0.f, 0.3f);
 					gGL.vertex3f(0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f,  mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
@@ -1932,7 +1932,7 @@ void LLManipTranslate::renderTranslationHandles()
 					color2.setVec(1.f, 0.f, 0.f, 0.6f);
 				}
 
-				gGL.begin(LLVertexBuffer::TRIANGLES);
+				gGL.begin(LLRender::TRIANGLES);
 				{
 					gGL.color4fv(color1.mV);
 					gGL.vertex3f(mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f), 0.f, mPlaneManipOffsetMeters * (PLANE_TICK_SIZE * 0.25f));
@@ -1947,7 +1947,7 @@ void LLManipTranslate::renderTranslationHandles()
 				gGL.end();
 
 				LLUI::setLineWidth(3.0f);
-				gGL.begin(LLVertexBuffer::LINES);
+				gGL.begin(LLRender::LINES);
 				{
 					gGL.color4f(0.f, 0.f, 0.f, 0.3f);
 					gGL.vertex3f(mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f,  0.f, mPlaneManipOffsetMeters * -PLANE_TICK_SIZE * 0.25f);
@@ -2011,7 +2011,7 @@ void LLManipTranslate::renderTranslationHandles()
 						color2.setVec(0.f, 0.8f, 0.f, 0.6f);
 					}
 				
-					gGL.begin(LLVertexBuffer::TRIANGLES);
+					gGL.begin(LLRender::TRIANGLES);
 					{
 						gGL.color4fv(color1.mV);
 						gGL.vertex3fv(v0.mV);
@@ -2026,7 +2026,7 @@ void LLManipTranslate::renderTranslationHandles()
 					gGL.end();
 
 					LLUI::setLineWidth(3.0f);
-					gGL.begin(LLVertexBuffer::LINES);
+					gGL.begin(LLRender::LINES);
 					{
 						gGL.color4f(0.f, 0.f, 0.f, 0.3f);
 						LLVector3 v12 = (v1 + v2) * .5f;
@@ -2052,7 +2052,7 @@ void LLManipTranslate::renderTranslationHandles()
 			}
 		}
 		{
-			LLGLSNoTexture gls_ui_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 			// Since we draw handles with depth testing off, we need to draw them in the 
 			// proper depth order.
@@ -2126,7 +2126,7 @@ void LLManipTranslate::renderTranslationHandles()
 
 void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_size, F32 arrow_size, F32 handle_size, BOOL reverse_direction)
 {
-	LLGLSNoTexture gls_ui_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLEnable gls_blend(GL_BLEND);
 	LLGLEnable gls_color_material(GL_COLOR_MATERIAL);
 
@@ -2160,7 +2160,7 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_
 
 		{
 			LLUI::setLineWidth(2.0f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 				vec.mV[index] = box_size;
 				gGL.vertex3f(vec.mV[0], vec.mV[1], vec.mV[2]);
 
diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp
index a5a4db8dc45..656fe743af8 100644
--- a/indra/newview/llmemoryview.cpp
+++ b/indra/newview/llmemoryview.cpp
@@ -146,7 +146,7 @@ void LLMemoryView::draw()
 	S32 height = getRect().getHeight();
 	
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_tex;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gl_rect_2d(0, height, width, 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
 	
 #if MEM_TRACK_TYPE
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 4f559105f6d..21b1bee54f6 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -226,7 +226,7 @@ void LLNetMap::draw()
 		LLGLEnable scissor(GL_SCISSOR_TEST);
 		
 		{
-			LLGLSNoTexture no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLLocalClipRect clip(getLocalRect());
 
 			glMatrixMode(GL_MODELVIEW);
@@ -286,8 +286,8 @@ void LLNetMap::draw()
 
 
 			// Draw using texture.
-			LLViewerImage::bindTexture(regionp->getLand().getSTexture());
-			gGL.begin(LLVertexBuffer::QUADS);
+			gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
+			gGL.begin(LLRender::QUADS);
 				gGL.texCoord2f(0.f, 1.f);
 				gGL.vertex2f(left, top);
 				gGL.texCoord2f(0.f, 0.f);
@@ -303,8 +303,8 @@ void LLNetMap::draw()
 			{
 				if (regionp->getLand().getWaterTexture())
 				{
-					LLViewerImage::bindTexture(regionp->getLand().getWaterTexture());
-					gGL.begin(LLVertexBuffer::QUADS);
+					gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture());
+					gGL.begin(LLRender::QUADS);
 						gGL.texCoord2f(0.f, 1.f);
 						gGL.vertex2f(left, top);
 						gGL.texCoord2f(0.f, 0.f);
@@ -350,11 +350,11 @@ void LLNetMap::draw()
 		map_center_agent.mV[VX] *= gMiniMapScale/region_width;
 		map_center_agent.mV[VY] *= gMiniMapScale/region_width;
 
-		LLViewerImage::bindTexture(mObjectImagep);
+		gGL.getTexUnit(0)->bind(mObjectImagep);
 		F32 image_half_width = 0.5f*mObjectMapPixels;
 		F32 image_half_height = 0.5f*mObjectMapPixels;
 
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 			gGL.texCoord2f(0.f, 1.f);
 			gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]);
 			gGL.texCoord2f(0.f, 0.f);
@@ -457,13 +457,13 @@ void LLNetMap::draw()
 		F32 ctr_y = (F32)center_sw_bottom;
 
 
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		if( LLNetMap::sRotateMap )
 		{
 			gGL.color4fv(gFrustumMapColor.mV);
 
-			gGL.begin( LLVertexBuffer::TRIANGLES  );
+			gGL.begin( LLRender::TRIANGLES  );
 				gGL.vertex2f( ctr_x, ctr_y );
 				gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
 				gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
@@ -477,7 +477,7 @@ void LLNetMap::draw()
 			gGL.pushMatrix();
 				gGL.translatef( ctr_x, ctr_y, 0 );
 				glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
-				gGL.begin( LLVertexBuffer::TRIANGLES  );
+				gGL.begin( LLRender::TRIANGLES  );
 					gGL.vertex2f( 0, 0 );
 					gGL.vertex2f( -half_width_pixels, far_clip_pixels );
 					gGL.vertex2f(  half_width_pixels, far_clip_pixels );
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 8125fb61c04..13f3d125edb 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -340,6 +340,11 @@ namespace {
 	boost::intrusive_ptr< LLIamHereLogin > gResponsePtr = 0;
 };
 
+void set_start_location(LLUICtrl* ctrl, void* data)
+{
+    LLURLSimString::setString(ctrl->getValue().asString());
+}
+
 //---------------------------------------------------------------------------
 // Public methods
 //---------------------------------------------------------------------------
@@ -426,7 +431,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 		combo->setCurrentByIndex( 0 );
 	}
 
-	combo->setCommitCallback( &LLPanelGeneral::set_start_location );
+	combo->setCommitCallback( &set_start_location );
 
 	LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
 	server_choice_combo->setCommitCallback(onSelectServer);
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index d54de05d23a..aebed450817 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -365,6 +365,17 @@ void LLPanelObject::getState( )
 	BOOL enable_scale	= objectp->permMove() && objectp->permModify();
 	BOOL enable_rotate	= objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
 
+	S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+	BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
+						 && (selected_count == 1);
+
+	if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1)
+	{
+		enable_move = FALSE;
+		enable_scale = FALSE;
+		enable_rotate = FALSE;
+	}
+
 	LLVector3 vec;
 	if (enable_move)
 	{
@@ -438,9 +449,6 @@ void LLPanelObject::getState( )
 	// BUG? Check for all objects being editable?
 	S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
 	BOOL editable = root_objectp->permModify();
-	S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
-	BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
-						 && (selected_count == 1);
 
 	// Select Single Message
 	childSetVisible("select_single", FALSE);
diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h
index 2af9cbafaeb..5191a80df88 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/newview/llpolymesh.h
@@ -150,7 +150,7 @@ class LLPolyMeshSharedData
 class LLJointRenderData
 {
 public:
-	LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint){}
+	LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
 	~LLJointRenderData(){}
 
 	const LLMatrix4*		mWorldMatrix;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 55bad7fc7d7..79b83133523 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -200,7 +200,7 @@ void LLPreviewTexture::draw()
 	if (!isMinimized())
 	{
 		LLGLSUIDefault gls_ui;
-		LLGLSNoTexture gls_notex;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		
 		const LLRect& border = mClientRect;
 		LLRect interior = mClientRect;
@@ -299,20 +299,20 @@ BOOL LLPreviewTexture::canSaveAs() const
 // virtual
 void LLPreviewTexture::saveAs()
 {
-	if( !mLoadingFullImage )
+	if( mLoadingFullImage ) return;
+
+	LLFilePicker& file_picker = LLFilePicker::instance();
+	if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA, LLDir::getScrubbedFileName(getItem()->getName())) )
 	{
-		LLFilePicker& file_picker = LLFilePicker::instance();
-		if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA ) )
-		{
-			// User canceled save.
-			return;
-		}
-		mSaveFileName = file_picker.getFirstFile();
-		mLoadingFullImage = TRUE;
-		getWindow()->incBusyCount();
-		mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave, 
-								   0, TRUE, FALSE, new LLUUID( mItemUUID ) );
+		// User canceled or we failed to acquire save file.
+		return;
 	}
+	// remember the user-approved/edited file name.
+	mSaveFileName = file_picker.getFirstFile();
+	mLoadingFullImage = TRUE;
+	getWindow()->incBusyCount();
+	mImage->setLoadedCallback( LLPreviewTexture::onFileLoadedForSave, 
+								0, TRUE, FALSE, new LLUUID( mItemUUID ) );
 }
 
 
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 9df60d67b5f..c79022a98f3 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -208,7 +208,7 @@ void LLProgressView::draw()
 	if (gStartImageGL)
 	{
 		LLGLSUIDefault gls_ui;
-		LLViewerImage::bindTexture(gStartImageGL);
+		gGL.getTexUnit(0)->bind(gStartImageGL);
 		gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f);
 		F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;
 		F32 view_aspect = (F32)width / (F32)height;
@@ -224,11 +224,11 @@ void LLProgressView::draw()
 			glScalef(1.f, view_aspect / image_aspect, 1.f);
 		}
 		gl_rect_2d_simple_tex( getRect().getWidth(), getRect().getHeight() );
-		gStartImageGL->unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 	else
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f(0.f, 0.f, 0.f, 1.f);
 		gl_rect_2d(getRect());
 	}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 76271a65bb0..7b7bdfd5826 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -4828,7 +4828,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 		return;
 	}
 
-	LLViewerImage::bindTexture(mSilhouetteImagep);
+	gGL.getTexUnit(0)->bind(mSilhouetteImagep.get());
 	LLGLSPipelineSelection gls_select;
 	gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
 	LLGLEnable blend(GL_BLEND);
@@ -4936,7 +4936,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 		stop_glerror();
 	}
 
-	mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 }
 
@@ -5313,7 +5313,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
 			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 			{
 				S32 i = 0;
 				for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
@@ -5334,7 +5334,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 
 		gGL.flush();
 		gGL.setSceneBlendType(LLRender::BT_ALPHA);
-		gGL.begin(LLVertexBuffer::TRIANGLES);
+		gGL.begin(LLRender::TRIANGLES);
 		{
 			S32 i = 0;
 			for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index 1ba4adf4d2a..1cba1de9e94 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -284,16 +284,16 @@ LLColor4U LLSky::getFadeColor() const
 
 void LLSky::init(const LLVector3 &sun_direction)
 {
-	mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, gAgent.getRegion()));
+	mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, NULL));
 	mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero);
 	gPipeline.addObject(mVOWLSkyp.get());
 
-	mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, gAgent.getRegion());
+	mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, NULL);
 	mVOSkyp->initSunDirection(sun_direction, LLVector3());
 	gPipeline.addObject((LLViewerObject *)mVOSkyp);
 
 
-	mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, gAgent.getRegion());
+	mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, NULL);
 	LLVOGround *groundp = mVOGroundp;
 	gPipeline.addObject((LLViewerObject *)groundp);
 
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 7ea791d2533..59bf29161eb 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -46,6 +46,7 @@
 #include "pipeline.h"
 #include "llrender.h"
 #include "lloctree.h"
+#include "llvoavatar.h"
 
 const F32 SG_OCCLUSION_FUDGE = 1.01f;
 #define SG_DISCARD_TOLERANCE 0.01f
@@ -1624,7 +1625,7 @@ class LLOctreeSelect : public LLOctreeCull
 
 void drawBox(const LLVector3& c, const LLVector3& r)
 {
-	gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+	gGL.begin(LLRender::TRIANGLE_STRIP);
 	//left front
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
@@ -1643,7 +1644,7 @@ void drawBox(const LLVector3& c, const LLVector3& r)
 	gGL.end();
 	
 	//bottom
-	gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+	gGL.begin(LLRender::TRIANGLE_STRIP);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,-1))).mV);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,-1))).mV);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,-1))).mV);
@@ -1651,7 +1652,7 @@ void drawBox(const LLVector3& c, const LLVector3& r)
 	gGL.end();
 
 	//top
-	gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+	gGL.begin(LLRender::TRIANGLE_STRIP);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(1,1,1))).mV);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(-1,1,1))).mV);
 	gGL.vertex3fv((c+r.scaledVec(LLVector3(1,-1,1))).mV);
@@ -1666,7 +1667,7 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
 	LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1));
 	LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1));
 
-	gGL.begin(LLVertexBuffer::LINES); 
+	gGL.begin(LLRender::LINES); 
 	
 	//top
 	gGL.vertex3fv((pos+v1).mV);
@@ -1814,7 +1815,7 @@ void pushVerts(LLDrawInfo* params, U32 mask)
 {
 	LLRenderPass::applyModelMatrix(*params);
 	params->mVertexBuffer->setBuffer(mask);
-	params->mVertexBuffer->drawRange(params->mParticle ? LLVertexBuffer::POINTS : LLVertexBuffer::TRIANGLES,
+	params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES,
 								params->mStart, params->mEnd, params->mCount, params->mOffset);
 }
 
@@ -1843,7 +1844,7 @@ void pushVerts(LLFace* face, U32 mask)
 		U16 end = start + face->getGeomCount()-1;
 		U32 count = face->getIndicesCount();
 		U16 offset = face->getIndicesStart();
-		buffer->drawRange(LLVertexBuffer::TRIANGLES, start, end, count, offset);
+		buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
 	}
 
 }
@@ -1853,7 +1854,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
 	if (buffer)
 	{
 		buffer->setBuffer(mask);
-		buffer->drawRange(LLVertexBuffer::TRIANGLES, 0, buffer->getRequestedVerts()-1, buffer->getRequestedIndices(), 0);
+		buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getRequestedVerts()-1, buffer->getRequestedIndices(), 0);
 	}
 }
 
@@ -1902,7 +1903,7 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
 			LLRenderPass::applyModelMatrix(*params);
 			glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
 			params->mVertexBuffer->setBuffer(mask);
-			params->mVertexBuffer->drawRange(params->mParticle ? LLVertexBuffer::POINTS : LLVertexBuffer::TRIANGLES,
+			params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES,
 				params->mStart, params->mEnd, params->mCount, params->mOffset);
 			col = (col+1)%col_count;
 		}
@@ -1972,7 +1973,7 @@ void renderOctree(LLSpatialGroup* group)
 						face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX);
 						//drawBox((face->mExtents[0] + face->mExtents[1])*0.5f,
 						//		(face->mExtents[1]-face->mExtents[0])*0.5f);
-						face->mVertexBuffer->draw(LLVertexBuffer::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
+						face->mVertexBuffer->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
 					}
 				}
 
@@ -2103,6 +2104,7 @@ void renderBoundingBox(LLDrawable* drawable)
 					gGL.color4f(0.5f,0.5f,0.5f,1.0f);
 					break;
 			case LLViewerObject::LL_VO_PART_GROUP:
+			case LLViewerObject::LL_VO_HUD_PART_GROUP:
 					gGL.color4f(0,0,1,1);
 					break;
 			case LLViewerObject::LL_VO_WATER:
@@ -2222,7 +2224,7 @@ void renderPoints(LLDrawable* drawablep)
 	LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 	if (drawablep->getNumFaces())
 	{
-		gGL.begin(LLVertexBuffer::POINTS);
+		gGL.begin(LLRender::POINTS);
 		gGL.color3f(1,1,1);
 		LLVector3 center(drawablep->getPositionGroup());
 		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
@@ -2298,9 +2300,17 @@ void renderRaycast(LLDrawable* drawablep)
 		LLGLEnable blend(GL_BLEND);
 		gGL.color4f(0,1,1,0.5f);
 
-		for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+		if (drawablep->getVOVolume() && gDebugRaycastFaceHit != -1)
 		{
-			pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+			pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX);
+			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+		}
+		else if (drawablep->isAvatar())
+		{
+			LLGLDepthTest depth(GL_FALSE);
+			LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get();
+			av->renderCollisionVolumes();
 		}
 
 		// draw intersection point
@@ -2468,7 +2478,7 @@ void LLSpatialPartition::renderDebug()
 	LLGLDisable cullface(GL_CULL_FACE);
 	LLGLEnable blend(GL_BLEND);
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
-	LLImageGL::unbindTexture(0);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gPipeline.disableLights();
 
 	LLSpatialBridge* bridge = asBridge();
@@ -2508,8 +2518,9 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 	LLVector3 *mNormal;
 	LLVector3 *mBinormal;
 	LLDrawable* mHit;
-	
-	LLOctreeIntersect(LLVector3 start, LLVector3 end,
+	BOOL mPickTransparent;
+
+	LLOctreeIntersect(LLVector3 start, LLVector3 end, BOOL pick_transparent,
 					  S32* face_hit, LLVector3* intersection, LLVector2* tex_coord, LLVector3* normal, LLVector3* binormal)
 		: mStart(start),
 		  mEnd(end),
@@ -2518,14 +2529,15 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 		  mTexCoord(tex_coord),
 		  mNormal(normal),
 		  mBinormal(binormal),
-		  mHit(NULL)
+		  mHit(NULL),
+		  mPickTransparent(pick_transparent)
 	{
 	}
 	
 	virtual void visit(const LLSpatialGroup::OctreeNode* branch) 
 	{	
 		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
-	{
+		{
 			check(*i);
 		}
 	}
@@ -2570,25 +2582,35 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 
 	virtual bool check(LLDrawable* drawable)
 	{	
+		LLVector3 local_start = mStart;
+		LLVector3 local_end = mEnd;
+
+		if (!gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
+		{
+			return false;
+		}
+
 		if (drawable->isSpatialBridge())
 		{
 			LLSpatialPartition *part = drawable->asPartition();
-
-			check(part->mOctree);
-	}
-
+			LLSpatialBridge* bridge = part->asBridge();
+			if (bridge && gPipeline.hasRenderType(bridge->mDrawableType))
+			{
+				check(part->mOctree);
+			}
+		}
 		else
-	{
-		LLViewerObject* vobj = drawable->getVObj();
+		{
+			LLViewerObject* vobj = drawable->getVObj();
 
 			if (vobj)
 			{
 				LLVector3 intersection;
-				if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
+				if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal))
 				{
 					mEnd = intersection;  // shorten ray so we only find CLOSER hits
 					if (mIntersection)
-		{
+					{
 						*mIntersection = intersection;
 					}
 					
@@ -2596,12 +2618,13 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 				}
 			}
 		}
-		
+				
 		return false;
 	}
 };
 
 LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+													 BOOL pick_transparent,													
 													 S32* face_hit,                   // return the face hit
 													 LLVector3* intersection,         // return the intersection point
 													 LLVector2* tex_coord,            // return the texture coordinates of the intersection point
@@ -2610,7 +2633,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con
 	)
 
 {
-	LLOctreeIntersect intersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal);
+	LLOctreeIntersect intersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
 	LLDrawable* drawable = intersect.check(mOctree);
 
 	return drawable;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index d9a81d8b9e1..2d9900da1b1 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -301,6 +301,7 @@ class LLSpatialPartition: public LLGeometryManager
 	BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
 	
 	LLDrawable* lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+									 BOOL pick_transparent, 
 									 S32* face_hit,                          // return the face hit
 									 LLVector3* intersection = NULL,         // return the intersection point
 									 LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
@@ -482,6 +483,12 @@ class LLParticlePartition : public LLSpatialPartition
 	U32 mRenderPass;
 };
 
+class LLHUDParticlePartition : public LLParticlePartition
+{
+public:
+	LLHUDParticlePartition();
+};
+
 //spatial partition for grass (implemented in LLVOGrass.cpp)
 class LLGrassPartition : public LLParticlePartition
 {
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 1f1e56fce8d..8206699932b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -89,6 +89,7 @@
 #include "llfeaturemanager.h"
 #include "llfirstuse.h"
 #include "llfloateractivespeakers.h"
+#include "llfloaterbeacons.h"
 #include "llfloatercamera.h"
 #include "llfloaterchat.h"
 #include "llfloatergesture.h"
@@ -849,6 +850,20 @@ bool idle_startup()
 		LLFile::mkdir(gDirUtilp->getChatLogsDir());
 		LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
 
+		//good as place as any to create user windlight directories
+		std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", ""));
+		LLFile::mkdir(user_windlight_path_name.c_str());		
+
+		std::string user_windlight_skies_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
+		LLFile::mkdir(user_windlight_skies_path_name.c_str());
+
+		std::string user_windlight_water_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
+		LLFile::mkdir(user_windlight_water_path_name.c_str());
+
+		std::string user_windlight_days_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/days", ""));
+		LLFile::mkdir(user_windlight_days_path_name.c_str());
+
+
 		if (show_connect_box)
 		{
 			if ( LLPanelLogin::isGridComboDirty() )
@@ -1646,6 +1661,11 @@ bool idle_startup()
 			LLFloaterActiveSpeakers::showInstance();
 		}
 
+		if (gSavedSettings.getBOOL("BeaconAlwaysOn"))
+		{
+			LLFloaterBeacons::showInstance();
+		}
+
 		if (!gNoRender)
 		{
 			// Move the progress view in front of the UI
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index fa85d893881..75bb3f545b9 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -33,6 +33,8 @@
 
 #include "llsurface.h"
 
+#include "llrender.h"
+
 #include "llviewerimagelist.h"
 #include "llpatchvertexarray.h"
 #include "patch_dct.h"
@@ -249,7 +251,7 @@ void LLSurface::createSTexture()
 
 		mSTexturep = new LLViewerImage(raw, FALSE);
 		mSTexturep->dontDiscard();
-		mSTexturep->bind();
+		gGL.getTexUnit(0)->bind(mSTexturep.get());
 		mSTexturep->setClamp(TRUE, TRUE);
 		gImageList.addImage(mSTexturep);
 	}
@@ -274,7 +276,7 @@ void LLSurface::createWaterTexture()
 		}
 		mWaterTexturep = new LLViewerImage(raw, FALSE);
 		mWaterTexturep->dontDiscard();
-		mWaterTexturep->bind();
+		gGL.getTexUnit(0)->bind(mWaterTexturep.get());
 		mWaterTexturep->setClamp(TRUE, TRUE);
 		gImageList.addImage(mWaterTexturep);
 	}
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 30126251226..158bae00b8c 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -96,7 +96,6 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 h
 	mNeedsUpload( FALSE ),
 	mUploadPending( FALSE ), // Not used for any logic here, just to sync sending of updates
 	mTexLayerSet( owner ),
-	mInitialized( FALSE ),
 	mBumpTexName(0)
 {
 	LLTexLayerSetBuffer::sGLByteCount += getSize();
@@ -106,11 +105,10 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 h
 		LLGLSUIDefault gls_ui;
 		glGenTextures(1, (GLuint*) &mBumpTexName);
 
-		LLImageGL::bindExternalTexture(mBumpTexName, 0, GL_TEXTURE_2D); 
+		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTexName);
 		stop_glerror();
 
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -118,7 +116,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 h
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
 		stop_glerror();
 
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLImageGL::sGlobalTextureMemory += mWidth * mHeight * 4;
 		LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4;
@@ -259,7 +257,7 @@ BOOL LLTexLayerSetBuffer::render()
 			LLGLSUIDefault gls_ui;
 
 			// read back into texture (this is done externally for the color data)
-			LLImageGL::bindExternalTexture( mBumpTexName, 0, GL_TEXTURE_2D ); 
+			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTexName);
 			stop_glerror();
 
 			glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight);
@@ -299,12 +297,17 @@ BOOL LLTexLayerSetBuffer::render()
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 	// we have valid texture data now
-	mInitialized = TRUE;
+	mTexture->setInitialized(true);
 	mNeedsUpdate = FALSE;
 
 	return success;
 }
 
+bool LLTexLayerSetBuffer::isInitialized(void) const
+{
+	return mTexture->isInitialized();
+}
+
 BOOL LLTexLayerSetBuffer::updateImmediate()
 {
 	mNeedsUpdate = TRUE;
@@ -551,24 +554,12 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user
 	delete baked_upload_data;
 }
 
-
-void LLTexLayerSetBuffer::bindTexture()
-{
-	if( mInitialized )
-	{
-		LLDynamicTexture::bindTexture();
-	}
-	else
-	{
-		gImageList.getImage(IMG_DEFAULT)->bind();
-	}
-}
-
 void LLTexLayerSetBuffer::bindBumpTexture( U32 stage )
 {
 	if( mBumpTexName ) 
 	{
-		LLImageGL::bindExternalTexture(mBumpTexName, stage, GL_TEXTURE_2D); 
+		gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTexName);
+		gGL.getTexUnit(0)->activate();
 	
 		if( mLastBindTime != LLImageGL::sLastFrameTime )
 		{
@@ -578,7 +569,8 @@ void LLTexLayerSetBuffer::bindBumpTexture( U32 stage )
 	}
 	else
 	{
-		LLImageGL::unbindTexture(stage, GL_TEXTURE_2D);
+		gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.getTexUnit(0)->activate();
 	}
 }
 
@@ -786,7 +778,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 			if( image_gl )
 			{
 				LLGLSUIDefault gls_ui;
-				image_gl->bind();
+				gGL.getTexUnit(0)->bind(image_gl);
 				gl_rect_2d_simple_tex( width, height );
 			}
 			else
@@ -794,7 +786,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 				success = FALSE;
 			}
 		}
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		gGL.flush();
 		gGL.setColorMask(true, true);
@@ -804,7 +796,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 	if( getInfo()->mClearAlpha )
 	{
 		// Set the alpha channel to one (clean up after previous blending)
-		LLGLSNoTextureNoAlphaTest gls_no_alpha;
+		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.f, 0.f, 0.f, 1.f );
 		gGL.flush();
 		gGL.setColorMask(false, true);
@@ -838,7 +831,8 @@ BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height )
 	}
 
 	// Set the alpha channel to one (clean up after previous blending)
-	LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha;
+	LLGLDisable no_alpha(GL_ALPHA_TEST);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	gGL.color4f( 0.f, 0.f, 0.f, 1.f );
 	gGL.setColorMask(false, true);
 
@@ -1358,13 +1352,13 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
 					BOOL old_clamps = image_gl->getClampS();
 					BOOL old_clampt = image_gl->getClampT();
 					
-					image_gl->bind();
+					gGL.getTexUnit(0)->bind(image_gl);
 					image_gl->setClamp(TRUE, TRUE);
 
 					gl_rect_2d_simple_tex( width, height );
 
 					image_gl->setClamp(old_clamps, old_clampt);
-					image_gl->unbindTexture(0, GL_TEXTURE_2D);
+					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				}
 			}
 			else
@@ -1380,9 +1374,9 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
 			LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
 			if( image_gl )
 			{
-				image_gl->bind();
+				gGL.getTexUnit(0)->bind(image_gl);
 				gl_rect_2d_simple_tex( width, height );
-				image_gl->unbindTexture(0, GL_TEXTURE_2D);
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			}
 			else
 			{
@@ -1396,7 +1390,8 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
 		getInfo()->mStaticImageFileName.empty() &&
 		color_specified )
 	{
-		LLGLSNoTextureNoAlphaTest gls;
+		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( net_color.mV);
 		gl_rect_2d_simple( width, height );
 	}
@@ -1518,7 +1513,8 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
 	// Note: if the first param is a mulitply, multiply against the current buffer's alpha
 	if( !first_param || !first_param->getMultiplyBlend() )
 	{
-		LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test;
+		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 		// Clear the alpha
 		gGL.flush();
@@ -1555,13 +1551,13 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
 
 					BOOL old_clamps = image_gl->getClampS();
 					BOOL old_clampt = image_gl->getClampT();					
-					image_gl->bind();
+					gGL.getTexUnit(0)->bind(image_gl);
 					image_gl->setClamp(TRUE, TRUE);
 
 					gl_rect_2d_simple_tex( width, height );
 
 					image_gl->setClamp(old_clamps, old_clampt);
-					image_gl->unbindTexture(0, GL_TEXTURE_2D);
+					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				}
 			}
 			else
@@ -1581,9 +1577,9 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
 					( (image_gl->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
 				{
 					LLGLSNoAlphaTest gls_no_alpha_test;
-					image_gl->bind();
+					gGL.getTexUnit(0)->bind(image_gl);
 					gl_rect_2d_simple_tex( width, height );
-					image_gl->unbindTexture(0, GL_TEXTURE_2D);
+					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				}
 			}
 			else
@@ -1597,7 +1593,8 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
 	// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
 	if( colorp->mV[VW] != 1.f )
 	{
-		LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test;
+		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( colorp->mV );
 		gl_rect_2d_simple( width, height );
 	}
@@ -1700,7 +1697,7 @@ BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 i
 		glGenTextures(1, &name );
 		stop_glerror();
 
-		LLImageGL::bindExternalTexture( name, 0, GL_TEXTURE_2D ); 
+		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name);
 		stop_glerror();
 
 		glTexImage2D(
@@ -1712,12 +1709,11 @@ BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 i
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 		
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 
 		gl_rect_2d_simple_tex( width, height );
 
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		glDeleteTextures(1, &name );
 		stop_glerror();
@@ -1736,7 +1732,7 @@ BOOL LLTexLayer::renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 i
 
 		gl_rect_2d_simple_tex( width, height );
 
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 
 	return TRUE;
@@ -2039,40 +2035,24 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
 		if( mCachedProcessedImageGL )
 		{
 			{
-				if (gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))
+				// Create the GL texture, and then hang onto it for future use.
+				if( mNeedsCreateTexture )
 				{
-					if( mNeedsCreateTexture )
-					{
-						mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
-						mNeedsCreateTexture = FALSE;
-						
-						mCachedProcessedImageGL->bind();
-						mCachedProcessedImageGL->setClamp(TRUE, TRUE);
-					}
-
-					LLGLSNoAlphaTest gls_no_alpha_test;
-					mCachedProcessedImageGL->bind();
-					gGradientPaletteList.setHardwarePalette( getInfo()->mDomain, effective_weight );
-					gl_rect_2d_simple_tex( width, height );
-					mCachedProcessedImageGL->unbindTexture(0, GL_TEXTURE_2D);
+					mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
+					mNeedsCreateTexture = FALSE;
+					
+					gGL.getTexUnit(0)->bind(mCachedProcessedImageGL);
+					mCachedProcessedImageGL->setClamp(TRUE, TRUE);
 				}
-				else
-				{
-					// Create the GL texture, and then hang onto it for future use.
-					if( mNeedsCreateTexture )
-					{
-						mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw);
-						mNeedsCreateTexture = FALSE;
-						
-						mCachedProcessedImageGL->bind();
-						mCachedProcessedImageGL->setClamp(TRUE, TRUE);
-					}
-				
-					LLGLSNoAlphaTest gls_no_alpha_test;
-					mCachedProcessedImageGL->bind();
-					gl_rect_2d_simple_tex( width, height );
-					mCachedProcessedImageGL->unbindTexture(0, GL_TEXTURE_2D);
+
+				LLGLSNoAlphaTest gls_no_alpha_test;
+				gGL.getTexUnit(0)->bind(mCachedProcessedImageGL);
+				if (gGLManager.mHasPalettedTextures && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_PALETTE))
+				{					
+					gGradientPaletteList.setHardwarePalette( getInfo()->mDomain, effective_weight );			
 				}
+				gl_rect_2d_simple_tex( width, height );
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 				stop_glerror();
 			}
 		}
@@ -2086,7 +2066,8 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height )
 	}
 	else
 	{
-		LLGLSNoTextureNoAlphaTest gls_no_texture_no_alpha_test;
+		LLGLDisable no_alpha(GL_ALPHA_TEST);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.f, 0.f, 0.f, effective_weight );
 		gl_rect_2d_simple( width, height );
 	}
@@ -2519,7 +2500,7 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i
 			}
 			image_gl->createGLTexture(0, image_raw);
 
-			image_gl->bind();
+			gGL.getTexUnit(0)->bind(image_gl);
 			image_gl->setClamp(TRUE, TRUE);
 
 			mStaticImageListGL [ namekey ] = image_gl;
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index befb262a4c6..992e392fc74 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -211,9 +211,8 @@ class LLTexLayerSetBuffer : public LLDynamicTexture
 	virtual void			postRender(BOOL success);
 	virtual BOOL			render();
 	BOOL					updateImmediate();
-	virtual void			bindTexture();
 	void					bindBumpTexture( U32 stage );
-	BOOL					isInitialized()							{ return mInitialized; }  // Initialized here means that we've done at least one render
+	bool					isInitialized(void) const;
 	BOOL					needsRender();
 	void					requestUpdate();
 	void					requestUpload();
@@ -236,7 +235,6 @@ class LLTexLayerSetBuffer : public LLDynamicTexture
 	BOOL					mUploadPending;
 	LLUUID					mUploadID;		// Identifys the current upload process (null if none).  Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
 	LLTexLayerSet*			mTexLayerSet;
-	BOOL					mInitialized;
 	LLGLuint				mBumpTexName;	// zero if none
 
 	static S32				sGLByteCount;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4f9d9f77638..7bdea15ac44 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -483,9 +483,9 @@ void LLFloaterTexturePicker::draw()
 		LLRect local_rect = getLocalRect();
 		if (gFocusMgr.childHasKeyboardFocus(this) && mOwner->isInVisibleChain() && mContextConeOpacity > 0.001f)
 		{
-			LLGLSNoTexture no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLGLEnable(GL_CULL_FACE);
-			gGL.begin(LLVertexBuffer::QUADS);
+			gGL.begin(LLRender::QUADS);
 			{
 				gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
 				gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index d83a2ec9447..14fa73d3b14 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -247,7 +247,7 @@ void LLTextureBar::draw()
 	LLFontGL::sMonospace->renderUTF8(fetch_state_desc[state].desc, 0, title_x2, getRect().getHeight(),
 									 fetch_state_desc[state].color,
 									 LLFontGL::LEFT, LLFontGL::TOP);
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// Draw the progress bar.
 	S32 bar_width = 100;
@@ -415,7 +415,7 @@ void LLGLTexMemBar::draw()
 
 	F32 bar_scale = (F32)bar_width / (max_bound_mem * 1.5f);
 	
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 	gGL.color4f(0.5f, 0.5f, 0.5f, 0.75f);
 	gl_rect_2d(left, top, right, bottom);
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 11e90e9c843..2959e3a3707 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -42,6 +42,7 @@
 #include "lltoolfocus.h"
 #include "llfocusmgr.h"
 #include "llagent.h"
+#include "llviewerjoystick.h"
 
 extern BOOL gDebugClicks;
 
@@ -160,6 +161,11 @@ BOOL LLTool::handleKey(KEY key, MASK mask)
 
 LLTool* LLTool::getOverrideTool(MASK mask)
 {
+	// NOTE: if in flycam mode, ALT-ZOOM camera should be disabled
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return NULL;
+	}
 	if (mask & MASK_ALT)
 	{
 		return LLToolCamera::getInstance();
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index 07a9650af2e..6bdd4e77676 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -491,7 +491,7 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region
 									const LLVector3& pos_world)
 {
 	glMatrixMode(GL_MODELVIEW);
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest mDepthTest(GL_TRUE);
 	glPushMatrix();
 	gGL.color4fv(OVERLAY_COLOR.mV);
@@ -503,7 +503,7 @@ void LLToolBrushLand::renderOverlay(LLSurface& land, const LLVector3& pos_region
 	S32 radioAction = gSavedSettings.getS32("RadioLandBrushAction");
 	F32 force = gSavedSettings.getF32("LandBrushForce"); // .1 to 100?
 	
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 	for(S32 di = -half_edge; di <= half_edge; di++)
 	{
 		if((i+di) < 0 || (i+di) >= (S32)land.mGridsPerEdge) continue;
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index d8d271bfdab..8430f49e5e9 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -240,6 +240,7 @@ BOOL LLVisualParamHint::render()
 	}
 	avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight);
 	gGL.color4f(1,1,1,1);
+	mTexture->setInitialized(true);
 	return TRUE;
 }
 
@@ -251,12 +252,12 @@ void LLVisualParamHint::draw()
 {
 	if (!mIsVisible) return;
 
-	bindTexture();
+	gGL.getTexUnit(0)->bind(getTexture());
 
 	gGL.color4f(1.f, 1.f, 1.f, 1.f);
 
 	LLGLSUIDefault gls_ui;
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.begin(LLRender::QUADS);
 	{
 		gGL.texCoord2i(0, 1);
 		gGL.vertex2i(0, mHeight);
@@ -269,7 +270,7 @@ void LLVisualParamHint::draw()
 	}
 	gGL.end();
 
-	LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp
index 0d403bbb287..5dde83e2ecf 100644
--- a/indra/newview/lltoolselectrect.cpp
+++ b/indra/newview/lltoolselectrect.cpp
@@ -175,7 +175,7 @@ void LLToolSelectRect::draw()
 		{
 			gGL.color4f(1.f, 1.f, 0.f, 1.f);
 		}
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gl_rect_2d(
 			llmin(mDragStartX, mDragEndX),
 			llmax(mDragStartY, mDragEndY),
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 85d9504740e..39554dd510a 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -445,7 +445,7 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color)
 	F32 y = 0.f;
 
 	LLColor4 ccol = LLColor4(1,1,1,(1.f-t)*0.25f);
-	gGL.begin(LLVertexBuffer::TRIANGLE_FAN);
+	gGL.begin(LLRender::TRIANGLE_FAN);
 	gGL.color4fv(ccol.mV);
 	gGL.vertex3f(0.f, 0.f, center_z);
 	// make sure circle is complete
@@ -494,7 +494,8 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 
 	LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global);
 
-	LLGLSTracker gls_tracker; // default - TEXTURE + CULL_FACE + LIGHTING + GL_BLEND + GL_ALPHA_TEST
+	LLGLSTracker gls_tracker; // default+ CULL_FACE + LIGHTING + GL_BLEND + GL_ALPHA_TEST
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDisable cull_face(GL_CULL_FACE);
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 	
@@ -535,7 +536,7 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 			an *= 2.f;
 			an += 1.0f+dr;
 		
-			gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+			gGL.begin(LLRender::TRIANGLE_STRIP);
 			gGL.color4fv(col_edge.mV);
 			gGL.vertex3f(-x*a, -y*a, z);
 			gGL.color4fv(col_edge_next.mV);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 9e5b566e602..2f907fddbf6 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -248,8 +248,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 	gViewerWindow->checkSettings();
 	
-	LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
-	gViewerWindow->performPick();
+	{
+		LLFastTimer ftm(LLFastTimer::FTM_PICK);
+		LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
+		gViewerWindow->performPick();
+	}
 	
 
 	LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
@@ -373,6 +376,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["arriving"]);
 			gImageList.mForceResetTextureStats = TRUE;
+			gAgent.resetView(TRUE, TRUE);
 			break;
 
 		case LLAgent::TELEPORT_ARRIVING:
@@ -690,7 +694,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		//	glMatrixMode(GL_MODELVIEW);
 		//	glPushMatrix();
 		//	{
-		//		LLGLSNoTexture gls_no_texture;
+		//		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		//		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
 		//		glLoadIdentity();
@@ -997,8 +1001,8 @@ void render_ui()
 
 void renderCoordinateAxes()
 {
-	LLGLSNoTexture gls_no_texture;
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.begin(LLRender::LINES);
 		gGL.color3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red
 		gGL.vertex3f(0.0f, 0.0f, 0.0f);
 		gGL.vertex3f(2.0f, 0.0f, 0.0f);
@@ -1048,10 +1052,10 @@ void renderCoordinateAxes()
 void draw_axes() 
 {
 	LLGLSUIDefault gls_ui;
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	// A vertical white line at origin
 	LLVector3 v = gAgent.getPositionAgent();
-	gGL.begin(LLVertexBuffer::LINES);
+	gGL.begin(LLRender::LINES);
 		gGL.color3f(1.0f, 1.0f, 1.0f); 
 		gGL.vertex3f(0.0f, 0.0f, 0.0f);
 		gGL.vertex3f(0.0f, 0.0f, 40.0f);
@@ -1194,7 +1198,7 @@ void render_disconnected_background()
 		raw->expandToPowerOfTwo();
 		gDisconnectedImagep->createGLTexture(0, raw);
 		gStartImageGL = gDisconnectedImagep;
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 
 	// Make sure the progress view always fills the entire window.
@@ -1213,10 +1217,10 @@ void render_disconnected_background()
 			const LLVector2& display_scale = gViewerWindow->getDisplayScale();
 			glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
 
-			LLViewerImage::bindTexture(gDisconnectedImagep);
+			gGL.getTexUnit(0)->bind(gDisconnectedImagep);
 			gGL.color4f(1.f, 1.f, 1.f, 1.f);
 			gl_rect_2d_simple_tex(width, height);
-			LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
 		glPopMatrix();
 	}
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index 71d98b73de6..ce510994e4d 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -149,7 +149,7 @@ void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
 // 	//----------------------------------------------------------------
 // 	if (mComponents & SC_AXES)
 // 	{
-// 		gGL.begin(LLVertexBuffer::LINES);
+// 		gGL.begin(LLRender::LINES);
 // 		gGL.color3f( 1.0f, 0.0f, 0.0f );
 // 		gGL.vertex3f( 0.0f,            0.0f, 0.0f );
 // 		gGL.vertex3f( 0.1f, 0.0f, 0.0f );
@@ -171,7 +171,7 @@ void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
 // 	{
 // 		gGL.color3f( 1.0f, 1.0f, 0.0f );
 
-// 		gGL.begin(LLVertexBuffer::TRIANGLES);
+// 		gGL.begin(LLRender::TRIANGLES);
 
 // 		// joint top half
 // 		glNormal3f(nc, nc, nc);
@@ -362,7 +362,7 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass )
 // 	// render the bone
 // 	gGL.color3f( 0.5f, 0.5f, 0.0f );
 
-// 	gGL.begin(LLVertexBuffer::TRIANGLES);
+// 	gGL.begin(LLRender::TRIANGLES);
 
 // 	gGL.vertex3f( length,     0.0f,       0.0f);
 // 	gGL.vertex3f( 0.0f,       boneSize,  0.0f);
@@ -524,14 +524,69 @@ LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &na
 void LLViewerJointCollisionVolume::renderCollision()
 {
 	updateWorldMatrix();
-	glMatrixMode(GL_MODELVIEW);
-	glPushMatrix();
+	
+	gGL.pushMatrix();
 	glMultMatrixf( &mXform.getWorldMatrix().mMatrix[0][0] );
 
-	glColor3f( 0.f, 0.f, 1.f );
-	gSphere.render();
+	gGL.color3f( 0.f, 0.f, 1.f );
+	
+	gGL.begin(LLRender::LINES);
+	
+	LLVector3 v[] = 
+	{
+		LLVector3(1,0,0),
+		LLVector3(-1,0,0),
+		LLVector3(0,1,0),
+		LLVector3(0,-1,0),
+
+		LLVector3(0,0,-1),
+		LLVector3(0,0,1),
+	};
+
+	//sides
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+
+	//top
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+
+	//bottom
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.end();
 
-	glPopMatrix();
+	gGL.popMatrix();
 }
 
 LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index d66d0da5b1a..225d5e912ff 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -91,7 +91,7 @@ U32 LLViewerJointAttachment::drawShape( F32 pixelArea, BOOL first_pass )
 		LLGLDisable cull_face(GL_CULL_FACE);
 		
 		gGL.color4f(1.f, 1.f, 1.f, 1.f);
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		{
 			gGL.vertex3f(-0.1f, 0.1f, 0.f);
 			gGL.vertex3f(-0.1f, -0.1f, 0.f);
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index f975e56b95f..0f207f66c0d 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -537,7 +537,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 
 	if (mTestImageName)
 	{
-		LLImageGL::bindExternalTexture( mTestImageName, 0, GL_TEXTURE_2D ); 
+		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
 
 		if (mIsTransparent)
 		{
@@ -553,12 +553,12 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 	{
 		if(	mLayerSet->hasComposite() )
 		{
-			mLayerSet->getComposite()->bindTexture();
+			gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture());
 		}
 		else
 		{
 			llwarns << "Layerset without composite" << llendl;
-			gImageList.getImage(IMG_DEFAULT)->bind();
+			gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT));
 		}
 	}
 	else
@@ -566,13 +566,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 	{
 		if (!mTexture->getClampS() || !mTexture->getClampT())
 		{
-			mTexture->bind();
+			gGL.getTexUnit(0)->bind(mTexture.get());
 			mTexture->overrideClamp (TRUE, TRUE);
 		}
 	}
 	else
 	{
-		gImageList.getImage(IMG_DEFAULT_AVATAR)->bind();
+		gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT_AVATAR));
 	}
 	
 	if (gRenderForSelect)
@@ -584,7 +584,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 		}
 		else
 		{
-			LLImageGL::unbindTexture(0);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
 	}
 	
@@ -605,14 +605,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 			}
 		}
 		
-		mFace->mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, start, end, count, offset);
+		mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
 	}
 	else
 	{
 		glPushMatrix();
 		LLMatrix4 jointToWorld = getWorldMatrix();
 		glMultMatrixf((GLfloat*)jointToWorld.mMatrix);
-		mFace->mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, start, end, count, offset);
+		mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
 		glPopMatrix();
 	}
 	gPipeline.addTrianglesDrawn(count/3);
@@ -626,7 +626,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass)
 
 	if (mTexture.notNull())
 	{
-		mTexture->bind();
+		gGL.getTexUnit(0)->bind(mTexture.get());
 		mTexture->restoreClamp();
 	}
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7f9ba3206c3..4bf5a2d4ea1 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -85,6 +85,7 @@
 #include "llfloateranimpreview.h"
 #include "llfloateravatarinfo.h"
 #include "llfloateravatartextures.h"
+#include "llfloaterbeacons.h"
 #include "llfloaterbuildoptions.h"
 #include "llfloaterbump.h"
 #include "llfloaterbuy.h"
@@ -788,12 +789,6 @@ void init_client_menu(LLMenuGL* menu)
 										&menu_check_control,
 										(void*)"QuietSnapshotsToDisk"));
 
-	menu->append(new LLMenuItemCheckGL( "Compress Snapshots to Disk",
-										&menu_toggle_control,
-										NULL,
-										&menu_check_control,
-										(void*)"CompressSnapshotsToDisk"));
-
 	menu->append(new LLMenuItemCheckGL("Show Mouselook Crosshairs",
 									   &menu_toggle_control,
 									   NULL,
@@ -941,6 +936,7 @@ void init_client_menu(LLMenuGL* menu)
 		sub->append(new LLMenuItemCallGL("Force LLError And Crash", &force_error_llerror));
         sub->append(new LLMenuItemCallGL("Force Bad Memory Access", &force_error_bad_memory_access));
 		sub->append(new LLMenuItemCallGL("Force Infinite Loop", &force_error_infinite_loop));
+		sub->append(new LLMenuItemCallGL("Force Disconnect Viewer", &handle_disconnect_viewer));
 		// *NOTE:Mani this isn't handled yet... sub->append(new LLMenuItemCallGL("Force Software Exception", &force_error_unhandled_exception)); 
 		sub->createJumpKeys();
 		menu->appendMenu(sub);
@@ -1209,9 +1205,6 @@ void init_debug_rendering_menu(LLMenuGL* menu)
 	sub_menu->append(new LLMenuItemCheckGL("Face Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,
 													&LLPipeline::toggleRenderDebugControl,
 													(void*)LLPipeline::RENDER_DEBUG_FACE_AREA));
-	sub_menu->append(new LLMenuItemCheckGL("Pick Render",	&LLPipeline::toggleRenderDebug, NULL,
-													&LLPipeline::toggleRenderDebugControl,
-													(void*)LLPipeline::RENDER_DEBUG_PICKING));
 	sub_menu->append(new LLMenuItemCheckGL("Lights",	&LLPipeline::toggleRenderDebug, NULL,
 													&LLPipeline::toggleRenderDebugControl,
 													(void*)LLPipeline::RENDER_DEBUG_LIGHTS));
@@ -1230,9 +1223,7 @@ void init_debug_rendering_menu(LLMenuGL* menu)
 	sub_menu->append(new LLMenuItemCheckGL("Sculpt",	&LLPipeline::toggleRenderDebug, NULL,
 													&LLPipeline::toggleRenderDebugControl,
 													(void*)LLPipeline::RENDER_DEBUG_SCULPTED));
-	
-	sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect));
-
+		
 	sub_menu->append(new LLMenuItemCallGL("Vectorize Perf Test", &run_vectorize_perf_test));
 
 	sub_menu = new LLMenuGL("Render Tests");
@@ -3201,26 +3192,7 @@ void reset_view_final( BOOL proceed, void* )
 		return;
 	}
 
-	gAgent.changeCameraToDefault();
-	
-	if (LLViewerJoystick::getInstance()->getOverrideCamera())
-	{
-		handle_toggle_flycam();
-	}
-
-	// reset avatar mode from eventual residual motion
-	if (LLToolMgr::getInstance()->inBuildMode())
-	{
-		LLViewerJoystick::getInstance()->moveAvatar(true);
-	}
-
-	gAgent.resetView(!gFloaterTools->getVisible());
-	gFloaterTools->close();
-	
-	gViewerWindow->showCursor();
-
-	// Switch back to basic toolset
-	LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+	gAgent.resetView(TRUE, TRUE);
 }
 
 class LLViewLookAtLastChatter : public view_listener_t
@@ -5305,6 +5277,10 @@ class LLShowFloater : public view_listener_t
 		{
 			LLFloaterActiveSpeakers::toggleInstance(LLSD());
 		}
+		else if (floater_name == "beacons")
+		{
+			LLFloaterBeacons::toggleInstance(LLSD());
+		}
 		return true;
 	}
 };
@@ -5352,6 +5328,10 @@ class LLFloaterVisible : public view_listener_t
 		{
 			new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD());
 		}
+		else if (floater_name == "beacons")
+		{
+			new_value = LLFloaterBeacons::instanceVisible(LLSD());
+		}
 		gMenuHolder->findControl(control_name)->setValue(new_value);
 		return true;
 	}
@@ -7112,148 +7092,6 @@ class LLViewCheckHighlightTransparent : public view_listener_t
 	}
 };
 
-class LLViewBeaconWidth : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		std::string width = userdata.asString();
-		if(width == "1")
-		{
-			gSavedSettings.setS32("DebugBeaconLineWidth", 1);
-		}
-		else if(width == "4")
-		{
-			gSavedSettings.setS32("DebugBeaconLineWidth", 4);
-		}
-		else if(width == "16")
-		{
-			gSavedSettings.setS32("DebugBeaconLineWidth", 16);
-		}
-		else if(width == "32")
-		{
-			gSavedSettings.setS32("DebugBeaconLineWidth", 32);
-		}
-
-		return true;
-	}
-};
-
-
-class LLViewToggleBeacon : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		std::string beacon = userdata.asString();
-		if (beacon == "scriptsbeacon")
-		{
-			LLPipeline::toggleRenderScriptedBeacons(NULL);
-			gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
-			// toggle the other one off if it's on
-			if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
-			{
-				LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
-				gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
-			}
-		}
-		else if (beacon == "physicalbeacon")
-		{
-			LLPipeline::toggleRenderPhysicalBeacons(NULL);
-			gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons(NULL) );
-		}
-		else if (beacon == "soundsbeacon")
-		{
-			LLPipeline::toggleRenderSoundBeacons(NULL);
-			gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons(NULL) );
-		}
-		else if (beacon == "particlesbeacon")
-		{
-			LLPipeline::toggleRenderParticleBeacons(NULL);
-			gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons(NULL) );
-		}
-		else if (beacon == "scripttouchbeacon")
-		{
-			LLPipeline::toggleRenderScriptedTouchBeacons(NULL);
-			gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons(NULL) );
-			// toggle the other one off if it's on
-			if (LLPipeline::getRenderScriptedBeacons(NULL) && LLPipeline::getRenderScriptedTouchBeacons(NULL))
-			{
-				LLPipeline::toggleRenderScriptedBeacons(NULL);
-				gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons(NULL) );
-			}
-		}
-		else if (beacon == "renderbeacons")
-		{
-			LLPipeline::toggleRenderBeacons(NULL);
-			gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
-			// toggle the other one on if it's not
-			if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
-			{
-				LLPipeline::toggleRenderHighlights(NULL);
-				gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
-			}
-		}
-		else if (beacon == "renderhighlights")
-		{
-			LLPipeline::toggleRenderHighlights(NULL);
-			gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights(NULL) );
-			// toggle the other one on if it's not
-			if (!LLPipeline::getRenderBeacons(NULL) && !LLPipeline::getRenderHighlights(NULL))
-			{
-				LLPipeline::toggleRenderBeacons(NULL);
-				gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons(NULL) );
-			}
-		}
-			
-		return true;
-	}
-};
-
-class LLViewCheckBeaconEnabled : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		std::string beacon = userdata["data"].asString();
-		bool new_value = false;
-		if (beacon == "scriptsbeacon")
-		{
-			new_value = gSavedSettings.getBOOL( "scriptsbeacon");
-			LLPipeline::setRenderScriptedBeacons(new_value);
-		}
-		else if (beacon == "physicalbeacon")
-		{
-			new_value = gSavedSettings.getBOOL( "physicalbeacon");
-			LLPipeline::setRenderPhysicalBeacons(new_value);
-		}
-		else if (beacon == "soundsbeacon")
-		{
-			new_value = gSavedSettings.getBOOL( "soundsbeacon");
-			LLPipeline::setRenderSoundBeacons(new_value);
-		}
-		else if (beacon == "particlesbeacon")
-		{
-			new_value = gSavedSettings.getBOOL( "particlesbeacon");
-			LLPipeline::setRenderParticleBeacons(new_value);
-		}
-		else if (beacon == "scripttouchbeacon")
-		{
-			new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
-			LLPipeline::setRenderScriptedTouchBeacons(new_value);
-		}
-		else if (beacon == "renderbeacons")
-		{
-			new_value = gSavedSettings.getBOOL( "renderbeacons");
-			LLPipeline::setRenderBeacons(new_value);
-		}
-		else if (beacon == "renderhighlights")
-		{
-			new_value = gSavedSettings.getBOOL( "renderhighlights");
-			LLPipeline::setRenderHighlights(new_value);
-		}
-		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
-		return true;
-	}
-};
-
 class LLViewToggleRenderType : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -7600,8 +7438,6 @@ void initialize_menus()
 	addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
 	addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
 	addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
-	addMenu(new LLViewToggleBeacon(), "View.ToggleBeacon");
-	addMenu(new LLViewBeaconWidth(), "View.BeaconWidth");
 	addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
 	addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
 	addMenu(new LLViewZoomOut(), "View.ZoomOut");
@@ -7617,7 +7453,6 @@ void initialize_menus()
 	addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
 	addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
 	addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
-	addMenu(new LLViewCheckBeaconEnabled(), "View.CheckBeaconEnabled");
 	addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
 	addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8b81a2fe5a8..426edb37caf 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -356,7 +356,7 @@ void process_layer_data(LLMessageSystem *mesgsys, void **user_data)
 // 		size_t nread = fread(buffer, 1, length, fXML);
 // 		if (nread < (size_t) length)
 // 		{
-// 			llwarns << "Short read" << llendl;
+// 			LL_WARNS("Messaging") << "Short read" << LL_ENDL;
 // 		}
 // 		buffer[nread] = '\0';
 // 		fclose(fXML);
@@ -4726,7 +4726,7 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 	gAgent.slamLookAt(look_at);
 
 	// likewise make sure the camera is behind the avatar
-	gAgent.resetView(TRUE);
+	gAgent.resetView(TRUE, TRUE);
 
 	// send camera update to new region
 	gAgent.updateCamera();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index cc031b43680..91c6999893a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -150,6 +150,8 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
 	  res = new LLVOGround(id, pcode, regionp); break;
 	case LL_VO_PART_GROUP:
 	  res = new LLVOPartGroup(id, pcode, regionp); break;
+	case LL_VO_HUD_PART_GROUP:
+	  res = new LLVOHUDPartGroup(id, pcode, regionp); break;
 	case LL_VO_WL_SKY:
 	  res = new LLVOWLSky(id, pcode, regionp); break;
 	default:
@@ -159,7 +161,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
 	return res;
 }
 
-LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
+LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, BOOL is_global)
 :	LLPrimitive(),
 	mChildList(),
 	mID(id),
@@ -201,7 +203,10 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mMedia(NULL),
 	mClickAction(0)
 {
-	llassert(mRegionp);
+	if(!is_global)
+	{
+		llassert(mRegionp);
+	}
 
 	LLPrimitive::init_primitive(pcode);
 
@@ -209,7 +214,11 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
 
 	mPositionRegion = LLVector3(0.f, 0.f, 0.f);
-	mPositionAgent = mRegionp->getOriginAgent();
+
+	if(!is_global)
+	{
+		mPositionAgent = mRegionp->getOriginAgent();
+	}
 
 	LLViewerObject::sNumObjects++;
 }
@@ -3049,28 +3058,38 @@ LLNameValue *LLViewerObject::getNVPair(const std::string& name) const
 
 void LLViewerObject::updatePositionCaches() const
 {
-	if (!isRoot())
+	if(mRegionp)
 	{
-		mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
-		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
-	}
-	else
-	{
-		mPositionRegion = getPosition();
-		mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+		if (!isRoot())
+		{
+			mPositionRegion = ((LLViewerObject *)getParent())->getPositionRegion() + getPosition() * getParent()->getRotation();
+			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+		}
+		else
+		{
+			mPositionRegion = getPosition();
+			mPositionAgent = mRegionp->getPosAgentFromRegion(mPositionRegion);
+		}
 	}
 }
 
 const LLVector3d LLViewerObject::getPositionGlobal() const
-{
-	LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
-
-	if (isAttachment())
+{	
+	if(mRegionp)
 	{
-		position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
-	}
+		LLVector3d position_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
 
-	return position_global;
+		if (isAttachment())
+		{
+			position_global = gAgent.getPosGlobalFromAgent(getRenderPosition());
+		}		
+		return position_global;
+	}
+	else
+	{
+		LLVector3d position_global(getPosition());
+		return position_global;
+	}	
 }
 
 const LLVector3 &LLViewerObject::getPositionAgent() const
@@ -3392,6 +3411,7 @@ LLViewerObject* LLViewerObject::getRootEdit() const
 
 BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 										  S32 face,
+										  BOOL pick_transparent,
 										  S32* face_hit,
 										  LLVector3* intersection,
 										  LLVector2* tex_coord,
@@ -3401,6 +3421,20 @@ BOOL LLViewerObject::lineSegmentIntersect(const LLVector3& start, const LLVector
 	return false;
 }
 
+BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end)
+{
+	if (mDrawable.isNull() || mDrawable->isDead())
+	{
+		return FALSE;
+	}
+
+	const LLVector3* ext = mDrawable->getSpatialExtents();
+
+	LLVector3 center = (ext[1]+ext[0])*0.5f;
+	LLVector3 size = (ext[1]-ext[0])*0.5f;
+
+	return LLLineSegmentBoxIntersect(start, end, center, size);
+}
 
 U8 LLViewerObject::getMediaType() const
 {
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index b6ff60ef9df..e172ae1e8a0 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -132,7 +132,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount
 	typedef std::list<LLPointer<LLViewerObject> > child_list_t;
 	typedef const child_list_t const_child_list_t;
 
-	LLViewerObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp);
+	LLViewerObject(const LLUUID &id, const LLPCode type, LLViewerRegion *regionp, BOOL is_global = FALSE);
 	MEM_TYPE_NEW(LLMemType::MTYPE_OBJECT);
 
 	virtual void markDead();				// Mark this object as dead, and clean up its references
@@ -248,6 +248,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount
 	//returns TRUE if intersection detected and returns information about intersection
 	virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES
+									  BOOL pick_transparent = FALSE,
 									  S32* face_hit = NULL,                   // which face was hit
 									  LLVector3* intersection = NULL,         // return the intersection point
 									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
@@ -255,6 +256,8 @@ class LLViewerObject : public LLPrimitive, public LLRefCount
 									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
 		);
 	
+	virtual BOOL lineSegmentBoundingBox(const LLVector3& start, const LLVector3& end);
+
 	virtual const LLVector3d getPositionGlobal() const;
 	virtual const LLVector3 &getPositionRegion() const;
 	virtual const LLVector3 getPositionEdit() const;
@@ -507,6 +510,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount
 		LL_VO_PART_GROUP =			LL_PCODE_APP | 0x90,
 		LL_VO_TRIANGLE_TORUS =		LL_PCODE_APP | 0xa0,
 		LL_VO_WL_SKY =				LL_PCODE_APP | 0xb0, // should this be moved to 0x40?
+		LL_VO_HUD_PART_GROUP =		LL_PCODE_APP | 0xc0,
 	} EVOType;
 
 	LLUUID			mID;
@@ -705,8 +709,8 @@ class LLAlphaObject : public LLViewerObject
 class LLStaticViewerObject : public LLViewerObject
 {
 public:
-	LLStaticViewerObject(const LLUUID& id, const LLPCode type, LLViewerRegion* regionp)
-		: LLViewerObject(id,type,regionp)
+	LLStaticViewerObject(const LLUUID& id, const LLPCode type, LLViewerRegion* regionp, BOOL is_global = FALSE)
+		: LLViewerObject(id,type,regionp, is_global)
 	{ }
 
 	virtual void updateDrawable(BOOL force_damped);
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index a2210863672..ab06a0f4fbe 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -163,15 +163,20 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
 
 BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object)
 {
-	U32 local_id = object.mLocalID;
-	LLHost region_host = object.getRegion()->getHost();
-	U32 ip = region_host.getAddress();
-	U32 port = region_host.getPort();
-	U64 ipport = (((U64)ip) << 32) | (U64)port;
-	U32 index = sIPAndPortToIndex[ipport];
+	if(object.getRegion())
+	{
+		U32 local_id = object.mLocalID;
+		LLHost region_host = object.getRegion()->getHost();
+		U32 ip = region_host.getAddress();
+		U32 port = region_host.getPort();
+		U64 ipport = (((U64)ip) << 32) | (U64)port;
+		U32 index = sIPAndPortToIndex[ipport];
+
+		U64	indexid = (((U64)index) << 32) | (U64)local_id;
+		return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE;
+	}
 
-	U64	indexid = (((U64)index) << 32) | (U64)local_id;
-	return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE;
+	return FALSE ;
 }
 
 void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 272080678f9..fe588534e5e 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -344,7 +344,7 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
 	media_url = media_url_buffer;
 	msg->getU8("DataBlock", "MediaAutoScale", media_auto_scale);
 
-	if (msg->getNumberOfBlocks("DataBlockExtended")) // do we have the extended data?
+	if (msg->has("DataBlockExtended")) // do we have the extended data?
 	{
 		char media_type_buffer[257];
 		msg->getString("DataBlockExtended", "MediaType", 255, media_type_buffer);
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 2b056a25835..ec7c2b1ec22 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -72,7 +72,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_
 	mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS);
 	mTexture->createGLTexture(0, mImageRaw);
 	gGL.getTexUnit(0)->activate();
-	mTexture->bind(0);
+	gGL.getTexUnit(0)->bind(mTexture);
 	mTexture->setClamp(TRUE, TRUE);
 	mTexture->setMipFilterNearest(TRUE);
 
@@ -748,7 +748,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 	LLSurface& land = mRegion->getLand();
 
 	LLGLSUIDefault gls_ui; // called from pipeline
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest mDepthTest(GL_TRUE);
 
 	// Find camera height off the ground (not from zero)
@@ -826,7 +826,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 			continue;
 		}
 
-		gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+		gGL.begin(LLRender::TRIANGLE_STRIP);
 
 		for (j = 0; j < vertex_per_edge; j++)
 		{
@@ -848,7 +848,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 			colorp  = mColorArray  + BYTES_PER_COLOR   * i;
 			vertexp = mVertexArray + FLOATS_PER_VERTEX * i;
 
-			gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+			gGL.begin(LLRender::TRIANGLE_STRIP);
 
 			for (j = 0; j < vertex_per_edge; j++)
 			{
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 779ef0a3c6e..5ac97930d30 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -116,7 +116,8 @@ void LLViewerPart::init(LLPointer<LLViewerPartSource> sourcep, LLViewerImage *im
 //
 
 
-LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 box_side)
+LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 box_side, bool hud)
+ : mHud(hud)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
 	mVOPartGroupp = NULL;
@@ -133,7 +134,14 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
 	mCenterAgent = center_agent;
 	mBoxRadius = F_SQRT3*box_side*0.5f;
 
+	if (mHud)
+	{
+		mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_HUD_PART_GROUP, getRegion());
+	}
+	else
+	{
 	mVOPartGroupp = (LLVOPartGroup *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_PART_GROUP, getRegion());
+	}
 	mVOPartGroupp->setViewerPartGroup(this);
 	mVOPartGroupp->setPositionAgent(getCenterAgent());
 	F32 scale = box_side * 0.5f;
@@ -223,6 +231,12 @@ BOOL LLViewerPartGroup::posInGroup(const LLVector3 &pos, const F32 desired_size)
 BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
+
+	if (part->mFlags & LLPartData::LL_PART_HUD && !mHud)
+	{
+		return FALSE;
+	}
+
 	BOOL uniform_part = part->mScale.mV[0] == part->mScale.mV[1] && 
 					!(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK);
 
@@ -530,7 +544,7 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
 		if(!return_group)
 		{
 			llassert_always(part->mPosAgent.isFinite());
-			LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size);
+	LLViewerPartGroup *groupp = createViewerPartGroup(part->mPosAgent, desired_size, part->mFlags & LLPartData::LL_PART_HUD);
 			groupp->mUniformParticles = (part->mScale.mV[0] == part->mScale.mV[1] && 
 									!(part->mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK));
 			if (!groupp->addPart(part))
@@ -555,12 +569,12 @@ LLViewerPartGroup *LLViewerPartSim::put(LLViewerPart* part)
 	return return_group ;
 }
 
-LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size)
+LLViewerPartGroup *LLViewerPartSim::createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size, bool hud)
 {
 	LLMemType mt(LLMemType::MTYPE_PARTICLES);
 	//find a box that has a center position divisible by PART_SIM_BOX_SIDE that encompasses
 	//pos_agent
-	LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size);
+	LLViewerPartGroup *groupp = new LLViewerPartGroup(pos_agent, desired_size, hud);
 	mViewerPartGroups.push_back(groupp);
 	return groupp;
 }
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index de763d3e53f..ceed4e28b00 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -87,7 +87,8 @@ class LLViewerPartGroup
 {
 public:
 	LLViewerPartGroup(const LLVector3 &center,
-					  const F32 box_radius);
+					  const F32 box_radius,
+					  bool hud);
 	virtual ~LLViewerPartGroup();
 
 	void cleanup();
@@ -115,6 +116,7 @@ class LLViewerPartGroup
 	U32 mID;
 
 	F32 mSkippedTime;
+	bool mHud;
 
 protected:
 	LLVector3 mCenterAgent;
@@ -178,7 +180,7 @@ class LLViewerPartSim : public LLSingleton<LLViewerPartSim>
 	U32 mID;
 
 protected:
-	LLViewerPartGroup *createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size);
+	LLViewerPartGroup *createViewerPartGroup(const LLVector3 &pos_agent, const F32 desired_size, bool hud);
 	LLViewerPartGroup *put(LLViewerPart* part);
 
 	group_list_t mViewerPartGroups;
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 9bdebbbd384..635374211c0 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -33,6 +33,7 @@
 #include "llviewerpartsource.h"
 
 #include "llviewercontrol.h"
+#include "llrender.h"
 
 #include "llagent.h"
 #include "lldrawable.h"
@@ -69,7 +70,7 @@ void LLViewerPartSource::updatePart(LLViewerPart &part, const F32 dt)
 {
 }
 
-void LLViewerPartSource::update(const F32 dt)
+void LLViewerPartSource::update(const F32 dt) 
 {
 	llerrs << "Creating default part source!" << llendl;
 }
@@ -99,7 +100,7 @@ LLViewerPartSourceScript::LLViewerPartSourceScript(LLViewerObject *source_objp)
 	mSourceObjectp = source_objp;
 	mPosAgent = mSourceObjectp->getPositionAgent();
 	mImagep = gImageList.getImageFromFile("pixiesmall.j2c");
-	mImagep->bind();
+	gGL.getTexUnit(0)->bind(mImagep.get());
 	mImagep->setClamp(TRUE, TRUE);
 }
 
@@ -282,6 +283,10 @@ void LLViewerPartSourceScript::update(const F32 dt)
 
 			part->init(this, mImagep, NULL);
 			part->mFlags = mPartSysData.mPartData.mFlags;
+			if (!mSourceObjectp.isNull() && mSourceObjectp->isHUDAttachment())
+			{
+				part->mFlags |= LLPartData::LL_PART_HUD;
+			}
 			part->mMaxAge = mPartSysData.mPartData.mMaxAge;
 			part->mStartColor = mPartSysData.mPartData.mStartColor;
 			part->mEndColor = mPartSysData.mPartData.mEndColor;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index fe6ce6faa0e..8eee8c0f1b9 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -215,6 +215,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS
 	mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME
 	mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE
+	mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
 	mObjectPartition.push_back(NULL);						//PARTITION_NONE
 	
 }
@@ -1028,12 +1029,18 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
 	msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
 	msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
 
+	BOOL has_agent_data = msg->has(_PREHASH_AgentData);
 	S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
 	for(S32 i = 0; i < count; i++)
 	{
 		msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
 		msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
 		msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
+		LLUUID agent_id = LLUUID::null;
+		if(has_agent_data)
+		{
+			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
+		}
 
 		//llinfos << "  object X: " << (S32)x_pos << " Y: " << (S32)y_pos
 		//		<< " Z: " << (S32)(z_pos * 4)
@@ -1059,6 +1066,10 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
 			pos <<= 8;
 			pos |= z_pos;
 			mMapAvatars.put(pos);
+			if(has_agent_data)
+			{
+				mMapAvatarIDs.put(agent_id);
+			}
 		}
 	}
 }
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index ffccc296f16..cffb878b904 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -81,6 +81,7 @@ class LLViewerRegion
 		PARTITION_GRASS,
 		PARTITION_VOLUME,
 		PARTITION_BRIDGE,
+		PARTITION_HUD_PARTICLE,
 		PARTITION_NONE,
 		NUM_PARTITIONS
 	} eObjectPartitions;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index f69f4fbb62c..39e0f63f5f5 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -108,7 +108,7 @@ GLint				gAvatarMatrixParam;
 LLViewerShaderMgr::LLViewerShaderMgr() :
 	mVertexShaderLevel(SHADER_COUNT, 0)
 {	
-/// Make sure WL Sky is the first program
+	/// Make sure WL Sky is the first program
 	mShaderList.push_back(&gWLSkyProgram);
 	mShaderList.push_back(&gWLCloudProgram);
 	mShaderList.push_back(&gAvatarProgram);
@@ -139,28 +139,28 @@ LLViewerShaderMgr * LLViewerShaderMgr::instance()
 	if(NULL == sInstance)
 	{
 		sInstance = new LLViewerShaderMgr();
-	}	
-	
-	return static_cast<LLViewerShaderMgr*>(sInstance);
 	}
 
+	return static_cast<LLViewerShaderMgr*>(sInstance);
+}
+
 void LLViewerShaderMgr::initAttribsAndUniforms(void)
-	{
+{
 	if (mReservedAttribs.empty())
-		{
+	{
 		mReservedAttribs.push_back("materialColor");
 		mReservedAttribs.push_back("specularColor");
 		mReservedAttribs.push_back("binormal");
-		
+
 		mAvatarAttribs.reserve(5);
 		mAvatarAttribs.push_back("weight");
 		mAvatarAttribs.push_back("clothing");
 		mAvatarAttribs.push_back("gWindDir");
 		mAvatarAttribs.push_back("gSinWaveParams");
 		mAvatarAttribs.push_back("gGravity");
-			
+
 		mAvatarUniforms.push_back("matrixPalette");
-			
+
 		mReservedUniforms.reserve(24);
 		mReservedUniforms.push_back("diffuseMap");
 		mReservedUniforms.push_back("specularMap");
@@ -186,16 +186,16 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
 		mReservedUniforms.push_back("cloud_scale");
 		mReservedUniforms.push_back("gamma");
 		mReservedUniforms.push_back("scene_light_strength");
-			
+
 		mWLUniforms.push_back("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");
-	
+
 		mGlowUniforms.push_back("glowDelta");
 		mGlowUniforms.push_back("glowStrength");
 
@@ -204,7 +204,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
 		mGlowExtractUniforms.push_back("lumWeights");
 		mGlowExtractUniforms.push_back("warmthWeights");
 		mGlowExtractUniforms.push_back("warmthAmount");
-	
+
 		mShinyUniforms.push_back("origin");
 
 		mWaterUniforms.reserve(12);
@@ -222,9 +222,9 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)
 		mWaterUniforms.push_back("kd");
 		mWaterUniforms.push_back("refScale");
 		mWaterUniforms.push_back("waterHeight");
-		}
-	}
-
+	}	
+}
+	
 
 //============================================================================
 // Set Levels
@@ -1087,12 +1087,12 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
 }
 
 std::string LLViewerShaderMgr::getShaderDirPrefix(void)
-	{
+{
 	return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
-	}
+}
 
 void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
-			{
+{
 	LLWLParamManager::instance()->updateShaderUniforms(shader);
 	LLWaterParamManager::instance()->updateShaderUniforms(shader);
 }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 0bb2cb81948..2aff4281ad5 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -168,6 +168,7 @@
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
+#include "llviewershadermgr.h"
 #include "llviewerstats.h"
 #include "llvoavatar.h"
 #include "llvovolume.h"
@@ -218,6 +219,7 @@ LLVector3       gDebugRaycastIntersection;
 LLVector2       gDebugRaycastTexCoord;
 LLVector3       gDebugRaycastNormal;
 LLVector3       gDebugRaycastBinormal;
+S32				gDebugRaycastFaceHit;
 
 // HUD display lines in lower right
 BOOL				gDisplayWindInfo = FALSE;
@@ -1102,6 +1104,7 @@ void LLViewerWindow::handleQuit(LLWindow *window)
 void LLViewerWindow::handleResize(LLWindow *window,  S32 width,  S32 height)
 {
 	reshape(width, height);
+	mResDirty = true;
 }
 
 // The top-level window has gained focus (e.g. via ALT-TAB)
@@ -1258,7 +1261,8 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
 
 BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
 {
-	if (!activating) gAgent.changeCameraToDefault();
+	//if (!activating) gAgent.changeCameraToDefault();
+
 	LLViewerJoystick::getInstance()->setNeedsReset(true);
 	return FALSE;
 }
@@ -1411,7 +1415,11 @@ LLViewerWindow::LLViewerWindow(
 	mHideCursorPermanent( FALSE ),
 	mCursorHidden(FALSE),
 	mIgnoreActivate( FALSE ),
-	mHoverPick()
+	mHoverPick(),
+	mResDirty(false),
+	mStatesDirty(false),
+	mIsFullscreenChecked(false),
+	mCurrResolutionIndex(0)
 {
 	// Default to application directory.
 	LLViewerWindow::sSnapshotBaseName = "Snapshot";
@@ -1546,7 +1554,7 @@ void LLViewerWindow::initGLDefaults()
 	glPixelStorei(GL_PACK_ALIGNMENT,1);
 	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
 
-	glEnable(GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 	// lights for objects
 	glShadeModel( GL_SMOOTH );
@@ -3043,8 +3051,9 @@ BOOL LLViewerWindow::handlePerFrameHover()
 
 	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
 	{
-		gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1,
-											  NULL,
+		gDebugRaycastFaceHit = -1;
+		gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
+											  &gDebugRaycastFaceHit,
 											  &gDebugRaycastIntersection,
 											  &gDebugRaycastTexCoord,
 											  &gDebugRaycastNormal,
@@ -3185,7 +3194,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 		// Render light for editing
 		if (LLSelectMgr::sRenderLightRadius && LLToolMgr::getInstance()->inEdit())
 		{
-			LLImageGL::unbindTexture(0);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLGLEnable gls_blend(GL_BLEND);
 			LLGLEnable gls_cull(GL_CULL_FACE);
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
@@ -3399,7 +3408,7 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
 	llassert_always(pick_info.mScreenRegion.notNull());
 	mPicks.push_back(pick_info);
 	
-	S32 scaled_x = llround((F32)pick_info.mMousePt.mX * mDisplayScale.mV[VX]);
+	/*S32 scaled_x = llround((F32)pick_info.mMousePt.mX * mDisplayScale.mV[VX]);
 	S32 scaled_y = llround((F32)pick_info.mMousePt.mY * mDisplayScale.mV[VY]);
 
 	// Default to not hitting anything
@@ -3468,7 +3477,7 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
 
 	setup3DRender();
 	setup2DRender();
-	setupViewport();
+	setupViewport();*/
 
 	// delay further event processing until we receive results of pick
 	mWindow->delayInputProcessing();
@@ -3530,6 +3539,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans
 LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 depth,
 												LLViewerObject *this_object,
 												S32 this_face,
+												BOOL pick_transparent,
 												S32* face_hit,
 												LLVector3 *intersection,
 												LLVector2 *uv,
@@ -3563,7 +3573,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
 	{
 		if (this_object->isHUDAttachment()) // is a HUD object?
 		{
-			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face,
+			if (this_object->lineSegmentIntersect(mouse_hud_start, mouse_hud_end, this_face, pick_transparent,
 												  face_hit, intersection, uv, normal, binormal))
 			{
 				found = this_object;
@@ -3572,7 +3582,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
 		
 		else // is a world object
 		{
-			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face,
+			if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent,
 												  face_hit, intersection, uv, normal, binormal))
 			{
 				found = this_object;
@@ -3582,13 +3592,13 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
 
 	else // check ALL objects
 			{
-		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end,
+		found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent,
 													face_hit, intersection, uv, normal, binormal);
 
 		if (!found) // if not found in HUD, look in world:
 
 			{
-			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end,
+			found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent,
 														  face_hit, intersection, uv, normal, binormal);
 			}
 
@@ -3812,13 +3822,8 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
 		return FALSE;
 	}
 
-	std::string extension("." + image->getExtension());
-	if (extension.empty())
-	{
-		extension = (gSavedSettings.getBOOL("CompressSnapshotsToDisk")) ? ".j2c" : ".bmp";
-	}
-
 	LLFilePicker::ESaveFilter pick_type;
+	std::string extension("." + image->getExtension());
 	if (extension == ".j2c")
 		pick_type = LLFilePicker::FFSAVE_J2C;
 	else if (extension == ".bmp")
@@ -3836,7 +3841,8 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
 	if ( ! isSnapshotLocSet())		
 	{
 		std::string proposed_name( sSnapshotBaseName );
-		proposed_name.append( extension );
+
+		// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
 
 		// pick a directory in which to save
 		LLFilePicker& picker = LLFilePicker::instance();
@@ -4153,7 +4159,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 					
 					snapshot_width = image_width;
 					snapshot_height = image_height;
-					target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB, TRUE);
+					target.allocate(snapshot_width, snapshot_height, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE, TRUE);
 					window_width = snapshot_width;
 					window_height = snapshot_height;
 					scale_factor = 1.f;
@@ -4381,7 +4387,7 @@ void LLViewerWindow::drawMouselookInstructions()
 		llround(font->getLineHeight() + 2 * INSTRUCTIONS_PAD));
 
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4f( 0.9f, 0.9f, 0.9f, 1.0f );
 		gl_rect_2d( instructions_rect );
 	}
@@ -4648,9 +4654,97 @@ void LLViewerWindow::getTargetWindow(BOOL& fullscreen, S32& width, S32& height)
 	}
 }
 
+bool LLViewerWindow::updateResolution()
+{
+	if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
+	{
+		getWindow()->setNativeAspectRatio(0.f);
+	}
+	else
+	{
+		getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio"));
+	}
+	
+	reshape(getWindowDisplayWidth(), getWindowDisplayHeight());
+	
+	// Screen resolution
+	S32 num_resolutions;
+	LLWindow::LLWindowResolution* supported_resolutions = getWindow()->getSupportedResolutions(num_resolutions);
+	
+	// check if resolution has changed
+	BOOL targetFullscreen;
+	S32 targetWidth;
+	S32 targetHeight;
+	
+	getTargetWindow(targetFullscreen, targetWidth, targetHeight);
+	
+	if ((mIsFullscreenChecked != (bool) targetFullscreen) ||
+		(mIsFullscreenChecked &&
+		 (supported_resolutions[mCurrResolutionIndex].mWidth != targetWidth ||
+		  supported_resolutions[mCurrResolutionIndex].mHeight != targetHeight)
+		 ))
+	{
+		// change fullscreen resolution or switch in/out of windowed mode
+		BOOL result;
+		
+		BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED);
+		if (mIsFullscreenChecked)
+		{
+			result = changeDisplaySettings(TRUE, 
+											LLCoordScreen(	supported_resolutions[mCurrResolutionIndex].mWidth, 
+															supported_resolutions[mCurrResolutionIndex].mHeight), 
+											gSavedSettings.getBOOL("DisableVerticalSync"),
+											logged_in);
+		}
+		else
+		{
+			result = changeDisplaySettings(FALSE, 
+											LLCoordScreen(gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight")), 
+											TRUE,
+											logged_in);
+		}
+		if (!result)
+		{
+			
+			// GL is non-existent at this point, so we can't continue.
+			llerrs << "LLPanelDisplay::apply() failed" << llendl;
+		}
+	}
+	
+	// force aspect ratio
+	if (mIsFullscreenChecked)
+	{
+		LLViewerCamera::getInstance()->setAspect( getDisplayAspectRatio() );
+	}
+	return true;
+}
+
+void LLViewerWindow::requestResolutionUpdate(bool fullscreen_checked, U32 resolution_index)
+{
+	mResDirty = true;
+	mIsFullscreenChecked = fullscreen_checked;
+	mCurrResolutionIndex = resolution_index;
+}
+
 
 BOOL LLViewerWindow::checkSettings()
 {
+	if (mStatesDirty)
+	{
+		gGL.refreshState();
+		LLViewerShaderMgr::instance()->setShaders();
+		mStatesDirty = false;
+	}
+	
+	// We want to update the resolution AFTER the states getting refreshed not before.
+	if (mResDirty)
+	{
+		updateResolution();
+		mResDirty = false;
+		// This will force a state update the next frame.
+		mStatesDirty = true;
+	}
+		
 	BOOL is_fullscreen = mWindow->getFullscreen();
 	if (is_fullscreen && !mWantFullscreen)
 	{
@@ -4659,6 +4753,7 @@ BOOL LLViewerWindow::checkSettings()
 											gSavedSettings.getS32("WindowHeight")),
 							  TRUE,
 							  mShowFullscreenProgress);
+		mStatesDirty = true;
 		return TRUE;
 	}
 	else if (!is_fullscreen && mWantFullscreen)
@@ -4678,6 +4773,7 @@ BOOL LLViewerWindow::checkSettings()
 
 		LLGLState::checkStates();
 		LLGLState::checkTextureChannels();
+		mStatesDirty = true;
 		return TRUE;
 	}
 	return FALSE;
@@ -5104,25 +5200,34 @@ LLPickInfo::~LLPickInfo()
 
 void LLPickInfo::fetchResults()
 {
+
+	S32 face_hit = -1;
+	LLVector3 intersection, normal, binormal;
+	LLVector2 uv;
+
+	LLViewerObject* hit_object = gViewerWindow->cursorIntersect(-1, -1, 512.f,
+									NULL, -1, mPickTransparent, &face_hit,
+									&intersection, &uv, &normal, &binormal);
+	
 	// read back colors and depth values from buffer
-	glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
-	glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_DEPTH_COMPONENT, GL_FLOAT, mPickDepthBuffer );
+	//glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, mPickBuffer);
+	//glReadPixels(mScreenRegion.mLeft, mScreenRegion.mBottom, mScreenRegion.getWidth(), mScreenRegion.getHeight(), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, mPickDepthBuffer );
 
 	// find pick region that is fully onscreen
 	LLCoordGL scaled_pick_point;;
 	scaled_pick_point.mX = llclamp(llround((F32)mMousePt.mX * gViewerWindow->getDisplayScale().mV[VX]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayWidth() - PICK_HALF_WIDTH);
 	scaled_pick_point.mY = llclamp(llround((F32)mMousePt.mY * gViewerWindow->getDisplayScale().mV[VY]), PICK_HALF_WIDTH, gViewerWindow->getWindowDisplayHeight() - PICK_HALF_WIDTH);
-	S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH;
-	S32 pick_id = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
-	F32 depth = mPickDepthBuffer[pixel_index];
+	//S32 pixel_index = PICK_HALF_WIDTH * PICK_DIAMETER + PICK_HALF_WIDTH;
+	//S32 pick_id = (U32)mPickBuffer[(pixel_index * 4) + 0] << 16 | (U32)mPickBuffer[(pixel_index * 4) + 1] << 8 | (U32)mPickBuffer[(pixel_index * 4) + 2];
+	//F32 depth = mPickDepthBuffer[pixel_index];
 
-	S32 x_offset = mMousePt.mX - llround((F32)scaled_pick_point.mX / gViewerWindow->getDisplayScale().mV[VX]);
-	S32 y_offset = mMousePt.mY - llround((F32)scaled_pick_point.mY / gViewerWindow->getDisplayScale().mV[VY]);
+	//S32 x_offset = mMousePt.mX - llround((F32)scaled_pick_point.mX / gViewerWindow->getDisplayScale().mV[VX]);
+	//S32 y_offset = mMousePt.mY - llround((F32)scaled_pick_point.mY / gViewerWindow->getDisplayScale().mV[VY]);
 
 	mPickPt = mMousePt;
 
 	// we hit nothing, scan surrounding pixels for something useful
-	if (!pick_id)
+	/*if (!pick_id)
 	{
 		S32 closest_distance = 10000;
 		//S32 closest_pick_name = 0;
@@ -5143,25 +5248,21 @@ void LLPickInfo::fetchResults()
 				}
 			}
 		}
-	}
+	}*/
 
-	U32 te_offset = ((U32)pick_id >> 20);
-	pick_id &= 0x000fffff;
 
-	//unproject relative clicked coordinate from window coordinate using GL
-	GLint viewport[4];
-	GLdouble modelview[16];
-	GLdouble projection[16];
-	GLfloat winX, winY;
-	GLdouble posX, posY, posZ;
+	U32 te_offset = face_hit > -1 ? face_hit : 0;
+	//pick_id &= 0x000fffff;
 
-	LLViewerObject* objectp = gObjectList.getSelectedObject(pick_id);
+	//unproject relative clicked coordinate from window coordinate using GL
+	
+	LLViewerObject* objectp = hit_object;
 
-	if (pick_id == (S32)GL_NAME_PARCEL_WALL)
-	{
-		mPickType = PICK_PARCEL_WALL;
-	}
-	else if (objectp)
+	//if (pick_id == (S32)GL_NAME_PARCEL_WALL)
+	//{
+	//	mPickType = PICK_PARCEL_WALL;
+	//}
+	if (objectp)
 	{
 		if( objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH )
 		{
@@ -5187,11 +5288,11 @@ void LLPickInfo::fetchResults()
 			{
 				mPickType = PICK_OBJECT;
 			}
-			mObjectOffset = gAgent.calcFocusOffset(objectp, mPickPt.mX, mPickPt.mY);
+			mObjectOffset = gAgent.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
 			mObjectID = objectp->mID;
 			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
 
-			glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix);
+			/*glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix);
 
 			for(U32 i = 0; i < 16; ++i)
 			{
@@ -5203,9 +5304,9 @@ void LLPickInfo::fetchResults()
 			winX = ((F32)mPickPt.mX) * gViewerWindow->getDisplayScale().mV[VX];
 			winY = ((F32)mPickPt.mY) * gViewerWindow->getDisplayScale().mV[VY];
 
-			gluUnProject( winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ);
+			gluUnProject( winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ);*/
 
-			mPosGlobal = gAgent.getPosGlobalFromAgent(LLVector3(posX, posY, posZ));
+			mPosGlobal = gAgent.getPosGlobalFromAgent(intersection);
 			
 			if (mWantSurfaceInfo)
 			{
@@ -5213,16 +5314,16 @@ void LLPickInfo::fetchResults()
 			}
 		}
 	}
-	else
-	{
+	//else
+	//{
 		// was this name referring to a hud icon?
-		mHUDIcon = LLHUDIcon::handlePick(pick_id);
-		if (mHUDIcon)
-		{
-			mPickType = PICK_ICON;
-			mPosGlobal = mHUDIcon->getPositionGlobal();
-		}
-	}
+	//	mHUDIcon = LLHUDIcon::handlePick(pick_id);
+	//	if (mHUDIcon)
+	//	{
+	//		mPickType = PICK_ICON;
+	//		mPosGlobal = mHUDIcon->getPositionGlobal();
+	//	}
+	//}
 
 	if (mPickCallback)
 	{
@@ -5237,16 +5338,19 @@ LLPointer<LLViewerObject> LLPickInfo::getObject() const
 
 void LLPickInfo::updateXYCoords()
 {
-	const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
-	LLPointer<LLViewerImage> imagep = gImageList.getImage(tep->getID());
-	if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
+	if (mObjectFace > -1)
 	{
-		LLCoordGL coords;
-		
-		coords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth());
-		coords.mY = llround(mUVCoords.mV[VY] * (F32)imagep->getHeight());
+		const LLTextureEntry* tep = getObject()->getTE(mObjectFace);
+		LLPointer<LLViewerImage> imagep = gImageList.getImage(tep->getID());
+		if(mUVCoords.mV[VX] >= 0.f && mUVCoords.mV[VY] >= 0.f && imagep.notNull())
+		{
+			LLCoordGL coords;
+			
+			coords.mX = llround(mUVCoords.mV[VX] * (F32)imagep->getWidth());
+			coords.mY = llround(mUVCoords.mV[VY] * (F32)imagep->getHeight());
 
-		gViewerWindow->getWindow()->convertCoords(coords, &mXYCoords);
+			gViewerWindow->getWindow()->convertCoords(coords, &mXYCoords);
+		}
 	}
 }
 
@@ -5257,7 +5361,7 @@ void LLPickInfo::drawPickBuffer() const
 		gGL.pushMatrix();
 		LLGLDisable no_blend(GL_BLEND);
 		LLGLDisable no_alpha_test(GL_ALPHA_TEST);
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		glPixelZoom(10.f, 10.f);
 		LLVector2 display_scale = gViewerWindow->getDisplayScale();
 		glRasterPos2f(((F32)mMousePt.mX * display_scale.mV[VX] + 10.f), 
@@ -5309,7 +5413,7 @@ void LLPickInfo::getSurfaceInfo()
 	if (objectp)
 	{
 		if (gViewerWindow->cursorIntersect(llround((F32)mMousePt.mX), llround((F32)mMousePt.mY), 1024.f,
-										   objectp, -1,
+										   objectp, -1, mPickTransparent,
 										   &mObjectFace,
 										   &mIntersection,
 										   &mSTCoords,
@@ -5318,7 +5422,7 @@ void LLPickInfo::getSurfaceInfo()
 		{
 			// if we succeeded with the intersect above, compute the texture coordinates:
 
-			if (objectp->mDrawable.notNull())
+			if (objectp->mDrawable.notNull() && mObjectFace > -1)
 			{
 				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
 
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 11c4126beba..6309cec8193 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -313,6 +313,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	LLViewerObject* cursorIntersect(S32 mouse_x = -1, S32 mouse_y = -1, F32 depth = 512.f,
 									LLViewerObject *this_object = NULL,
 									S32 this_face = -1,
+									BOOL pick_transparent = FALSE,
 									S32* face_hit = NULL,
 									LLVector3 *intersection = NULL,
 									LLVector2 *uv = NULL,
@@ -340,6 +341,8 @@ class LLViewerWindow : public LLWindowCallbacks
 	void			toggleFullscreen(BOOL show_progress);
 
 	// handle shutting down GL and bringing it back up
+	bool			updateResolution(void);
+	void			requestResolutionUpdate(bool fullscreen_checked, U32 resolution_index);
 	BOOL			checkSettings();
 	void			restartDisplay(BOOL show_progress_bar);
 	BOOL			changeDisplaySettings(BOOL fullscreen, LLCoordScreen size, BOOL disable_vsync, BOOL show_progress_bar);
@@ -421,6 +424,11 @@ class LLViewerWindow : public LLWindowCallbacks
 	std::string		mInitAlert;			// Window / GL initialization requires an alert
 	
 	class LLDebugText* mDebugText; // Internal class for debug text
+	
+	bool			mResDirty;
+	bool			mStatesDirty;
+	bool			mIsFullscreenChecked; // Did the user check the fullscreen checkbox in the display settings
+	U32			mCurrResolutionIndex;
 
 protected:
 	static std::string sSnapshotBaseName;
@@ -473,6 +481,7 @@ extern LLVector3        gDebugRaycastIntersection;
 extern LLVector2        gDebugRaycastTexCoord;
 extern LLVector3        gDebugRaycastNormal;
 extern LLVector3        gDebugRaycastBinormal;
+extern S32				gDebugRaycastFaceHit;
 
 extern S32 CHAT_BAR_HEIGHT; 
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 391bb915fa8..aec26fa6a17 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -244,6 +244,11 @@ static F32 calc_bouncy_animation(F32 x)
 	return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
 }
 
+BOOL LLLineSegmentCapsuleIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& p1, const LLVector3& p2, const F32& radius, LLVector3& result)
+{
+	return FALSE;
+}
+
 //-----------------------------------------------------------------------------
 // Static Data
 //-----------------------------------------------------------------------------
@@ -753,7 +758,7 @@ LLVOAvatar::LLVOAvatar(
 	mRippleTimeLast = 0.f;
 
 	mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c");
-	mShadowImagep->bind();
+	gGL.getTexUnit(0)->bind(mShadowImagep.get());
 	mShadowImagep->setClamp(TRUE, TRUE);
 	
 	mInAir = FALSE;
@@ -1569,6 +1574,96 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax)
 	newMax += buffer;
 }
 
+//-----------------------------------------------------------------------------
+// renderCollisionVolumes()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::renderCollisionVolumes()
+{
+	for (S32 i = 0; i < mNumCollisionVolumes; i++)
+	{
+		mCollisionVolumes[i].renderCollision();
+	}
+
+	if (mNameText.notNull())
+	{
+		LLVector3 unused;
+		mNameText->lineSegmentIntersect(LLVector3(0,0,0), LLVector3(0,0,1), unused, TRUE);
+	}
+}
+
+BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+									  S32 face,
+									  BOOL pick_transparent,
+									  S32* face_hit,
+									  LLVector3* intersection,
+									  LLVector2* tex_coord,
+									  LLVector3* normal,
+									  LLVector3* bi_normal
+		)
+{
+
+	if (mIsSelf && !gAgent.needsRenderAvatar())
+	{
+		return FALSE;
+	}
+
+	if (lineSegmentBoundingBox(start, end))
+	{
+		for (S32 i = 0; i < mNumCollisionVolumes; ++i)
+		{
+			mCollisionVolumes[i].updateWorldMatrix();
+
+			glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix);
+			glh::matrix4f inverse = mat.inverse();
+			glh::matrix4f norm_mat = inverse.transpose();
+
+			glh::vec3f p1(start.mV);
+			glh::vec3f p2(end.mV);
+
+			inverse.mult_matrix_vec(p1);
+			inverse.mult_matrix_vec(p2);
+
+			LLVector3 position;
+			LLVector3 norm;
+
+			if (linesegment_sphere(LLVector3(p1.v), LLVector3(p2.v), LLVector3(0,0,0), 1.f, position, norm))
+			{
+				glh::vec3f res_pos(position.mV);
+				mat.mult_matrix_vec(res_pos);
+				
+				norm.normalize();
+				glh::vec3f res_norm(norm.mV);
+				norm_mat.mult_matrix_dir(res_norm);
+
+				if (intersection)
+				{
+					*intersection = LLVector3(res_pos.v);
+				}
+
+				if (normal)
+				{
+					*normal = LLVector3(res_norm.v);
+				}
+
+				return TRUE;
+			}
+		}
+	}
+	
+	LLVector3 position;
+	if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position))
+	{
+		if (intersection)
+		{
+			*intersection = position;
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 
 //-----------------------------------------------------------------------------
 // parseSkeletonFile()
@@ -4138,7 +4233,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 		LLVector3 collide_point = slaved_pos;
 		collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
 
-		gGL.begin(LLVertexBuffer::LINES);
+		gGL.begin(LLRender::LINES);
 		{
 			F32 SQUARE_SIZE = 0.2f;
 			gGL.color4f(1.f, 0.f, 0.f, 1.f);
@@ -4285,7 +4380,7 @@ U32 LLVOAvatar::renderFootShadows()
 	LLGLDepthTest test(GL_TRUE, GL_FALSE);
 	//render foot shadows
 	LLGLEnable blend(GL_BLEND);
-	mShadowImagep->bind();
+	gGL.getTexUnit(0)->bind(mShadowImagep.get());
 	glColor4fv(mShadow0Facep->getRenderColor().mV);
 	mShadow0Facep->renderIndexed(foot_mask);
 	glColor4fv(mShadow1Facep->getRenderColor().mV);
@@ -4331,8 +4426,8 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color)
 	color.mV[3] = (U8) (alpha*255);
 	
 	gGL.color4ubv(color.mV);
-	mImpostor.bindTexture();
-	gGL.begin(LLVertexBuffer::QUADS);
+	gGL.getTexUnit(0)->bind(&mImpostor);
+	gGL.begin(LLRender::QUADS);
 	gGL.texCoord2f(0,0);
 	gGL.vertex3fv((pos+left-up).mV);
 	gGL.texCoord2f(1,0);
@@ -4347,17 +4442,6 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color)
 	return 6;
 }
 
-//-----------------------------------------------------------------------------
-// renderCollisionVolumes()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::renderCollisionVolumes()
-{
-	for (S32 i = 0; i < mNumCollisionVolumes; i++)
-	{
-		mCollisionVolumes[i].renderCollision();
-	}
-}
-
 //------------------------------------------------------------------------
 // LLVOAvatar::updateTextures()
 //------------------------------------------------------------------------
@@ -4392,23 +4476,23 @@ void LLVOAvatar::updateTextures(LLAgent &agent)
 	{
 		if( head_baked && ! mHeadBakedLoaded )
 		{
-			getTEImage( TEX_HEAD_BAKED )->bind();
+			gGL.getTexUnit(0)->bind(getTEImage( TEX_HEAD_BAKED ));
 		}
 		if( upper_baked && ! mUpperBakedLoaded )
 		{
-			getTEImage( TEX_UPPER_BAKED )->bind();
+			gGL.getTexUnit(0)->bind(getTEImage( TEX_UPPER_BAKED ));
 		}
 		if( lower_baked && ! mLowerBakedLoaded )
 		{
-			getTEImage( TEX_LOWER_BAKED )->bind();
+			gGL.getTexUnit(0)->bind(getTEImage( TEX_LOWER_BAKED ));
 		}
 		if( eyes_baked && ! mEyesBakedLoaded )
 		{
-			getTEImage( TEX_EYES_BAKED )->bind();
+			gGL.getTexUnit(0)->bind(getTEImage( TEX_EYES_BAKED ));
 		}
 		if( skirt_baked && ! mSkirtBakedLoaded )
 		{
-			getTEImage( TEX_SKIRT_BAKED )->bind();
+			gGL.getTexUnit(0)->bind(getTEImage( TEX_SKIRT_BAKED ));
 		}
 	}
 
@@ -5714,7 +5798,9 @@ BOOL LLVOAvatar::loadMeshNodes()
 
 		//	llinfos << "Parsing mesh data for " << type << "..." << llendl;
 
-		mesh->setColor( 0.8f, 0.8f, 0.8f, 1.0f );
+		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
+		// Do not touch!!!
+		mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f );
 
 		LLPolyMesh *poly_mesh = NULL;
 
@@ -6952,7 +7038,7 @@ BOOL LLVOAvatar::bindScratchTexture( LLGLenum format )
 	GLuint gl_name = getScratchTexName( format, &texture_bytes );
 	if( gl_name )
 	{
-		LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D );
+		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
 		stop_glerror();
 
 		F32* last_bind_time = LLVOAvatar::sScratchTexLastBindTime.getIfThere( format );
@@ -7010,7 +7096,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
 		glGenTextures(1, &name );
 		stop_glerror();
 
-		LLImageGL::bindExternalTexture( name, 0, GL_TEXTURE_2D ); 
+		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, name);
 		stop_glerror();
 
 		glTexImage2D(
@@ -7025,7 +7111,7 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
 		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
 		stop_glerror();
 
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D); 
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		stop_glerror();
 
 		LLVOAvatar::sScratchTexNames.addData( format, new LLGLuint( name ) );
@@ -8634,7 +8720,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,
 			glGenTextures(1, (GLuint*) &gl_name );
 			stop_glerror();
 
-			LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D ); 
+			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
 			stop_glerror();
 
 			glTexImage2D(
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index de117a5bb91..74fdb72c840 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -308,6 +308,16 @@ class LLVOAvatar :
 	U32 renderTransparent();
 	void renderCollisionVolumes();
 	
+	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+									  S32 face = -1,                          // which face to check, -1 = ALL_SIDES
+									  BOOL pick_transparent = FALSE,
+									  S32* face_hit = NULL,                   // which face was hit
+									  LLVector3* intersection = NULL,         // return the intersection point
+									  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
+									  LLVector3* normal = NULL,               // return the surface normal at the intersection point
+									  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
+		);
+
 	/*virtual*/ void updateTextures(LLAgent &agent);
 	// If setting a baked texture, need to request it from a non-local sim.
 	/*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid);
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index c7326688a01..d416ae5bf68 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -578,3 +578,146 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
 	}
 	clearChanged(SHIFTED);
 }
+
+// virtual 
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+	
+{
+	BOOL ret = FALSE;
+	if (!mbCanSelect ||
+		mDrawable->isDead() || 
+		!gPipeline.hasRenderType(mDrawable->getRenderType()))
+	{
+		return FALSE;
+	}
+
+	LLVector3 dir = end-start;
+
+	mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
+	
+	LLVector3 position;
+	// Create random blades of grass with gaussian distribution
+	F32 x,y,xf,yf,dzx,dzy;
+
+	LLColor4U color(255,255,255,255);
+
+	F32 width  = sSpeciesTable[mSpecies]->mBladeSizeX;
+	F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
+
+	LLVector2 tc[4];
+	LLVector3 v[4];
+	// LLVector3 n[4]; // unused!
+
+	F32 closest_t = 1.f;
+
+	for (S32 i = 0;  i < mNumBlades; i++)
+	{
+		x   = exp_x[i] * mScale.mV[VX];
+		y   = exp_y[i] * mScale.mV[VY];
+		xf  = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i];
+		yf  = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i];
+		dzx = dz_x [i];
+		dzy = dz_y [i];
+
+		LLVector3 v1,v2,v3;
+		F32 blade_height= GRASS_BLADE_HEIGHT * height * w_mod[i];
+
+		tc[0]   = LLVector2(0, 0);
+		tc[1]   = LLVector2(0, 0.98f);
+		tc[2]   = LLVector2(1, 0);
+		tc[3]   = LLVector2(1, 0.98f);
+	
+		position.mV[0]  = mPosition.mV[VX] + x + xf;
+		position.mV[1]  = mPosition.mV[VY] + y + yf;
+		position.mV[2]  = mRegionp->getLand().resolveHeightRegion(position);
+		v[0]    = v1 = position + mRegionp->getOriginAgent();
+		
+
+
+		position.mV[0] += dzx;
+		position.mV[1] += dzy;
+		position.mV[2] += blade_height;
+		v[1]    = v2 = position + mRegionp->getOriginAgent();
+		
+		position.mV[0]  = mPosition.mV[VX] + x - xf;
+		position.mV[1]  = mPosition.mV[VY] + y - xf;
+		position.mV[2]  = mRegionp->getLand().resolveHeightRegion(position);
+		v[2]    = v3 = position + mRegionp->getOriginAgent();
+		
+		LLVector3 normal1 = (v1-v2) % (v2-v3);
+		normal1.normalize();
+		
+		position.mV[0] += dzx;
+		position.mV[1] += dzy;
+		position.mV[2] += blade_height;
+		v[3]    = v1 = position + mRegionp->getOriginAgent();
+	
+
+		F32 a,b,t;
+
+		BOOL hit = FALSE;
+
+
+		U32 idx0 = 0,idx1 = 0,idx2 = 0;
+
+		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, &a, &b, &t, FALSE))
+		{
+			hit = TRUE;
+			idx0 = 0; idx1 = 1; idx2 = 2;
+		}
+		else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, &a, &b, &t, FALSE))
+		{
+			hit = TRUE;
+			idx0 = 1; idx1 = 3; idx2 = 2;
+		}
+		else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, &a, &b, &t, FALSE))
+		{
+			normal1 = -normal1;
+			hit = TRUE;
+			idx0 = 2; idx1 = 1; idx2 = 0;
+		}
+		else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, &a, &b, &t, FALSE))
+		{
+			normal1 = -normal1;
+			hit = TRUE;
+			idx0 = 2; idx1 = 3; idx2 = 1;
+		}
+
+		if (hit)
+		{
+			if (t >= 0.f &&
+				t <= 1.f &&
+				t < closest_t)
+			{
+
+				LLVector2 hit_tc = ((1.f - a - b)  * tc[idx0] +
+									  a              * tc[idx1] +
+									  b              * tc[idx2]);
+				if (pick_transparent ||
+					getTEImage(0)->getMask(hit_tc))
+				{
+					closest_t = t;
+					if (intersection != NULL)
+					{
+						*intersection = start+dir*closest_t;
+					}
+
+					if (tex_coord != NULL)
+					{
+						*tex_coord = hit_tc;
+					}
+
+					if (normal != NULL)
+					{
+						*normal    = normal1;
+					}
+					ret = TRUE;
+				}
+			}
+		}
+	}
+
+	return ret;
+}
+
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 1a142414097..c16040ae6ca 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -80,6 +80,16 @@ class LLVOGrass : public LLAlphaObject
 	/*virtual*/ BOOL    isActive() const; // Whether this object needs to do an idleUpdate.
 	BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
 
+	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, 
+										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES
+										  BOOL pick_transparent = FALSE,
+										  S32* face_hit = NULL,                 // which face was hit
+										  LLVector3* intersection = NULL,       // return the intersection point
+										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point
+										  LLVector3* normal = NULL,             // return the surface normal at the intersection point
+										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point
+		);
+
 	static S32 sMaxGrassSpecies;
 
 	struct GrassSpeciesData
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 361f2ebf503..7e279adb0bb 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -45,7 +45,7 @@
 #include "pipeline.h"
 
 LLVOGround::LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-:	LLStaticViewerObject(id, pcode, regionp)
+:	LLStaticViewerObject(id, pcode, regionp, TRUE)
 {
 	mbCanSelect = FALSE;
 }
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 6eb3851d16e..02635a7f82f 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -378,20 +378,20 @@ void LLVoiceVisualizer::render()
 		//-----------------------------
 		// bind texture 0 (the dot)
 		//-----------------------------
-		mSoundSymbol.mTexture[0]->bind(); 
+		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
 		
 		//-------------------------------------------------------------
 		// now render the dot
 		//-------------------------------------------------------------
 		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
 		
-		gGL.begin( LLVertexBuffer::TRIANGLE_STRIP );
+		gGL.begin( LLRender::TRIANGLE_STRIP );
 			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
 			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
 			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
 		gGL.end();
 
-		gGL.begin( LLVertexBuffer::TRIANGLE_STRIP );
+		gGL.begin( LLRender::TRIANGLE_STRIP );
 			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
 			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
 			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
@@ -503,18 +503,19 @@ void LLVoiceVisualizer::render()
 				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
 							
 				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
-				mSoundSymbol.mTexture[i]->bind();
+				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
+
 				
 				//---------------------------------------------------
 				// now, render the mofo
 				//---------------------------------------------------
-				gGL.begin( LLVertexBuffer::TRIANGLE_STRIP );
+				gGL.begin( LLRender::TRIANGLE_STRIP );
 					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
 					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
 					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
 				gGL.end();
 
-				gGL.begin( LLVertexBuffer::TRIANGLE_STRIP );
+				gGL.begin( LLRender::TRIANGLE_STRIP );
 					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
 					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
 					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
@@ -550,8 +551,8 @@ VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
 	//-----------------------------------------------------------------------------------------
 	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
 	
-			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.66666f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
-	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.33333f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
+			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
+	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
 	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
 
 	return gesticulationLevel;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 3724a94edd8..657e1680f18 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -133,15 +133,16 @@ F32 LLVOPartGroup::getPartSize(S32 idx)
 	return 0.f;
 }
 
+LLVector3 LLVOPartGroup::getCameraPosition() const
+{
+	return gAgent.getCameraPositionAgent();
+}
+
 BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 {
 	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_PARTICLES);
 
 	dirtySpatialGroup();
-
- 	LLVector3 at;
-	LLVector3 position_agent;
-	LLVector3 camera_agent = LLViewerCamera::getInstance()->getOrigin();
 	
 	S32 num_parts = mViewerPartGroupp->getCount();
 	LLFace *facep;
@@ -187,7 +188,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 		const LLViewerPart *part = mViewerPartGroupp->mParticles[i];
 
 		LLVector3 part_pos_agent(part->mPosAgent);
-		at = part_pos_agent - camera_agent;
+		LLVector3 at(part_pos_agent - LLViewerCamera::getInstance()->getOrigin());
 
 		F32 camera_dist_squared = at.lengthSquared();
 		F32 inv_camera_dist_squared;
@@ -278,9 +279,10 @@ void LLVOPartGroup::getGeometry(S32 idx,
 
 	
 	LLVector3 part_pos_agent(part.mPosAgent);
-	LLVector3 camera_agent = gAgent.getCameraPositionAgent();
+	LLVector3 camera_agent = getCameraPosition(); 
 	LLVector3 at = part_pos_agent - camera_agent;
-	LLVector3 up, right;
+	LLVector3 up;
+	LLVector3 right;
 
 	right = at % LLVector3(0.f, 0.f, 1.f);
 	right.normalize();
@@ -308,6 +310,7 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	right *= 0.5f*part.mScale.mV[0];
 	up *= 0.5f*part.mScale.mV[1];
 
+
 	const LLVector3& normal = -LLViewerCamera::getInstance()->getXAxis();
 		
 	*verticesp++ = part_pos_agent + up - right;
@@ -355,6 +358,13 @@ LLParticlePartition::LLParticlePartition()
 	mLODPeriod = 1;
 }
 
+LLHUDParticlePartition::LLHUDParticlePartition() :
+	LLParticlePartition()
+{
+	mDrawableType = LLPipeline::RENDER_TYPE_HUD;
+	mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
+}
+
 void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
 {
 	group->mBufferUsage = mBufferUsage;
@@ -480,3 +490,24 @@ F32 LLParticlePartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
 	return 1024.f;
 }
 
+U32 LLVOHUDPartGroup::getPartitionType() const
+{ 
+	// Commenting out and returning PARTITION_NONE because DEV-16909 
+	// (SVC-2396: Particles not handled properly as hud) didn't work completely 
+	// so this disables HUD particles until they can be fixed properly. -MG
+	//return LLViewerRegion::PARTITION_HUD_PARTICLE; 
+	return LLViewerRegion::PARTITION_NONE;
+}
+
+LLDrawable* LLVOHUDPartGroup::createDrawable(LLPipeline *pipeline)
+{
+	pipeline->allocDrawable(this);
+	mDrawable->setLit(FALSE);
+	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_HUD);
+	return mDrawable;
+}
+
+LLVector3 LLVOHUDPartGroup::getCameraPosition() const
+{
+	return LLVector3(-1,0,0);
+}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index d8e1da7e5a8..30c5105dd3b 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -80,6 +80,23 @@ class LLVOPartGroup : public LLAlphaObject
 	~LLVOPartGroup();
 
 	LLViewerPartGroup *mViewerPartGroupp;
+
+	virtual LLVector3 getCameraPosition() const;
+
+};
+
+
+class LLVOHUDPartGroup : public LLVOPartGroup
+{
+public:
+	LLVOHUDPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : 
+	  LLVOPartGroup(id, pcode, regionp)   
+	{
+	}
+protected:
+	LLDrawable* createDrawable(LLPipeline *pipeline);
+	U32 getPartitionType() const;
+	virtual LLVector3 getCameraPosition() const;
 };
 
 #endif // LL_LLVOPARTGROUP_H
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index e619ca17548..711aeca1635 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -294,7 +294,7 @@ void LLSkyTex::createGLImage(S32 which)
 
 void LLSkyTex::bindTexture(BOOL curr)
 {
-	mImageGL[getWhich(curr)]->bind();
+	gGL.getTexUnit(0)->bind(mImageGL[getWhich(curr)]);
 }
 
 /***************************************
@@ -308,7 +308,7 @@ S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X;
 S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y;
 
 LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-:	LLStaticViewerObject(id, pcode, regionp),
+:	LLStaticViewerObject(id, pcode, regionp, TRUE),
 	mSun(SUN_DISK_RADIUS), mMoon(MOON_DISK_RADIUS),
 	mBrightnessScale(1.f),
 	mBrightnessScaleNew(0.f),
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 968cc69d3aa..e912a19f814 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -916,6 +916,87 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
 	}
 }
 
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+	
+{
+
+	if (!lineSegmentBoundingBox(start, end))
+	{
+		return FALSE;
+	}
+
+	LLVector3 delta = end-start;
+		
+	LLVector3 pdelta = delta;
+	pdelta.mV[2] = 0;
+
+	F32 plength = pdelta.length();
+	
+	F32 tdelta = 1.f/plength;
+
+	LLVector3 origin = start - mRegionp->getOriginAgent();
+
+	if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
+	{
+		//origin is under ground, treat as no intersection
+		return FALSE;
+	}
+
+	//step one meter at a time until intersection point found
+
+	F32 t = 0.f;
+	while ( t <= 1.f)
+	{
+		LLVector3 sample = origin + delta*t;
+		
+		F32 height = mRegionp->getLandHeightRegion(sample);
+		if (height > sample.mV[2])
+		{ //ray went below ground, positive intersection
+			//quick and dirty binary search to get impact point
+			tdelta = -tdelta*0.5f;
+			F32 err_dist = 0.001f;
+			F32 dist = fabsf(sample.mV[2] - height);
+
+			while (dist > err_dist && tdelta*tdelta > 0.0f)
+			{
+				t += tdelta;
+				sample = origin+delta*t;
+				height = mRegionp->getLandHeightRegion(sample);
+				if ((tdelta < 0 && height < sample.mV[2]) ||
+					(height > sample.mV[2] && tdelta > 0))
+				{ //jumped over intersection point, go back
+					tdelta = -tdelta;
+				}
+				tdelta *= 0.5f;
+				dist = fabsf(sample.mV[2] - height);
+			}
+
+			if (intersection)
+			{
+				sample.mV[2] = mRegionp->getLandHeightRegion(sample);
+				*intersection = sample + mRegionp->getOriginAgent();
+			}
+
+			if (normal)
+			{
+				*normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
+			}
+
+			return TRUE;
+		}
+
+		t += tdelta;
+		if (t > 1 && t < 1.f+tdelta*0.99f)
+		{ //make sure end point is checked (saves vertical lines coming up negative)
+			t = 1.f;
+		}
+	}
+
+
+	return FALSE;
+}
+
 void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
 {
 	LLVector3 posAgent = getPositionAgent();
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index ede01eb1a9a..ddb929bb916 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -85,6 +85,16 @@ class LLVOSurfacePatch : public LLStaticViewerObject
 	void dirtyPatch();
 	void dirtyGeom();
 
+	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, 
+										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES
+										  BOOL pick_transparent = FALSE,
+										  S32* face_hit = NULL,                 // which face was hit
+										  LLVector3* intersection = NULL,       // return the intersection point
+										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point
+										  LLVector3* normal = NULL,             // return the surface normal at the intersection point
+										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point
+		);
+
 	BOOL			mDirtiedPatch;
 protected:
 	~LLVOSurfacePatch();
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 0c9b524f7f4..7e3b96eb8f7 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -312,7 +312,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
 	mTreeImagep = gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID);
 	if (mTreeImagep)
 	{
-		mTreeImagep->bindTexture(0);
+		gGL.getTexUnit(0)->bind(mTreeImagep.get());
 	}
 	mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
 	mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength;
@@ -931,6 +931,48 @@ void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax)
 	mDrawable->setPositionGroup(center);
 }
 
+BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+	
+{
+
+	if (!lineSegmentBoundingBox(start, end))
+	{
+		return FALSE;
+	}
+
+	const LLVector3* ext = mDrawable->getSpatialExtents();
+
+	LLVector3 center = (ext[1]+ext[0])*0.5f;
+	LLVector3 size = (ext[1]-ext[0]);
+
+	LLQuaternion quat = getRotation();
+
+	center -= LLVector3(0,0,size.magVec() * 0.25f)*quat;
+
+	size.scaleVec(LLVector3(0.25f, 0.25f, 1.f));
+	size.mV[0] = llmin(size.mV[0], 1.f);
+	size.mV[1] = llmin(size.mV[1], 1.f);
+
+	LLVector3 pos, norm;
+		
+	if (linesegment_tetrahedron(start, end, center, size, quat, pos, norm))
+	{
+		if (intersection)
+		{
+			*intersection = pos;
+		}
+
+		if (normal)
+		{
+			*normal = norm;
+		}
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
 U32 LLVOTree::getPartitionType() const
 { 
 	return LLViewerRegion::PARTITION_TREE; 
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index dee282c7522..ca0bd17ccf5 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -80,6 +80,17 @@ class LLVOTree : public LLViewerObject
 
 	U32 drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD, S32 stop_level, U16 depth, U16 trunk_depth,  F32 scale, F32 twist, F32 droop,  F32 branches, F32 alpha);
  
+
+	 /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, 
+										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES
+										  BOOL pick_transparent = FALSE,
+										  S32* face_hit = NULL,                 // which face was hit
+										  LLVector3* intersection = NULL,       // return the intersection point
+										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point
+										  LLVector3* normal = NULL,             // return the surface normal at the intersection point
+										  LLVector3* bi_normal = NULL           // return the surface bi-normal at the intersection point
+		);
+
 	static S32 sMaxTreeSpecies;
 
 	struct TreeSpeciesData
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8b147dc7cd5..50cf336d079 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -605,7 +605,7 @@ BOOL LLVOVolume::setMaterial(const U8 material)
 void LLVOVolume::setTexture(const S32 face)
 {
 	llassert(face < getNumTEs());
-	LLViewerImage::bindTexture(getTEImage(face));
+	gGL.getTexUnit(0)->bind(getTEImage(face));
 }
 
 void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped)
@@ -1934,10 +1934,18 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
 }
 
 
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, S32 *face_hitp,
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
 									  LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
 	
 {
+	if (!mbCanSelect ||
+		(gHideSelectedObjects && isSelected()) ||
+			mDrawable->isDead() || 
+			!gPipeline.hasRenderType(mDrawable->getRenderType()))
+	{
+		return FALSE;
+	}
+
 	LLVolume* volume = getVolume();
 	if (volume)
 	{	
@@ -1946,37 +1954,88 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
 		v_start = agentPositionToVolume(start);
 		v_end = agentPositionToVolume(end);
 		
-		S32 face_hit = volume->lineSegmentIntersect(v_start, v_end, face,
-													intersection, tex_coord, normal, bi_normal);
-		if (face_hit >= 0)
+		LLVector3 p;
+		LLVector3 n;
+		LLVector2 tc;
+		LLVector3 bn;
+
+		if (intersection != NULL)
 		{
-			if (face_hitp != NULL)
-			{
-				*face_hitp = face_hit;
-			}
+			p = *intersection;
+		}
+
+		if (tex_coord != NULL)
+		{
+			tc = *tex_coord;
+		}
+
+		if (normal != NULL)
+		{
+			n = *normal;
+		}
+
+		if (bi_normal != NULL)
+		{
+			bn = *bi_normal;
+		}
+
+		S32 face_hit = -1;
+
+		S32 start_face, end_face;
+		if (face == -1)
+		{
+			start_face = 0;
+			end_face = volume->getNumFaces();
+		}
+		else
+		{
+			start_face = face;
+			end_face = face+1;
+		}
+
+		for (S32 i = start_face; i < end_face; ++i)
+		{
+			face_hit = volume->lineSegmentIntersect(v_start, v_end, i,
+													&p, &tc, &n, &bn);
 			
-			if (intersection != NULL)
+			if (face_hit >= 0)
 			{
-				*intersection = volumePositionToAgent(*intersection);  // must map back to agent space
-			}
+				LLFace* face = mDrawable->getFace(face_hit);
+				if (pick_transparent || !face->getTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+				{
+					if (face_hitp != NULL)
+					{
+						*face_hitp = face_hit;
+					}
+					
+					if (intersection != NULL)
+					{
+						*intersection = volumePositionToAgent(p);  // must map back to agent space
+					}
 
-			if (normal != NULL)
-			{
-				*normal = volumeDirectionToAgent(*normal);
-				(*normal).normalize();
-			}
+					if (normal != NULL)
+					{
+						*normal = volumeDirectionToAgent(n);
+						(*normal).normVec();
+					}
 
-			if (bi_normal != NULL)
-			{
-				*bi_normal = volumeDirectionToAgent(*bi_normal);
-				(*bi_normal).normalize();
-			}
+					if (bi_normal != NULL)
+					{
+						*bi_normal = volumeDirectionToAgent(bn);
+						(*bi_normal).normVec();
+					}
 
-			
-			return TRUE;
+					if (tex_coord != NULL)
+					{
+						*tex_coord = tc;
+					}
+					
+					return TRUE;
+				}
+			}
 		}
 	}
-	
+		
 	return FALSE;
 }
 
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 58a1b308a4c..49ac91bd38c 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -114,6 +114,7 @@ class LLVOVolume : public LLViewerObject
 
 	/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, 
 										  S32 face = -1,                        // which face to check, -1 = ALL_SIDES
+										  BOOL pick_transparent = FALSE,
 										  S32* face_hit = NULL,                 // which face was hit
 										  LLVector3* intersection = NULL,       // return the intersection point
 										  LLVector2* tex_coord = NULL,          // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 18c03d870f1..8391a314f6e 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -87,7 +87,7 @@ inline U32 LLVOWLSky::getStarsNumIndices(void)
 }
 
 LLVOWLSky::LLVOWLSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-	: LLStaticViewerObject(id, pcode, regionp)
+	: LLStaticViewerObject(id, pcode, regionp, TRUE)
 {
 	initStars();
 }
@@ -488,7 +488,7 @@ void LLVOWLSky::drawStars(void)
 	if (mStarsVerts.notNull())
 	{
 		mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
-		mStarsVerts->draw(LLVertexBuffer::POINTS, getStarsNumIndices(), 0);
+		mStarsVerts->draw(LLRender::POINTS, getStarsNumIndices(), 0);
 	}
 }
 
@@ -513,7 +513,7 @@ void LLVOWLSky::drawDome(void)
 		strips_segment->setBuffer(data_mask);
 
 		strips_segment->drawRange(
-			LLVertexBuffer::TRIANGLE_STRIP, 
+			LLRender::TRIANGLE_STRIP, 
 			0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(), 
 			0);
 		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices() - 2);
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 29f086b7f96..50a65450a87 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -89,48 +89,57 @@ LLWaterParamManager::~LLWaterParamManager()
 void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 {
 	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
-	LL_INFOS2("AppInit", "Shaders") << "Loading water settings from " << path_name << LL_ENDL;
-
-	//mParamList.clear();
-	
+	LL_INFOS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
+			
 	bool found = true;			
 	while(found) 
 	{
 		std::string name;
 		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
-
-		LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
-		
-		// if we have one
-		if(found) 
+		if(found)
 		{
+
+			name=name.erase(name.length()-4);
+
 			// bugfix for SL-46920: preventing filenames that break stuff.
 			char * curl_str = curl_unescape(name.c_str(), name.size());
 			std::string unescaped_name(curl_str);
 			curl_free(curl_str);
 			curl_str = NULL;
 
-			// not much error checking here since we're getting rid of this
-			std::string water_name = unescaped_name.substr(0, unescaped_name.size() - 4);
-		
-			std::string cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", name));
-			LL_DEBUGS2("AppInit", "Shaders") << "Loading water from " << cur_path << LL_ENDL;
+			LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
+			loadPreset(unescaped_name,FALSE);
+		}
+	}
+
+	// And repeat for user presets, note the user presets will modify any system presets already loaded
+
+	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
+	LL_INFOS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
 			
-			llifstream water_xml(cur_path);
-			if (water_xml)
-			{
-				LLSD water_data(LLSD::emptyMap());
-				LLPointer<LLSDParser> parser = new LLSDXMLParser();
-				parser->parse(water_xml, water_data, LLSDSerialize::SIZE_UNLIMITED);
+	found = true;			
+	while(found) 
+	{
+		std::string name;
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name, false);
+		if(found)
+		{
+			name=name.erase(name.length()-4);
 
-				addParamSet(water_name, water_data);
-				water_xml.close();
-			}
+			// bugfix for SL-46920: preventing filenames that break stuff.
+			char * curl_str = curl_unescape(name.c_str(), name.size());
+			std::string unescaped_name(curl_str);
+			curl_free(curl_str);
+			curl_str = NULL;
+
+			LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
+			loadPreset(unescaped_name,FALSE);
 		}
 	}
+
 }
 
-void LLWaterParamManager::loadPreset(const std::string & name)
+void LLWaterParamManager::loadPreset(const std::string & name,bool propagate)
 {
 	// bugfix for SL-46920: preventing filenames that break stuff.
 	char * curl_str = curl_escape(name.c_str(), name.size());
@@ -142,8 +151,17 @@ void LLWaterParamManager::loadPreset(const std::string & name)
 
 	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
 	llinfos << "Loading water settings from " << pathName << llendl;
-
-	llifstream presetsXML(pathName);
+	
+	std::ifstream presetsXML;
+	presetsXML.open(pathName.c_str());
+	
+	// That failed, try loading from the users area instead.
+	if(!presetsXML)
+	{
+		pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename);
+		llinfos << "Loading User water setting from " << pathName << llendl;
+		presetsXML.open(pathName.c_str());
+	}
 
 	if (presetsXML)
 	{
@@ -170,10 +188,12 @@ void LLWaterParamManager::loadPreset(const std::string & name)
 		return;
 	}
 
-	getParamSet(name, mCurParams);
-
-	propagateParameters();
-}
+	if(propagate)
+	{
+		getParamSet(name, mCurParams);
+		propagateParameters();
+	}
+}	
 
 void LLWaterParamManager::savePreset(const std::string & name)
 {
@@ -187,7 +207,7 @@ void LLWaterParamManager::savePreset(const std::string & name)
 
 	// make an empty llsd
 	LLSD paramsData(LLSD::emptyMap());
-	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
+	std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", escaped_filename));
 
 	// fill it with LLSD windlight params
 	paramsData = mParamList[name].getAll();
@@ -390,7 +410,8 @@ bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_fr
 
 	if(delete_from_disk)
 	{
-		std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
+
+		std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
 		
 		// use full curl escaped name
 		char * curl_str = curl_escape(name.c_str(), name.size());
diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h
index 6f31ebce5c7..fd7c1d5177f 100644
--- a/indra/newview/llwaterparammanager.h
+++ b/indra/newview/llwaterparammanager.h
@@ -228,7 +228,8 @@ class LLWaterParamManager
 	void loadAllPresets(const std::string & fileName);
 
 	/// load an individual preset into the sky
-	void loadPreset(const std::string & name);
+
+	void loadPreset(const std::string & name,bool propagate=true);
 
 	/// save the parameter presets to file
 	void savePreset(const std::string & name);
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index b55c3e5b6d5..4270a6a0aa2 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -106,84 +106,65 @@ LLWLParamManager::~LLWLParamManager()
 
 void LLWLParamManager::loadPresets(const std::string& file_name)
 {
-	// if fileName exists, use legacy loading form the big file, otherwise, search the sky 
-	// directory, and add the list
-	if(file_name != "") 
+	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
+	LL_INFOS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
+			
+	bool found = true;			
+	while(found) 
 	{
-		std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", file_name));
-		LL_INFOS2("AppInit", "Shaders") << "Loading WindLight settings from " << path_name << LL_ENDL;
-
-		llifstream presetsXML(path_name);
-	
-		if (presetsXML)
+		std::string name;
+		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
+		if(found)
 		{
-			LLSD paramsData(LLSD::emptyMap());
 
-			LLPointer<LLSDParser> parser = new LLSDXMLParser();
+			name=name.erase(name.length()-4);
 
-			parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
+			// bugfix for SL-46920: preventing filenames that break stuff.
+			char * curl_str = curl_unescape(name.c_str(), name.size());
+			std::string unescaped_name(curl_str);
+			curl_free(curl_str);
+			curl_str = NULL;
 
-			LLSD::map_const_iterator endParams = paramsData.endMap();
-			for(LLSD::map_const_iterator curParams = paramsData.beginMap();
-				curParams != endParams;
-				++curParams)
-			{
-				addParamSet(curParams->first, curParams->second);
-			}
+			LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
+			loadPreset(unescaped_name,FALSE);
 		}
 	}
-	
-	// otherwise, search the sky directory and find things there
-	else
+
+	// And repeat for user presets, note the user presets will modify any system presets already loaded
+
+	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
+	LL_INFOS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
+			
+	found = true;			
+	while(found) 
 	{
-		std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
-		LL_INFOS2("AppInit", "Shaders") << "Loading WindLight settings from " << path_name << LL_ENDL;
-	
-		//mParamList.clear();
-		
-		bool found = true;			
-		while(found) 
+		std::string name;
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name, false);
+		if(found)
 		{
-			std::string name;
-			found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
+			name=name.erase(name.length()-4);
+
+			// bugfix for SL-46920: preventing filenames that break stuff.
+			char * curl_str = curl_unescape(name.c_str(), name.size());
+			std::string unescaped_name(curl_str);
+			curl_free(curl_str);
+			curl_str = NULL;
 
 			LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
-			
-			// if we have one
-			if(found) 
-			{
-				// bugfix for SL-46920: preventing filenames that break stuff.
-				char * curl_str = curl_unescape(name.c_str(), name.size());
-				std::string unescaped_name(curl_str);
-				curl_free(curl_str);
-				curl_str = NULL;
-
-				// not much error checking here since we're getting rid of this
-				std::string sky_name = unescaped_name.substr(0, unescaped_name.size() - 4);
-			
-				std::string cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", name));
-				LL_DEBUGS2("AppInit", "Shaders") << "Loading sky from " << cur_path << LL_ENDL;
-				
-				llifstream sky_xml(cur_path);
-				if (sky_xml)
-				{
-					LLSD sky_data(LLSD::emptyMap());
-					LLPointer<LLSDParser> parser = new LLSDXMLParser();
-					parser->parse(sky_xml, sky_data, LLSDSerialize::SIZE_UNLIMITED);
-
-					addParamSet(sky_name, sky_data);
-					sky_xml.close();
-				}
-			}
+			loadPreset(unescaped_name,FALSE);
 		}
 	}
+
 }
 
 void LLWLParamManager::savePresets(const std::string & fileName)
 {
+	//Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder
+	//and not over the RO system wide version.
+
 	LLSD paramsData(LLSD::emptyMap());
 	
-	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", fileName));
+	std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName));
 
 	for(std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
 		mIt != mParamList.end();
@@ -201,8 +182,9 @@ void LLWLParamManager::savePresets(const std::string & fileName)
 	presetsXML.close();
 }
 
-void LLWLParamManager::loadPreset(const std::string & name)
+void LLWLParamManager::loadPreset(const std::string & name,bool propagate)
 {
+	
 	// bugfix for SL-46920: preventing filenames that break stuff.
 	char * curl_str = curl_escape(name.c_str(), name.size());
 	std::string escaped_filename(curl_str);
@@ -214,7 +196,16 @@ void LLWLParamManager::loadPreset(const std::string & name)
 	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
 	llinfos << "Loading WindLight sky setting from " << pathName << llendl;
 
-	llifstream presetsXML(pathName);
+	llifstream presetsXML;
+	presetsXML.open(pathName.c_str());
+
+	// That failed, try loading from the users area instead.
+	if(!presetsXML)
+	{
+		pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename);
+		llinfos << "Loading User WindLight sky setting from " << pathName << llendl;
+		presetsXML.open(pathName.c_str());
+	}
 
 	if (presetsXML)
 	{
@@ -241,10 +232,13 @@ void LLWLParamManager::loadPreset(const std::string & name)
 		return;
 	}
 
-	getParamSet(name, mCurParams);
-
-	propagateParameters();
-}
+	
+	if(propagate)
+	{
+		getParamSet(name, mCurParams);
+		propagateParameters();
+	}
+}	
 
 void LLWLParamManager::savePreset(const std::string & name)
 {
@@ -258,7 +252,7 @@ void LLWLParamManager::savePreset(const std::string & name)
 
 	// make an empty llsd
 	LLSD paramsData(LLSD::emptyMap());
-	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
+	std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename));
 
 	// fill it with LLSD windlight params
 	paramsData = mParamList[name].getAll();
@@ -533,7 +527,7 @@ bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_
 	
 	if(delete_from_disk)
 	{
-		std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
+		std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
 		
 		// use full curl escaped name
 		char * curl_str = curl_escape(name.c_str(), name.size());
diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
index 1a2b2a39032..f74e9697b3f 100644
--- a/indra/newview/llwlparammanager.h
+++ b/indra/newview/llwlparammanager.h
@@ -135,7 +135,7 @@ class LLWLParamManager
 	void savePresets(const std::string & fileName);
 
 	/// load an individual preset into the sky
-	void loadPreset(const std::string & name);
+	void loadPreset(const std::string & name,bool propogate=true);
 
 	/// save the parameter presets to file
 	void savePreset(const std::string & name);
@@ -195,7 +195,6 @@ class LLWLParamManager
 	// singleton pattern implementation
 	static LLWLParamManager * instance();
 
-
 public:
 
 	// helper variables
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8cebf1c12a2..63f9ef0b577 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -32,6 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llworld.h"
+#include "llrender.h"
 
 #include "indra_constants.h"
 #include "llstl.h"
@@ -108,7 +109,7 @@ LLWorld::LLWorld() :
 	*(default_texture++) = MAX_WATER_COLOR.mV[3];
 	
 	mDefaultWaterTexturep = new LLViewerImage(raw, FALSE);
-	mDefaultWaterTexturep->bind();
+	gGL.getTexUnit(0)->bind(mDefaultWaterTexturep.get());
 	mDefaultWaterTexturep->setClamp(TRUE, TRUE);
 
 }
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 3352e977685..102f56a9a30 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -498,7 +498,8 @@ void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**)
 		new_layer.LayerDefined = TRUE;
 		msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block);
 		new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE);
-		new_layer.LayerImage->bindTexture(0);
+		
+		gGL.getTexUnit(0)->bind(new_layer.LayerImage.get());
 		new_layer.LayerImage->setClamp(TRUE, TRUE);
 		
 		U32 left, right, top, bottom;
@@ -610,7 +611,7 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**)
 			siminfo->mWaterHeight = (F32) water_height;
 			siminfo->mMapImageID[agent_flags] = image_id;
 			siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE);
-			siminfo->mCurrentImage->bindTexture(0);
+			gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get());
 			siminfo->mCurrentImage->setClamp(TRUE, TRUE);
 			
 			if (siminfo->mMapImageID[2].notNull())
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index e63dcfc1e85..aa1c13ac348 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -301,7 +301,7 @@ void LLWorldMapView::draw()
 
 	LLLocalClipRect clip(getLocalRect());
 	{
-		LLGLSNoTexture no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	
 		glMatrixMode(GL_MODELVIEW);
 
@@ -377,7 +377,7 @@ void LLWorldMapView::draw()
 		
 		// Draw using the texture.  If we don't clamp we get artifact at
 		// the edge.
-		LLViewerImage::bindTexture(current_image);
+		gGL.getTexUnit(0)->bind(current_image);
 
 		// Draw map image into RGB
 		//gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -385,7 +385,7 @@ void LLWorldMapView::draw()
 		gGL.setColorMask(true, false);
 		gGL.color4f(1.f, 1.f, 1.f, layer_alpha);
 
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 			gGL.texCoord2f(0.0f, 1.0f);
 			gGL.vertex3f(left, top, -1.0f);
 			gGL.texCoord2f(0.0f, 0.0f);
@@ -401,7 +401,7 @@ void LLWorldMapView::draw()
 		gGL.setColorMask(false, true);
 		gGL.color4f(1.f, 1.f, 1.f, 1.f);
 
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 			gGL.texCoord2f(0.0f, 1.0f);
 			gGL.vertex2f(left, top);
 			gGL.texCoord2f(0.0f, 0.0f);
@@ -434,7 +434,7 @@ void LLWorldMapView::draw()
 		if (info->mOverlayImage.isNull() && info->mMapImageID[2].notNull())
 		{
 			info->mOverlayImage = gImageList.getImage(info->mMapImageID[2], MIPMAP_TRUE, FALSE);
-			info->mOverlayImage->bind(0);
+			gGL.getTexUnit(0)->bind(info->mOverlayImage.get());
 			info->mOverlayImage->setClamp(TRUE, TRUE);
 		}
 		
@@ -536,13 +536,13 @@ void LLWorldMapView::draw()
 			// Draw using the texture.  If we don't clamp we get artifact at
 			// the edge.
 			LLGLSUIDefault gls_ui;
-			LLViewerImage::bindTexture(simimage);
+			gGL.getTexUnit(0)->bind(simimage);
 
 			gGL.setSceneBlendType(LLRender::BT_ALPHA);
 			F32 alpha = sim_alpha * info->mAlpha;
 			gGL.color4f(1.f, 1.0f, 1.0f, alpha);
 
-			gGL.begin(LLVertexBuffer::QUADS);
+			gGL.begin(LLRender::QUADS);
 				gGL.texCoord2f(0.f, 1.f);
 				gGL.vertex3f(left, top, 0.f);
 				gGL.texCoord2f(0.f, 0.f);
@@ -555,9 +555,9 @@ void LLWorldMapView::draw()
 
 			if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->getHasGLTexture())
 			{
-				LLViewerImage::bindTexture(overlayimage);
+				gGL.getTexUnit(0)->bind(overlayimage);
 				gGL.color4f(1.f, 1.f, 1.f, alpha);
-				gGL.begin(LLVertexBuffer::QUADS);
+				gGL.begin(LLRender::QUADS);
 					gGL.texCoord2f(0.f, 1.f);
 					gGL.vertex3f(left, top, -0.5f);
 					gGL.texCoord2f(0.f, 0.f);
@@ -577,8 +577,8 @@ void LLWorldMapView::draw()
 				gGL.setColorMask(false, true);
 				gGL.color4f(1.f, 1.f, 1.f, 1.f);
 
-				LLGLSNoTexture gls_no_texture;
-				gGL.begin(LLVertexBuffer::QUADS);
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+				gGL.begin(LLRender::QUADS);
 					gGL.vertex2f(left, top);
 					gGL.vertex2f(left, bottom);
 					gGL.vertex2f(right, bottom);
@@ -596,8 +596,8 @@ void LLWorldMapView::draw()
 			gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA);
 			gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f);
 
-			LLGLSNoTexture gls_no_texture;
-			gGL.begin(LLVertexBuffer::QUADS);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+			gGL.begin(LLRender::QUADS);
 				gGL.vertex2f(left, top);
 				gGL.vertex2f(left, bottom);
 				gGL.vertex2f(right, bottom);
@@ -612,9 +612,9 @@ void LLWorldMapView::draw()
 		{
 			gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
 			
-			LLGLSNoTexture gls_no_texture;
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			gGL.color3f(1.f, 0.f, 0.f);
-			gGL.begin(LLVertexBuffer::LINES);
+			gGL.begin(LLRender::LINES);
 				gGL.vertex2f(left, top);
 				gGL.vertex2f(right, bottom);
 				gGL.vertex2f(left, bottom);
@@ -683,7 +683,7 @@ void LLWorldMapView::draw()
 	// Draw background rectangle
 	LLGLSUIDefault gls_ui;
 	{
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f);
 		gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA);
 		gGL.color4fv( mBackgroundColor.mV );
@@ -969,7 +969,7 @@ void LLWorldMapView::drawFrustum()
 	F32 ctr_x = getRect().getWidth() * 0.5f + sPanX;
 	F32 ctr_y = getRect().getHeight() * 0.5f + sPanY;
 
-	LLGLSNoTexture gls_no_texture;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// Since we don't rotate the map, we have to rotate the frustum.
 	gGL.pushMatrix();
@@ -978,7 +978,7 @@ void LLWorldMapView::drawFrustum()
 
 		// Draw triangle with more alpha in far pixels to make it 
 		// fade out in distance.
-		gGL.begin( LLVertexBuffer::TRIANGLES  );
+		gGL.begin( LLRender::TRIANGLES  );
 			gGL.color4f(1.f, 1.f, 1.f, 0.25f);
 			gGL.vertex2f( 0, 0 );
 
@@ -1184,11 +1184,11 @@ static void drawDot(F32 x_pixels, F32 y_pixels,
 		F32 top =		y_pixels + dot_radius;
 		F32 bottom =	y_pixels - dot_radius;
 
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( color.mV );
 		LLUI::setLineWidth(1.5f);
 		F32 h_bar = relative_z > HEIGHT_THRESHOLD ? top : bottom; // horizontal bar Y
-		gGL.begin( LLVertexBuffer::LINES );
+		gGL.begin( LLRender::LINES );
 			gGL.vertex2f(center, top);
 			gGL.vertex2f(left, h_bar);
 			gGL.vertex2f(right, h_bar);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2bd18319469..817331b9902 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -330,8 +330,15 @@ void LLPipeline::init()
 	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
 	mRenderDebugMask = 0;	// All debug starts off
 
+	// Don't turn on ground when this is set
+	// Mac Books with intel 950s need this
+	if(!gSavedSettings.getBOOL("RenderGround"))
+	{
+		toggleRenderType(RENDER_TYPE_GROUND);
+	}
+
 	mOldRenderDebugMask = mRenderDebugMask;
-	
+
 	mBackfaceCull = TRUE;
 
 	stop_glerror();
@@ -454,7 +461,7 @@ void LLPipeline::resizeScreenTexture()
 		}
 	
 		mScreen.release();
-		mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB);		
+		mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE);		
 
 		llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
 	}
@@ -556,7 +563,7 @@ void LLPipeline::createGLBuffers()
 
 			for (U32 j = 0; j < 3; j++)
 			{
-				glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j]);
+				gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j]);
 				glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 				glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 				glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -583,10 +590,11 @@ void LLPipeline::createGLBuffers()
 			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE);
 		}
 		
+
 		GLuint resX = gViewerWindow->getWindowDisplayWidth();
 		GLuint resY = gViewerWindow->getWindowDisplayHeight();
-		
-		mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB);
+	
+		mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE);
 	}
 }
 
@@ -1212,7 +1220,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
 	LLVertexBuffer::unbind();
 	LLGLDisable blend(GL_BLEND);
 	LLGLDisable test(GL_ALPHA_TEST);
-	LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	gGL.setColorMask(false, false);
 	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
@@ -1357,7 +1365,7 @@ void LLPipeline::doOcclusion(LLCamera& camera)
 	}
 	LLGLDisable blend(GL_BLEND);
 	LLGLDisable test(GL_ALPHA_TEST);
-	LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
 
 	if (LLPipeline::sUseOcclusion > 1)
@@ -2368,7 +2376,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
 		sUnderWaterRender = FALSE;
 	}
 
-	LLViewerImage::sDefaultImagep->bind(0);
+	gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep);
 	LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE);
 	
 	//////////////////////////////////////////////
@@ -2604,11 +2612,11 @@ void LLPipeline::renderDebug()
 		// Debug composition layers
 		F32 x, y;
 
-		LLGLSNoTexture gls_no_texture;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		if (gAgent.getRegion())
 		{
-			gGL.begin(LLVertexBuffer::POINTS);
+			gGL.begin(LLRender::POINTS);
 			// Draw the composition layer for the region that I'm in.
 			for (x = 0; x <= 260; x++)
 			{
@@ -2654,6 +2662,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
 
 	LLGLSDefault gls_default;
 	LLGLSObjectSelect gls_object_select;
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLGLDepthTest gls_depth(GL_TRUE,GL_TRUE);
 	disableLights();
 	
@@ -3458,7 +3467,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			atten = x / (light_radius); // % of brightness at radius
 			quad = 0.0f;
 		}
-		//mHWLightColors[cur_light] = light_color;
+		mHWLightColors[2] = light_color;
 		S32 gllight = GL_LIGHT2;
 		glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
 		glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
@@ -3999,6 +4008,7 @@ BOOL LLPipeline::getRenderHighlights(void*)
 }
 
 LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+														BOOL pick_transparent,												
 														S32* face_hit,
 														LLVector3* intersection,         // return the intersection point
 														LLVector2* tex_coord,            // return the texture coordinates of the intersection point
@@ -4008,6 +4018,10 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
 {
 	LLDrawable* drawable = NULL;
 
+	LLVector3 local_end = end;
+
+	LLVector3 position;
+
 	for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
 	{
@@ -4015,24 +4029,49 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
 
 		for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
 		{
-			if ((j == LLViewerRegion::PARTITION_VOLUME) || (j == LLViewerRegion::PARTITION_BRIDGE))  // only check these partitions for now
+			if ((j == LLViewerRegion::PARTITION_VOLUME) || 
+				(j == LLViewerRegion::PARTITION_BRIDGE) || 
+				(j == LLViewerRegion::PARTITION_TERRAIN) ||
+				(j == LLViewerRegion::PARTITION_TREE) ||
+				(j == LLViewerRegion::PARTITION_GRASS))  // only check these partitions for now
 			{
 				LLSpatialPartition* part = region->getSpatialPartition(j);
-				if (part)
+				if (part && hasRenderType(part->mDrawableType))
 				{
-					LLDrawable* hit = part->lineSegmentIntersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal);
+					LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
 					if (hit)
 					{
 						drawable = hit;
+						local_end = position;						
 					}
 				}
 			}
 		}
 	}
+
+	//check all avatar nametags (silly, isn't it?)
+	for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin();
+		iter != LLCharacter::sInstances.end();
+		++iter)
+	{
+		LLVOAvatar* av = (LLVOAvatar*) *iter;
+		if (av->mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position))
+		{
+			drawable = av->mDrawable;
+			local_end = position;
+		}
+	}
+
+	if (intersection)
+	{
+		*intersection = position;
+	}
+
 	return drawable ? drawable->getVObj().get() : NULL;
 }
 
 LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+													  BOOL pick_transparent,													
 													  S32* face_hit,
 													  LLVector3* intersection,         // return the intersection point
 													  LLVector2* tex_coord,            // return the texture coordinates of the intersection point
@@ -4047,15 +4086,27 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
 	{
 		LLViewerRegion* region = *iter;
 
+		BOOL toggle = FALSE;
+		if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+		{
+			toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+			toggle = TRUE;
+		}
+
 		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
 		if (part)
 		{
-			LLDrawable* hit = part->lineSegmentIntersect(start, end, face_hit, intersection, tex_coord, normal, bi_normal);
+			LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
 			if (hit)
 			{
 				drawable = hit;
 			}
 		}
+
+		if (toggle)
+		{
+			toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+		}
 	}
 	return drawable ? drawable->getVObj().get() : NULL;
 }
@@ -4209,7 +4260,8 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam)
 
 	LLPipeline::sReflectionRender = TRUE;
 
-	cube_map->bind();
+	gGL.getTexUnit(cube_map->getStage())->bind(cube_map);
+	gGL.getTexUnit(0)->activate();
 	GLint width;
 	glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
 	if (width != res)
@@ -4221,8 +4273,10 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam)
 			glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); 
 		}
 	}
-	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
-	cube_map->disable();
+	gGL.getTexUnit(cube_map->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
+	gGL.getTexUnit(cube_map->getStage())->disable();
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 	BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
 	if (toggle_ui)
@@ -4266,7 +4320,7 @@ void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam)
 	gPipeline.calcNearbyLights(cube_cam);
 
 	stop_glerror();
-	LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
 	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
 										GL_RENDERBUFFER_EXT, mCubeDepth);		
@@ -4422,7 +4476,8 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
 	glPushMatrix();
 
 	cube_out->enableTexture(0);
-	cube_out->bind();
+	gGL.getTexUnit(cube_out->getStage())->bind(cube_out);
+	gGL.getTexUnit(0)->activate();
 	GLint width;
 	glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
 	if (width != res)
@@ -4434,8 +4489,8 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
 			glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); 
 		}
 	}
-	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
-
+	gGL.getTexUnit(cube_out->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
+	gGL.getTexUnit(0)->activate();
 	glViewport(0, 0, res, res);
 	LLGLEnable blend(GL_BLEND);
 	
@@ -4463,16 +4518,17 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
 
 		if (j == 0)
 		{
-			cube_in->bind();
+			gGL.getTexUnit(cube_in->getStage())->bind(cube_in);
 		}
 		else
 		{
-			glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j-1]);
+			gGL.getTexUnit(cube_in->getStage())->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j-1]);
 		}
+		gGL.getTexUnit(0)->activate();
 
 		stop_glerror();
 
-		LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]);
 		stop_glerror();
 
@@ -4501,7 +4557,7 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
 
 	stop_glerror();
 
-	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
+	gGL.getTexUnit(cube_in->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
 	
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 	gGL.setColorMask(true, false);
@@ -4510,7 +4566,8 @@ void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
 	glMatrixMode(GL_MODELVIEW);
 	glPopMatrix();
 
-	cube_in->disableTexture();
+	gGL.getTexUnit(cube_in->getStage())->disable();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 	gViewerWindow->setupViewport();
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
@@ -4578,7 +4635,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 
 	if (for_snapshot)
 	{
-		mGlow[1].bindTexture();
+		gGL.getTexUnit(0)->bind(&mGlow[1]);
 		{
 			//LLGLEnable stencil(GL_STENCIL_TEST);
 			//glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF);
@@ -4587,7 +4644,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 			LLGLEnable blend(GL_BLEND);
 			gGL.setSceneBlendType(LLRender::BT_ADD);
 			tc2.setVec(1,1);				
-			gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+			gGL.begin(LLRender::TRIANGLE_STRIP);
 			gGL.color4f(1,1,1,1);
 			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
 			gGL.vertex2f(-1,-1);
@@ -4637,15 +4694,15 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 		LLGLEnable test(GL_ALPHA_TEST);
 		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-		LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
 		
-		glDisable(GL_TEXTURE_2D);
-		glEnable(GL_TEXTURE_RECTANGLE_ARB);
-		mScreen.bindTexture();
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);		
+		gGL.getTexUnit(0)->disable();
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
+		gGL.getTexUnit(0)->bind(&mScreen);
 
 		gGL.color4f(1,1,1,1);
 		gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
-		gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+		gGL.begin(LLRender::TRIANGLE_STRIP);
 		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
 		gGL.vertex2f(-1,-1);
 		
@@ -4659,8 +4716,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 		gGL.vertex2f(1,1);
 		gGL.end();
 		
-		glEnable(GL_TEXTURE_2D);
-		glDisable(GL_TEXTURE_RECTANGLE_ARB);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 		mGlow[2].flush();
 	}
@@ -4690,7 +4746,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 
 	for (S32 i = 0; i < kernel; i++)
 	{
-		LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		{
 			LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
 			mGlow[i%2].bindTarget();
@@ -4699,11 +4755,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 			
 		if (i == 0)
 		{
-			mGlow[2].bindTexture();
+			gGL.getTexUnit(0)->bind(&mGlow[2]);
 		}
 		else
 		{
-			mGlow[(i-1)%2].bindTexture();
+			gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]);
 		}
 
 		if (i%2 == 0)
@@ -4715,7 +4771,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 			gGlowProgram.uniform2f("glowDelta", 0, delta);
 		}
 
-		gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
+		gGL.begin(LLRender::TRIANGLE_STRIP);
 		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
 		gGL.vertex2f(-1,-1);
 		
@@ -4780,8 +4836,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 		LLGLEnable blend(GL_BLEND);
 		gGL.blendFunc(GL_ONE, GL_ONE);
 
-		glDisable(GL_TEXTURE_2D);
-		glEnable(GL_TEXTURE_RECTANGLE_ARB);
+		gGL.getTexUnit(0)->disable();
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
 		mScreen.bindTexture();
 		
 		gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
@@ -4801,8 +4857,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 
 		gGL.flush();
 		
-		glEnable(GL_TEXTURE_2D);
-		glDisable(GL_TEXTURE_RECTANGLE_ARB);
+		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 
 		gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 	}*/
@@ -4847,12 +4902,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 
 		//tex unit 0
 		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
-		
-		mGlow[1].bindTexture();
+	
+		gGL.getTexUnit(0)->bind(&mGlow[1]);
 		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 		glTexCoordPointer(2, GL_FLOAT, 0, uv0);
 		gGL.getTexUnit(1)->activate();
-		glEnable(GL_TEXTURE_RECTANGLE_ARB);
+		gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE);
 		
 		//tex unit 1
 		gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
@@ -4863,14 +4918,16 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
 
 		glVertexPointer(2, GL_FLOAT, 0, v);
 		
-		mScreen.bindTexture();
+		gGL.getTexUnit(1)->bind(&mScreen);
+		gGL.getTexUnit(1)->activate();
 		
 		LLGLEnable multisample(GL_MULTISAMPLE_ARB);
 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 		
-		glDisable(GL_TEXTURE_RECTANGLE_ARB);
+		gGL.getTexUnit(1)->disable();
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
+
 		glClientActiveTextureARB(GL_TEXTURE0_ARB);
 		gGL.getTexUnit(0)->activate();
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -4948,7 +5005,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
 		if (!LLViewerCamera::getInstance()->cameraUnderWater())
 		{	//generate planar reflection map
-			LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			glClearColor(0,0,0,0);
 			gGL.setColorMask(true, true);
 			mWaterRef.bindTarget();
@@ -5053,7 +5110,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 			}
 			LLViewerCamera::updateFrustumPlanes(camera);
 
-			LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			LLColor4& col = LLDrawPoolWater::sWaterFogColor;
 			glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
 			gGL.setColorMask(true, true);
@@ -5230,10 +5287,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		resY != avatar->mImpostor.getHeight())
 	{
 		avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE);
-		avatar->mImpostor.bindTexture();
+		gGL.getTexUnit(0)->bind(&avatar->mImpostor);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	}
 
 	{
@@ -5270,13 +5327,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 		}
 		
 		gGL.setSceneBlendType(LLRender::BT_ADD);
-		LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 		LLGLDepthTest depth(GL_FALSE, GL_FALSE);
 
 		gGL.color4f(1,1,1,1);
 		gGL.color4ub(64,64,64,255);
-		gGL.begin(LLVertexBuffer::QUADS);
+		gGL.begin(LLRender::QUADS);
 		gGL.vertex3fv((pos+left-up).mV);
 		gGL.vertex3fv((pos-left-up).mV);
 		gGL.vertex3fv((pos-left+up).mV);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 4ba6f39456b..bacfed0aedf 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -131,6 +131,7 @@ class LLPipeline
 		
 	//get the object between start and end that's closest to start.
 	LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+												BOOL pick_transparent,
 												S32* face_hit,                          // return the face hit
 												LLVector3* intersection = NULL,         // return the intersection point
 												LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
@@ -138,6 +139,7 @@ class LLPipeline
 												LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point  
 		);
 	LLViewerObject* lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+											  BOOL pick_transparent,
 											  S32* face_hit,                          // return the face hit
 											  LLVector3* intersection = NULL,         // return the intersection point
 											  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 88fbfd4ba5b..feeb5287212 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -3,7 +3,7 @@
 	<text length="1" name="text_box" type="string">
 		Chat-Schriftgröße:
 	</text>
-	<radio_group name="chat font size">
+	<radio_group name="chat_font_size">
 		<radio_item length="1" name="radio" type="string">
 			Klein
 		</radio_item>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index ddd7f598caf..de044f11bda 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -4,7 +4,7 @@
 		Taille de la police 
 du chat :
 	</text>
-	<radio_group name="chat font size">
+	<radio_group name="chat_font_size">
 		<radio_item type="string" length="1" name="radio">
 			Petite
 		</radio_item>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index 1ad08fb553e..96a4bc3d990 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -3,7 +3,7 @@
 	<text length="1" name="text_box" type="string">
 		チャットのフォント:
 	</text>
-	<radio_group name="chat font size">
+	<radio_group name="chat_font_size">
 		<radio_item length="1" name="radio" type="string">
 			小
 		</radio_item>
-- 
GitLab