From f13884e528c327dbbc638b72322e08b544d0f6c0 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 15 Feb 2011 14:12:58 -0700
Subject: partial fix for SH-895/STORM-336: memory leaking. fixed vertex buffer
 caused leaking.

---
 indra/llrender/llvertexbuffer.cpp       | 101 ++++++++++++++++++++++++++++++--
 indra/llrender/llvertexbuffer.h         |  15 +++--
 indra/newview/app_settings/settings.xml |  11 ++++
 indra/newview/llviewercontrol.cpp       |  10 ++++
 indra/newview/llviewerwindow.cpp        |   2 +-
 indra/newview/pipeline.cpp              |  20 ++++++-
 indra/newview/pipeline.h                |   1 +
 7 files changed, 148 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 02160b09c4..660dc14d02 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -47,6 +47,7 @@ U32 LLVertexBuffer::sSetCount = 0;
 S32 LLVertexBuffer::sCount = 0;
 S32 LLVertexBuffer::sGLCount = 0;
 S32 LLVertexBuffer::sMappedCount = 0;
+BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
 BOOL LLVertexBuffer::sEnableVBOs = TRUE;
 U32 LLVertexBuffer::sGLRenderBuffer = 0;
 U32 LLVertexBuffer::sGLRenderIndices = 0;
@@ -212,6 +213,11 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 {
 	llassert(mRequestedNumVerts >= 0);
 
+	if(mDirty)
+	{
+		postUpdate() ;
+	}
+
 	if (start >= (U32) mRequestedNumVerts ||
 	    end >= (U32) mRequestedNumVerts)
 	{
@@ -251,6 +257,12 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(mRequestedNumIndices >= 0);
+
+	if(mDirty)
+	{
+		postUpdate() ;
+	}
+
 	if (indices_offset >= (U32) mRequestedNumIndices ||
 	    indices_offset + count > (U32) mRequestedNumIndices)
 	{
@@ -282,6 +294,12 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(mRequestedNumVerts >= 0);
+
+	if(mDirty)
+	{
+		postUpdate() ;
+	}
+
 	if (first >= (U32) mRequestedNumVerts ||
 	    first + count > (U32) mRequestedNumVerts)
 	{
@@ -305,9 +323,10 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 }
 
 //static
-void LLVertexBuffer::initClass(bool use_vbo)
+void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
 	sEnableVBOs = use_vbo;
+	sDisableVBOMapping = no_vbo_mapping ;
 	LLGLNamePool::registerPool(&sDynamicVBOPool);
 	LLGLNamePool::registerPool(&sDynamicIBOPool);
 	LLGLNamePool::registerPool(&sStreamVBOPool);
@@ -369,7 +388,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 	mFilthy(FALSE),
 	mEmpty(TRUE),
 	mResized(FALSE),
-	mDynamicSize(FALSE)
+	mDynamicSize(FALSE),
+	mDirty(FALSE)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
 	if (!sEnableVBOs)
@@ -567,6 +587,8 @@ void LLVertexBuffer::destroyGLBuffer()
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
@@ -594,11 +616,13 @@ void LLVertexBuffer::destroyGLIndices()
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped." << llendl;
 			}
-			releaseIndices();
+			releaseIndices();			
 		}
 		else
 		{
@@ -799,6 +823,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
 
 	if (mResized && useVBOs())
 	{
+		freeClientBuffer() ;
 		setBuffer(0);
 	}
 }
@@ -822,6 +847,60 @@ BOOL LLVertexBuffer::useVBOs() const
 }
 
 //----------------------------------------------------------------------------
+void LLVertexBuffer::freeClientBuffer()
+{
+	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
+	{
+		delete[] mMappedData ;
+		delete[] mMappedIndexData ;
+		mMappedData = NULL ;
+		mMappedIndexData = NULL ;
+	}
+}
+
+void LLVertexBuffer::preUpdate()
+{
+	if(!useVBOs() || !sDisableVBOMapping)
+	{
+		return ;
+	}
+
+	if(!mMappedData)
+	{
+		U32 size = getSize() ;
+		mMappedData = new U8[size];
+		memset(mMappedData, 0, size);
+	}
+
+	if(!mMappedIndexData)
+	{
+		U32 size = getIndicesSize();
+		mMappedIndexData = new U8[size];
+		memset(mMappedIndexData, 0, size);
+	}
+
+	mDirty = TRUE ;
+}
+
+void LLVertexBuffer::postUpdate() const
+{
+	if(!useVBOs() || !sDisableVBOMapping)
+	{
+		return ;
+	}
+
+	llassert_always(mMappedData && mMappedIndexData) ;
+
+	//release the existing buffers
+	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
+	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
+
+	//update to the new buffers
+	glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage);
+	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage);
+
+	mDirty = FALSE ;
+}
 
 // Map for data access
 U8* LLVertexBuffer::mapBuffer(S32 access)
