Preliminary work on general purpose incremental compile support in osgViewer.
This commit is contained in:
@@ -57,16 +57,35 @@
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::GraphicsThread> > GraphicsThreads;
|
||||
|
||||
struct ReleaseBlockOnCompileCompleted : public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
|
||||
{
|
||||
|
||||
ReleaseBlockOnCompileCompleted(osg::RefBlockCount* block):
|
||||
_block(block) {}
|
||||
|
||||
virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
|
||||
{
|
||||
if (_block.valid()) _block->completed();
|
||||
|
||||
// tell IncrementalCompileOperation that it's now safe to remove the compileSet
|
||||
|
||||
osg::notify(osg::NOTICE)<<"compileCompleted("<<compileSet<<")"<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::RefBlockCount> _block;
|
||||
};
|
||||
|
||||
|
||||
class LoadAndCompileOperation : public osg::Operation
|
||||
{
|
||||
public:
|
||||
|
||||
LoadAndCompileOperation(const std::string& filename, GraphicsThreads& graphicsThreads, osg::RefBlockCount* block):
|
||||
LoadAndCompileOperation(const std::string& filename, osgUtil::IncrementalCompileOperation* ico , osg::RefBlockCount* block):
|
||||
Operation("Load and compile Operation", false),
|
||||
_filename(filename),
|
||||
_graphicsThreads(graphicsThreads),
|
||||
_incrementalCompileOperation(ico),
|
||||
_block(block) {}
|
||||
|
||||
virtual void operator () (osg::Object* object)
|
||||
@@ -74,28 +93,28 @@ public:
|
||||
// osg::notify(osg::NOTICE)<<"LoadAndCompileOperation "<<_filename<<std::endl;
|
||||
|
||||
_loadedModel = osgDB::readNodeFile(_filename);
|
||||
if (_loadedModel.valid() && !_graphicsThreads.empty())
|
||||
{
|
||||
osg::ref_ptr<osgUtil::GLObjectsOperation> compileOperation = new osgUtil::GLObjectsOperation(_loadedModel.get());
|
||||
|
||||
for(GraphicsThreads::iterator gitr = _graphicsThreads.begin();
|
||||
gitr != _graphicsThreads.end();
|
||||
++gitr)
|
||||
{
|
||||
(*gitr)->add( compileOperation.get() );
|
||||
// requiresBarrier = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_block.valid()) _block->completed();
|
||||
if (_loadedModel.valid() && _incrementalCompileOperation.valid())
|
||||
{
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
|
||||
new osgUtil::IncrementalCompileOperation::CompileSet(_loadedModel);
|
||||
|
||||
compileSet->_compileCompletedCallback = new ReleaseBlockOnCompileCompleted(_block.get());
|
||||
|
||||
_incrementalCompileOperation->add(compileSet.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_block.valid()) _block->completed();
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"done LoadAndCompileOperation "<<_filename<<std::endl;
|
||||
}
|
||||
|
||||
std::string _filename;
|
||||
GraphicsThreads _graphicsThreads;
|
||||
osg::ref_ptr<osg::Node> _loadedModel;
|
||||
osg::ref_ptr<osg::RefBlockCount> _block;
|
||||
std::string _filename;
|
||||
osg::ref_ptr<osg::Node> _loadedModel;
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation> _incrementalCompileOperation;
|
||||
osg::ref_ptr<osg::RefBlockCount> _block;
|
||||
|
||||
};
|
||||
|
||||
@@ -108,9 +127,10 @@ public:
|
||||
typedef std::vector< osg::ref_ptr<osg::Node> > Nodes;
|
||||
|
||||
|
||||
MasterOperation(const std::string& filename):
|
||||
MasterOperation(const std::string& filename, osgUtil::IncrementalCompileOperation* ico):
|
||||
Operation("Master reading operation",true),
|
||||
_filename(filename)
|
||||
_filename(filename),
|
||||
_incrementalCompileOperation(ico)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -256,9 +276,6 @@ public:
|
||||
if (gt) threads.push_back(gt);
|
||||
}
|
||||
|
||||
bool requiresBarrier = false;
|
||||
|
||||
|
||||
if (_operationQueue.valid())
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Using OperationQueue"<<std::endl;
|
||||
@@ -276,7 +293,7 @@ public:
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Adding LoadAndCompileOperation "<<*nitr<<std::endl;
|
||||
|
||||
osg::ref_ptr<LoadAndCompileOperation> loadAndCompile = new LoadAndCompileOperation( *nitr, threads, _endOfLoadBlock.get() );
|
||||
osg::ref_ptr<LoadAndCompileOperation> loadAndCompile = new LoadAndCompileOperation( *nitr, _incrementalCompileOperation.get(), _endOfLoadBlock.get() );
|
||||
loadAndCompileList.push_back(loadAndCompile);
|
||||
_operationQueue->add( loadAndCompile.get() );
|
||||
}
|
||||
@@ -300,7 +317,6 @@ public:
|
||||
if ((*litr)->_loadedModel.valid())
|
||||
{
|
||||
nodesToAdd[(*litr)->_filename] = (*litr)->_loadedModel;
|
||||
requiresBarrier = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +324,11 @@ public:
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
_endOfLoadBlock = new osg::RefBlockCount(newFiles.size());
|
||||
|
||||
_endOfLoadBlock->reset();
|
||||
|
||||
for(Files::iterator nitr = newFiles.begin();
|
||||
nitr != newFiles.end();
|
||||
++nitr)
|
||||
@@ -318,38 +339,30 @@ public:
|
||||
{
|
||||
nodesToAdd[*nitr] = loadedModel;
|
||||
|
||||
osg::ref_ptr<osgUtil::GLObjectsOperation> compileOperation = new osgUtil::GLObjectsOperation(loadedModel.get());
|
||||
|
||||
for(GraphicsThreads::iterator gitr = threads.begin();
|
||||
gitr != threads.end();
|
||||
++gitr)
|
||||
if (_incrementalCompileOperation.valid())
|
||||
{
|
||||
(*gitr)->add( compileOperation.get() );
|
||||
requiresBarrier = true;
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
|
||||
new osgUtil::IncrementalCompileOperation::CompileSet(loadedModel.get());
|
||||
|
||||
compileSet->_compileCompletedCallback = new ReleaseBlockOnCompileCompleted(_endOfLoadBlock.get());
|
||||
|
||||
_incrementalCompileOperation->add(compileSet.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
_endOfLoadBlock->completed();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_endOfLoadBlock->completed();
|
||||
}
|
||||
}
|
||||
|
||||
_endOfLoadBlock->block();
|
||||
|
||||
}
|
||||
|
||||
if (requiresBarrier)
|
||||
{
|
||||
_endOfCompilebarrier = new osg::BarrierOperation(threads.size()+1);
|
||||
_endOfCompilebarrier->setKeep(false);
|
||||
|
||||
for(GraphicsThreads::iterator gitr = threads.begin();
|
||||
gitr != threads.end();
|
||||
++gitr)
|
||||
{
|
||||
(*gitr)->add(_endOfCompilebarrier.get());
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Waiting for Compile to complete"<<std::endl;
|
||||
|
||||
// wait for the graphics threads to complete.
|
||||
_endOfCompilebarrier->block();
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"done ... Waiting for Compile to complete"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool requiresBlock = false;
|
||||
@@ -454,6 +467,7 @@ public:
|
||||
FilenameNodeMap _nodesToAdd;
|
||||
OpenThreads::Block _updatesMergedBlock;
|
||||
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation> _incrementalCompileOperation;
|
||||
osg::ref_ptr<osg::BarrierOperation> _endOfCompilebarrier;
|
||||
osg::ref_ptr<osg::RefBlockCount> _endOfLoadBlock;
|
||||
|
||||
@@ -618,6 +632,9 @@ int main(int argc, char** argv)
|
||||
// add the record camera path handler
|
||||
viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
|
||||
|
||||
// attach an IncrementaCompileOperation to allow the master loading
|
||||
// to be handled with an incremental compile to avoid frame drops when large objects are added.
|
||||
viewer.setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation());
|
||||
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
@@ -631,7 +648,7 @@ int main(int argc, char** argv)
|
||||
std::string masterFilename;
|
||||
while(arguments.read("-m",masterFilename))
|
||||
{
|
||||
masterOperation = new MasterOperation(masterFilename);
|
||||
masterOperation = new MasterOperation(masterFilename, viewer.getIncrementalCompileOperation());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -123,13 +123,117 @@ class OSGUTIL_EXPORT GLObjectsOperation : public osg::GraphicsOperation
|
||||
GLObjectsOperation(osg::Node* subgraph, GLObjectsVisitor::Mode mode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES|GLObjectsVisitor::CHECK_BLACK_LISTED_MODES);
|
||||
|
||||
virtual void operator () (osg::GraphicsContext* context);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
GLObjectsVisitor::Mode _mode;
|
||||
};
|
||||
|
||||
class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation
|
||||
{
|
||||
public:
|
||||
|
||||
IncrementalCompileOperation();
|
||||
|
||||
typedef std::vector<osg::GraphicsContext*> 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<osg::Texture> > Textures;
|
||||
typedef std::list< osg::ref_ptr<osg::Drawable> > Drawables;
|
||||
typedef std::list< osg::ref_ptr<osg::Program> > Programs;
|
||||
|
||||
bool empty() const { return _textures.empty() && _drawables.empty() && _programs.empty(); }
|
||||
|
||||
Textures _textures;
|
||||
Drawables _drawables;
|
||||
Programs _programs;
|
||||
};
|
||||
|
||||
class CompileSet;
|
||||
typedef std::set<osg::GraphicsContext*> ContextSet;
|
||||
typedef std::map<osg::GraphicsContext*, osg::ref_ptr<CompileData> > 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);
|
||||
|
||||
osg::ref_ptr<osg::Group> _attachmentPoint;
|
||||
osg::ref_ptr<osg::Node> _subgraphToCompile;
|
||||
osg::ref_ptr<CompileCompletedCallback> _compileCompletedCallback;
|
||||
CompileMap _compileMap;
|
||||
|
||||
// protected:
|
||||
|
||||
virtual ~CompileSet() {}
|
||||
};
|
||||
|
||||
typedef std::list< osg::ref_ptr<CompileSet> > 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();
|
||||
|
||||
|
||||
OpenThreads::Mutex _toCompileMutex;
|
||||
CompileSets _toCompile;
|
||||
|
||||
OpenThreads::Mutex _compiledMutex;
|
||||
CompileSets _compiled;
|
||||
|
||||
ContextSet _contexts;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <osg/Stats>
|
||||
|
||||
#include <osgUtil/UpdateVisitor>
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
|
||||
#include <osgGA/MatrixManipulator>
|
||||
#include <osgGA/EventVisitor>
|
||||
@@ -184,6 +185,15 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object
|
||||
|
||||
/** Get the graphics operation to call on realization of the viewers graphics windows.*/
|
||||
osg::Operation* getRealizeOperation() { return _realizeOperation.get(); }
|
||||
|
||||
|
||||
/** Set the incremental compile operation.
|
||||
* Used to manage the OpenGL object compilation and merging of subgraphs in a way that avoids overloading
|
||||
* the rendering of frame with too many new objects in one frame. */
|
||||
void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
|
||||
|
||||
/** Get the incremental compile operation. */
|
||||
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation() { return _incrementalCompileOperation.get(); }
|
||||
|
||||
|
||||
/** Check to see if windows are still open, if not set viewer done to true. */
|
||||
@@ -260,29 +270,30 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object
|
||||
|
||||
virtual void viewerInit() = 0;
|
||||
|
||||
bool _firstFrame;
|
||||
bool _done;
|
||||
int _keyEventSetsDone;
|
||||
bool _quitEventSetsDone;
|
||||
bool _releaseContextAtEndOfFrameHint;
|
||||
bool _firstFrame;
|
||||
bool _done;
|
||||
int _keyEventSetsDone;
|
||||
bool _quitEventSetsDone;
|
||||
bool _releaseContextAtEndOfFrameHint;
|
||||
|
||||
ThreadingModel _threadingModel;
|
||||
bool _threadsRunning;
|
||||
ThreadingModel _threadingModel;
|
||||
bool _threadsRunning;
|
||||
|
||||
BarrierPosition _endBarrierPosition;
|
||||
BarrierPosition _endBarrierPosition;
|
||||
|
||||
osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
|
||||
osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;
|
||||
osg::ref_ptr<osg::EndOfDynamicDrawBlock> _endDynamicDrawBlock;
|
||||
osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
|
||||
osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;
|
||||
osg::ref_ptr<osg::EndOfDynamicDrawBlock> _endDynamicDrawBlock;
|
||||
|
||||
osg::ref_ptr<osgGA::EventVisitor> _eventVisitor;
|
||||
osg::ref_ptr<osgGA::EventVisitor> _eventVisitor;
|
||||
|
||||
osg::ref_ptr<osg::OperationQueue> _updateOperations;
|
||||
osg::ref_ptr<osgUtil::UpdateVisitor> _updateVisitor;
|
||||
osg::ref_ptr<osg::OperationQueue> _updateOperations;
|
||||
osg::ref_ptr<osgUtil::UpdateVisitor> _updateVisitor;
|
||||
|
||||
osg::ref_ptr<osg::Operation> _realizeOperation;
|
||||
osg::ref_ptr<osg::Operation> _realizeOperation;
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation> _incrementalCompileOperation;
|
||||
|
||||
osg::observer_ptr<osg::GraphicsContext> _currentContext;
|
||||
osg::observer_ptr<osg::GraphicsContext> _currentContext;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ GraphicsContext::GraphicsContexts GraphicsContext::getRegisteredGraphicsContexts
|
||||
|
||||
GraphicsContext* GraphicsContext::getOrCreateCompileContext(unsigned int contextID)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"GraphicsContext::createCompileContext."<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"GraphicsContext::createCompileContext."<<std::endl;
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
|
||||
@@ -349,7 +349,7 @@ GraphicsContext* GraphicsContext::getOrCreateCompileContext(unsigned int context
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
|
||||
s_contextIDMap[contextID]._compileContext = gc;
|
||||
osg::notify(osg::INFO)<<" succeeded GraphicsContext::createCompileContext."<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<" succeeded GraphicsContext::createCompileContext."<<std::endl;
|
||||
return gc.release();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -13,10 +13,16 @@
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Notify>
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GLObjectsVisitor
|
||||
//
|
||||
GLObjectsVisitor::GLObjectsVisitor(Mode mode)
|
||||
{
|
||||
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
|
||||
@@ -145,6 +151,11 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset)
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GLObjectsVisitor
|
||||
//
|
||||
|
||||
GLObjectsOperation::GLObjectsOperation(GLObjectsVisitor::Mode mode):
|
||||
osg::GraphicsOperation("GLObjectOperation",false),
|
||||
_mode(mode)
|
||||
@@ -182,3 +193,156 @@ void GLObjectsOperation::operator () (osg::GraphicsContext* context)
|
||||
}
|
||||
// osg::notify(osg::NOTICE)<<"GLObjectsOperation::after >>>>>>>>>>> "<<std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IncrementalCompileOperation
|
||||
//
|
||||
IncrementalCompileOperation::IncrementalCompileOperation():
|
||||
osg::GraphicsOperation("IncrementalCompileOperation",true)
|
||||
{
|
||||
}
|
||||
|
||||
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::NOTICE)<<"IncrementalCompileOperation::add("<<subgraphToCompile<<")"<<std::endl;
|
||||
add(new CompileSet(subgraphToCompile));
|
||||
}
|
||||
|
||||
void IncrementalCompileOperation::add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::add("<<attachmentPoint<<", "<<subgraphToCompile<<")"<<std::endl;
|
||||
add(new CompileSet(attachmentPoint, subgraphToCompile));
|
||||
}
|
||||
|
||||
|
||||
void IncrementalCompileOperation::add(CompileSet* compileSet, bool callBuildCompileMap)
|
||||
{
|
||||
if (!compileSet) return;
|
||||
|
||||
if (callBuildCompileMap) compileSet->buildCompileMap(_contexts);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::add(CompileSet = "<<compileSet<<", "<<", "<<callBuildCompileMap<<")"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_toCompileMutex);
|
||||
_toCompile.push_back(compileSet);
|
||||
}
|
||||
|
||||
void IncrementalCompileOperation::mergeCompiledSubgraphs()
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::mergeCompiledSubgraphs()"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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();
|
||||
}
|
||||
|
||||
void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& context)
|
||||
{
|
||||
}
|
||||
|
||||
void IncrementalCompileOperation::operator () (osg::GraphicsContext* context)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"IncrementalCompileOperation::operator () ("<<context<<")"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> toCompile_lock(_toCompileMutex);
|
||||
for(CompileSets::iterator itr = _toCompile.begin();
|
||||
itr != _toCompile.end();
|
||||
)
|
||||
{
|
||||
CompileSet* cs = itr->get();
|
||||
CompileMap& cm = cs->_compileMap;
|
||||
CompileData* cd = cm[context].get();
|
||||
|
||||
if (cd)
|
||||
{
|
||||
// compile textures
|
||||
cd->_textures.clear();
|
||||
|
||||
// compile drawables
|
||||
cd->_drawables.clear();
|
||||
|
||||
// compile programs
|
||||
cd->_programs.clear();
|
||||
}
|
||||
|
||||
if (!cd || cd->empty())
|
||||
{
|
||||
if (cs->_compileCompletedCallback.valid())
|
||||
{
|
||||
if (cs->_compileCompletedCallback->compileCompleted(cs))
|
||||
{
|
||||
// callback will handle merging of subgraph so no need to place CompileSet in merge.
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> compilded_lock(_compiledMutex);
|
||||
_compiled.push_back(cs);
|
||||
}
|
||||
}
|
||||
|
||||
// remove from toCompileSet;
|
||||
itr = _toCompile.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,6 +497,10 @@ void CompositeViewer::realize()
|
||||
}
|
||||
}
|
||||
|
||||
// attach contexts to _incrementalCompileOperation if attached.
|
||||
if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
|
||||
|
||||
|
||||
bool grabFocus = true;
|
||||
if (grabFocus)
|
||||
{
|
||||
@@ -994,6 +998,12 @@ void CompositeViewer::updateTraversal()
|
||||
|
||||
}
|
||||
|
||||
if (_incrementalCompileOperation.valid())
|
||||
{
|
||||
// merge subgraphs that have been compiled by the incremental compiler operation.
|
||||
_incrementalCompileOperation->mergeCompiledSubgraphs();
|
||||
}
|
||||
|
||||
if (_updateOperations.valid())
|
||||
{
|
||||
_updateOperations->runOperations(this);
|
||||
|
||||
@@ -448,7 +448,10 @@ void Viewer::realize()
|
||||
gc->releaseContext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// attach contexts to _incrementalCompileOperation if attached.
|
||||
if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
|
||||
|
||||
bool grabFocus = true;
|
||||
if (grabFocus)
|
||||
{
|
||||
@@ -898,6 +901,13 @@ void Viewer::updateTraversal()
|
||||
{
|
||||
_updateOperations->runOperations(this);
|
||||
}
|
||||
|
||||
if (_incrementalCompileOperation.valid())
|
||||
{
|
||||
// merge subgraphs that have been compiled by the incremental compiler operation.
|
||||
_incrementalCompileOperation->mergeCompiledSubgraphs();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
|
||||
|
||||
@@ -375,7 +375,7 @@ void ViewerBase::startThreading()
|
||||
|
||||
if (!gc->isRealized())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
|
||||
osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizing window "<<gc<<std::endl;
|
||||
gc->realize();
|
||||
}
|
||||
|
||||
@@ -551,6 +551,21 @@ void ViewerBase::removeUpdateOperation(osg::Operation* operation)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerBase::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico)
|
||||
{
|
||||
if (_incrementalCompileOperation == ico) return;
|
||||
|
||||
Contexts contexts;
|
||||
getContexts(contexts, false);
|
||||
|
||||
if (_incrementalCompileOperation.valid()) _incrementalCompileOperation->removeContexts(contexts);
|
||||
|
||||
// assign new operation
|
||||
_incrementalCompileOperation = ico;
|
||||
|
||||
if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
|
||||
}
|
||||
|
||||
int ViewerBase::run()
|
||||
{
|
||||
if (!isRealized())
|
||||
|
||||
Reference in New Issue
Block a user