Show
Ignore:
Timestamp:
08/22/07 19:17:25 (10 years ago)
Author:
robert
Message:

Refactored the implementation of cull/draw for DrawThreadPerContex? and CullThreadPerCameraDrawThreadPerContex?
and added an experimental draw serialization.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgViewer/Renderer.cpp

    r7212 r7270  
    120120// 
    121121// 
     122//  TheadSafeQueue 
     123 
     124osgUtil::SceneView* Renderer::TheadSafeQueue::takeFront() 
     125{ 
     126    if (_queue.empty()) _block.block(); 
     127 
     128    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     129    if (_queue.empty()) return 0; 
     130 
     131    osgUtil::SceneView* front = _queue.front(); 
     132    _queue.pop_front(); 
     133 
     134    if (_queue.empty()) _block.set(false); 
     135     
     136    return front; 
     137} 
     138 
     139void Renderer::TheadSafeQueue::add(osgUtil::SceneView* sv) 
     140{ 
     141    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     142    _queue.push_back(sv); 
     143    _block.set(true); 
     144} 
     145 
     146static OpenThreads::Mutex s_drawSerializerMutex; 
     147 
     148/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     149// 
     150// 
    122151//  Renderer 
    123  
    124152Renderer::Renderer(osg::Camera* camera): 
    125153    osg::GraphicsOperation("Renderer",true), 
    126154    OpenGLQuerySupport(), 
     155    _serializeDraw(true), 
    127156    _camera(camera), 
    128157    _done(false), 
     
    131160 
    132161    DEBUG_MESSAGE<<"Render::Render() "<<this<<std::endl; 
    133  
    134     _lockHeld[0]  = false; 
    135     _lockHeld[1]  = false; 
    136162 
    137163    _sceneView[0] = new osgUtil::SceneView; 
     
    159185    _sceneView[1]->setCamera(_camera.get(), false); 
    160186 
    161     _currentCull = 0; 
    162     _currentDraw = 0; 
    163  
    164187    // lock the mutex for the current cull SceneView to 
    165188    // prevent the draw traversal from reading from it before the cull traversal has been completed. 
    166     if (!_graphicsThreadDoesCull) 
    167     { 
    168          _mutex[_currentCull].lock(); 
    169          _lockHeld[_currentCull] = true; 
    170     } 
     189    _availableQueue.add(_sceneView[0].get()); 
     190    _availableQueue.add(_sceneView[1].get()); 
     191         
     192    DEBUG_MESSAGE<<"_availableQueue.size()="<<_availableQueue._queue.size()<<std::endl; 
    171193 
    172194    _flushOperation = new osg::FlushDeletedGLObjectsOperation(0.1); 
     
    183205 
    184206    _graphicsThreadDoesCull = flag; 
    185  
    186     _currentCull = 0; 
    187     _currentDraw = 0; 
    188  
    189     if (_graphicsThreadDoesCull) 
    190     { 
    191         // need to disable any locks held by the cull 
    192         if (_lockHeld[0]) 
    193         { 
    194             _lockHeld[0] = false; 
    195             _mutex[0].unlock(); 
    196         } 
    197  
    198         if (_lockHeld[1]) 
    199         { 
    200             _lockHeld[1] = false; 
    201             _mutex[1].unlock(); 
    202         } 
    203  
    204         DEBUG_MESSAGE<<"Disabling locks in Renderer"<<std::endl; 
    205     } 
    206     else 
    207     { 
    208         DEBUG_MESSAGE<<"Enable locks in Renderer"<<std::endl; 
    209      
    210         // need to set a lock for cull 
    211         _mutex[_currentCull].lock(); 
    212         _lockHeld[_currentCull] = true; 
    213     } 
    214207} 
    215208 
     
    255248 
    256249    // note we assume lock has already been aquired. 
    257     osgUtil::SceneView* sceneView = _sceneView[_currentCull].get(); 
     250    osgUtil::SceneView* sceneView = _availableQueue.takeFront(); 
     251 
     252    DEBUG_MESSAGE<<"cull() got SceneView "<<sceneView<<std::endl; 
    258253 
    259254    if (sceneView) 
     
    271266        const osg::FrameStamp* fs = state->getFrameStamp(); 
    272267        int frameNumber = fs ? fs->getFrameNumber() : 0; 
    273  
    274         _frameNumber[_currentCull] = frameNumber; 
    275268 
    276269        // do cull taversal 
     
    297290            stats->setAttribute(frameNumber, "Cull traversal time taken", osg::Timer::instance()->delta_s(beforeCullTick, afterCullTick)); 
    298291        } 
    299     } 
    300  
    301  
    302     // relase the mutex associated with this cull traversal, let the draw commence. 
    303     _lockHeld[_currentCull] = false; 
    304     _mutex[_currentCull].unlock(); 
    305  
    306     // swap which SceneView we need to do cull traversal on next. 
    307     _currentCull = 1 - _currentCull; 
    308  
    309     // aquire the lock for it for the new cull traversal 
    310     _mutex[_currentCull].lock(); 
    311     _lockHeld[_currentCull] = true; 
     292 
     293        _drawQueue.add(sceneView); 
     294 
     295    } 
    312296 
    313297    DEBUG_MESSAGE<<"end cull() "<<this<<std::endl; 
     
    318302    DEBUG_MESSAGE<<"draw() "<<this<<std::endl; 
    319303 
    320     osgUtil::SceneView* sceneView = _sceneView[_currentDraw].get(); 
     304    osg::Timer_t startDrawTick = osg::Timer::instance()->tick(); 
     305 
     306    osgUtil::SceneView* sceneView = _drawQueue.takeFront(); 
     307 
     308 
     309 
     310    DEBUG_MESSAGE<<"draw() got SceneView "<<sceneView<<std::endl; 
    321311 
    322312    osg::GraphicsContext* compileContext = osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()); 
     
    325315    if (sceneView || _done) 
    326316    { 
    327         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex[_currentDraw]); 
    328  
    329317        osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView()); 
    330318        osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0; 
     
    348336        osg::Stats* stats = sceneView->getCamera()->getStats(); 
    349337        osg::State* state = sceneView->getState(); 
    350         int frameNumber = _frameNumber[_currentDraw]; 
     338        int frameNumber = state->getFrameStamp()->getFrameNumber(); 
    351339 
    352340        if (!_initialized) 
     
    363351        } 
    364352 
    365         osg::Timer_t beforeDrawTick = osg::Timer::instance()->tick(); 
    366  
    367353        bool aquireGPUStats = stats && _timerQuerySupported && stats->collectStats("gpu"); 
    368354 
     
    379365        } 
    380366 
    381         sceneView->draw(); 
     367        osg::Timer_t beforeDrawTick; 
     368 
     369        if (_serializeDraw)  
     370        { 
     371            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex); 
     372            beforeDrawTick = osg::Timer::instance()->tick(); 
     373            sceneView->draw(); 
     374        } 
     375        else 
     376        { 
     377            beforeDrawTick = osg::Timer::instance()->tick(); 
     378            sceneView->draw(); 
     379        } 
     380 
     381        _availableQueue.add(sceneView); 
    382382 
    383383        double availableTime = 0.004; // 4 ms 
     
    402402        } 
    403403 
    404         glFlush(); 
    405  
    406  
     404        //glFlush(); 
     405         
    407406        osg::Timer_t afterDrawTick = osg::Timer::instance()->tick(); 
     407 
     408//        osg::notify(osg::NOTICE)<<"Time wait for draw = "<<osg::Timer::instance()->delta_m(startDrawTick, beforeDrawTick)<<std::endl; 
     409//        osg::notify(osg::NOTICE)<<"     time for draw = "<<osg::Timer::instance()->delta_m(beforeDrawTick, afterDrawTick)<<std::endl; 
    408410 
    409411        if (stats && stats->collectStats("rendering")) 
     
    415417    } 
    416418 
    417     _currentDraw = 1-_currentDraw; 
    418  
    419419    DEBUG_MESSAGE<<"end draw() "<<this<<std::endl; 
    420420} 
     
    424424    DEBUG_MESSAGE<<"cull_draw() "<<this<<std::endl; 
    425425 
    426     osgUtil::SceneView* sceneView = _sceneView[_currentDraw].get(); 
     426    osgUtil::SceneView* sceneView = _sceneView[0].get(); 
    427427    if (!sceneView || _done) return; 
    428428 
     
    434434    osg::GraphicsContext* compileContext = osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()); 
    435435    osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0; 
    436  
    437     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex[_currentDraw]); 
    438436 
    439437    if (_done) 
     
    480478#endif 
    481479 
     480 
    482481    // do draw traveral 
    483482    if (aquireGPUStats)  
     
    487486    } 
    488487 
    489     sceneView->draw(); 
     488    osg::Timer_t beforeDrawTick; 
     489 
     490    if (_serializeDraw)  
     491    { 
     492        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex); 
     493         
     494        beforeDrawTick = osg::Timer::instance()->tick(); 
     495        sceneView->draw(); 
     496    } 
     497    else 
     498    { 
     499        beforeDrawTick = osg::Timer::instance()->tick(); 
     500        sceneView->draw(); 
     501    } 
    490502 
    491503    double availableTime = 0.004; // 4 ms 
     
    520532        stats->setAttribute(frameNumber, "Cull traversal time taken", osg::Timer::instance()->delta_s(beforeCullTick, afterCullTick)); 
    521533 
    522         stats->setAttribute(frameNumber, "Draw traversal begin time", osg::Timer::instance()->delta_s(_startTick, afterCullTick)); 
     534        stats->setAttribute(frameNumber, "Draw traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeDrawTick)); 
    523535        stats->setAttribute(frameNumber, "Draw traversal end time", osg::Timer::instance()->delta_s(_startTick, afterDrawTick)); 
    524         stats->setAttribute(frameNumber, "Draw traversal time taken", osg::Timer::instance()->delta_s(afterCullTick, afterDrawTick)); 
     536        stats->setAttribute(frameNumber, "Draw traversal time taken", osg::Timer::instance()->delta_s(beforeDrawTick, afterDrawTick)); 
    525537    } 
    526538 
     
    555567    _done = true; 
    556568 
    557     if (_lockHeld[0]) 
    558     { 
    559         _lockHeld[0] = false; 
    560         _mutex[0].unlock(); 
    561     } 
    562  
    563     if (_lockHeld[1]) 
    564     { 
    565         _lockHeld[1] = false; 
    566         _mutex[1].unlock(); 
    567     } 
    568 } 
     569    _availableQueue.release(); 
     570    _drawQueue.release(); 
     571}