Improvements to GLBufferObject and TextureObject pools

This commit is contained in:
Robert Osfield
2010-12-15 12:34:16 +00:00
parent c26a241c55
commit 0e7cedab3a
2 changed files with 93 additions and 75 deletions

View File

@@ -31,17 +31,6 @@
using namespace osg;
// static cache of deleted buffer object lists which can only
// by completely deleted once the appropriate OpenGL context
// is set. Used osg::BufferObject::deleteBufferObject(..) and flushDeletedBufferObjects(..) below.
typedef std::multimap<unsigned int,GLuint> BufferObjectMap;
typedef osg::buffered_object<BufferObjectMap> DeletedBufferObjectCache;
static OpenThreads::Mutex s_mutex_deletedBufferObjectCache;
static DeletedBufferObjectCache s_deletedBufferObjectCache;
unsigned int s_minimumNumberOfGLBufferObjectsToRetainInCache = 1000;
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// GLBufferObject
@@ -522,9 +511,6 @@ void GLBufferObjectSet::deleteAllGLBufferObjects()
{
// OSG_NOTICE<<"GLBufferObjectSet::deleteAllGLBufferObjects()"<<std::endl;
// clean up the pending orphans.
handlePendingOrphandedGLBufferObjects();
GLBufferObject* to = _head;
while(to!=0)
{
@@ -546,9 +532,6 @@ void GLBufferObjectSet::deleteAllGLBufferObjects()
_head = 0;
_tail = 0;
// clean up the pending orphans.
handlePendingOrphandedGLBufferObjects();
// do the actual delete.
flushAllDeletedGLBufferObjects();
@@ -592,6 +575,15 @@ void GLBufferObjectSet::discardAllGLBufferObjects()
void GLBufferObjectSet::flushAllDeletedGLBufferObjects()
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedGLBufferObjects.empty())
{
// OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedGLBufferObjects();
}
}
for(GLBufferObjectList::iterator itr = _orphanedGLBufferObjects.begin();
itr != _orphanedGLBufferObjects.end();
++itr)
@@ -615,7 +607,14 @@ void GLBufferObjectSet::discardAllDeletedGLBufferObjects()
// OSG_NOTICE<<"GLBufferObjectSet::discardAllDeletedGLBufferObjects()"<<std::endl;
// clean up the pending orphans.
handlePendingOrphandedGLBufferObjects();
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedGLBufferObjects.empty())
{
// OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedGLBufferObjects();
}
}
unsigned int numDiscarded = _orphanedGLBufferObjects.size();
@@ -624,10 +623,10 @@ void GLBufferObjectSet::discardAllDeletedGLBufferObjects()
// update the GLBufferObjectManager's running total of current pool size
_parent->setCurrGLBufferObjectPoolSize( _parent->getCurrGLBufferObjectPoolSize() - numDiscarded*_profile._size );
// update the number of active and orphaned TextureOjects
_parent->getNumberOrphanedGLBufferObjects() -= 1;
_parent->getNumberActiveGLBufferObjects() += 1;
_parent->getNumberDeleted() += 1;
// update the number of active and orphaned GLBufferObjects
_parent->getNumberOrphanedGLBufferObjects() -= numDiscarded;
_parent->getNumberActiveGLBufferObjects() += numDiscarded;
_parent->getNumberDeleted() += numDiscarded;
// just clear the list as there is nothing else we can do with them when discarding them
@@ -636,18 +635,32 @@ void GLBufferObjectSet::discardAllDeletedGLBufferObjects()
void GLBufferObjectSet::flushDeletedGLBufferObjects(double currentTime, double& availableTime)
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedGLBufferObjects.empty())
{
// OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedGLBufferObjects();
}
}
if (_parent->getCurrGLBufferObjectPoolSize()<=_parent->getMaxGLBufferObjectPoolSize())
{
OSG_INFO<<"Plenty of space in GLBufferObject pool"<<std::endl;
return;
}
// if nothing to delete return
if (_orphanedGLBufferObjects.empty()) return;
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
// if we don't have too many orphaned texture objects then don't bother deleting them, as we can potentially reuse them later.
if (_parent->getNumberOrphanedGLBufferObjects()<=s_minimumNumberOfGLBufferObjectsToRetainInCache) return;
unsigned int numDeleted = 0;
unsigned int maxNumObjectsToDelete = _parent->getNumberOrphanedGLBufferObjects()-s_minimumNumberOfGLBufferObjectsToRetainInCache;
if (maxNumObjectsToDelete>4) maxNumObjectsToDelete = 4;
unsigned int sizeRequired = _parent->getCurrGLBufferObjectPoolSize() - _parent->getMaxGLBufferObjectPoolSize();
unsigned int maxNumObjectsToDelete = static_cast<unsigned int>(ceil(double(sizeRequired) / double(_profile._size)));
OSG_INFO<<"_parent->getCurrGLBufferObjectPoolSize()="<<_parent->getCurrGLBufferObjectPoolSize() <<" _parent->getMaxGLBufferObjectPoolSize()="<< _parent->getMaxGLBufferObjectPoolSize()<<std::endl;
OSG_INFO<<"Looking to reclaim "<<sizeRequired<<", going to look to remove "<<maxNumObjectsToDelete<<" from "<<_orphanedGLBufferObjects.size()<<" orhpans"<<std::endl;
ElapsedTime timer;
@@ -664,7 +677,7 @@ void GLBufferObjectSet::flushDeletedGLBufferObjects(double currentTime, double&
// OSG_NOTICE<<"Size before = "<<_orphanedGLBufferObjects.size();
_orphanedGLBufferObjects.erase(_orphanedGLBufferObjects.begin(), itr);
//OSG_NOTICE<<", after = "<<_orphanedGLBufferObjects.size()<<" numDeleted = "<<numDeleted<<std::endl;
// OSG_NOTICE<<", after = "<<_orphanedGLBufferObjects.size()<<" numDeleted = "<<numDeleted<<std::endl;
// update the number of TO's in this GLBufferObjectSet
_numOfGLBufferObjects -= numDeleted;
@@ -681,6 +694,15 @@ void GLBufferObjectSet::flushDeletedGLBufferObjects(double currentTime, double&
bool GLBufferObjectSet::makeSpace(unsigned int& size)
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedGLBufferObjects.empty())
{
// OSG_NOTICE<<"GLBufferSet::::makeSpace(..) handling orphans"<<std::endl;
handlePendingOrphandedGLBufferObjects();
}
}
if (!_orphanedGLBufferObjects.empty())
{
unsigned int sizeAvailable = _orphanedGLBufferObjects.size() * _profile._size;
@@ -701,18 +723,18 @@ GLBufferObject* GLBufferObjectSet::takeFromOrphans(BufferObject* bufferObject)
// remove from orphan list.
_orphanedGLBufferObjects.pop_front();
// assign to new texture
// assign to new GLBufferObject
glbo->assign(bufferObject);
glbo->setProfile(_profile);
// update the number of active and orphaned TextureOjects
// update the number of active and orphaned GLBufferObjects
_parent->getNumberOrphanedGLBufferObjects() -= 1;
_parent->getNumberActiveGLBufferObjects() += 1;
// place at back of active list
addToBack(glbo.get());
// OSG_NOTICE<<"Reusing orhpahned GLBufferObject, _numOfGLBufferObjects="<<_numOfGLBufferObjects<<std::endl;
OSG_INFO<<"Reusing orphaned GLBufferObject, _numOfGLBufferObjects="<<_numOfGLBufferObjects<<std::endl;
return glbo.release();
}
@@ -751,11 +773,11 @@ GLBufferObject* GLBufferObjectSet::takeOrGenerate(BufferObject* bufferObject)
if (original_BufferObject.valid())
{
original_BufferObject->setGLBufferObject(_contextID,0);
// OSG_NOTICE<<"GLBufferObjectSet="<<this<<": Reusing an active GLBufferObject "<<glbo.get()<<" _numOfGLBufferObjects="<<_numOfGLBufferObjects<<" size="<<_profile._size<<std::endl;
OSG_INFO<<"GLBufferObjectSet="<<this<<": Reusing an active GLBufferObject "<<glbo.get()<<" _numOfGLBufferObjects="<<_numOfGLBufferObjects<<" size="<<_profile._size<<std::endl;
}
else
{
// OSG_NOTICE<<"Reusing a recently orphaned active GLBufferObject "<<glbo.get()<<std::endl;
OSG_INFO<<"Reusing a recently orphaned active GLBufferObject "<<glbo.get()<<std::endl;
}
moveToBack(glbo.get());
@@ -1081,10 +1103,7 @@ void GLBufferObjectManager::flushDeletedGLBufferObjects(double currentTime, doub
void GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to)
{
if (to->_set) to->_set->orphan(to);
else
{
OSG_NOTICE<<"GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) Not implemented yet"<<std::endl;
}
else OSG_NOTICE<<"GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) Not implemented yet"<<std::endl;
}

