void Viewer::realize() { //OSG_INFO<<"Viewer::realize()"<<std::endl; // 保存了osg::GraphicsContext指针的向量组 Contexts contexts; // 获取所有的图形上下文,并保存到这个向量组中来 getContexts(contexts); // 如果没有得到任何图形上下文的话,就说明仿真系统还没有合适的显示平台 // 这个时候就需要创建一个缺省的GraphicsContext设备,并再次执行getContexts if (contexts.empty()) { OSG_INFO<<"Viewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl; // no windows are already set up so set up a default view // 创建缺省GraphicsContext设备的方法有以下几种: // 读取OSG_CONFIG_FILE环境变量的内容,如果用户在这个环境变量中定义了一个文件路径的话 // 使用配置文件设置当前视景器 const char* ptr = 0; if ((ptr = getenv("OSG_CONFIG_FILE")) != 0) { readConfiguration(ptr); } else { int screenNum = -1; if ((ptr = getenv("OSG_SCREEN")) != 0) { if (strlen(ptr)!=0) screenNum = atoi(ptr); else screenNum = -1; } int x = -1, y = -1, width = -1, height = -1; if ((ptr = getenv("OSG_WINDOW")) != 0) { std::istringstream iss(ptr); iss >> x >> y >> width >> height; } if (width>0 && height>0) { if (screenNum>=0) setUpViewInWindow(x, y, width, height, screenNum); else setUpViewInWindow(x,y,width,height); } else if (screenNum>=0) { setUpViewOnSingleScreen(screenNum); } else { setUpViewAcrossAllScreens(); } }
void Viewer::realize() { //OSG_INFO<<"Viewer::realize()"<<std::endl; setCameraWithFocus(0); Contexts contexts; getContexts(contexts); if (contexts.empty()) { OSG_INFO<<"Viewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl; // no windows are already set up so set up a default view const char* ptr = 0; if ((ptr = getenv("OSG_CONFIG_FILE")) != 0) { readConfiguration(ptr); } else { int screenNum = -1; if ((ptr = getenv("OSG_SCREEN")) != 0) { if (strlen(ptr)!=0) screenNum = atoi(ptr); else screenNum = -1; } int x = -1, y = -1, width = -1, height = -1; if ((ptr = getenv("OSG_WINDOW")) != 0) { std::istringstream iss(ptr); iss >> x >> y >> width >> height; } if (width>0 && height>0) { if (screenNum>=0) setUpViewInWindow(x, y, width, height, screenNum); else setUpViewInWindow(x,y,width,height); } else if (screenNum>=0) { setUpViewOnSingleScreen(screenNum); } else { setUpViewAcrossAllScreens(); } }
ViewerBase::ThreadingModel ViewerBase::suggestBestThreadingModel() { const char* str = getenv("OSG_THREADING"); if (str) { if (strcmp(str,"SingleThreaded")==0) return SingleThreaded; else if (strcmp(str,"CullDrawThreadPerContext")==0) return CullDrawThreadPerContext; else if (strcmp(str,"DrawThreadPerContext")==0) return DrawThreadPerContext; else if (strcmp(str,"CullThreadPerCameraDrawThreadPerContext")==0) return CullThreadPerCameraDrawThreadPerContext; } Contexts contexts; getContexts(contexts); if (contexts.empty()) return SingleThreaded; #if 0 // temporary hack to disable multi-threading under Windows till we find good solutions for // crashes that users are seeing. return SingleThreaded; #endif Cameras cameras; getCameras(cameras); if (cameras.empty()) return SingleThreaded; int numProcessors = OpenThreads::GetNumberOfProcessors(); if (contexts.size()==1) { if (numProcessors==1) return SingleThreaded; else return DrawThreadPerContext; } #if 1 if (numProcessors >= static_cast<int>(cameras.size()+contexts.size())) { return CullThreadPerCameraDrawThreadPerContext; } #endif return DrawThreadPerContext; }
void CompositeViewer::realize() { //OSG_INFO<<"CompositeViewer::realize()"<<std::endl; setCameraWithFocus(0); if (_views.empty()) { OSG_NOTICE<<"CompositeViewer::realize() - No views to realize."<<std::endl; _done = true; return; } Contexts contexts; getContexts(contexts); if (contexts.empty()) { OSG_INFO<<"CompositeViewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl; // no windows are already set up so set up a default view _views[0]->setUpViewAcrossAllScreens(); getContexts(contexts); } if (contexts.empty()) { OSG_NOTICE<<"CompositeViewer::realize() - failed to set up any windows"<<std::endl; _done = true; return; } unsigned int maxTexturePoolSize = osg::DisplaySettings::instance()->getMaxTexturePoolSize(); unsigned int maxBufferObjectPoolSize = osg::DisplaySettings::instance()->getMaxBufferObjectPoolSize(); for(Contexts::iterator citr = contexts.begin(); citr != contexts.end(); ++citr) { osg::GraphicsContext* gc = *citr; // set the pool sizes, 0 the default will result in no GL object pools. gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize); gc->getState()->setMaxBufferObjectPoolSize(maxBufferObjectPoolSize); gc->realize(); if (_realizeOperation.valid() && gc->valid()) { gc->makeCurrent(); (*_realizeOperation)(gc); gc->releaseContext(); } } // attach contexts to _incrementalCompileOperation if attached. if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts); bool grabFocus = true; if (grabFocus) { for(Contexts::iterator citr = contexts.begin(); citr != contexts.end(); ++citr) { osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr); if (gw) { gw->grabFocusIfPointerInWindow(); } } } startThreading(); // initialize the global timer to be relative to the current time. osg::Timer::instance()->setStartTick(); // pass on the start tick to all the associated eventqueues setStartTick(osg::Timer::instance()->getStartTick()); if (osg::DisplaySettings::instance()->getCompileContextsHint()) { int numProcessors = OpenThreads::GetNumberOfProcessors(); int processNum = 0; for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i) { osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i); if (gc) { gc->createGraphicsThread(); gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors); gc->getGraphicsThread()->startThread(); ++processNum; } } } }
void ViewerBase::startThreading() { if (_threadsRunning) return; OSG_INFO<<"Viewer::startThreading() - starting threading"<<std::endl; // release any context held by the main thread. releaseContext(); _threadingModel = _threadingModel==AutomaticSelection ? suggestBestThreadingModel() : _threadingModel; Contexts contexts; getContexts(contexts); OSG_INFO<<"Viewer::startThreading() - contexts.size()="<<contexts.size()<<std::endl; Cameras cameras; getCameras(cameras); unsigned int numThreadsOnStartBarrier = 0; unsigned int numThreadsOnEndBarrier = 0; switch(_threadingModel) { case(SingleThreaded): numThreadsOnStartBarrier = 1; numThreadsOnEndBarrier = 1; return; case(CullDrawThreadPerContext): numThreadsOnStartBarrier = contexts.size()+1; numThreadsOnEndBarrier = contexts.size()+1; break; case(DrawThreadPerContext): numThreadsOnStartBarrier = 1; numThreadsOnEndBarrier = 1; break; case(CullThreadPerCameraDrawThreadPerContext): numThreadsOnStartBarrier = cameras.size()+1; numThreadsOnEndBarrier = 1; break; default: OSG_NOTICE<<"Error: Threading model not selected"<<std::endl; return; } // using multi-threading so make sure that new objects are allocated with thread safe ref/unref osg::Referenced::setThreadSafeReferenceCounting(true); Scenes scenes; getScenes(scenes); for(Scenes::iterator scitr = scenes.begin(); scitr != scenes.end(); ++scitr) { if ((*scitr)->getSceneData()) { OSG_INFO<<"Making scene thread safe"<<std::endl; // make sure that existing scene graph objects are allocated with thread safe ref/unref (*scitr)->getSceneData()->setThreadSafeRefUnref(true); // 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()); } } int numProcessors = OpenThreads::GetNumberOfProcessors(); bool affinity = numProcessors>1; Contexts::iterator citr; unsigned int numViewerDoubleBufferedRenderingOperation = 0; bool graphicsThreadsDoesCull = _threadingModel == CullDrawThreadPerContext || _threadingModel==SingleThreaded; for(Cameras::iterator camItr = cameras.begin(); camItr != cameras.end(); ++camItr) { osg::Camera* camera = *camItr; Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer()); if (renderer) { renderer->setGraphicsThreadDoesCull(graphicsThreadsDoesCull); renderer->setDone(false); renderer->reset(); ++numViewerDoubleBufferedRenderingOperation; } } if (_threadingModel==CullDrawThreadPerContext) { _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; _endDynamicDrawBlock = 0; } else if (_threadingModel==DrawThreadPerContext || _threadingModel==CullThreadPerCameraDrawThreadPerContext) { _startRenderingBarrier = 0; _endRenderingDispatchBarrier = 0; _endDynamicDrawBlock = new osg::EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation); #ifndef OSGUTIL_RENDERBACKEND_USE_REF_PTR if (!osg::Referenced::getDeleteHandler()) osg::Referenced::setDeleteHandler(new osg::DeleteHandler(2)); else osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(2); #endif } if (numThreadsOnStartBarrier>1) { _startRenderingBarrier = new osg::BarrierOperation(numThreadsOnStartBarrier, osg::BarrierOperation::NO_OPERATION); } if (numThreadsOnEndBarrier>1) { _endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsOnEndBarrier, _endBarrierOperation); } osg::ref_ptr<osg::BarrierOperation> swapReadyBarrier = contexts.empty() ? 0 : new osg::BarrierOperation(contexts.size(), osg::BarrierOperation::NO_OPERATION); osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation(); typedef std::map<OpenThreads::Thread*, int> ThreadAffinityMap; ThreadAffinityMap threadAffinityMap; unsigned int processNum = 1; for(citr = contexts.begin(); citr != contexts.end(); ++citr, ++processNum) { osg::GraphicsContext* gc = (*citr); if (!gc->isRealized()) { OSG_INFO<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl; gc->realize(); } gc->getState()->setDynamicObjectRenderingCompletedCallback(_endDynamicDrawBlock.get()); // 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()); // add the rendering operation itself. gc->getGraphicsThread()->add(new osg::RunOperations()); if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==BeforeSwapBuffers && _endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } if (swapReadyBarrier.valid()) gc->getGraphicsThread()->add(swapReadyBarrier.get()); // add the swap buffers gc->getGraphicsThread()->add(swapOp.get()); if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==AfterSwapBuffers && _endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } } if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && numThreadsOnStartBarrier>1) { Cameras::iterator camItr; for(camItr = cameras.begin(); camItr != cameras.end(); ++camItr, ++processNum) { 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 if (_startRenderingBarrier.valid()) camera->getCameraThread()->add(_startRenderingBarrier.get()); Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer()); renderer->setGraphicsThreadDoesCull(false); camera->getCameraThread()->add(renderer); if (_endRenderingDispatchBarrier.valid()) { // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); } } for(camItr = cameras.begin(); camItr != cameras.end(); ++camItr) { osg::Camera* camera = *camItr; if (camera->getCameraThread() && !camera->getCameraThread()->isRunning()) { OSG_INFO<<" camera->getCameraThread()-> "<<camera->getCameraThread()<<std::endl; camera->getCameraThread()->startThread(); } } } #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) { osg::GraphicsContext* gc = (*citr); if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning()) { OSG_INFO<<" gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl; gc->getGraphicsThread()->startThread(); // OpenThreads::Thread::YieldCurrentThread(); } } _threadsRunning = true; OSG_INFO<<"Set up threading"<<std::endl; }