From a84df15c0add239b26f184f2a11ee7061cce41c2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 6 Nov 2014 10:40:54 +0000 Subject: [PATCH] Introduced use of MarkerObject to IncrmentalCompileOperation/DatabasePager as a way of marking objects that have already been processed and compiled, thus avoid potential threading conflicts when paged subgraphs are reused. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14470 16af8721-9629-0410-8352-f15c8da7e697 --- include/osg/Object | 13 ++++ include/osgDB/DatabasePager | 5 ++ include/osgUtil/IncrementalCompileOperation | 9 ++- src/osgDB/DatabasePager.cpp | 49 ++++++++---- src/osgDB/InputStream.cpp | 13 +--- src/osgUtil/IncrementalCompileOperation.cpp | 85 +++++++++++++-------- 6 files changed, 114 insertions(+), 60 deletions(-) diff --git a/include/osg/Object b/include/osg/Object index 0f9715bcd..2b7f95915 100644 --- a/include/osg/Object +++ b/include/osg/Object @@ -269,6 +269,19 @@ T* cloneType(const T* t) } } +/** DummyObject that can be used as placeholder but otherwise has no other functionality.*/ +class DummyObject : public osg::Object +{ +public: + DummyObject() {} + DummyObject(const DummyObject& dummy, const osg::CopyOp& copyop) {} + META_Object(osg, DummyObject) +protected: + virtual ~DummyObject() {} +}; + + + } #endif diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 5c8444843..f5e3bb934 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -286,6 +286,9 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl virtual bool containsPagedLOD(const osg::observer_ptr& plod) const = 0; }; + void setMarkerObject(osg::Object* mo) { _markerObject = mo; } + osg::Object* getMarkerObject() { return _markerObject.get(); } + const osg::Object* getMarkerObject() const { return _markerObject.get(); } protected: @@ -469,6 +472,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl double _maximumTimeToMergeTile; double _totalTimeToMergeTiles; unsigned int _numTilesMerges; + + osg::ref_ptr _markerObject; }; } diff --git a/include/osgUtil/IncrementalCompileOperation b/include/osgUtil/IncrementalCompileOperation index cdd42800c..c739cd6d5 100644 --- a/include/osgUtil/IncrementalCompileOperation +++ b/include/osgUtil/IncrementalCompileOperation @@ -24,7 +24,7 @@ class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor { public: - StateToCompile(GLObjectsVisitor::Mode mode); + StateToCompile(GLObjectsVisitor::Mode mode, osg::Object* markerObject=0); typedef std::set DrawableSet; typedef std::set StateSetSet; @@ -40,6 +40,7 @@ class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor ProgramSet _programs; bool _assignPBOToImages; osg::ref_ptr _pbo; + osg::ref_ptr _markerObject; bool empty() const { return _textures.empty() && _programs.empty() && _drawables.empty(); } @@ -290,6 +291,10 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; } CompileSets& getCompiled() { return _compiled; } + void setMarkerObject(osg::Object* mo) { _markerObject = mo; } + osg::Object* getMarkerObject() { return _markerObject.get(); } + const osg::Object* getMarkerObject() const { return _markerObject.get(); } + protected: virtual ~IncrementalCompileOperation(); @@ -315,6 +320,8 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation ContextSet _contexts; + osg::ref_ptr _markerObject; + }; } diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 00d7df6d6..f5ede57d1 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -294,8 +294,8 @@ public: class DatabasePager::FindCompileableGLObjectsVisitor : public osgUtil::StateToCompile { public: - FindCompileableGLObjectsVisitor(const DatabasePager* pager): - osgUtil::StateToCompile(osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES), + FindCompileableGLObjectsVisitor(const DatabasePager* pager, osg::Object* markerObject): + osgUtil::StateToCompile(osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES, markerObject), _pager(pager), _changeAutoUnRef(false), _valueAutoUnRef(false), _changeAnisotropy(false), _valueAnisotropy(1.0) @@ -340,29 +340,46 @@ public: bool requiresCompilation() const { return !empty(); } - virtual void apply(osg::Geode& geode) + virtual void apply(osg::Drawable& drawable) { - StateToCompile::apply(geode); - - if (_kdTreeBuilder.valid()) + if (_kdTreeBuilder.valid() && _markerObject!=drawable.getUserData()) { - geode.accept(*_kdTreeBuilder); + drawable.accept(*_kdTreeBuilder); + } + + StateToCompile::apply(drawable); + + + if (drawable.getUserData()==0) + { + drawable.setUserData(_markerObject.get()); } } void apply(osg::Texture& texture) { + // apply any changes if the texture is not static. + if (texture.getDataVariance()!=osg::Object::STATIC && + _markerObject!=texture.getUserData()) + { + if (_changeAutoUnRef) + { + texture.setUnRefImageDataAfterApply(_valueAutoUnRef); + } + + if ((_changeAnisotropy && texture.getMaxAnisotropy() != _valueAnisotropy)) + { + texture.setMaxAnisotropy(_valueAnisotropy); + } + } + StateToCompile::apply(texture); - if (_changeAutoUnRef) + if (texture.getUserData()==0) { - texture.setUnRefImageDataAfterApply(_valueAutoUnRef); + texture.setUserData(_markerObject.get()); } - if ((_changeAnisotropy && texture.getMaxAnisotropy() != _valueAnisotropy)) - { - texture.setMaxAnisotropy(_valueAnisotropy); - } } const DatabasePager* _pager; @@ -875,7 +892,7 @@ void DatabasePager::DatabaseThread::run() loadedModel->getBound(); // find all the compileable rendering objects - DatabasePager::FindCompileableGLObjectsVisitor stateToCompile(_pager); + DatabasePager::FindCompileableGLObjectsVisitor stateToCompile(_pager, _pager->getMarkerObject()); loadedModel->accept(stateToCompile); bool loadedObjectsNeedToBeCompiled = _pager->_doPreCompile && @@ -1074,6 +1091,9 @@ DatabasePager::DatabasePager(const DatabasePager& rhs) { //OSG_INFO<<"Constructing DatabasePager(const DatabasePager& )"<setName("HasBeenByStateToCompileProcessedMarker"); + _startThreadCalled = false; _done = false; @@ -1129,6 +1149,7 @@ DatabasePager::DatabasePager(const DatabasePager& rhs) void DatabasePager::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico) { _incrementalCompileOperation = ico; + if (_incrementalCompileOperation.valid()) _markerObject = _incrementalCompileOperation->getMarkerObject(); } DatabasePager::~DatabasePager() diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index 6bcd95137..816de6a96 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -23,17 +23,6 @@ using namespace osgDB; static std::string s_lastSchema; -class DummyObject : public osg::Object -{ -public: - DummyObject() {} - DummyObject(const DummyObject& dummy, const osg::CopyOp& copyop) {} - META_Object(osgDB, DummyObject) -protected: - virtual ~DummyObject() {} -}; - - InputStream::InputStream( const osgDB::Options* options ) : _fileVersion(0), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0) { @@ -78,7 +67,7 @@ InputStream::InputStream( const osgDB::Options* options ) } // assign dummy object to used for reading field properties that will be discarded. - _dummyReadObject = new DummyObject; + _dummyReadObject = new osg::DummyObject; } InputStream::~InputStream() diff --git a/src/osgUtil/IncrementalCompileOperation.cpp b/src/osgUtil/IncrementalCompileOperation.cpp index 520f4dbbd..b2645386a 100644 --- a/src/osgUtil/IncrementalCompileOperation.cpp +++ b/src/osgUtil/IncrementalCompileOperation.cpp @@ -53,10 +53,11 @@ static osg::ApplicationUsageProxy UCO_e3(osg::ApplicationUsage::ENVIRONMENTAL_VA // // CollectStateToCompile // -StateToCompile::StateToCompile(GLObjectsVisitor::Mode mode): +StateToCompile::StateToCompile(GLObjectsVisitor::Mode mode, osg::Object* markerObject): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _mode(mode), - _assignPBOToImages(false) + _assignPBOToImages(false), + _markerObject(markerObject) { } @@ -76,35 +77,44 @@ void StateToCompile::apply(osg::Drawable& drawable) _drawablesHandled.insert(&drawable); - if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS) + if (_markerObject!=drawable.getUserData()) { - drawable.setUseDisplayList(false); - } + if (drawable.getDataVariance()!=osg::Object::STATIC) + { + 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_DISPLAY_LISTS) + { + drawable.setUseDisplayList(true); + } - if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS) - { - drawable.setUseVertexBufferObjects(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::SWITCH_OFF_VERTEX_BUFFER_OBJECTS) + { + drawable.setUseVertexBufferObjects(false); + } + } - if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && - (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) - { - _drawables.insert(&drawable); - } + if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && + (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) + { + _drawables.insert(&drawable); + } - if (drawable.getStateSet()) - { - apply(*(drawable.getStateSet())); + if (drawable.getStateSet()) + { + apply(*(drawable.getStateSet())); + } + + // mark the drawable as visited + if (drawable.getUserData()==0) drawable.setUserData(_markerObject.get()); } } @@ -114,22 +124,20 @@ void StateToCompile::apply(osg::StateSet& stateset) _statesetsHandled.insert(&stateset); - if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES) + if ((_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES)!=0 && + _markerObject!=stateset.getUserData()) { osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); - if (program) + if (program && _markerObject!=program->getUserData()) { _programs.insert(program); + + // mark the stateset as visited + if (program->getUserData()==0) program->setUserData(_markerObject.get()); } const osg::StateSet::TextureAttributeList& tal = stateset.getTextureAttributeList(); -#if 0 - if (tal.size()>1) - { - tal.erase(tal.begin()+1,tal.end()); - } -#endif for(osg::StateSet::TextureAttributeList::const_iterator itr = tal.begin(); itr != tal.end(); ++itr) @@ -149,11 +157,17 @@ void StateToCompile::apply(osg::StateSet& stateset) } } } + + // mark the stateset as visited + if (stateset.getUserData()==0) stateset.setUserData(_markerObject.get()); } } void StateToCompile::apply(osg::Texture& texture) { + // don't make any changes if Texture already processed + if (_markerObject==texture.getUserData()) return; + if (_assignPBOToImages) { unsigned int numRequringPBO = 0; @@ -199,6 +213,8 @@ void StateToCompile::apply(osg::Texture& texture) } } + if (texture.getUserData()==0) texture.setUserData(_markerObject.get()); + _textures.insert(&texture); } @@ -435,6 +451,9 @@ IncrementalCompileOperation::IncrementalCompileOperation(): _currentFrameNumber(0), _compileAllTillFrameNumber(0) { + _markerObject = new osg::DummyObject; + _markerObject->setName("HasBeenProcessedByStateToCompile"); + _targetFrameRate = 100.0; _minimumTimeAvailableForGLCompileAndDeletePerFrame = 0.001; // 1ms. _maximumNumOfObjectsToCompilePerFrame = 20;