diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c01c15391de812273bea8f96c7ebcd03f19dbaa1..babaa65c353e8320173ce2b82a7c84545a872455 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -280,6 +280,7 @@ PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
 PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
 PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
 PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
+PFNGLISSHADERPROC glIsShader = NULL;
 PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
 PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL;
 PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL;
@@ -1314,6 +1315,7 @@ void LLGLManager::initExtensions()
 		glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
 		glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
 		glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
+        glIsShader = (PFNGLISSHADERPROC) GLH_EXT_GET_PROC_ADDRESS("glIsShader");
 		glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
 		glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
 		glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 722dd9050bc1819fb31c72382226805e04f5593b..258d2270386a14d734e7a29c0cac0c5701080428 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -129,6 +129,7 @@ extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
 extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
 extern PFNGLGETHANDLEARBPROC glGetHandleARB;
 extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
+extern PFNGLISSHADERPROC glIsShader;
 extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
 extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
 extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
@@ -397,6 +398,7 @@ extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
 extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
 extern PFNGLGETHANDLEARBPROC glGetHandleARB;
 extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
+extern PFNGLISSHADERPROC glIsShader;
 extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
 extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
 extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
@@ -644,6 +646,7 @@ extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
 extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
 extern PFNGLGETHANDLEARBPROC glGetHandleARB;
 extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
+extern PFNGLISSHADERPROC glIsShader;
 extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
 extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
 extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 902c08b6ba8b98face63f48601caba7e162ff2fb..782304ae418e58bd18408d49b137f1939dbc1f4a 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -344,13 +344,17 @@ void LLGLSLShader::unloadInternal()
     {
         GLhandleARB obj[1024];
         GLsizei count;
+        glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
 
-        glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj);
         for (GLsizei i = 0; i < count; i++)
         {
-            glDetachObjectARB(mProgramObject, obj[i]);
+            // avoid opengl errors when multiple programs link a common shader obj
+            if (glIsShader(obj[i]))
+            {
+                glDetachObjectARB(mProgramObject, obj[i]);
                 glDeleteObjectARB(obj[i]);
             }
+        }
 
         glDeleteObjectARB(mProgramObject);
 
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index b110a6a810b873d45c1217b180a4b9033bcde735..2aee7b450acc116ecc355a6480cff6cedcde43ff 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -408,7 +408,7 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
 
 void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures)
 {
-	pushBatches(type, mask, batch_textures);
+	pushBatches(type, mask, true, batch_textures);
 }
 
 void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index d651d540b9cd89c7fa601303ca4785512ef681c2..f4a5d60f7c2e52dde7be5e960a11ef16993bf720 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -289,23 +289,6 @@ void LLVOGrass::idleUpdate(LLAgent &agent, const F64 &time)
 		return;
 	}
 
-	if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass
-	{
-		if(mNumBlades)
-		{
-			mNumBlades = 0 ;
-			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
-		}
-		return;
-	}
-	else if(!mNumBlades)//restart grass rendering
-	{
-		mNumBlades = GRASS_MAX_BLADES ;
-		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
-		
-		return;
-	}
-
 	if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
 	{
 		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
@@ -352,11 +335,15 @@ BOOL LLVOGrass::updateLOD()
 	{
 		return FALSE;
 	}
+
+    LLFace* face = mDrawable->getFace(0);
+
 	if(LLVOTree::isTreeRenderingStopped())
 	{
 		if(mNumBlades)
 		{
 			mNumBlades = 0 ;
+            face->setSize(0, 0);
 			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
 		}
 		return TRUE ;
@@ -366,8 +353,6 @@ BOOL LLVOGrass::updateLOD()
 		mNumBlades = GRASS_MAX_BLADES;
 	}
 
-	LLFace* face = mDrawable->getFace(0);
-
 	F32 tan_angle = 0.f;
 	S32 num_blades = 0;