diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 331f988382a3476edb77981d890c20dbb97b1279..07a0d8c402d0906338d9ee87dfc23974211dae83 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -51,6 +51,7 @@ set(llrender_SOURCE_FILES
     lltexture.cpp
     lluiimage.cpp
     llvertexbuffer.cpp
+    llglcommonfunc.cpp
     )
     
 set(llrender_HEADER_FILES
@@ -78,6 +79,7 @@ set(llrender_HEADER_FILES
     lltexture.h
     lluiimage.h
     llvertexbuffer.h
+    llglcommonfunc.h
     )
 
 set_source_files_properties(${llrender_HEADER_FILES}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index aa98b3f6bc635992f59132175486c58b59506bec..4c4302d05ba3e101c2cc6081ebe69b6fc428648a 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -256,6 +256,9 @@ void clear_glerror();
 	if the existing GL state does not match the expected GL state.
 
 */
+
+#include "boost/function.hpp"
+
 class LLGLState
 {
 public:
@@ -297,6 +300,20 @@ class LLGLEnableAlphaReject : public LLGLState
 	LLGLEnableAlphaReject(bool enable);
 };
 
+// Enable with functor
+class LLGLEnableFunc : LLGLState
+{
+public:
+	LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
+		: LLGLState(state, enable)
+	{
+		if (enable)
+		{
+			func();
+		}
+	}
+};
+
 /// TODO: Being deprecated.
 class LLGLEnable : public LLGLState
 {
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9ec28927fad6dc3ffed63df355c940f5b23d8cc
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -0,0 +1,37 @@
+/**
+* @file llglcommonfunc.cpp
+* @brief Implementation of the LLGLCommonFunc.
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llglheaders.h"
+#include "llglcommonfunc.h"
+
+namespace LLGLCommonFunc 
+{
+	void selected_stencil_test()
+	{
+		glStencilFunc(GL_ALWAYS, 2, 0xffff);
+		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+	}
+}
diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h
new file mode 100644
index 0000000000000000000000000000000000000000..f1f8ff7bc40300c9ec33f3d106bdb2a98dc96ac1
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.h
@@ -0,0 +1,30 @@
+/**
+* @file llphoenixfunc.h
+* @brief File include common opengl code snippets
+*
+* $LicenseInfo:firstyear=2003&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+namespace LLGLCommonFunc
+{
+	void selected_stencil_test();
+}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index f74164aea6b234e5cf1ea0f50210bcec8b5789b1..075375082d0e587cb7571fb63c00c199ce853f93 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -49,6 +49,7 @@
 #include "llviewercamera.h"
 #include "lldrawpoolwlsky.h"
 #include "llglslshader.h"
+#include "llglcommonfunc.h"
 
 S32 LLDrawPool::sNumDrawPools = 0;
 
@@ -504,7 +505,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
 		{
 			params.mGroup->rebuildMesh();
 		}
-		
+
+		LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+	
 		params.mVertexBuffer->setBuffer(mask);
 		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
 		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 60056ac21dd4dc9dacf4e7bffb008122fd724388..32630237cebb73e5285c487d76368f52a3b309bf 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -47,6 +47,7 @@
 #include "llviewerregion.h"
 #include "lldrawpoolwater.h"
 #include "llspatialpartition.h"
+#include "llglcommonfunc.h"
 
 BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
 
@@ -583,11 +584,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 
 				{
 					LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
-    gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);					
-				params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
-                
-				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
-				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+
+					LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
+					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+					params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+
+					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 				}
 				
 				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
@@ -597,7 +601,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
 				{
 					// install glow-accumulating blend mode
 					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
-						      LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+					LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
 
 					emissive_shader->bind();
 					
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index f92320490ab62a2c85d34b6421f6a12de1380a98..63e96a93b53e530d5a5fec93b6a767a2b3938d2f 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -30,6 +30,7 @@
 #include "lldrawpoolmaterials.h"
 #include "llviewershadermgr.h"
 #include "pipeline.h"
+#include "llglcommonfunc.h"
 
 S32 diffuse_channel = -1;
 
@@ -211,6 +212,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
 	{
 		params.mGroup->rebuildMesh();
 	}
+
+	LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
 	params.mVertexBuffer->setBuffer(mask);
 	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
 	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index c2190b7756b880f8f3b11bf87121d180a07ea247..92a09357c8fa5adc77405f2118df0aceb10915db 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1060,6 +1060,7 @@ void LLManipTranslate::render()
 		renderGuidelines();
 	}
 	{
+		LLGLDisable gls_stencil(GL_STENCIL_TEST);
 		renderTranslationHandles();
 		renderSnapGuides();
 	}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c44aca6fa500ad3c0b9031fd9cff1169a7f816c6..4bf2aa2d0be3a0ee2293e86fde481937f79905e1 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6271,92 +6271,101 @@ void pushWireframe(LLDrawable* drawable)
 
 void LLSelectNode::renderOneWireframe(const LLColor4& color)
 {
-	//Need to because crash on ATI 3800 (and similar cards) MAINT-5018 
-	LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+    //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 
+    LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
 
-	LLViewerObject* objectp = getObject();
-	if (!objectp)
-	{
-		return;
-	}
+    LLViewerObject* objectp = getObject();
+    if (!objectp)
+    {
+        return;
+    }
 
-	LLDrawable* drawable = objectp->mDrawable;
-	if(!drawable)
-	{
-		return;
-	}
+    LLDrawable* drawable = objectp->mDrawable;
+    if (!drawable)
+    {
+        return;
+    }
 
-	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+    LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
 
-	if (shader)
-	{
-		gDebugProgram.bind();
-	}
+    if (shader)
+    {
+        gDebugProgram.bind();
+    }
 
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	
-	BOOL is_hud_object = objectp->isHUDAttachment();
+    gGL.matrixMode(LLRender::MM_MODELVIEW);
+    gGL.pushMatrix();
 
-	if (drawable->isActive())
-	{
-		gGL.loadMatrix(gGLModelView);
-		gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
-	}
-	else if (!is_hud_object)
-	{
-		gGL.loadIdentity();
-		gGL.multMatrix(gGLModelView);
-		LLVector3 trans = objectp->getRegion()->getOriginAgent();		
-		gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);		
-	}
-	
-	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-	
-	if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
-	{
-		gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
-		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
-		if (shader)
-		{
-			gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
-			pushWireframe(drawable);
-		}
-		else
-		{
-			LLGLEnable fog(GL_FOG);
-			glFogi(GL_FOG_MODE, GL_LINEAR);
-			float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
-			LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
-			glFogf(GL_FOG_START, d);
-			glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
-			glFogfv(GL_FOG_COLOR, fogCol.mV);
+    BOOL is_hud_object = objectp->isHUDAttachment();
 
-			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
-			{
-				gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
-				pushWireframe(drawable);
-			}
-		}
-	}
+    if (drawable->isActive())
+    {
+        gGL.loadMatrix(gGLModelView);
+        gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
+    }
+    else if (!is_hud_object)
+    {
+        gGL.loadIdentity();
+        gGL.multMatrix(gGLModelView);
+        LLVector3 trans = objectp->getRegion()->getOriginAgent();
+        gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+    }
 
-	gGL.flush();
-	gGL.setSceneBlendType(LLRender::BT_ALPHA);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-	gGL.diffuseColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
-	
-	LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
-	glPolygonOffset(3.f, 3.f);
-	glLineWidth(3.f);
-	pushWireframe(drawable);
-	glLineWidth(1.f);
-	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-	gGL.popMatrix();
+    if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
+    {
+        gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+        LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+        if (shader)
+        {
+            gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+            pushWireframe(drawable);
+        }
+        else
+        {
+            LLGLEnable fog(GL_FOG);
+            glFogi(GL_FOG_MODE, GL_LINEAR);
+            float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
+            LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
+            glFogf(GL_FOG_START, d);
+            glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+            glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+            gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+            {
+                gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+                pushWireframe(drawable);
+            }
+        }
+    }
 
-	if (shader)
-	{
-		shader->bind();
-	}
+    gGL.flush();
+    gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+    gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2);
+
+    {
+        LLGLDisable depth(GL_BLEND);
+        LLGLEnable stencil(GL_STENCIL_TEST);
+        glStencilFunc(GL_NOTEQUAL, 2, 0xffff);
+        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+        LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+        glPolygonOffset(3.f, 3.f);
+        glLineWidth(5.f);
+        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+        pushWireframe(drawable);
+    }
+
+    glLineWidth(1.f);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    gGL.popMatrix();
+
+    if (shader)
+    {
+        shader->bind();
+    }
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d2a87ee2afa53c1033b8296b5989c8021e389632..9791f4a9213b3e6a9e7f02438dab63099e433201 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3941,6 +3941,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
 
 LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, 
 					   LLViewerTexture* texture, LLVertexBuffer* buffer,
+					   bool selected,
 					   BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
 :	LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"),
 	mVertexBuffer(buffer),
@@ -3968,7 +3969,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
 	mHasGlow(FALSE),
 	mEnvIntensity(0.0f),
 	mAlphaMaskCutoff(0.5f),
-	mDiffuseAlphaMode(0)
+	mDiffuseAlphaMode(0),
+	mSelected(selected)
 {
 	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
 	
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index f7bcce6daf8830ccfd45c79bf766509e7a8a52fa..6104b92d43d7ee80197ab22c29300e6a8fd429e4 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -75,6 +75,7 @@ class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLD
 
 	LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, 
 				LLViewerTexture* image, LLVertexBuffer* buffer, 
+				bool selected,
 				BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
 	
 
@@ -117,6 +118,7 @@ class LLDrawInfo : public LLRefCount, public LLTrace::MemTrackableNonVirtual<LLD
 	F32  mEnvIntensity;
 	F32  mAlphaMaskCutoff;
 	U8   mDiffuseAlphaMode;
+	bool mSelected;
 
 
 	struct CompareTexture
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 96ef160c7262cbc06d8214bf0343569560df13a1..86a9e7e2ad848bea176db901e34a483167aa33f4 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1005,7 +1005,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 															  gPipeline.mDeferredScreen.getHeight(), 0, 0, 
 															  gPipeline.mDeferredScreen.getWidth(), 
 															  gPipeline.mDeferredScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
 				}
 			}
 			else
@@ -1017,7 +1017,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 															  gPipeline.mScreen.getHeight(), 0, 0, 
 															  gPipeline.mScreen.getWidth(), 
 															  gPipeline.mScreen.getHeight(), 
-															  GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
 				}
 			}
 		}
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index de63a3963cdcd78b905e0af861137af1c5f69a47..b5c90a8f604224203ead03ba03da1417ebc651a5 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -741,7 +741,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
 			U32 count = facep->getIndicesCount();
 			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), 
 				//facep->getTexture(),
-				buffer, fullbright); 
+				buffer, object->isSelected(), fullbright);
 
 			const LLVector4a* exts = group->getObjectExtents();
 			info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index f7b21338f8a37e350c8e7fd171674f2449504ef2..f006ad2867ce5bb9aac157cc36f2e793f4d2111c 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -964,7 +964,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
 			U32 count = facep->getIndicesCount();
 			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), 
 				//facep->getTexture(),
-				buffer, fullbright); 
+				buffer, object->isSelected(), fullbright);
 
 			const LLVector4a* exts = group->getObjectExtents();
 			info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 1ef3d85eb311576187f892bb07a162314e21bc2e..ad4466073a61befe1f1c5efba1b796f716d985cd 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4415,7 +4415,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
 	}
 
-	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
+	bool selected = facep->getViewerObject()->isSelected();
+
+	if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)
 	{
 		return;
 	}
@@ -4512,7 +4514,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 			batchable = true;
 		}
 	}
-	
+
 	if (idx >= 0 && 
 		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&
 		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -4528,7 +4530,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
 		draw_vec[idx]->mTextureMatrix == tex_mat &&
 		draw_vec[idx]->mModelMatrix == model_mat &&
-		draw_vec[idx]->mShaderMask == shader_mask)
+		draw_vec[idx]->mShaderMask == shader_mask &&
+		draw_vec[idx]->mSelected == selected)
 	{
 		draw_vec[idx]->mCount += facep->getIndicesCount();
 		draw_vec[idx]->mEnd += facep->getGeomCount();
@@ -4550,7 +4553,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		U32 offset = facep->getIndicesStart();
 		U32 count = facep->getIndicesCount();
 		LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, 
-			facep->getVertexBuffer(), fullbright, bump); 
+			facep->getVertexBuffer(), selected, fullbright, bump);
 		draw_info->mGroup = group;
 		draw_info->mVSize = facep->getVirtualSize();
 		draw_vec.push_back(draw_info);
@@ -4577,26 +4580,25 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 
 		if (mat)
 		{
-				draw_info->mMaterialID = mat_id;
+			draw_info->mMaterialID = mat_id;
 
-				// We have a material.  Update our draw info accordingly.
+			// We have a material.  Update our draw info accordingly.
 				
-				if (!mat->getSpecularID().isNull())
-				{
-					LLVector4 specColor;
-					specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
-					specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
-					specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
-					specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
-					draw_info->mSpecColor = specColor;
-					draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
-					draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
-				}
+			if (!mat->getSpecularID().isNull())
+			{
+				LLVector4 specColor;
+				specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+				specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+				specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+				specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+				draw_info->mSpecColor = specColor;
+				draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+				draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+			}
 
-				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
-				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
-				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
-				
+			draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+			draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
 		}
 		else 
 		{
@@ -6050,7 +6052,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 					}
 					else
 					{
-					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
 					}
 					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
 					{ //if this is the deferred render and a bump map is present, register in post deferred bump
@@ -6072,8 +6074,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 						}
 						else
 						{
-						registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
-					}
+							registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+						}
 				}
 				}
 				
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 205585b34e033e59944d789e70473c0403451d68..5a8e6ced6c97f2e21ded38bf9ddd72534d90ae47 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2656,7 +2656,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
 	{
 		scratch_space->copyContents(source, 
 									0, 0, source.getWidth(), source.getHeight(), 
-									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
 	}
 
 	dest.bindTarget();
@@ -4584,12 +4584,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
 
 	LLGLEnable cull(GL_CULL_FACE);
 
-	LLGLEnable stencil(GL_STENCIL_TEST);
-	glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
-	stop_glerror();
-	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-	stop_glerror();
-
 	for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
 	{
 		LLDrawPool *poolp = *iter;
@@ -8145,7 +8139,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
 	if (LLRenderTarget::sUseFBO)
 	{ //copy depth buffer from mScreen to framebuffer
 		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 
-			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
 	}
 	
 
@@ -9026,7 +9020,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
 		{
 			LLGLDepthTest depth(GL_TRUE);
 			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
-							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	
+							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);	
 		}
 
 		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);