@@ -836,6 +915,12 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
 		llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
 	}
 		
+	if(useVBOs() && sDisableVBOMapping)
+	{
+		preUpdate() ;
+		return mMappedData ;
+	}
+
 	if (!mLocked && useVBOs())
 	{
 		{
@@ -906,7 +991,11 @@ void LLVertexBuffer::unmapBuffer()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
 	if (mMappedData || mMappedIndexData)
 	{
-		if (useVBOs() && mLocked)
+		if(sDisableVBOMapping && useVBOs())
+		{
+			return ;
+		}
+		else if (useVBOs() && mLocked)
 		{
 			stop_glerror();
 			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
@@ -1152,13 +1241,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				}
 			}
 
-			if (mGLBuffer)
+			if (mGLBuffer && !sDisableVBOMapping)
 			{
 				stop_glerror();
 				glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
 				stop_glerror();
 			}
-			if (mGLIndices)
+			if (mGLIndices && !sDisableVBOMapping)
 			{
 				stop_glerror();
 				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 94fa790957..18d50c87bb 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -80,7 +80,7 @@ public:
 
 	static BOOL	sUseStreamDraw;
 
-	static void initClass(bool use_vbo);
+	static void initClass(bool use_vbo, bool no_vbo_mapping);
 	static void cleanupClass();
 	static void setupClientArrays(U32 data_mask);
  	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
@@ -152,6 +152,11 @@ public:
 	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
 	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
 		
+	void preUpdate() ;
+	void postUpdate() const ;
+	void freeClientBuffer() ;
+	void dirty() {mDirty = TRUE;}
+
 	// Only call each getVertexPointer, etc, once before calling unmapBuffer()
 	// call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
 	// example:
@@ -216,6 +221,7 @@ protected:
 	S32		mOffsets[TYPE_MAX];
 	BOOL	mResized;		// if TRUE, client buffer has been resized and GL buffer has not
 	BOOL	mDynamicSize;	// if TRUE, buffer has been resized at least once (and should be padded)
+	mutable BOOL    mDirty ;
 
 	class DirtyRegion
 	{
@@ -240,13 +246,14 @@ public:
 	static std::vector<U32> sDeleteList;
 	typedef std::list<LLVertexBuffer*> buffer_list_t;
 		
+	static BOOL sDisableVBOMapping; //disable glMapBufferARB
 	static BOOL sEnableVBOs;
+	static BOOL sVBOActive;
+	static BOOL sIBOActive;
 	static S32 sTypeOffsets[TYPE_MAX];
 	static U32 sGLMode[LLRender::NUM_MODES];
 	static U32 sGLRenderBuffer;
-	static U32 sGLRenderIndices;
-	static BOOL sVBOActive;
-	static BOOL sIBOActive;
+	static U32 sGLRenderIndices;	
 	static U32 sLastMask;
 	static U32 sAllocatedBytes;
 	static U32 sBindCount;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6630d8f400..58abd4c091 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8451,6 +8451,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RenderVBOMappingDisable</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable VBO glMapBufferARB</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
   <key>RenderUseStreamVBO</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 8c5a52c187..3c53e54203 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -309,6 +309,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue)
 	return true;
 }
 
+static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue)
+{
+	if (gPipeline.isInit())
+	{
+		gPipeline.setDisableVBOMapping(newvalue.asBoolean());
+	}
+	return true;
+}
+
 static bool handleWLSkyDetailChanged(const LLSD&)
 {
 	if (gSky.mVOWLSkyp.notNull())
@@ -589,6 +598,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
 	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
+	gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _2));
 	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
 	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
 	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 274dbe2cc8..0028ced6c8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1477,7 +1477,7 @@ LLViewerWindow::LLViewerWindow(
 	{
 		gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
 	}
-	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"));
+	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
 
 	if (LLFeatureManager::getInstance()->isSafe()
 		|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 39bc354250..13e537fae5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -5313,7 +5313,25 @@ void LLPipeline::setUseVBO(BOOL use_vbo)
 		}
 		
 		resetVertexBuffers();
-		LLVertexBuffer::initClass(use_vbo);
+		LLVertexBuffer::initClass(use_vbo, gSavedSettings.getBOOL("RenderVBOMappingDisable"));
+	}
+}
+
+void LLPipeline::setDisableVBOMapping(BOOL no_vbo_mapping)
+{
+	if (LLVertexBuffer::sEnableVBOs && no_vbo_mapping != LLVertexBuffer::sDisableVBOMapping)
+	{
+		if (no_vbo_mapping)
+		{
+			llinfos << "Disabling VBO glMapBufferARB." << llendl;
+		}
+		else
+		{ 
+			llinfos << "Enabling VBO glMapBufferARB." << llendl;
+		}
+		
+		resetVertexBuffers();
+		LLVertexBuffer::initClass(true, no_vbo_mapping);
 	}
 }
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index cef3d87f36..e99b0d71e3 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -111,6 +111,7 @@ public:
 
 	void resetVertexBuffers(LLDrawable* drawable);
 	void setUseVBO(BOOL use_vbo);
