From 0e7cedab3a450b4e0c289562d5c570707eec12e3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Dec 2010 12:34:16 +0000 Subject: [PATCH] Improvements to GLBufferObject and TextureObject pools --- src/osg/BufferObject.cpp | 93 ++++++++++++++++++++++++---------------- src/osg/Texture.cpp | 75 ++++++++++++++++---------------- 2 files changed, 93 insertions(+), 75 deletions(-) diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index 493aadbd7..5b5dd0d42 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -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 BufferObjectMap; -typedef osg::buffered_object 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()"< lock(_mutex); + if (!_pendingOrphanedGLBufferObjects.empty()) + { + // OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"< lock(_mutex); + if (!_pendingOrphanedGLBufferObjects.empty()) + { + // OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<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 lock(_mutex); + if (!_pendingOrphanedGLBufferObjects.empty()) + { + // OSG_NOTICE<<"GLBufferObjectSet::flushDeletedGLBufferObjects(..) handling orphans"<getCurrGLBufferObjectPoolSize()<=_parent->getMaxGLBufferObjectPoolSize()) + { + OSG_INFO<<"Plenty of space in GLBufferObject pool"<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(ceil(double(sizeRequired) / double(_profile._size))); + OSG_INFO<<"_parent->getCurrGLBufferObjectPoolSize()="<<_parent->getCurrGLBufferObjectPoolSize() <<" _parent->getMaxGLBufferObjectPoolSize()="<< _parent->getMaxGLBufferObjectPoolSize()<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<_set) to->_set->orphan(to); - else - { - OSG_NOTICE<<"GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) Not implemented yet"< lock(_mutex); + if (!_pendingOrphanedTextureObjects.empty()) + { + // OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"< lock(_mutex); + if (!_pendingOrphanedTextureObjects.empty()) + { + // OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<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(..)"< lock(_mutex); + if (!_pendingOrphanedTextureObjects.empty()) + { + // OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<getCurrTexturePoolSize()<=_parent->getMaxTexturePoolSize()) { - // OSG_NOTICE<<"Plenty of space in TexturePool"< 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(ceil(double(sizeRequired) / double(_profile._size))); - // OSG_NOTICE<<"_parent->getCurrTexturePoolSize()="<<_parent->getCurrTexturePoolSize() <<" _parent->getMaxTexturePoolSize()="<< _parent->getMaxTexturePoolSize()<getCurrTexturePoolSize()="<<_parent->getCurrTexturePoolSize() <<" _parent->getMaxTexturePoolSize()="<< _parent->getMaxTexturePoolSize()< lock(_mutex); - handlePendingOrphandedTextureObjects(); + if (!_pendingOrphanedTextureObjects.empty()) + { + // OSG_NOTICE<<"Texture::TextureObjectSet::Texture::TextureObjectSet::makeSpace(..) handling orphans"< 0.0);