diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 192c6157a8f1ce67342bdfec554b6a101ccce5c2..cc1549925b3984fa26189570585b024b4ca3d1b9 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4521,15 +4521,65 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 
 	if (!partial_build)
 	{
-		int idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
-		for(int gx = 0;gx<grid_size;gx++){
-			for(int gy = 0;gy<grid_size;gy++){
-				if (mTypeMask & TOP_MASK){
-					for(int i=5;i>=0;i--)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
-				}else{
-					for(int i=0;i<6;i++)mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
+		mTriStrip.clear();
+		S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
+		for(S32 gx = 0;gx<grid_size;gx++)
+		{
+			
+			for(S32 gy = 0;gy<grid_size;gy++)
+			{
+				if (mTypeMask & TOP_MASK)
+				{
+					for(S32 i=5;i>=0;i--)
+					{
+						mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
+					}
+					
+					if (gy == 0)
+					{
+						mTriStrip.push_back((gx+1)*(grid_size+1));
+						mTriStrip.push_back((gx+1)*(grid_size+1));
+						mTriStrip.push_back(gx*(grid_size+1));
+					}
+
+					mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));
+					mTriStrip.push_back(gy+1+gx*(grid_size+1));
+					
+					
+					if (gy == grid_size-1)
+					{
+						mTriStrip.push_back(gy+1+gx*(grid_size+1));
+					}
+				}
+				else
+				{
+					for(S32 i=0;i<6;i++)
+					{
+						mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
+					}
+
+					if (gy == 0)
+					{
+						mTriStrip.push_back(gx*(grid_size+1));
+						mTriStrip.push_back(gx*(grid_size+1));
+						mTriStrip.push_back((gx+1)*(grid_size+1));
+					}
+
+					mTriStrip.push_back(gy+1+gx*(grid_size+1));
+					mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));
+					
+					if (gy == grid_size-1)
+					{
+						mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));
+					}
 				}
 			}
+			
+		}
+
+		if (mTriStrip.size()%2 == 1)
+		{
+			mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
 		}
 	}
 		
@@ -4771,6 +4821,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
 					pt2--;
 				}
 			}
+
+			makeTriStrip();
 		}
 		else
 		{
@@ -4875,67 +4927,108 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
 					pt2--;
 				}
 			}
+
+			makeTriStrip();
 		}
 	}
 	else
 	{
 		// Not hollow, generate the triangle fan.
+		U16 v1 = 2;
+		U16 v2 = 1;
+
 		if (mTypeMask & TOP_MASK)
 		{
-			if (mTypeMask & OPEN_MASK)
-			{
-				// SOLID OPEN TOP
-				// Generate indices
-				// This is a tri-fan, so we reuse the same first point for all triangles.
-				for (S32 i = 0; i < (num_vertices - 2); i++)
-				{
-					mIndices[3*i] = num_vertices - 1;
-					mIndices[3*i+1] = i;
-					mIndices[3*i+2] = i + 1;
-				}
-			}
-			else
-			{
-				// SOLID CLOSED TOP
-				for (S32 i = 0; i < (num_vertices - 2); i++)
-				{				
-					//MSMSM fix these caps but only for the un-cut case
-					mIndices[3*i] = num_vertices - 1;
-					mIndices[3*i+1] = i;
-					mIndices[3*i+2] = i + 1;
-				}
-			}
+			v1 = 1;
+			v2 = 2;
+		}
+
+		for (S32 i = 0; i < (num_vertices - 2); i++)
+		{
+			mIndices[3*i] = num_vertices - 1;
+			mIndices[3*i+v1] = i;
+			mIndices[3*i+v2] = i + 1;
+		}
+
+		//make tri strip
+		if (mTypeMask & OPEN_MASK)
+		{
+			makeTriStrip();
 		}
 		else
 		{
-			if (mTypeMask & OPEN_MASK)
+			S32 j = num_vertices-2;
+			if (mTypeMask & TOP_MASK)
 			{
-				// SOLID OPEN BOTTOM
-				// Generate indices
-				// This is a tri-fan, so we reuse the same first point for all triangles.
-				for (S32 i = 0; i < (num_vertices - 2); i++)
+				mTriStrip.push_back(0);
+				for (S32 i = 1; i <= j; ++i)
 				{
-					mIndices[3*i] = num_vertices - 1;
-					mIndices[3*i+1] = i + 1;
-					mIndices[3*i+2] = i;
+					mTriStrip.push_back(i);
+					if (i != j)
+					{
+						mTriStrip.push_back(j);
+					}
+					--j;
 				}
 			}
 			else
 			{
-				// SOLID CLOSED BOTTOM
-				for (S32 i = 0; i < (num_vertices - 2); i++)
+				mTriStrip.push_back(j);
+				for (S32 i = 1; i <= j; ++i)
 				{
-					//MSMSM fix these caps but only for the un-cut case
-					mIndices[3*i] = num_vertices - 1;
-					mIndices[3*i+1] = i + 1;
-					mIndices[3*i+2] = i;
+					if (i != j)
+					{
+						mTriStrip.push_back(j);
+					}
+					mTriStrip.push_back(i);
+					--j;
 				}
 			}
+			
+			mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
+
+			if (mTriStrip.size()%2 == 1)
+			{
+				mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
+			}
 		}
 	}