+	void setDisableVBOMapping(BOOL no_vbo_mapping);
 	void generateImpostor(LLVOAvatar* avatar);
 	void bindScreenToTexture();
 	void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
-- 
cgit v1.2.3


From 417069f152e6f4e2f50e7b41b0505765302eb823 Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 22 Feb 2011 11:22:50 -0700
Subject: more fix for SH-895/STORM-336: memory leaking. fixed vertex buffer
 caused leaking.

---
 indra/llrender/llvertexbuffer.cpp | 185 ++++++++++++++++++++------------------
 indra/llrender/llvertexbuffer.h   |  10 +--
 2 files changed, 100 insertions(+), 95 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 660dc14d02..71bdca60e5 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -213,11 +213,6 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
 {
 	llassert(mRequestedNumVerts >= 0);
 
-	if(mDirty)
-	{
-		postUpdate() ;
-	}
-
 	if (start >= (U32) mRequestedNumVerts ||
 	    end >= (U32) mRequestedNumVerts)
 	{
@@ -258,11 +253,6 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(mRequestedNumIndices >= 0);
 
-	if(mDirty)
-	{
-		postUpdate() ;
-	}
-
 	if (indices_offset >= (U32) mRequestedNumIndices ||
 	    indices_offset + count > (U32) mRequestedNumIndices)
 	{
@@ -295,11 +285,6 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(mRequestedNumVerts >= 0);
 
-	if(mDirty)
-	{
-		postUpdate() ;
-	}
-
 	if (first >= (U32) mRequestedNumVerts ||
 	    first + count > (U32) mRequestedNumVerts)
 	{
@@ -326,7 +311,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
 	sEnableVBOs = use_vbo;
-	sDisableVBOMapping = no_vbo_mapping ;
+	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
 	LLGLNamePool::registerPool(&sDynamicVBOPool);
 	LLGLNamePool::registerPool(&sDynamicIBOPool);
 	LLGLNamePool::registerPool(&sStreamVBOPool);
@@ -388,8 +373,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
 	mFilthy(FALSE),
 	mEmpty(TRUE),
 	mResized(FALSE),
-	mDynamicSize(FALSE),
-	mDirty(FALSE)
+	mDynamicSize(FALSE)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
 	if (!sEnableVBOs)
@@ -442,6 +426,8 @@ LLVertexBuffer::~LLVertexBuffer()
 	destroyGLBuffer();
 	destroyGLIndices();
 	sCount--;
+
+	llassert_always(!mMappedData && !mMappedIndexData) ;
 };
 
 //----------------------------------------------------------------------------
@@ -858,48 +844,24 @@ void LLVertexBuffer::freeClientBuffer()
 	}
 }
 
-void LLVertexBuffer::preUpdate()
+void LLVertexBuffer::allocateClientVertexBuffer()
 {
-	if(!useVBOs() || !sDisableVBOMapping)
-	{
-		return ;
-	}
-
 	if(!mMappedData)
 	{
 		U32 size = getSize() ;
 		mMappedData = new U8[size];
 		memset(mMappedData, 0, size);
 	}
+}
 
+void LLVertexBuffer::allocateClientIndexBuffer()
+{
 	if(!mMappedIndexData)
 	{
 		U32 size = getIndicesSize();
 		mMappedIndexData = new U8[size];
 		memset(mMappedIndexData, 0, size);
 	}
-
-	mDirty = TRUE ;
-}
-
-void LLVertexBuffer::postUpdate() const
-{
-	if(!useVBOs() || !sDisableVBOMapping)
-	{
-		return ;
-	}
-
-	llassert_always(mMappedData && mMappedIndexData) ;
-
-	//release the existing buffers
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
-	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
-
-	//update to the new buffers
-	glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage);
-	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage);
-
-	mDirty = FALSE ;
 }
 
 // Map for data access
@@ -915,12 +877,6 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
 		llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
 	}
 		
-	if(useVBOs() && sDisableVBOMapping)
-	{
-		preUpdate() ;
-		return mMappedData ;
-	}
-
 	if (!mLocked && useVBOs())
 	{
 		{
@@ -928,12 +884,28 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
 			setBuffer(0);
 			mLocked = TRUE;
 			stop_glerror();	
-			mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+			if(sDisableVBOMapping)
+			{
+				allocateClientVertexBuffer() ;
+			}
+			else
+			{
+				mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			}
 			stop_glerror();
 		}
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
-			mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+			if(sDisableVBOMapping)
+			{
+				allocateClientIndexBuffer() ;
+			}
+			else
+			{
+				mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			}
 			stop_glerror();
 		}
 
