diff --git a/include/osgUtil/IncrementalCompileOperation b/include/osgUtil/IncrementalCompileOperation index 2b4c9b7d2..f7a486c92 100644 --- a/include/osgUtil/IncrementalCompileOperation +++ b/include/osgUtil/IncrementalCompileOperation @@ -20,6 +20,35 @@ namespace osgUtil { +class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor +{ + public: + + StateToCompile(GLObjectsVisitor::Mode mode); + + typedef std::set DrawableSet; + typedef std::set StateSetSet; + typedef std::set TextureSet; + typedef std::set ProgramSet; + + DrawableSet _drawablesHandled; + StateSetSet _statesetsHandled; + + GLObjectsVisitor::Mode _mode; + DrawableSet _drawables; + TextureSet _textures; + ProgramSet _programs; + + bool empty() const { return _textures.empty() && _programs.empty() && _drawables.empty(); } + + virtual void apply(osg::Node& node); + virtual void apply(osg::Geode& node); + + virtual void apply(osg::Drawable& drawable); + virtual void apply(osg::StateSet& stateset); + virtual void apply(osg::Texture& texture); +}; + class OSGUTIL_EXPORT CompileStats : public osg::Referenced { public: @@ -93,7 +122,12 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation public: IncrementalCompileOperation(); - + + /** Return true if the IncrementCompileOperation is active.*/ + bool isActive() const { return !_contexts.empty(); } + + bool requiresCompile(StateToCompile& stateToCompile); + /** Set the target frame rate that the IncrementalCompileOperation should assume. * Typically one would set this to the value refresh rate of your display system i.e. 60Hz. * Default value is 100. @@ -163,6 +197,10 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation void addGraphicsContext(osg::GraphicsContext* gc); void removeGraphicsContext(osg::GraphicsContext* gc); + typedef std::set ContextSet; + ContextSet& getContextSet() { return _contexts; } + const ContextSet& getContextSet() const { return _contexts; } + /** Merge subgraphs that have been compiled.*/ void mergeCompiledSubgraphs(); @@ -235,7 +273,6 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation class CompileSet; - typedef std::set ContextSet; struct CompileCompletedCallback : public virtual osg::Referenced { @@ -256,7 +293,8 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation _attachmentPoint(attachmentPoint), _subgraphToCompile(subgraphToCompile) {} - void buildCompileMap(ContextSet& context, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES); + void buildCompileMap(ContextSet& contexts, StateToCompile& stateToCompile); + void buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES); bool compile(CompileInfo& compileInfo); @@ -299,8 +337,6 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation virtual ~IncrementalCompileOperation(); - // forward declare to keep within class namespace - class CollectStateToCompile; double _targetFrameRate; double _minimumTimeAvailableForGLCompileAndDeletePerFrame; diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 55659cdde..c8d15cfdb 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -290,18 +290,38 @@ public: // // FindCompileableGLObjectsVisitor // -class DatabasePager::FindCompileableGLObjectsVisitor : public osg::NodeVisitor +class DatabasePager::FindCompileableGLObjectsVisitor : public osgUtil::StateToCompile { public: - FindCompileableGLObjectsVisitor(bool changeAutoUnRef, bool valueAutoUnRef, - bool changeAnisotropy, float valueAnisotropy, - DatabasePager::DrawablePolicy drawablePolicy, - const DatabasePager* pager): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef), - _changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy), - _drawablePolicy(drawablePolicy), _pager(pager) + FindCompileableGLObjectsVisitor(const DatabasePager* pager): + osgUtil::StateToCompile(osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES), + _pager(pager), + _changeAutoUnRef(false), _valueAutoUnRef(false), + _changeAnisotropy(false), _valueAnisotropy(1.0) { + _changeAutoUnRef = _pager->_changeAutoUnRef; + _valueAutoUnRef = _pager->_valueAutoUnRef; + _changeAnisotropy = _pager->_changeAnisotropy; + _valueAnisotropy = _pager->_valueAnisotropy; + + switch(_pager->_drawablePolicy) + { + case DatabasePager::DO_NOT_MODIFY_DRAWABLE_SETTINGS: + // do nothing, leave settings as they came in from loaded database. + // OSG_NOTICE<<"DO_NOT_MODIFY_DRAWABLE_SETTINGS"<getBuildKdTreesHint()==osgDB::Options::BUILD_KDTREES && osgDB::Registry::instance()->getKdTreeBuilder()) { @@ -311,25 +331,11 @@ public: META_NodeVisitor("osgDB","FindCompileableGLObjectsVisitor") - bool requiresCompilation() const { return true; } - - virtual void apply(osg::Node& node) - { - apply(node.getStateSet()); - - traverse(node); - } + bool requiresCompilation() const { return !empty(); } virtual void apply(osg::Geode& geode) { - apply(geode.getStateSet()); - - for(unsigned int i=0;igetTextureAttributeList().size();++i) - { - osg::Texture* texture = dynamic_cast(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE)); - // Has this texture already been encountered? - if (texture && !_textureSet.count(texture)) - { - _textureSet.insert(texture); - if (_changeAutoUnRef) texture->setUnRefImageDataAfterApply(_valueAutoUnRef); - if ((_changeAnisotropy - && texture->getMaxAnisotropy() != _valueAnisotropy)) - { - if (_changeAnisotropy) - texture->setMaxAnisotropy(_valueAnisotropy); - } - } - } + StateToCompile::apply(texture); + if (_changeAutoUnRef) + { + texture.setUnRefImageDataAfterApply(_valueAutoUnRef); + } + + if ((_changeAnisotropy && texture.getMaxAnisotropy() != _valueAnisotropy)) + { + texture.setMaxAnisotropy(_valueAnisotropy); } } - inline void apply(osg::Drawable* drawable) - { - if (_drawableSet.count(drawable)) - return; - - _drawableSet.insert(drawable); - - apply(drawable->getStateSet()); - - switch(_drawablePolicy) - { - case DatabasePager::DO_NOT_MODIFY_DRAWABLE_SETTINGS: - // do nothing, leave settings as they came in from loaded database. - // OSG_NOTICE<<"DO_NOT_MODIFY_DRAWABLE_SETTINGS"<setUseDisplayList(true); - drawable->setUseVertexBufferObjects(false); - break; - case DatabasePager::USE_VERTEX_BUFFER_OBJECTS: - drawable->setUseDisplayList(true); - drawable->setUseVertexBufferObjects(true); - // OSG_NOTICE<<"USE_VERTEX_BUFFER_OBJECTS"<setUseDisplayList(false); - drawable->setUseVertexBufferObjects(false); - // OSG_NOTICE<<"USE_VERTEX_ARRAYS"< > _textureSet; - std::set > _drawableSet; osg::ref_ptr _kdTreeBuilder; protected: @@ -918,24 +875,24 @@ void DatabasePager::DatabaseThread::run() loadedModel->getBound(); // find all the compileable rendering objects - DatabasePager::FindCompileableGLObjectsVisitor frov(_pager->_changeAutoUnRef, _pager->_valueAutoUnRef, - _pager->_changeAnisotropy, _pager->_valueAnisotropy, - _pager->_drawablePolicy, - _pager); + DatabasePager::FindCompileableGLObjectsVisitor stateToCompile(_pager); + loadedModel->accept(stateToCompile); - loadedModel->accept(frov); - - bool loadedObjectsNeedToBeCompiled = (_pager->_doPreCompile && frov.requiresCompilation() && _pager->_incrementalCompileOperation.valid()); + bool loadedObjectsNeedToBeCompiled = _pager->_doPreCompile && + _pager->_incrementalCompileOperation.valid() && + _pager->_incrementalCompileOperation->requiresCompile(stateToCompile); // move the databaseRequest from the front of the fileRequest to the end of // dataToCompile or dataToMerge lists. - osgUtil::IncrementalCompileOperation::CompileSet* compileSet = 0; + osg::ref_ptr compileSet = 0; if (loadedObjectsNeedToBeCompiled) { // OSG_NOTICE<<"Using IncrementalCompileOperation"<buildCompileMap(_pager->_incrementalCompileOperation->getContextSet(), stateToCompile); compileSet->_compileCompletedCallback = new DatabasePagerCompileCompletedCallback(_pager, databaseRequest.get()); + _pager->_incrementalCompileOperation->add(compileSet, false); } { OpenThreads::ScopedLock drLock(_pager->_dr_mutex); @@ -948,7 +905,6 @@ void DatabasePager::DatabaseThread::run() // addLoadedDataToSceneGraph. if (loadedObjectsNeedToBeCompiled) { - _pager->_incrementalCompileOperation->add(compileSet); OpenThreads::ScopedLock listLock( _pager->_dataToCompileList->_requestMutex); _pager->_dataToCompileList->addNoLock(databaseRequest.get()); @@ -1054,7 +1010,7 @@ DatabasePager::DatabasePager() } - _doPreCompile = false; + _doPreCompile = true; if( (ptr = getenv("OSG_DO_PRE_COMPILE")) != 0) { _doPreCompile = strcmp(ptr,"yes")==0 || strcmp(ptr,"YES")==0 || @@ -1064,12 +1020,6 @@ DatabasePager::DatabasePager() // initialize the stats variables resetStats(); - // make sure a SharedStateManager exists. - //osgDB::Registry::instance()->getOrCreateSharedStateManager(); - - //if (osgDB::Registry::instance()->getSharedStateManager()) - //osgDB::Registry::instance()->setUseObjectCacheHint(true); - _fileRequestQueue = new ReadQueue(this,"fileRequestQueue"); _httpRequestQueue = new ReadQueue(this,"httpRequestQueue"); diff --git a/src/osgUtil/IncrementalCompileOperation.cpp b/src/osgUtil/IncrementalCompileOperation.cpp index 45640d3b2..aa05b8873 100644 --- a/src/osgUtil/IncrementalCompileOperation.cpp +++ b/src/osgUtil/IncrementalCompileOperation.cpp @@ -51,125 +51,117 @@ static osg::ApplicationUsageProxy UCO_e2(osg::ApplicationUsage::ENVIRONMENTAL_VA // // CollectStateToCompile // -class IncrementalCompileOperation::CollectStateToCompile : public osg::NodeVisitor +StateToCompile::StateToCompile(GLObjectsVisitor::Mode mode): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _mode(mode) { -public: +} - CollectStateToCompile(GLObjectsVisitor::Mode mode): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _mode(mode) {} - - GLObjectsVisitor::Mode _mode; - - typedef std::set DrawableSet; - typedef std::set StateSetSet; - typedef std::set TextureSet; - typedef std::set ProgramSet; - - DrawableSet _drawablesHandled; - StateSetSet _statesetsHandled; - - DrawableSet _drawables; - TextureSet _textures; - ProgramSet _programs; - - void apply(osg::Node& node) +void StateToCompile::apply(osg::Node& node) +{ + if (node.getStateSet()) { - if (node.getStateSet()) - { - apply(*(node.getStateSet())); - } - - traverse(node); + apply(*(node.getStateSet())); } - void apply(osg::Geode& node) + traverse(node); +} + +void StateToCompile::apply(osg::Geode& node) +{ + if (node.getStateSet()) { - if (node.getStateSet()) + apply(*(node.getStateSet())); + } + + for(unsigned int i=0;igetStateSet()) + { + apply(*(drawable->getStateSet())); + } + } + } +} + +void StateToCompile::apply(osg::Drawable& drawable) +{ + if (_drawablesHandled.count(&drawable)!=0) return; + + _drawablesHandled.insert(&drawable); + + if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS) + { + drawable.setUseDisplayList(false); + } + + if (_mode&GLObjectsVisitor::SWITCH_ON_DISPLAY_LISTS) + { + drawable.setUseDisplayList(true); + } + + if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS) + { + drawable.setUseVertexBufferObjects(true); + } + + if (_mode&GLObjectsVisitor::SWITCH_OFF_VERTEX_BUFFER_OBJECTS) + { + drawable.setUseVertexBufferObjects(false); + } + + if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && + (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) + { + _drawables.insert(&drawable); + } +} + +void StateToCompile::apply(osg::StateSet& stateset) +{ + if (_statesetsHandled.count(&stateset)!=0) return; + + _statesetsHandled.insert(&stateset); + + if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES) + { + osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); + if (program) + { + _programs.insert(program); } - for(unsigned int i=0;igetStateSet()) + osg::Texture* texture = dynamic_cast(texItr->second.first.get()); + if (texture) { - apply(*(drawable->getStateSet())); + if (_textures.count(texture)==0) + { + apply(*texture); + } } } } } +} - void apply(osg::Drawable& drawable) - { - if (_drawablesHandled.count(&drawable)!=0) return; - - _drawablesHandled.insert(&drawable); - - if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS) - { - drawable.setUseDisplayList(false); - } - - if (_mode&GLObjectsVisitor::SWITCH_ON_DISPLAY_LISTS) - { - drawable.setUseDisplayList(true); - } - - if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS) - { - drawable.setUseVertexBufferObjects(true); - } - - if (_mode&GLObjectsVisitor::SWITCH_OFF_VERTEX_BUFFER_OBJECTS) - { - drawable.setUseVertexBufferObjects(false); - } - - if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && - (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) - { - _drawables.insert(&drawable); - } - - } - - void apply(osg::StateSet& stateset) - { - if (_statesetsHandled.count(&stateset)!=0) return; - - _statesetsHandled.insert(&stateset); - - if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES) - { - osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); - if (program) - { - _programs.insert(program); - } - - osg::StateSet::TextureAttributeList& tal = stateset.getTextureAttributeList(); - for(osg::StateSet::TextureAttributeList::iterator itr = tal.begin(); - itr != tal.end(); - ++itr) - { - osg::StateSet::AttributeList& al = *itr; - osg::StateAttribute::TypeMemberPair tmp(osg::StateAttribute::TEXTURE,0); - osg::StateSet::AttributeList::iterator texItr = al.find(tmp); - if (texItr != al.end()) - { - osg::Texture* texture = dynamic_cast(texItr->second.first.get()); - if (texture) _textures.insert(texture); - } - } - } - } - -}; +void StateToCompile::apply(osg::Texture& texture) +{ + _textures.insert(&texture); +} ///////////////////////////////////////////////////////////////// // @@ -391,14 +383,11 @@ bool IncrementalCompileOperation::CompileList::compile(CompileInfo& compileInfo) // // CompileSet // -void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode) +void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, StateToCompile& stc) { - if (contexts.empty() || !_subgraphToCompile) return; + if (contexts.empty() || stc.empty()) return; - CollectStateToCompile cstc(mode); - _subgraphToCompile->accept(cstc); - - if (cstc._textures.empty() && cstc._programs.empty() && cstc._drawables.empty()) return; + if (stc.empty()) return; for(ContextSet::iterator itr = contexts.begin(); itr != contexts.end(); @@ -406,24 +395,24 @@ void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contex { // increment the number of compile lists that will need to compile ++_numberCompileListsToCompile; - + CompileList& cl = _compileMap[*itr]; - for(CollectStateToCompile::DrawableSet::iterator ditr = cstc._drawables.begin(); - ditr != cstc._drawables.end(); + for(StateToCompile::DrawableSet::iterator ditr = stc._drawables.begin(); + ditr != stc._drawables.end(); ++ditr) { cl.add(*ditr); } - for(CollectStateToCompile::TextureSet::iterator titr = cstc._textures.begin(); - titr != cstc._textures.end(); + for(StateToCompile::TextureSet::iterator titr = stc._textures.begin(); + titr != stc._textures.end(); ++titr) { cl.add(*titr); } - for(CollectStateToCompile::ProgramSet::iterator pitr = cstc._programs.begin(); - pitr != cstc._programs.end(); + for(StateToCompile::ProgramSet::iterator pitr = stc._programs.begin(); + pitr != stc._programs.end(); ++pitr) { cl.add(*pitr); @@ -431,6 +420,16 @@ void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contex } } +void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode) +{ + if (contexts.empty() || !_subgraphToCompile) return; + + StateToCompile stc(mode); + _subgraphToCompile->accept(stc); + + buildCompileMap(contexts, stc); +} + bool IncrementalCompileOperation::CompileSet::compile(CompileInfo& compileInfo) { CompileList& compileList = _compileMap[compileInfo.getState()->getGraphicsContext()]; @@ -545,6 +544,11 @@ void IncrementalCompileOperation::removeGraphicsContext(osg::GraphicsContext* gc } } +bool IncrementalCompileOperation::requiresCompile(StateToCompile& stateToCompile) +{ + return isActive() && !stateToCompile.empty(); +} + void IncrementalCompileOperation::add(osg::Node* subgraphToCompile) { OSG_INFO<<"IncrementalCompileOperation::add("<