+		
 	return TRUE;
 }
 
+void LLVolumeFace::makeTriStrip()
+{
+	for (U32 i = 0; i < mIndices.size(); i+=3)
+	{
+		U16 i0 = mIndices[i];
+		U16 i1 = mIndices[i+1];
+		U16 i2 = mIndices[i+2];
+
+		if ((i/3)%2 == 1)
+		{
+			mTriStrip.push_back(i0);
+			mTriStrip.push_back(i0);
+			mTriStrip.push_back(i1);
+			mTriStrip.push_back(i2);
+			mTriStrip.push_back(i2);
+		}
+		else
+		{
+			mTriStrip.push_back(i2);
+			mTriStrip.push_back(i2);
+			mTriStrip.push_back(i1);
+			mTriStrip.push_back(i0);
+			mTriStrip.push_back(i0);
+		}
+	}
+
+	if (mTriStrip.size()%2 == 1)
+	{
+		mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
+	}
+}
+
 void LLVolumeFace::createBinormals()
 {
 	LLMemType m1(LLMemType::MTYPE_VOLUME);
@@ -5136,9 +5229,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 
 	if (!partial_build)
 	{
+		mTriStrip.clear();
+
 		// Now we generate the indices.
 		for (t = 0; t < (mNumT-1); t++)
 		{
+			//prepend terminating index to strip
+			mTriStrip.push_back(mNumS*t);
+
 			for (s = 0; s < (mNumS-1); s++)
 			{	
 				mIndices[cur_index++] = s   + mNumS*t;			//bottom left
@@ -5148,6 +5246,14 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 				mIndices[cur_index++] = s+1 + mNumS*t;			//bottom right
 				mIndices[cur_index++] = s+1 + mNumS*(t+1);		//top right
 
+				if (s == 0)
+				{
+					mTriStrip.push_back(s+mNumS*t);
+					mTriStrip.push_back(s+mNumS*(t+1));
+				}
+				mTriStrip.push_back(s+1+mNumS*t);
+				mTriStrip.push_back(s+1+mNumS*(t+1));
+				
 				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1;						//bottom left/top right neighbor face 
 				if (t < mNumT-2) {												//top right/top left neighbor face 
 					mEdge[cur_edge++] = (mNumS-1)*2*(t+1)+s*2+1;
@@ -5188,6 +5294,13 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 				}
 				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2;							//top right/bottom left neighbor face	
 			}
+			//append terminating vertex to strip
+			mTriStrip.push_back(mNumS-1+mNumS*(t+1));
+		}
+
+		if (mTriStrip.size()%2 == 1)
+		{
+			mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
 		}
 	}
 
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 871b334452180ca76160900b6961b015eb4874dd..d9f80f0e30e5d099294b0862aa187d94409e1446 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -798,7 +798,8 @@ public:
 
 	BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
 	void createBinormals();
-
+	void makeTriStrip();
+	
 	class VertexData
 	{
 	public:
@@ -839,6 +840,7 @@ public:
 
 	std::vector<VertexData> mVertices;
 	std::vector<U16>	mIndices;
+	std::vector<U16>	mTriStrip;
 	std::vector<S32>	mEdge;
 
 private:
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 73c08c4867579395d77309823554192a734af6ef..7e4ab1a8723ba5a190b1914617163db072f66626 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7443,6 +7443,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+  <key>RenderUseTriStrips</key>
+  <map>
+    <key>Comment</key>
+    <string>Use triangle strips for rendering prims.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
     <key>RenderUseFarClip</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 95ddacb722a5e0d39e3b1d6f0a8bb6416886c809..ef946ac49e5cfe99ff3fc99ddf682a20e3ce4433 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -496,8 +496,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
 			params.mGroup->rebuildMesh();
 		}
 		params.mVertexBuffer->setBuffer(mask);
-		params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-		gPipeline.addTrianglesDrawn(params.mCount/3);
+		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 	}
 
 	if (params.mTextureMatrix && texture && params.mTexture.notNull())
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 7be6e82251717b97f76ac671609d28e5dba20fc6..875c9ac6a9d597ca84c3e78891bbe43df646a6ea 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -251,8 +251,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
 					params.mGroup->rebuildMesh();
 				}
 				params.mVertexBuffer->setBuffer(mask);
