From b3b420de5dc43c6909498f469978378c697a8b69 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 8 Feb 2007 12:14:26 +0000 Subject: [PATCH] Updated the handling of closing of windows --- include/osgViewer/Viewer | 11 ++-- src/osgViewer/Viewer.cpp | 122 ++++++++++++++++++--------------------- 2 files changed, 61 insertions(+), 72 deletions(-) diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index 7887f22ab..868b7b038 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -149,14 +149,15 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View /** Get the graphics operation to call on realization of the viewers graphics windows.*/ osg::Operation* getRealizeOperation() { return _realizeOperation.get(); } + /** Set up the threading and processor affinity as per the viewers threading model.*/ + void setUpThreading(); + /** Stop any threads begin run by viewer.*/ void stopThreading(); - /** Start any threads required by the viewer, as per viewers ThreadingModel.*/ + /** Start any threads required by the viewer.*/ void startThreading(); - - /** Set up the Operations to render the various viewer cameras on the viewers graphics windows.*/ void setUpRenderingSupport(); @@ -199,9 +200,7 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View osg::ref_ptr _endRenderingDispatchBarrier; osg::ref_ptr _endDynamicDrawBlock; - unsigned int computeNumberOfThreadsIncludingMainRequired(); - - unsigned int _numThreadsOnBarrier; + unsigned int _numWindowsOpenAtLastSetUpThreading; typedef std::list< osg::ref_ptr > SceneViews; SceneViews _sceneViews; diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index fb9ed0834..2e7f9a7f5 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -548,7 +548,7 @@ Viewer::Viewer(): _threadsRunning(false), _useMainThreadForRenderingTraversal(true), _endBarrierPosition(AfterSwapBuffers), - _numThreadsOnBarrier(0) + _numWindowsOpenAtLastSetUpThreading(0) { _frameStamp = new osg::FrameStamp; _frameStamp->setFrameNumber(0); @@ -709,6 +709,40 @@ void Viewer::setThreadingModel(ThreadingModel threadingModel) if (_threadingModel!=SingleThreaded) startThreading(); } +void Viewer::setUpThreading() +{ + Contexts contexts; + getContexts(contexts); + + _numWindowsOpenAtLastSetUpThreading = contexts.size(); + + if (_threadingModel==SingleThreaded) + { + if (_threadsRunning) stopThreading(); + else + { + // we'll set processor affinity here to help single threaded apps + // with multiple processor cores, and using the database pager. + int numProcessors = OpenThreads::GetNumberOfProcessors(); + bool affinity = numProcessors>1; + if (affinity) + { + OpenThreads::SetProcessorAffinityOfCurrentThread(0); + if (_scene.valid() && _scene->getDatabasePager()) + { + _scene->getDatabasePager()->setProcessorAffinity(1); + } + } + } + } + else + { + if (!_threadsRunning) startThreading(); + } + +} + + void Viewer::setUseMainThreadForRenderingTraversals(bool flag) { if (_useMainThreadForRenderingTraversal==flag) return; @@ -821,8 +855,9 @@ void Viewer::stopThreading() _threadsRunning = false; _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; - _numThreadsOnBarrier = 0; _endDynamicDrawBlock = 0; + _numWindowsOpenAtLastSetUpThreading = contexts.size(); + osg::notify(osg::INFO)<<"Viewer::stopThreading() - stopped threading."<resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); } - osg::notify(osg::INFO)<<"_numThreadsOnBarrier = "<<_numThreadsOnBarrier<1; @@ -1044,10 +1042,10 @@ void Viewer::startThreading() _endDynamicDrawBlock = new EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation); } - if (_numThreadsOnBarrier>1) + if (numThreadsOnBarrier>1) { - _startRenderingBarrier = new osg::BarrierOperation(_numThreadsOnBarrier, osg::BarrierOperation::NO_OPERATION); - _endRenderingDispatchBarrier = new osg::BarrierOperation(_numThreadsOnBarrier, osg::BarrierOperation::NO_OPERATION); + _startRenderingBarrier = new osg::BarrierOperation(numThreadsOnBarrier, osg::BarrierOperation::NO_OPERATION); + _endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsOnBarrier, osg::BarrierOperation::NO_OPERATION); } @@ -1070,13 +1068,8 @@ void Viewer::startThreading() // create the a graphics thread for this context gc->createGraphicsThread(); -#if 1 if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); - threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors; -#else - if (affinity) gc->getGraphicsThread()->setProcessorAffinity(1); -#endif gc->getGraphicsThread()->add(new ViewerCompileOperation(getSceneData())); @@ -1108,7 +1101,7 @@ void Viewer::startThreading() } - if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && _numThreadsOnBarrier>1) + if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && numThreadsOnBarrier>1) { Cameras::iterator camItr = cameras.begin(); if (_useMainThreadForRenderingTraversal) ++camItr; @@ -1120,12 +1113,9 @@ void Viewer::startThreading() osg::Camera* camera = *camItr; camera->createCameraThread(); -#if 1 if (affinity) camera->getCameraThread()->setProcessorAffinity(processNum % numProcessors); threadAffinityMap[camera->getCameraThread()] = processNum % numProcessors; -#else - if (affinity) camera->getCameraThread()->setProcessorAffinity(1); -#endif + osg::GraphicsContext* gc = camera->getGraphicsContext(); // add the startRenderingBarrier @@ -1205,22 +1195,23 @@ void Viewer::startThreading() } _threadsRunning = true; + _numWindowsOpenAtLastSetUpThreading = contexts.size(); osg::notify(osg::INFO)<<"Set up threading"< 1) startThreading(); + startThreading(); } - - if (numThreadsIncludingMainThread==0) _done = true; + + if (_numWindowsOpenAtLastSetUpThreading==0) _done = true; } @@ -1550,8 +1541,7 @@ void Viewer::realize() // pass on the start tick to all the associated eventqueues setStartTick(osg::Timer::instance()->getStartTick()); - startThreading(); - + setUpThreading(); }