@@ -947,37 +919,51 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
 			llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; 
 			llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
 
-			//--------------------
-			//print out more debug info before crash
-			llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
-			GLint size ;
-			glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
-			llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
-			//--------------------
+			if(!sDisableVBOMapping)
+			{
+				//--------------------
+				//print out more debug info before crash
+				llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
+				GLint size ;
+				glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
+				llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
+				//--------------------
 
-			GLint buff;
-			glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
-			if ((GLuint)buff != mGLBuffer)
+				GLint buff;
+				glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+				if ((GLuint)buff != mGLBuffer)
+				{
+					llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+				}
+
+				
+				llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+			}
+			else
 			{
-				llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+				llerrs << "memory allocation for vertex data failed." << llendl ;
 			}
-
-			
-			llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
 		}
 
 		if (!mMappedIndexData)
 		{
 			log_glerror();
 
-			GLint buff;
-			glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
-			if ((GLuint)buff != mGLIndices)
+			if(!sDisableVBOMapping)
 			{
-				llerrs << "Invalid GL index buffer bound: " << buff << llendl;
-			}
+				GLint buff;
+				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+				if ((GLuint)buff != mGLIndices)
+				{
+					llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+				}
 
-			llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+				llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+			}
+			else
+			{
+				llerrs << "memory allocation for Index data failed. " << llendl ;
+			}
 		}
 
 		sMappedCount++;
@@ -991,17 +977,31 @@ void LLVertexBuffer::unmapBuffer()
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
 	if (mMappedData || mMappedIndexData)
 	{
-		if(sDisableVBOMapping && useVBOs())
+		if (useVBOs() && mLocked)
 		{
-			return ;
-		}
-		else if (useVBOs() && mLocked)
-		{
-			stop_glerror();
-			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
-			stop_glerror();
-			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
-			stop_glerror();
+			if(sDisableVBOMapping)
+			{
+				if(mMappedData)
+				{
+					stop_glerror();
+					glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+					stop_glerror();
+				}
+				if(mMappedIndexData)
+				{
+					stop_glerror();
+					glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+					stop_glerror();
+				}
+			}
+			else
+			{
+				stop_glerror();
+				glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
+				stop_glerror();
+				glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+				stop_glerror();
+			}
 
 			/*if (!sMapped)
 			{
@@ -1015,15 +1015,22 @@ void LLVertexBuffer::unmapBuffer()
 				//throw out client data (we won't be using it again)
 				mEmpty = TRUE;
 				mFinal = TRUE;
+
+				if(sDisableVBOMapping)
+				{
+					freeClientBuffer() ;
+				}
 			}
 			else
 			{
 				mEmpty = FALSE;
 			}
 
-			mMappedIndexData = NULL;
-			mMappedData = NULL;
-			
+			if(!sDisableVBOMapping)
+			{
+				mMappedIndexData = NULL;
+				mMappedData = NULL;
+			}
 			mLocked = FALSE;
 		}
 	}
@@ -1241,13 +1248,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				}
 			}
 
-			if (mGLBuffer && !sDisableVBOMapping)
+			if (mGLBuffer)
 			{
 				stop_glerror();
 				glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
 				stop_glerror();
 			}
-			if (mGLIndices && !sDisableVBOMapping)
+			if (mGLIndices)
 			{
 				stop_glerror();
 				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 18d50c87bb..09a16d5b9d 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -152,11 +152,10 @@ public:
 	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
 	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
 		
-	void preUpdate() ;
-	void postUpdate() const ;
 	void freeClientBuffer() ;
-	void dirty() {mDirty = TRUE;}
-
+	void allocateClientVertexBuffer() ;
+	void allocateClientIndexBuffer() ;
+	
 	// Only call each getVertexPointer, etc, once before calling unmapBuffer()
 	// call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
 	// example:
@@ -221,8 +220,7 @@ protected:
 	S32		mOffsets[TYPE_MAX];
 	BOOL	mResized;		// if TRUE, client buffer has been resized and GL buffer has not
 	BOOL	mDynamicSize;	// if TRUE, buffer has been resized at least once (and should be padded)
-	mutable BOOL    mDirty ;
-
+	
 	class DirtyRegion
 	{
 	public:
-- 
cgit v1.2.3


From 2ebcf802cbec59b4d9fe404af5bd125818d4eefa Mon Sep 17 00:00:00 2001
From: Xiaohong Bao <bao@lindenlab.com>
Date: Tue, 22 Feb 2011 13:28:48 -0700
Subject: set "RenderVBOMappingDisable" to be true by default to stop VBO
 memory leaking.

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 58abd4c091..a010524091 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8460,7 +8460,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
   <key>RenderUseStreamVBO</key>
   <map>
-- 
cgit v1.2.3