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
This commit is contained in:
Robert Osfield 2014-11-06 10:40:54 +00:00
parent 7f592b7ad5
commit a84df15c0a
6 changed files with 114 additions and 60 deletions

View File

@ -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

View File

@ -286,6 +286,9 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
virtual bool containsPagedLOD(const osg::observer_ptr<osg::PagedLOD>& 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<osg::Object> _markerObject;
};
}

View File

@ -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<osg::Drawable*> DrawableSet;
typedef std::set<osg::StateSet*> StateSetSet;
@ -40,6 +40,7 @@ class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor
ProgramSet _programs;
bool _assignPBOToImages;
osg::ref_ptr<osg::PixelBufferObject> _pbo;
osg::ref_ptr<osg::Object> _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<osg::Object> _markerObject;
};
}

View File

@ -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& )"<<std::endl;
_markerObject = new osg::DummyObject;
_markerObject->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()

View File

@ -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()

View File

@ -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<osg::Program*>(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;