-				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-				gPipeline.addTrianglesDrawn(params.mCount/3);
+				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 			}
 		}
 	}
@@ -381,8 +381,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
 				}
 
 				params.mVertexBuffer->setBuffer(mask);
-				params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-				gPipeline.addTrianglesDrawn(params.mCount/3);
+				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 
 				if (params.mTextureMatrix && params.mTexture.notNull())
 				{
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 03a8b108e299077e3e29961a2ca4d9c0087ab4d7..d09d4a412fa13e0924268f4a38bdcf2d8679f429 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -560,8 +560,8 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
 			params.mGroup->rebuildMesh();
 		}
 		params.mVertexBuffer->setBuffer(mask);
-		params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-		gPipeline.addTrianglesDrawn(params.mCount/3);
+		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 	}
 }
 
@@ -1231,8 +1231,8 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
 		params.mGroup->rebuildMesh();
 	}
 	params.mVertexBuffer->setBuffer(mask);
-	params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-	gPipeline.addTrianglesDrawn(params.mCount/3);
+	params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+	gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
 	if (params.mTextureMatrix)
 	{
 		if (mShiny)
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 5521fb05a82fcf7b87ae500afca251e2b7105bb7..1a5d55d793b1f7011e140e903dc04bd484443bd3 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -115,7 +115,7 @@ void LLDrawPoolTree::render(S32 pass)
 			LLFace *face = *iter;
 			face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
 			face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); 
-			gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3);
+			gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices());
 		}
 	}
 }
@@ -237,7 +237,7 @@ void LLDrawPoolTree::renderForSelect()
 				
 				face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
 				face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); 
-				gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3);
+				gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices());
 			}
 		}
 	}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 80acc71a41edb14f0396cae7ef165882aa3fed97..ebebd485d24f3d0da467d25385b993ab2f588397 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -870,7 +870,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	llpushcallstacks ;
 	const LLVolumeFace &vf = volume.getVolumeFace(f);
 	S32 num_vertices = (S32)vf.mVertices.size();
