diff --git a/include/osg/Camera b/include/osg/Camera index 987549fd1..376029201 100644 --- a/include/osg/Camera +++ b/include/osg/Camera @@ -541,6 +541,11 @@ class OSG_EXPORT Camera : public Transform, public CullSettings } } + /** Set the process affinity hint for any Camera Threads that are/will be assigned to this Camera.*/ + void setProcessorAffinity(const OpenThreads::Affinity& affinity); + OpenThreads::Affinity& getProcessorAffinity() { return _affinity; } + const OpenThreads::Affinity& getProcessorAffinity() const { return _affinity; } + /** Create a operation thread for this camera.*/ void createCameraThread(); @@ -707,6 +712,7 @@ class OSG_EXPORT Camera : public Transform, public CullSettings unsigned int _attachmentMapModifiedCount; + OpenThreads::Affinity _affinity; ref_ptr _cameraThread; ref_ptr _graphicsContext; diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index 530c3fe97..33d7b0b12 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -145,6 +145,9 @@ class OSG_EXPORT GraphicsContext : public Object bool overrideRedirect; DisplaySettings::SwapMethod swapMethod; + + // hint of what affinity to use for any thrads associated with the graphics context created using these Traits + OpenThreads::Affinity affinity; }; /** Simple resolution structure used by WindowingSystemInterface to get and set screen resolution. diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 14388b503..428d0f4bb 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -126,9 +126,9 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl }; - virtual void setProcessorAffinty(const OpenThreads::Affinity& affinity); - OpenThreads::Affinity& getProcessorAffinty() { return _affinity; } - const OpenThreads::Affinity& getProcessorAffinty() const { return _affinity; } + virtual void setProcessorAffinity(const OpenThreads::Affinity& affinity); + OpenThreads::Affinity& getProcessorAffinity() { return _affinity; } + const OpenThreads::Affinity& getProcessorAffinity() const { return _affinity; } void setUpThreads(unsigned int totalNumThreads=2, unsigned int numHttpThreads=1); diff --git a/include/osgViewer/ViewerBase b/include/osgViewer/ViewerBase index 37da75753..66418f653 100644 --- a/include/osgViewer/ViewerBase +++ b/include/osgViewer/ViewerBase @@ -59,6 +59,15 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object /** set up windows and associated threads.*/ virtual void realize() = 0; + + /** analyse the viewer configuration and select an appropriate Affinity for main thread, and any graphics, camera threads and database pagers that are required.*/ + virtual void configureAffinity(); + + /** Set the processor affinity of main thread.*/ + virtual void setProcessorAffinty(const OpenThreads::Affinity& affinity) { _affinity = affinity; } + OpenThreads::Affinity& getProcessorAffinty() { return _affinity; } + const OpenThreads::Affinity& getProcessorAffinty() const { return _affinity; } + enum ThreadingModel { SingleThreaded, @@ -283,7 +292,7 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object virtual void getUsage(osg::ApplicationUsage& usage) const = 0; bool getRequestRedraw() const { return _requestRedraw; } - + bool getRequestContinousUpdate() const { return _requestContinousUpdate; } protected: @@ -318,6 +327,7 @@ protected: bool _quitEventSetsDone; bool _releaseContextAtEndOfFrameHint; + OpenThreads::Affinity _affinity; ThreadingModel _threadingModel; bool _threadsRunning; diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index e4132a68f..0da0914de 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -74,6 +74,7 @@ Camera::Camera(const Camera& camera,const CopyOp& copyop): _implicitBufferAttachmentRenderMask(camera._implicitBufferAttachmentRenderMask), _implicitBufferAttachmentResolveMask(camera._implicitBufferAttachmentResolveMask), _attachmentMapModifiedCount(camera._attachmentMapModifiedCount), + _affinity(camera._affinity), _initialDrawCallback(camera._initialDrawCallback), _preDrawCallback(camera._preDrawCallback), _postDrawCallback(camera._postDrawCallback), @@ -521,6 +522,12 @@ void Camera::resize(int width, int height, int resizeMask) } } +void Camera::setProcessorAffinity(const OpenThreads::Affinity& affinity) +{ + _affinity = affinity; + + if (_cameraThread.valid()) _cameraThread->setProcessorAffinity(affinity); +} void Camera::createCameraThread() { @@ -543,6 +550,8 @@ void Camera::setCameraThread(OperationThread* gt) _cameraThread = gt; + _cameraThread->setProcessorAffinity(_affinity); + if (_cameraThread.valid()) { _cameraThread->setParent(this); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 2c1b82719..b8fce4436 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -589,6 +589,11 @@ void GraphicsContext::createGraphicsThread() if (!_graphicsThread) { setGraphicsThread(new GraphicsThread); + + if (_traits.valid()) + { + _graphicsThread->setProcessorAffinity(_traits->affinity); + } } } diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 44ee17cd5..852b14491 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -1190,7 +1190,7 @@ DatabasePager::DatabasePager(const DatabasePager& rhs) _databaseThreads.push_back(new DatabaseThread(**dt_itr,this)); } - setProcessorAffinty(rhs.getProcessorAffinty()); + setProcessorAffinity(rhs.getProcessorAffinity()); _activePagedLODList = rhs._activePagedLODList->clone(); @@ -1249,7 +1249,7 @@ DatabasePager* DatabasePager::create() new DatabasePager; } -void DatabasePager::setProcessorAffinty(const OpenThreads::Affinity& affinity) +void DatabasePager::setProcessorAffinity(const OpenThreads::Affinity& affinity) { _affinity = affinity; diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index d4b9a2567..fcb12326b 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -627,7 +627,6 @@ void CompositeViewer::realize() // attach contexts to _incrementalCompileOperation if attached. if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts); - bool grabFocus = true; if (grabFocus) { @@ -655,9 +654,6 @@ void CompositeViewer::realize() if (osg::DisplaySettings::instance()->getCompileContextsHint()) { - int numProcessors = osg::maximum(1, OpenThreads::GetNumberOfProcessors()); - int processNum = 0; - for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i) { osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i); @@ -665,10 +661,7 @@ void CompositeViewer::realize() if (gc) { gc->createGraphicsThread(); - gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); gc->getGraphicsThread()->startThread(); - - ++processNum; } } } diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index aef8c7878..8371f6ef6 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -171,12 +171,12 @@ Viewer::Viewer(osg::ArgumentParser& arguments) if (ss3d) { - setThreadingModel(SingleThreaded); + //setThreadingModel(SingleThreaded); setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get()); } else { - setThreadingModel(SingleThreaded); + //setThreadingModel(SingleThreaded); setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get()); } } @@ -604,9 +604,6 @@ void Viewer::realize() if (osg::DisplaySettings::instance()->getCompileContextsHint()) { - int numProcessors = osg::maximum(1, OpenThreads::GetNumberOfProcessors()); - int processNum = 0; - for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i) { osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i); @@ -614,10 +611,7 @@ void Viewer::realize() if (gc) { gc->createGraphicsThread(); - gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); gc->getGraphicsThread()->startThread(); - - ++processNum; } } } diff --git a/src/osgViewer/ViewerBase.cpp b/src/osgViewer/ViewerBase.cpp index 9642a7a4d..c3c1eb541 100644 --- a/src/osgViewer/ViewerBase.cpp +++ b/src/osgViewer/ViewerBase.cpp @@ -57,6 +57,7 @@ void ViewerBase::viewerBaseInit() _keyEventSetsDone = osgGA::GUIEventAdapter::KEY_Escape; _quitEventSetsDone = true; _releaseContextAtEndOfFrameHint = true; + _threadingModel = AutomaticSelection; _threadsRunning = false; _endBarrierPosition = AfterSwapBuffers; @@ -81,6 +82,95 @@ void ViewerBase::viewerBaseInit() } } +void ViewerBase::configureAffinity() +{ + unsigned int numProcessors = OpenThreads::GetNumberOfProcessors(); + OSG_NOTICE<<"ViewerBase::configureAffinity() numProcessors="<setProcessorAffinity(OpenThreads::Affinity((availableProcessor++)%numProcessors)); + } + } + + if (requiresDrawThreads) + { + Contexts contexts; + getContexts(contexts); + + for(Contexts::iterator itr = contexts.begin(); + itr != contexts.end(); + ++itr) + { + if ((*itr)->getTraits()) + { + osg::GraphicsContext::Traits* traits = const_cast((*itr)->getTraits()); + traits->affinity = OpenThreads::Affinity((availableProcessor++)%numProcessors); + } + } + } + + if (availableProcessor DatabasePagers; + DatabasePagers databasePagers; + + for(Scenes::iterator itr = scenes.begin(); + itr != scenes.end(); + ++itr) + { + if ((*itr)->getDatabasePager()) databasePagers.push_back((*itr)->getDatabasePager()); + } + + OSG_NOTICE<<" databasePagers = "<setProcessorAffinity(OpenThreads::Affinity(availableProcessor, numProcessors-availableProcessor)); + } + } +} + void ViewerBase::setThreadingModel(ThreadingModel threadingModel) { if (_threadingModel == threadingModel) return; @@ -140,37 +230,40 @@ ViewerBase::ThreadingModel ViewerBase::suggestBestThreadingModel() void ViewerBase::setUpThreading() { + if (_threadingModel==AutomaticSelection) + { + _threadingModel = suggestBestThreadingModel(); + } + + // configure affinity before we start threads + configureAffinity(); + Contexts contexts; getContexts(contexts); + // set up affinity of main thread + OpenThreads::SetProcessorAffinityOfCurrentThread(_affinity); + + // set up the number of graphics contexts. + { + Scenes scenes; + getScenes(scenes); + + for(Scenes::iterator scitr = scenes.begin(); + scitr != scenes.end(); + ++scitr) + { + if ((*scitr)->getSceneData()) + { + // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it. + (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); + } + } + } + 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); - - Scenes scenes; - getScenes(scenes); - - for(Scenes::iterator scitr = scenes.begin(); - scitr != scenes.end(); - ++scitr) - { - if ((*scitr)->getSceneData()) - { - // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it. - (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); - } - } - } - } } else { @@ -272,8 +365,6 @@ void ViewerBase::startThreading() // release any context held by the main thread. releaseContext(); - _threadingModel = _threadingModel==AutomaticSelection ? suggestBestThreadingModel() : _threadingModel; - Contexts contexts; getContexts(contexts); @@ -325,9 +416,6 @@ void ViewerBase::startThreading() } } - int numProcessors = osg::maximum(1, OpenThreads::GetNumberOfProcessors()); - bool affinity = numProcessors>1; - Contexts::iterator citr; unsigned int numViewerDoubleBufferedRenderingOperation = 0; @@ -383,13 +471,9 @@ void ViewerBase::startThreading() osg::ref_ptr swapOp = new osg::SwapBuffersOperation(); - typedef std::map ThreadAffinityMap; - ThreadAffinityMap threadAffinityMap; - - unsigned int processNum = 1; for(citr = contexts.begin(); citr != contexts.end(); - ++citr, ++processNum) + ++citr) { osg::GraphicsContext* gc = (*citr); @@ -404,9 +488,6 @@ void ViewerBase::startThreading() // create the a graphics thread for this context gc->createGraphicsThread(); - if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); - threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors; - // add the startRenderingBarrier if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get()); @@ -438,14 +519,11 @@ void ViewerBase::startThreading() for(camItr = cameras.begin(); camItr != cameras.end(); - ++camItr, ++processNum) + ++camItr) { osg::Camera* camera = *camItr; camera->createCameraThread(); - if (affinity) camera->getCameraThread()->setProcessorAffinity(processNum % numProcessors); - threadAffinityMap[camera->getCameraThread()] = processNum % numProcessors; - osg::GraphicsContext* gc = camera->getGraphicsContext(); // add the startRenderingBarrier @@ -479,34 +557,6 @@ void ViewerBase::startThreading() } } -#if 0 - if (affinity) - { - OpenThreads::SetProcessorAffinityOfCurrentThread(0); - if (_scene.valid() && _scene->getDatabasePager()) - { -#if 0 - _scene->getDatabasePager()->setProcessorAffinity(1); -#else - _scene->getDatabasePager()->setProcessorAffinity(0); -#endif - } - } -#endif - -#if 0 - if (affinity) - { - for(ThreadAffinityMap::iterator titr = threadAffinityMap.begin(); - titr != threadAffinityMap.end(); - ++titr) - { - titr->first->setProcessorAffinity(titr->second); - } - } -#endif - - for(citr = contexts.begin(); citr != contexts.end(); ++citr)