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:
parent
7f592b7ad5
commit
a84df15c0a
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user