-	S32 num_indices = (S32)vf.mIndices.size();
+	S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size();
 	
 	if (mVertexBuffer.notNull())
 	{
@@ -1063,9 +1063,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
 	if (full_rebuild)
 	{
 		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex);
-		for (U16 i = 0; i < num_indices; i++)
+		if (LLPipeline::sUseTriStrips)
 		{
-			*indicesp++ = vf.mIndices[i] + index_offset;
+			for (U16 i = 0; i < num_indices; i++)
+			{
+				*indicesp++ = vf.mTriStrip[i] + index_offset;
+			}
+		}
+		else
+		{
+			for (U16 i = 0; i < num_indices; i++)
+			{
+				*indicesp++ = vf.mIndices[i] + index_offset;
+			}
 		}
 	}
 	
@@ -1617,8 +1627,13 @@ S32 LLFace::pushVertices(const U16* index_array) const
 {
 	if (mIndicesCount)
 	{
-		mVertexBuffer->drawRange(LLRender::TRIANGLES, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
-		gPipeline.addTrianglesDrawn(mIndicesCount/3);
+		U32 render_type = LLRender::TRIANGLES;
+		if (mDrawInfo)
+		{
+			render_type = mDrawInfo->mDrawMode;
+		}
+		mVertexBuffer->drawRange(render_type, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
+		gPipeline.addTrianglesDrawn(mIndicesCount, render_type);
 	}
 
 	return mIndicesCount;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 2a57d48f16bd45e722d0b0b9fc6d7fa6b55cf46a..d6e9256feea2af8ad1461e46505e914117135fb2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3380,7 +3380,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
 	mVSize(0.f),
 	mGroup(NULL),
 	mFace(NULL),
-	mDistance(0.f)
+	mDistance(0.f),
+	mDrawMode(LLRender::TRIANGLES)
 {
 	mDebugColor = (rand() << 16) + rand();
 	if (mStart >= mVertexBuffer->getRequestedVerts() ||
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 64c2a9acbc7d94d7da76ad693d94b5e7217a1803..7896488379e0d80dc8aa7f1b808032648117787f 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -93,6 +93,7 @@ public:
 	LLFace* mFace; //associated face
 	F32 mDistance;
 	LLVector3 mExtents[2];
+	U32 mDrawMode;
 
 	struct CompareTexture
 	{
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 64eabe65cfebefa2889aa58731d2aa4ab1e9d6db..5daea96123f383e678b673d805f9978d2b53c944 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -510,6 +510,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
 	gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
 	gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
+	gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 1a67fc09664de606e6ce747f514df615b49274d1..7225aa15238fc5c3cec5a12328fb65c35a435460 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -626,7 +626,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 		mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
 		glPopMatrix();
 	}
-	gPipeline.addTrianglesDrawn(count/3);
+	gPipeline.addTrianglesDrawn(count);
 
 	triangle_count += count;
 	
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 24f1c4bd246717d25b0840422439fcf7daf8a56e..55e2c58a520fb86b215dd5d2a0fbfc8255c72709 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -1141,7 +1141,7 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 
 				glLoadMatrixf((F32*) scale_mat.mMatrix);
  				glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_LOD], GL_UNSIGNED_SHORT, indicesp + sLODIndexOffset[trunk_LOD]);
-				gPipeline.addTrianglesDrawn(LEAF_INDICES/3);
+				gPipeline.addTrianglesDrawn(LEAF_INDICES);
 				stop_glerror();
 				ret += sLODIndexCount[trunk_LOD];
 			}
@@ -1191,7 +1191,7 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 			
 				glLoadMatrixf((F32*) scale_mat.mMatrix);
 				glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
-				gPipeline.addTrianglesDrawn(LEAF_INDICES/3);							
+				gPipeline.addTrianglesDrawn(LEAF_INDICES);							
 				stop_glerror();
 				ret += LEAF_INDICES;
 			}
@@ -1216,7 +1216,7 @@ U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp, S32 trunk_LOD
 					
 		glLoadMatrixf((F32*) scale_mat.mMatrix);
 		glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT, indicesp);
