diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 52ee24998..5570c6a26 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -33,7 +33,7 @@ #include #include -#include +#include #include diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index 6216b2e71..ae6a8533e 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -131,124 +131,6 @@ class OSGUTIL_EXPORT GLObjectsOperation : public osg::GraphicsOperation GLObjectsVisitor::Mode _mode; }; -class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation -{ - public: - - IncrementalCompileOperation(); - - typedef std::vector Contexts; - void assignContexts(Contexts& contexts); - void removeContexts(Contexts& contexts); - - void addGraphicsContext(osg::GraphicsContext* gc); - void removeGraphicsContext(osg::GraphicsContext* gc); - - - /** Merge subgraphs that have been compiled.*/ - void mergeCompiledSubgraphs(); - - virtual void operator () (osg::GraphicsContext* context); - - - - struct CompileData : public osg::Referenced - { - 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 _drawables.empty() && _textures.empty() && _programs.empty(); } - - Drawables _drawables; - Textures _textures; - Programs _programs; - }; - - class CompileSet; - typedef std::set ContextSet; - typedef std::map CompileMap; - - struct CompileCompletedCallback : public osg::Referenced - { - virtual bool compileCompleted(CompileSet* compileSet) = 0; - }; - - class CompileSet : public osg::Referenced - { - public: - - - CompileSet() {} - - CompileSet(osg::Node*subgraphToCompile): - _subgraphToCompile(subgraphToCompile) {} - - CompileSet(osg::Group* attachmentPoint, osg::Node*subgraphToCompile): - _attachmentPoint(attachmentPoint), - _subgraphToCompile(subgraphToCompile) {} - - 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; - osg::ref_ptr _compileCompletedCallback; - CompileMap _compileMap; - - // protected: - - virtual ~CompileSet() {} - }; - - typedef std::list< osg::ref_ptr > CompileSets; - - - /** Add a subgraph to be compiled.*/ - void add(osg::Node* subgraphToCompile); - - /** Add a subgraph to be compiled and add automatically to attachPoint on call to mergeCompiledSubgraphs.*/ - void add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile); - - /** Add a CompileSet to be compiled.*/ - void add(CompileSet* compileSet, bool callBuildCompileMap=true); - - - OpenThreads::Mutex* getToCompiledMutex() { return &_toCompileMutex; } - CompileSets& getToCompile() { return _compiled; } - - OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; } - CompileSets& getCompiled() { return _compiled; } - - protected: - - virtual ~IncrementalCompileOperation(); - - // forward declare to keep within class namespace - class CollectStateToCompile; - - - OpenThreads::Mutex _toCompileMutex; - CompileSets _toCompile; - - OpenThreads::Mutex _compiledMutex; - CompileSets _compiled; - - ContextSet _contexts; - -}; - - } #endif diff --git a/include/osgUtil/IncrementalCompileOperation b/include/osgUtil/IncrementalCompileOperation new file mode 100644 index 000000000..eae923f8b --- /dev/null +++ b/include/osgUtil/IncrementalCompileOperation @@ -0,0 +1,197 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGUTIL_INCREMENTALCOMPILEOPERATOR +#define OSGUTIL_INCREMENTALCOMPILEOPERATOR + +#include + +namespace osgUtil { + +class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation +{ + public: + + IncrementalCompileOperation(); + + /** 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. + * Usage notes. The TargetFrameRate and the MinimumTimeAvailableForGLCompileAndDeletePerFrame + * parameters are not directly used by IncrementalCompileOperation, but are should be used as a guide for how + * long to set aside per frame for compiling and deleting OpenGL objects. The longer amount of + * time to set aside the faster databases will be paged in but with increased chance of frame drops, + * the lower the amount of time the set aside the slower databases will paged it but with better + * chance of avoid any frame drops. The default values are chosen to achieve the later when running + * on a modern mid to high end PC. + * The way to compute the amount of available time use a scheme such as : + * availableTime = maximum(1.0/targetFrameRate - timeTakenDuringUpdateCullAndDraw, minimumTimeAvailableForGLCompileAndDeletePerFrame). + */ + void setTargetFrameRate(double tfr) { _targetFrameRate = tfr; } + + /** Get the target frame rate that the IncrementalCompileOperation should assume.*/ + double getTargetFrameRate() const { return _targetFrameRate; } + + /** Set the minimum amount of time (in seconds) that should be made available for compiling and delete OpenGL objects per frame. + * Default value is 0.001 (1 millisecond). + * For usage see notes in setTargetFrameRate.*/ + void setMinimumTimeAvailableForGLCompileAndDeletePerFrame(double ta) { _minimumTimeAvailableForGLCompileAndDeletePerFrame = ta; } + + /** Get the minimum amount of time that should be made available for compiling and delete OpenGL objects per frame. + * For usage see notes in setTargetFrameRate.*/ + double getMinimumTimeAvailableForGLCompileAndDeletePerFrame() const { return _minimumTimeAvailableForGLCompileAndDeletePerFrame; } + + /** Set the maximum number of OpenGL objects that the page should attempt to compile per frame. + * Note, Lower values reduces chances of a frame drop but lower the rate that database will be paged in at. + * Default value is 8. */ + void setMaximumNumOfObjectsToCompilePerFrame(unsigned int num) { _maximumNumOfObjectsToCompilePerFrame = num; } + + /** Get the maximum number of OpenGL objects that the page should attempt to compile per frame.*/ + unsigned int getMaximumNumOfObjectsToCompilePerFrame() const { return _maximumNumOfObjectsToCompilePerFrame; } + + + /** FlushTimeRatio governs how much of the spare time in each frame is used for flushing deleted OpenGL objects. + * Default value is 0.5, valid range is 0.1 to 0.9.*/ + void setFlushTimeRatio(double ratio) { _flushTimeRatio = ratio; } + double getFlushTimeRatio() const { return _flushTimeRatio; } + + /** ConservativeTimeRatio governs how much of the measured spare time in each frame is used for flushing deleted and compile new OpenGL objects. + * Default value is 0.5, valid range is 0.1 to 1.0. + * A ratio near 1.0 will lead to paged databases being compiled and merged quicker but increase the chances of frame drop. + * A ratio near 0.1 will lead to paged databases being compiled and merged closer but reduse the chances of frame drop.*/ + void setConservativeTimeRatio(double ratio) { _conservativeTimeRatio = ratio; } + double getConservativeTimeRatio() const { return _conservativeTimeRatio; } + + + + typedef std::vector Contexts; + void assignContexts(Contexts& contexts); + void removeContexts(Contexts& contexts); + + void addGraphicsContext(osg::GraphicsContext* gc); + void removeGraphicsContext(osg::GraphicsContext* gc); + + + /** Merge subgraphs that have been compiled.*/ + void mergeCompiledSubgraphs(); + + virtual void operator () (osg::GraphicsContext* context); + + + + struct CompileData : public osg::Referenced + { + 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 _drawables.empty() && _textures.empty() && _programs.empty(); } + + Drawables _drawables; + Textures _textures; + Programs _programs; + }; + + class CompileSet; + typedef std::set ContextSet; + typedef std::map CompileMap; + + struct CompileCompletedCallback : public osg::Referenced + { + virtual bool compileCompleted(CompileSet* compileSet) = 0; + }; + + class CompileSet : public osg::Referenced + { + public: + + + CompileSet() {} + + CompileSet(osg::Node*subgraphToCompile): + _subgraphToCompile(subgraphToCompile) {} + + CompileSet(osg::Group* attachmentPoint, osg::Node*subgraphToCompile): + _attachmentPoint(attachmentPoint), + _subgraphToCompile(subgraphToCompile) {} + + 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; + osg::ref_ptr _compileCompletedCallback; + CompileMap _compileMap; + + // protected: + + virtual ~CompileSet() {} + }; + + typedef std::list< osg::ref_ptr > CompileSets; + + + /** Add a subgraph to be compiled.*/ + void add(osg::Node* subgraphToCompile); + + /** Add a subgraph to be compiled and add automatically to attachPoint on call to mergeCompiledSubgraphs.*/ + void add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile); + + /** Add a CompileSet to be compiled.*/ + void add(CompileSet* compileSet, bool callBuildCompileMap=true); + + + OpenThreads::Mutex* getToCompiledMutex() { return &_toCompileMutex; } + CompileSets& getToCompile() { return _compiled; } + + OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; } + CompileSets& getCompiled() { return _compiled; } + + protected: + + virtual ~IncrementalCompileOperation(); + + // forward declare to keep within class namespace + class CollectStateToCompile; + + double _targetFrameRate; + double _minimumTimeAvailableForGLCompileAndDeletePerFrame; + unsigned int _maximumNumOfObjectsToCompilePerFrame; + double _flushTimeRatio; + double _conservativeTimeRatio; + + OpenThreads::Mutex _toCompileMutex; + CompileSets _toCompile; + + OpenThreads::Mutex _compiledMutex; + CompileSets _compiled; + + ContextSet _contexts; + +}; + + +} + +#endif + diff --git a/include/osgViewer/ViewerBase b/include/osgViewer/ViewerBase index cb43f386d..86cb2ad5e 100644 --- a/include/osgViewer/ViewerBase +++ b/include/osgViewer/ViewerBase @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/src/osgUtil/CMakeLists.txt b/src/osgUtil/CMakeLists.txt index 93a3a1bca..e35c162a8 100644 --- a/src/osgUtil/CMakeLists.txt +++ b/src/osgUtil/CMakeLists.txt @@ -22,6 +22,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/HighlightMapGenerator ${HEADER_PATH}/IntersectionVisitor ${HEADER_PATH}/IntersectVisitor + ${HEADER_PATH}/IncrementalCompileOperation ${HEADER_PATH}/LineSegmentIntersector ${HEADER_PATH}/OperationArrayFunctor ${HEADER_PATH}/Optimizer @@ -62,6 +63,7 @@ ADD_LIBRARY(${LIB_NAME} HighlightMapGenerator.cpp IntersectionVisitor.cpp IntersectVisitor.cpp + IncrementalCompileOperation.cpp LineSegmentIntersector.cpp Optimizer.cpp PlaneIntersector.cpp diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index 182e8558e..845a77e0f 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -16,10 +16,6 @@ #include #include -#include - -#include - namespace osgUtil { @@ -198,356 +194,5 @@ void GLObjectsOperation::operator () (osg::GraphicsContext* context) // osg::notify(osg::NOTICE)<<"GLObjectsOperation::after >>>>>>>>>>> "<add(this); - _contexts.insert(gc); - } -} - -void IncrementalCompileOperation::removeGraphicsContext(osg::GraphicsContext* gc) -{ - if (_contexts.count(gc)!=0) - { - gc->remove(this); - _contexts.erase(gc); - } -} - -void IncrementalCompileOperation::add(osg::Node* subgraphToCompile) -{ - osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::add("<_subgraphToCompile.valid()) - { - // force a compute of the bound of the subgraph to avoid the update traversal from having to do this work - // and reducing the change of frame drop. - compileSet->_subgraphToCompile->getBound(); - } - - if (callBuildCompileMap) compileSet->buildCompileMap(_contexts); - - osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::add(CompileSet = "< lock(_toCompileMutex); - _toCompile.push_back(compileSet); -} - -void IncrementalCompileOperation::mergeCompiledSubgraphs() -{ - // osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::mergeCompiledSubgraphs()"< compilded_lock(_compiledMutex); - - for(CompileSets::iterator itr = _compiled.begin(); - itr != _compiled.end(); - ++itr) - { - CompileSet* cs = itr->get(); - if (cs->_attachmentPoint.valid()) - { - cs->_attachmentPoint->addChild(cs->_subgraphToCompile.get()); - } - } - - _compiled.clear(); -} - -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 () ("<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]; - - if (!cd.empty()) - { - osg::notify(osg::NOTICE)<<"cd._drawables.size()="<_compileCompletedCallback.valid()) - { - if (cs->_compileCompletedCallback->compileCompleted(cs)) - { - // callback will handle merging of subgraph so no need to place CompileSet in merge. - } - else - { - OpenThreads::ScopedLock compilded_lock(_compiledMutex); - _compiled.push_back(cs); - } - } - - } - } -} } // end of namespace osgUtil diff --git a/src/osgUtil/IncrementalCompileOperation.cpp b/src/osgUtil/IncrementalCompileOperation.cpp new file mode 100644 index 000000000..f3b9a886e --- /dev/null +++ b/src/osgUtil/IncrementalCompileOperation.cpp @@ -0,0 +1,428 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include + +#include +#include +#include +#include + +#include + +#include + +namespace osgUtil +{ + +IncrementalCompileOperation::IncrementalCompileOperation(): + osg::GraphicsOperation("IncrementalCompileOperation",true), + _flushTimeRatio(0.5), + _conservativeTimeRatio(0.5) +{ + _targetFrameRate = 100.0; + _minimumTimeAvailableForGLCompileAndDeletePerFrame = 0.001; // 1ms. + _maximumNumOfObjectsToCompilePerFrame = 20; + const char* ptr = 0; + if( (ptr = getenv("OSG_MINIMUM_COMPILE_TIME_PER_FRAME")) != 0) + { + _minimumTimeAvailableForGLCompileAndDeletePerFrame = atof(ptr); + } + + if( (ptr = getenv("OSG_MAXIMUM_OBJECTS_TO_COMPILE_PER_FRAME")) != 0) + { + _maximumNumOfObjectsToCompilePerFrame = atoi(ptr); + } +} + +IncrementalCompileOperation::~IncrementalCompileOperation() +{ +} + +void IncrementalCompileOperation::assignContexts(Contexts& contexts) +{ + for(Contexts::iterator itr = contexts.begin(); + itr != contexts.end(); + ++itr) + { + osg::GraphicsContext* gc = *itr; + addGraphicsContext(gc); + } +} + +void IncrementalCompileOperation::removeContexts(Contexts& contexts) +{ + for(Contexts::iterator itr = contexts.begin(); + itr != contexts.end(); + ++itr) + { + osg::GraphicsContext* gc = *itr; + removeGraphicsContext(gc); + } +} + + +void IncrementalCompileOperation::addGraphicsContext(osg::GraphicsContext* gc) +{ + if (_contexts.count(gc)==0) + { + gc->add(this); + _contexts.insert(gc); + } +} + +void IncrementalCompileOperation::removeGraphicsContext(osg::GraphicsContext* gc) +{ + if (_contexts.count(gc)!=0) + { + gc->remove(this); + _contexts.erase(gc); + } +} + +void IncrementalCompileOperation::add(osg::Node* subgraphToCompile) +{ + osg::notify(osg::INFO)<<"IncrementalCompileOperation::add("<_subgraphToCompile.valid()) + { + // force a compute of the bound of the subgraph to avoid the update traversal from having to do this work + // and reducing the change of frame drop. + compileSet->_subgraphToCompile->getBound(); + } + + if (callBuildCompileMap) compileSet->buildCompileMap(_contexts); + + osg::notify(osg::INFO)<<"IncrementalCompileOperation::add(CompileSet = "< lock(_toCompileMutex); + _toCompile.push_back(compileSet); +} + +void IncrementalCompileOperation::mergeCompiledSubgraphs() +{ + // osg::notify(osg::INFO)<<"IncrementalCompileOperation::mergeCompiledSubgraphs()"< compilded_lock(_compiledMutex); + + for(CompileSets::iterator itr = _compiled.begin(); + itr != _compiled.end(); + ++itr) + { + CompileSet* cs = itr->get(); + if (cs->_attachmentPoint.valid()) + { + cs->_attachmentPoint->addChild(cs->_subgraphToCompile.get()); + } + } + + _compiled.clear(); +} + +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 () ("<getState()->getFrameStamp(); + double currentTime = fs ? fs->getReferenceTime() : 0.0; + + double currentElapsedFrameTime = context->getTimeSinceLastClear(); + + osg::notify(level)<<"currentTime = "<_compileCompletedCallback.valid()) + { + if (cs->_compileCompletedCallback->compileCompleted(cs)) + { + // callback will handle merging of subgraph so no need to place CompileSet in merge. + } + else + { + OpenThreads::ScopedLock compilded_lock(_compiledMutex); + _compiled.push_back(cs); + } + } + + } + } +} + +} // end of namespace osgUtil diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index b33cafb19..1cf1ddf9e 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -83,9 +83,19 @@ void RenderBin::removeRenderBinPrototype(RenderBin* proto) RenderBinPrototypeList* list = renderBinPrototypeList(); if (list && proto) { - RenderBinPrototypeList::iterator itr = list->find(proto->className()); - if (itr != list->end()) list->erase(itr); + for(RenderBinPrototypeList::iterator itr = list->begin(); + itr != list->end(); + ++itr) + { + if (itr->second == proto) + { + // osg::notify(osg::NOTICE)<<"Found protype, now erasing "<first<erase(itr); + return; + } + } } + // osg::notify(osg::NOTICE)<<"Not found protype"<