summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2011-02-15 14:12:58 -0700
committerXiaohong Bao <bao@lindenlab.com>2011-02-15 14:12:58 -0700
commitf13884e528c327dbbc638b72322e08b544d0f6c0 (patch)
tree6d6405932d386b3f6b25ab9ae8347e3454758744 /indra/llrender
parentb6571ee127f22316be8b9e32c771f8bfb35a0b00 (diff)
partial fix for SH-895/STORM-336: memory leaking. fixed vertex buffer caused leaking.
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llvertexbuffer.cpp101
-rw-r--r--indra/llrender/llvertexbuffer.h15
2 files changed, 106 insertions, 10 deletions
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;