-		gPipeline.addTrianglesDrawn(LEAF_INDICES/3);
+		gPipeline.addTrianglesDrawn(LEAF_INDICES);
 		stop_glerror();
 		ret += LEAF_INDICES;
 
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index fbb44c8e76515a8889604338f379c89e5e3b640b..f1b27fb4df5f4f60e5582ae1daa5ba05df99a8ca 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1515,7 +1515,14 @@ void LLVOVolume::updateFaceSize(S32 idx)
 	else
 	{
 		const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
-		facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
+		if (LLPipeline::sUseTriStrips)
+		{
+			facep->setSize(vol_face.mVertices.size(), vol_face.mTriStrip.size());
+		}
+		else
+		{
+			facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
+		}
 	}
 }
 
@@ -3265,6 +3272,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_info->mExtents[0] = facep->mExtents[0];
 		draw_info->mExtents[1] = facep->mExtents[1];
 		validate_draw_info(*draw_info);
+
+		if (LLPipeline::sUseTriStrips)
+		{
+			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;
+		}
 	}
 }
 
@@ -3349,7 +3361,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 			drawablep->updateFaceSize(i);
 			LLFace* facep = drawablep->getFace(i);
 
-			if (cur_total > max_total)
+			if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
 			{
 				facep->mVertexBuffer = NULL;
 				facep->mLastVertexBuffer = NULL;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 0272a2ab342186523c0846759b57cc0feabbca15..1749ccef94b18918683c6382f54105f44951d9e6 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -519,7 +519,7 @@ void LLVOWLSky::drawDome(void)
 			LLRender::TRIANGLE_STRIP, 
 			0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(), 
 			0);
-		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices() - 2);
+		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices(), LLRender::TRIANGLE_STRIP);
 	}
 
 #else
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e2179fb25777e1669feaa513830864c8a91c80fb..259ca21e93766b8e5264a14c711e06ffa539c0c4 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -270,6 +270,7 @@ BOOL	LLPipeline::sDelayVBUpdate = TRUE;
 BOOL	LLPipeline::sFastAlpha = TRUE;
 BOOL	LLPipeline::sDisableShaders = FALSE;
 BOOL	LLPipeline::sRenderBump = TRUE;
+BOOL	LLPipeline::sUseTriStrips = TRUE;
 BOOL	LLPipeline::sUseFarClip = TRUE;
 BOOL	LLPipeline::sShadowRender = FALSE;
 BOOL	LLPipeline::sWaterReflections = FALSE;
@@ -358,6 +359,7 @@ void LLPipeline::init()
 
 	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
 	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
 
@@ -3490,9 +3492,19 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
 }
 
 
-void LLPipeline::addTrianglesDrawn(S32 count)
+void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
 {
 	assertInitialized();
+	S32 count = 0;
+	if (render_type == LLRender::TRIANGLE_STRIP)
+	{
+		count = index_count-2;
+	}
+	else
+	{
+		count = index_count/3;
+	}
+
 	mTrianglesDrawn += count;
 	mBatchCount++;
 	mMaxBatchSize = llmax(mMaxBatchSize, count);
@@ -5344,6 +5356,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
 void LLPipeline::resetVertexBuffers()
 {
 	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
 
 	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
 			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 46231048e81f8b0b17677712a0636c2cb3f9922f..6aecc23aac7ad9cfc5902c14e6a9693f5eed3e12 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -277,7 +277,7 @@ public:
 	LLCullResult::sg_list_t::iterator beginAlphaGroups();
 	LLCullResult::sg_list_t::iterator endAlphaGroups();
 	
-	void addTrianglesDrawn(S32 count);
+	void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
 	BOOL hasRenderType(const U32 type) const				{ return (type && (mRenderTypeMask & (1<<type))) ? TRUE : FALSE; }
 	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
 	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; }
@@ -447,7 +447,7 @@ public:
 	static BOOL				sFastAlpha;
 	static BOOL				sDisableShaders; // if TRUE, rendering will be done without shaders
 	static BOOL				sRenderBump;
-	static BOOL				sUseFBO;
+	static BOOL				sUseTriStrips;
 	static BOOL				sUseFarClip;
 	static BOOL				sShadowRender;
 	static BOOL				sWaterReflections;