View File

@@ -266,9 +266,6 @@ void Texture::TextureObjectSet::deleteAllTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::deleteAllTextureObjects()"<<std::endl;
// move the pending orhpans into the orhans list
handlePendingOrphandedTextureObjects();
// detect all the active texture objects from their Textures
TextureObject* to = _head;
while(to!=0)
@@ -331,6 +328,14 @@ void Texture::TextureObjectSet::discardAllTextureObjects()
void Texture::TextureObjectSet::flushAllDeletedTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushAllDeletedTextureObjects()"<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
for(TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
itr != _orphanedTextureObjects.end();
@@ -359,7 +364,14 @@ void Texture::TextureObjectSet::discardAllDeletedTextureObjects()
// OSG_NOTICE<<"Texture::TextureObjectSet::discardAllDeletedTextureObjects()"<<std::endl;
// clean up the pending orphans.
handlePendingOrphandedTextureObjects();
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
unsigned int numDiscarded = _orphanedTextureObjects.size();
@@ -369,9 +381,8 @@ void Texture::TextureObjectSet::discardAllDeletedTextureObjects()
_parent->setCurrTexturePoolSize( _parent->getCurrTexturePoolSize() - numDiscarded*_profile._size );
// update the number of active and orphaned TextureOjects
_parent->getNumberOrphanedTextureObjects() -= 1;
_parent->getNumberActiveTextureObjects() += 1;
_parent->getNumberDeleted() += 1;
_parent->getNumberOrphanedTextureObjects() -= numDiscarded;
_parent->getNumberDeleted() += numDiscarded;
// just clear the list as there is nothing else we can do with them when discarding them
_orphanedTextureObjects.clear();
@@ -381,23 +392,21 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double currentTime, d
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..)"<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
if (_parent->getCurrTexturePoolSize()<=_parent->getMaxTexturePoolSize())
{
// OSG_NOTICE<<"Plenty of space in TexturePool"<<std::endl;
// OSG_NOTICE<<"Plenty of space in TextureObject pool"<<std::endl;
return;
}
#if 1
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
handlePendingOrphandedTextureObjects();
}
#endif
// if nothing to delete return
if (_orphanedTextureObjects.empty())
{
@@ -407,23 +416,11 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double currentTime, d
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
#if 0
// if we don't have too many orphaned texture objects then don't bother deleting them, as we can potentially reuse them later.
if (_parent->getNumberOrphanedTextureObjects()<=s_minimumNumberOfTextureObjectsToRetainInCache) return;
unsigned int numDeleted = 0;
unsigned int maxNumObjectsToDelete = _parent->getNumberOrphanedTextureObjects()-s_minimumNumberOfTextureObjectsToRetainInCache;
if (maxNumObjectsToDelete>4) maxNumObjectsToDelete = 4;
#else
unsigned int numDeleted = 0;
unsigned int sizeRequired = _parent->getCurrTexturePoolSize() - _parent->getMaxTexturePoolSize();
unsigned int maxNumObjectsToDelete = static_cast<unsigned int>(ceil(double(sizeRequired) / double(_profile._size)));
// OSG_NOTICE<<"_parent->getCurrTexturePoolSize()="<<_parent->getCurrTexturePoolSize() <<" _parent->getMaxTexturePoolSize()="<< _parent->getMaxTexturePoolSize()<<std::endl;
// OSG_NOTICE<<"Looking to reclaim "<<sizeRequired<<", going to look to remove "<<maxNumObjectsToDelete<<" from "<<_orphanedTextureObjects.size()<<" orhpans"<<std::endl;
#endif
OSG_INFO<<"_parent->getCurrTexturePoolSize()="<<_parent->getCurrTexturePoolSize() <<" _parent->getMaxTexturePoolSize()="<< _parent->getMaxTexturePoolSize()<<std::endl;
OSG_INFO<<"Looking to reclaim "<<sizeRequired<<", going to look to remove "<<maxNumObjectsToDelete<<" from "<<_orphanedTextureObjects.size()<<" orhpans"<<std::endl;
ElapsedTime timer;
@@ -459,14 +456,14 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double currentTime, d
bool Texture::TextureObjectSet::makeSpace(unsigned int& size)
{
#if 1
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::Texture::TextureObjectSet::makeSpace(..) handling orphans"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
handlePendingOrphandedTextureObjects();
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::Texture::TextureObjectSet::makeSpace(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
#endif
if (!_orphanedTextureObjects.empty())
{
@@ -498,7 +495,7 @@ Texture::TextureObject* Texture::TextureObjectSet::takeFromOrphans(Texture* text
// place at back of active list
addToBack(to.get());
// OSG_INFO<<"Reusing orhpahned TextureObject, _numOfTextureObjects="<<_numOfTextureObjects<<std::endl;
OSG_INFO<<"Reusing orphaned TextureObject, _numOfTextureObjects="<<_numOfTextureObjects<<std::endl;
return to.release();
}
@@ -882,6 +879,7 @@ void Texture::TextureObjectManager::flushDeletedTextureObjects(double currentTim
{
ElapsedTime elapsedTime(&(getDeleteTime()));
#if 0
static double max_ratio = 0.0f;
double ratio = double(getCurrTexturePoolSize())/double(getMaxTexturePoolSize());
if (ratio>max_ratio)
@@ -889,6 +887,7 @@ void Texture::TextureObjectManager::flushDeletedTextureObjects(double currentTim
max_ratio = ratio;
}
// OSG_NOTICE<<"TexturePool Size ratio "<<ratio<<", max ratio "<<max_ratio<<std::endl;
#endif
for(TextureSetMap::iterator itr = _textureSetMap.begin();
(itr != _textureSetMap.end()) && (availableTime > 0.0);