From a4e682bb2879a34baed23ba06fd49d86a95abaea Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 3 Aug 2016 20:12:20 +0100 Subject: [PATCH] Added support for clean up Vertex Array Objects --- include/osg/VertexArrayState | 8 ++- src/osg/Drawable.cpp | 42 ++++++++++----- src/osg/VertexArrayState.cpp | 101 ++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 20 deletions(-) diff --git a/include/osg/VertexArrayState b/include/osg/VertexArrayState index efc96371b..9c61858e3 100644 --- a/include/osg/VertexArrayState +++ b/include/osg/VertexArrayState @@ -134,9 +134,6 @@ public: /** Disable all the vertex attributes that have been marked as to be disabled.*/ void applyDisablingOfVertexAttributes(osg::State& state); - - - // Verex Array Object methods. void generateVretexArrayObject(); @@ -144,14 +141,15 @@ public: void unbindVertexArrayObject() const; - GLint getVertexArrayObject() const { return _vertexArrayObject; } + void deleteVertexArrayObject(); - void releaseGLObjects(); + GLint getVertexArrayObject() const { return _vertexArrayObject; } void setRequiresSetArrays(bool flag) { _requiresSetArrays = flag; } bool getRequiresSetArrays() const { return _requiresSetArrays; } + void release(); public: diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index bba87a5aa..04f292288 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -312,31 +312,36 @@ void Drawable::releaseGLObjects(State* state) const if (_drawCallback.valid()) _drawCallback->releaseGLObjects(state); - if (!_useDisplayList) return; - if (state) { // get the contextID (user defined ID of 0 upwards) for the // current OpenGL context. unsigned int contextID = state->getContextID(); - // get the globj for the current contextID. - GLuint& globj = _globjList[contextID]; - - // call the globj if already set otherwise compile and execute. - if( globj != 0 ) + if (_useDisplayList) { - Drawable::deleteDisplayList(contextID,globj, getGLObjectSizeHint()); - globj = 0; + // get the globj for the current contextID. + GLuint& globj = _globjList[contextID]; + + // call the globj if already set otherwise compile and execute. + if( globj != 0 ) + { + Drawable::deleteDisplayList(contextID,globj, getGLObjectSizeHint()); + globj = 0; + } + } + + VertexArrayState* vas = contextID <_vertexArrayStateList.size() ? _vertexArrayStateList[contextID] : 0; + if (vas) + { + vas->release(); + _vertexArrayStateList[contextID] = 0; } } else { - const_cast(this)->dirtyDisplayList(); + const_cast(this)->dirtyGLObjects(); } - - - // TODO release VAO's.. } void Drawable::setSupportsDisplayList(bool flag) @@ -371,6 +376,7 @@ void Drawable::setUseDisplayList(bool flag) #ifdef OSG_GL_DISPLAYLISTS_AVAILABLE // if was previously set to true, remove display list. + if (_useDisplayList) { dirtyDisplayList(); @@ -444,6 +450,16 @@ void Drawable::dirtyGLObjects() } } #endif + + for(i=0; i<_vertexArrayStateList.size(); ++i) + { + VertexArrayState* vas = _vertexArrayStateList[i].get(); + if (vas) + { + vas->release(); + _vertexArrayStateList[i] = 0; + } + } } diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 7a317dea6..8b8e4b9f3 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -13,12 +13,100 @@ #include #include +#include using namespace osg; #define VAS_NOTICE OSG_INFO //#define VAS_NOTICE OSG_NOTICE + +class VertexArrayStateManager : public GraphicsObjectManager +{ +public: + VertexArrayStateManager(unsigned int contextID): + GraphicsObjectManager("VertexArrayStateManager", contextID) + { + } + + virtual void flushDeletedGLObjects(double, double& availableTime) + { + // if no time available don't try to flush objects. + if (availableTime<=0.0) return; + + VAS_NOTICE<<"VertexArrayStateManager::flushDeletedGLObjects()"< lock(_mutex_vertexArrayStateList); + + // trim from front + VertexArrayStateList::iterator ditr=_vertexArrayStateList.begin(); + for(; + ditr!=_vertexArrayStateList.end() && elapsedTimeget(); + vas->deleteVertexArrayObject(); + + elapsedTime = timer.delta_s(start_tick,timer.tick()); + } + + if (ditr!=_vertexArrayStateList.begin()) _vertexArrayStateList.erase(_vertexArrayStateList.begin(),ditr); + + } + + elapsedTime = timer.delta_s(start_tick,timer.tick()); + + availableTime -= elapsedTime; + } + + virtual void flushAllDeletedGLObjects() + { + VAS_NOTICE<<"VertexArrayStateManager::flushAllDeletedGLObjects()"< lock(_mutex_vertexArrayStateList); + for(VertexArrayStateList::iterator itr = _vertexArrayStateList.begin(); + itr != _vertexArrayStateList.end(); + ++itr) + { + VertexArrayState* vas = itr->get(); + vas->deleteVertexArrayObject(); + } + _vertexArrayStateList.clear(); + } + + virtual void deleteAllGLObjects() + { + OSG_INFO<<"VertexArrayStateManager::deleteAllGLObjects() Not currently implementated"< lock(_mutex_vertexArrayStateList); + _vertexArrayStateList.clear(); + } + + void release(VertexArrayState* vas) + { + VAS_NOTICE<<"VertexArrayStateManager::release("< lock(_mutex_vertexArrayStateList); + _vertexArrayStateList.push_back(vas); + } + +protected: + + typedef std::list< osg::ref_ptr > VertexArrayStateList; + OpenThreads::Mutex _mutex_vertexArrayStateList; + VertexArrayStateList _vertexArrayStateList; +}; + #ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE /////////////////////////////////////////////////////////////////////////////////// // @@ -363,15 +451,17 @@ void VertexArrayState::unbindVertexArrayObject() const _ext->glBindVertexArray (0); } -void VertexArrayState::releaseGLObjects() +void VertexArrayState::deleteVertexArrayObject() { if (_vertexArrayObject) { + VAS_NOTICE<<" VertexArrayState::deleteVertexArrayObject() "<<_vertexArrayObject<glDeleteVertexArrays(1, &_vertexArrayObject); + _vertexArrayObject = 0; } } - void VertexArrayState::assignVertexArrayDispatcher() { #ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE @@ -608,3 +698,10 @@ void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& sta disable(_vertexAttribArrays[i].get(), state); } } + +void VertexArrayState::release() +{ + VAS_NOTICE<<"VertexArrayState::release() "<(_ext->contextID)->release(this); +}