From 173357252b7cf0f29ce3982ae84fbfa5cfd45a66 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Mar 2009 14:56:20 +0000 Subject: [PATCH] Further work on IncrementalCompileOperation --- include/osgUtil/GLObjectsVisitor | 24 ++- src/osgUtil/GLObjectsVisitor.cpp | 256 +++++++++++++++++++++++++++---- 2 files changed, 245 insertions(+), 35 deletions(-) diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index 1b20394f1..64c654eda 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -153,20 +153,20 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation struct CompileData : public osg::Referenced { - typedef std::list< osg::ref_ptr > Textures; typedef std::list< osg::ref_ptr > Drawables; + typedef std::list< osg::ref_ptr > Textures; typedef std::list< osg::ref_ptr > Programs; - bool empty() const { return _textures.empty() && _drawables.empty() && _programs.empty(); } + bool empty() const { return _drawables.empty() && _textures.empty() && _programs.empty(); } - Textures _textures; Drawables _drawables; + Textures _textures; Programs _programs; }; class CompileSet; typedef std::set ContextSet; - typedef std::map > CompileMap; + typedef std::map CompileMap; struct CompileCompletedCallback : public osg::Referenced { @@ -187,7 +187,18 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation _attachmentPoint(attachmentPoint), _subgraphToCompile(subgraphToCompile) {} - void buildCompileMap(ContextSet& context); + void buildCompileMap(ContextSet& context, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES); + + bool compileCompleted() const + { + for(CompileMap::const_iterator itr = _compileMap.begin(); + itr != _compileMap.end(); + ++itr) + { + if (!(itr->second.empty())) return false; + } + return true; + } osg::ref_ptr _attachmentPoint; osg::ref_ptr _subgraphToCompile; @@ -221,6 +232,9 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation protected: virtual ~IncrementalCompileOperation(); + + // forward declare to keep within class namespace + class CollectStateToCompile; OpenThreads::Mutex _toCompileMutex; diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 7c173cdd6..e1e24002c 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -11,13 +11,17 @@ * OpenSceneGraph Public License for more details. */ #include + #include #include +#include + #include -using namespace osg; -using namespace osgUtil; +#include +namespace osgUtil +{ ///////////////////////////////////////////////////////////////// // @@ -51,7 +55,7 @@ void GLObjectsVisitor::apply(osg::Geode& node) for(unsigned int i=0;igetLastAppliedProgramObject()){ - GL2Extensions* extensions = GL2Extensions::Get(_renderInfo.getState()->getContextID(), true); + osg::GL2Extensions* extensions = osg::GL2Extensions::Get(_renderInfo.getState()->getContextID(), true); extensions->glUseProgram(0); _renderInfo.getState()->setLastAppliedProgramObject(0); } @@ -275,7 +279,7 @@ void IncrementalCompileOperation::add(CompileSet* compileSet, bool callBuildComp void IncrementalCompileOperation::mergeCompiledSubgraphs() { - osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::mergeCompiledSubgraphs()"< compilded_lock(_compiledMutex); @@ -293,38 +297,234 @@ void IncrementalCompileOperation::mergeCompiledSubgraphs() _compiled.clear(); } -void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& context) +class IncrementalCompileOperation::CollectStateToCompile : public osg::NodeVisitor { +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) + { + if (node.getStateSet()) + { + apply(*(node.getStateSet())); + } + + traverse(node); + } + + void apply(osg::Geode& node) + { + if (node.getStateSet()) + { + apply(*(node.getStateSet())); + } + + for(unsigned int i=0;igetStateSet()) + { + apply(*(drawable->getStateSet())); + } + } + } + } + + 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) + { + _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 IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode) +{ + if (contexts.empty() || !_subgraphToCompile) return; + + CollectStateToCompile cstc(mode); + _subgraphToCompile->accept(cstc); + + if (cstc._textures.empty() && cstc._programs.empty() && cstc._drawables.empty()) return; + + for(ContextSet::iterator itr = contexts.begin(); + itr != contexts.end(); + ++itr) + { + CompileData& cd = _compileMap[*itr]; + std::copy(cstc._textures.begin(), cstc._textures.end(), std::back_inserter(cd._textures)); + std::copy(cstc._programs.begin(), cstc._programs.end(), std::back_inserter(cd._programs)); + std::copy(cstc._drawables.begin(), cstc._drawables.end(), std::back_inserter(cd._drawables)); + } + } void IncrementalCompileOperation::operator () (osg::GraphicsContext* context) { - osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::operator () ("< toCompile_lock(_toCompileMutex); - for(CompileSets::iterator itr = _toCompile.begin(); - itr != _toCompile.end(); - ) + osg::RenderInfo renderInfo; + renderInfo.setState(context->getState()); + + + CompileSets toCompileCopy; + { + OpenThreads::ScopedLock toCompile_lock(_toCompileMutex); + std::copy(_toCompile.begin(),_toCompile.end(),std::back_inserter(toCompileCopy)); + } + + for(CompileSets::iterator itr = toCompileCopy.begin(); + itr != toCompileCopy.end(); + ++itr) { CompileSet* cs = itr->get(); CompileMap& cm = cs->_compileMap; - CompileData* cd = cm[context].get(); + CompileData& cd = cm[context]; - if (cd) - { - // compile textures - cd->_textures.clear(); + if (!cd.empty()) + { + osg::notify(osg::NOTICE)<<"cd._drawables.size()="<_compileCompletedCallback.valid()) { if (cs->_compileCompletedCallback->compileCompleted(cs)) { @@ -336,13 +536,9 @@ void IncrementalCompileOperation::operator () (osg::GraphicsContext* context) _compiled.push_back(cs); } } - - // remove from toCompileSet; - itr = _toCompile.erase(itr); - } - else - { - ++itr; + } } } + +} // end of namespace osgUtil