Moved compile setup from osgViewer::ViewerBase into osgViewer::Renderer to

avoid threading issues associated with compile running in a parallel with 
update/cull on the first frame.

Also added automatic recompile when a new SceneData is applied to a View.
This commit is contained in:
Robert Osfield 2008-05-10 17:04:02 +00:00
parent 0dfba5dbe5
commit 4d7b2edd4c
4 changed files with 43 additions and 7 deletions

View File

@ -66,10 +66,16 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation, public OpenGLQu
void setGraphicsThreadDoesCull(bool flag); void setGraphicsThreadDoesCull(bool flag);
bool getGraphicsThreadDoesCull() const { return _graphicsThreadDoesCull; } bool getGraphicsThreadDoesCull() const { return _graphicsThreadDoesCull; }
virtual void cull(); virtual void cull();
virtual void draw(); virtual void draw();
virtual void cull_draw(); virtual void cull_draw();
virtual void compile();
void setCompileOnNextDraw(bool flag) { _compileOnNextDraw = flag; }
bool getCompileOnNextDraw() const { return _compileOnNextDraw; }
virtual void operator () (osg::Object* object); virtual void operator () (osg::Object* object);
virtual void operator () (osg::GraphicsContext* context); virtual void operator () (osg::GraphicsContext* context);
@ -136,6 +142,7 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation, public OpenGLQu
bool _done; bool _done;
bool _graphicsThreadDoesCull; bool _graphicsThreadDoesCull;
bool _compileOnNextDraw;
osg::ref_ptr<osgUtil::SceneView> _sceneView[2]; osg::ref_ptr<osgUtil::SceneView> _sceneView[2];

View File

@ -167,7 +167,8 @@ Renderer::Renderer(osg::Camera* camera):
_conservativeTimeRatio(0.5), _conservativeTimeRatio(0.5),
_camera(camera), _camera(camera),
_done(false), _done(false),
_graphicsThreadDoesCull(true) _graphicsThreadDoesCull(true),
_compileOnNextDraw(true)
{ {
DEBUG_MESSAGE<<"Render::Render() "<<this<<std::endl; DEBUG_MESSAGE<<"Render::Render() "<<this<<std::endl;
@ -251,6 +252,22 @@ void Renderer::updateSceneView(osgUtil::SceneView* sceneView)
if (view) _startTick = view->getStartTick(); if (view) _startTick = view->getStartTick();
} }
void Renderer::compile()
{
DEBUG_MESSAGE<<"Renderer::compile()"<<std::endl;
_compileOnNextDraw = false;
osgUtil::SceneView* sceneView = _sceneView[0].get();
if (!sceneView || _done) return;
if (sceneView->getSceneData())
{
osgUtil::GLObjectsVisitor glov;
glov.setState(sceneView->getState());
sceneView->getSceneData()->accept(glov);
}
}
void Renderer::cull() void Renderer::cull()
{ {
@ -322,8 +339,13 @@ void Renderer::draw()
osg::GraphicsContext* compileContext = sceneView ? osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()) : 0; osg::GraphicsContext* compileContext = sceneView ? osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()) : 0;
osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0; osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0;
if (sceneView || _done) if (sceneView && !_done)
{ {
if (_compileOnNextDraw)
{
compile();
}
osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView()); osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());
osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0; osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0;
@ -431,6 +453,11 @@ void Renderer::cull_draw()
osgUtil::SceneView* sceneView = _sceneView[0].get(); osgUtil::SceneView* sceneView = _sceneView[0].get();
if (!sceneView || _done) return; if (!sceneView || _done) return;
if (_compileOnNextDraw)
{
compile();
}
updateSceneView(sceneView); updateSceneView(sceneView);
osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView()); osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());

View File

@ -1634,6 +1634,10 @@ void View::assignSceneDataToCameras()
{ {
_camera->removeChildren(0,_camera->getNumChildren()); _camera->removeChildren(0,_camera->getNumChildren());
if (sceneData) _camera->addChild(sceneData); if (sceneData) _camera->addChild(sceneData);
Renderer* renderer = dynamic_cast<Renderer*>(_camera->getRenderer());
if (renderer) renderer->setCompileOnNextDraw(true);
} }
for(unsigned i=0; i<getNumSlaves(); ++i) for(unsigned i=0; i<getNumSlaves(); ++i)
@ -1643,6 +1647,9 @@ void View::assignSceneDataToCameras()
{ {
slave._camera->removeChildren(0,slave._camera->getNumChildren()); slave._camera->removeChildren(0,slave._camera->getNumChildren());
if (sceneData) slave._camera->addChild(sceneData); if (sceneData) slave._camera->addChild(sceneData);
Renderer* renderer = dynamic_cast<Renderer*>(slave._camera->getRenderer());
if (renderer) renderer->setCompileOnNextDraw(true);
} }
} }
} }

View File

@ -26,8 +26,6 @@
#include <osgUtil/Optimizer> #include <osgUtil/Optimizer>
#include <osgUtil/IntersectionVisitor> #include <osgUtil/IntersectionVisitor>
#include <osgUtil/GLObjectsVisitor>
#include <osgUtil/RenderLeaf>
static osg::ApplicationUsageProxy ViewerBase_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_CONFIG_FILE <filename>","Specify a viewer configuration file to load by default."); static osg::ApplicationUsageProxy ViewerBase_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_CONFIG_FILE <filename>","Specify a viewer configuration file to load by default.");
static osg::ApplicationUsageProxy ViewerBase_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_THREADING <value>","Set the threading model using by Viewer, <value> can be SingleThreaded, CullDrawThreadPerContext, DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext."); static osg::ApplicationUsageProxy ViewerBase_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_THREADING <value>","Set the threading model using by Viewer, <value> can be SingleThreaded, CullDrawThreadPerContext, DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext.");
@ -281,7 +279,6 @@ void ViewerBase::startThreading()
// using multi-threading so make sure that new objects are allocated with thread safe ref/unref // using multi-threading so make sure that new objects are allocated with thread safe ref/unref
osg::Referenced::setThreadSafeReferenceCounting(true); osg::Referenced::setThreadSafeReferenceCounting(true);
Scenes scenes; Scenes scenes;
getScenes(scenes); getScenes(scenes);
for(Scenes::iterator scitr = scenes.begin(); for(Scenes::iterator scitr = scenes.begin();
@ -375,8 +372,6 @@ void ViewerBase::startThreading()
if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors; threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors;
gc->getGraphicsThread()->add(new osgUtil::GLObjectsOperation());
// add the startRenderingBarrier // add the startRenderingBarrier
if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get()); if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get());