diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index df4c618ac10e187cad7aee71b970e880b970baae..cd7d7a12e3f109fcf11481097f654e6a3696c3af 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -4520,15 +4520,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]);
 		}
 	}
 		
@@ -4770,6 +4820,8 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
 					pt2--;
 				}
 			}
+
+			makeTriStrip();
 		}
 		else
 		{
@@ -4874,67 +4926,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);
@@ -5135,9 +5228,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
@@ -5147,6 +5245,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;
@@ -5187,6 +5293,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 @@ class LLVolumeFace
 
 	BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
 	void createBinormals();
-
+	void makeTriStrip();
+	
 	class VertexData
 	{
 	public:
@@ -839,6 +840,7 @@ class LLVolumeFace
 
 	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 8a447502b083f5bbc4392738030eaa1ccefbde8f..ce19dda9a54b1c5a55f66f3b36a2ad328851c7db 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7386,6 +7386,17 @@
       <key>Value</key>
       <integer>1</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 6d7736141494967cfee8e6aa2aab8f54e5aad250..0e02bc4b01c94a2f8b4e752002428745dacbf18f 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -250,8 +250,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);
 			}
 		}
 	}
@@ -380,8 +380,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 965ac1cad0b11cf40ca5833be8446d0ac57e6f8a..93840e077c67fa13f36dd76c6645b7a791e786c6 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -868,7 +868,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())
 	{
@@ -1058,9 +1058,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;
+			}
 		}
 	}
 	
@@ -1572,8 +1582,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 @@ class LLDrawInfo : public LLRefCount
 	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 827d34138fe666ff770d5ed91f0e0dd5ba25d003..0b7f6900ed8775828390ce5b7ff1f5494982a723 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 25ed931fb50afd3d456440e5da63d2de5b8d703a..b87ad7fc478128ac3758cd01ad4bfd0151bf2095 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1514,7 +1514,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());
+		}
 	}
 }
 
@@ -3264,6 +3271,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;
+		}
 	}
 }
 
@@ -3348,7 +3360,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 d5f87b73fe24fa3226a26764b6664547a34c888b..91da9e39e07f71abfde2e1a7e95d11ce758d1b1d 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");
 
@@ -3495,9 +3497,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);
@@ -5349,6 +5361,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 c5285943e8487b5ca86d3104ed94be8aa5948ede..1bf2ee941b49226168e6cffc53fb4d6439701c26 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -277,7 +277,7 @@ class LLPipeline
 	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 @@ class LLPipeline
 	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;