Added support for clean up Vertex Array Objects

This commit is contained in:
Robert Osfield 2016-08-03 20:12:20 +01:00
parent 4131d2da34
commit a4e682bb28
3 changed files with 131 additions and 20 deletions

View File

@ -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:

View File

@ -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<Drawable*>(this)->dirtyDisplayList();
const_cast<Drawable*>(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;
}
}
}

View File

@ -13,12 +13,100 @@
#include <osg/VertexArrayState>
#include <osg/State>
#include <osg/ContextData>
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()"<<std::endl;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_vertexArrayStateList);
// trim from front
VertexArrayStateList::iterator ditr=_vertexArrayStateList.begin();
for(;
ditr!=_vertexArrayStateList.end() && elapsedTime<availableTime;
++ditr)
{
VertexArrayState* vas = ditr->get();
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()"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
}
virtual void discardAllGLObjects()
{
VAS_NOTICE<<"VertexArrayStateManager::flushAllDeletedGLObjects()"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_vertexArrayStateList);
_vertexArrayStateList.clear();
}
void release(VertexArrayState* vas)
{
VAS_NOTICE<<"VertexArrayStateManager::release("<<this<<")"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_vertexArrayStateList);
_vertexArrayStateList.push_back(vas);
}
protected:
typedef std::list< osg::ref_ptr<VertexArrayState> > 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<<std::endl;
_ext->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() "<<this<<std::endl;
osg::get<VertexArrayStateManager>(_ext->contextID)->release(this);
}