root/OpenSceneGraph/trunk/src/osgViewer/Renderer.cpp @ 9552

Revision 9552, 24.4 kB (checked in by robert, 5 years ago)

Ported onscreen camera stats across to using thread safe stats collection

RevLine 
[7178]1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <stdio.h>
15
16#include <osg/GLExtensions>
17
18#include <osgUtil/Optimizer>
19#include <osgUtil/GLObjectsVisitor>
[9552]20#include <osgUtil/Statistics>
[7178]21
22#include <osgViewer/Renderer>
23#include <osgViewer/View>
24
25#include <osgDB/DatabasePager>
[8647]26#include <osgDB/ImagePager>
[7178]27
28#include <osg/io_utils>
29
30#include <sstream>
31
32using namespace osgViewer;
33
34//#define DEBUG_MESSAGE osg::notify(osg::NOTICE)
[7858]35#define DEBUG_MESSAGE osg::notify(osg::DEBUG_FP)
[7178]36
37
38OpenGLQuerySupport::OpenGLQuerySupport():
39    _startTick(0),
40    _initialized(false),
41    _timerQuerySupported(false),
42    _extensions(0),
43    _previousQueryTime(0.0)
44{
45}
46
47void OpenGLQuerySupport::checkQuery(osg::Stats* stats)
48{
49    for(QueryFrameNumberList::iterator itr = _queryFrameNumberList.begin();
50        itr != _queryFrameNumberList.end();
51        )
52    {
53        GLuint query = itr->first;
54        GLint available = 0;
55        _extensions->glGetQueryObjectiv(query, GL_QUERY_RESULT_AVAILABLE, &available);
56        if (available)
57        {
58            GLuint64EXT timeElapsed = 0;
59            _extensions->glGetQueryObjectui64v(query, GL_QUERY_RESULT, &timeElapsed);
60
61            double timeElapsedSeconds = double(timeElapsed)*1e-9;
62            double currentTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
63            double estimatedEndTime = (_previousQueryTime + currentTime) * 0.5;
64            double estimatedBeginTime = estimatedEndTime - timeElapsedSeconds;
65
66            stats->setAttribute(itr->second, "GPU draw begin time", estimatedBeginTime);
67            stats->setAttribute(itr->second, "GPU draw end time", estimatedEndTime);
68            stats->setAttribute(itr->second, "GPU draw time taken", timeElapsedSeconds);
69
70
71            itr = _queryFrameNumberList.erase(itr);
72            _availableQueryObjects.push_back(query);
73        }
74        else
75        {
76            ++itr;
77        }
78
79    }
80    _previousQueryTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
81}
82
83GLuint OpenGLQuerySupport::createQueryObject()
84{
85    if (_availableQueryObjects.empty())
86    {
87        GLuint query;
88        _extensions->glGenQueries(1, &query);
89        return query;
90    }
91    else
92    {
93        GLuint query = _availableQueryObjects.back();
94        _availableQueryObjects.pop_back();
95        return query;
96    }
97}
98
99void OpenGLQuerySupport::beginQuery(int frameNumber)
100{
101    GLuint query = createQueryObject();
102    _extensions->glBeginQuery(GL_TIME_ELAPSED, query);
103    _queryFrameNumberList.push_back(QueryFrameNumberPair(query, frameNumber));       
104}
105
106void OpenGLQuerySupport::endQuery()
107{
108    _extensions->glEndQuery(GL_TIME_ELAPSED);
109}
110
111void OpenGLQuerySupport::initialize(osg::State* state)
112{
113    if (_initialized) return;
114
115    _initialized = true;
116    _extensions = osg::Drawable::getExtensions(state->getContextID(),true);
117    _timerQuerySupported = _extensions && _extensions->isTimerQuerySupported();
118    _previousQueryTime = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
119}
120
121///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122//
123//
[9130]124//  ThreadSafeQueue
[7270]125
[9130]126Renderer::ThreadSafeQueue::ThreadSafeQueue()
[7285]127{
128    _block.set(false);
129}
130
[9130]131Renderer::ThreadSafeQueue::~ThreadSafeQueue()
[7295]132{
133}
134
[9130]135osgUtil::SceneView* Renderer::ThreadSafeQueue::takeFront()
[7270]136{
137    if (_queue.empty()) _block.block();
138
139    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
140    if (_queue.empty()) return 0;
141
142    osgUtil::SceneView* front = _queue.front();
143    _queue.pop_front();
144
145    if (_queue.empty()) _block.set(false);
146   
147    return front;
148}
149
[9130]150void Renderer::ThreadSafeQueue::add(osgUtil::SceneView* sv)
[7270]151{
152    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
153    _queue.push_back(sv);
154    _block.set(true);
155}
156
157static OpenThreads::Mutex s_drawSerializerMutex;
158
159///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
160//
161//
[7178]162//  Renderer
163Renderer::Renderer(osg::Camera* camera):
164    osg::GraphicsOperation("Renderer",true),
165    OpenGLQuerySupport(),
[8121]166    _targetFrameRate(100.0),
167    _minimumTimeAvailableForGLCompileAndDeletePerFrame(0.001),
168    _flushTimeRatio(0.5),
169    _conservativeTimeRatio(0.5),
[7178]170    _camera(camera),
171    _done(false),
[8299]172    _graphicsThreadDoesCull(true),
173    _compileOnNextDraw(true)
[7178]174{
175
176    DEBUG_MESSAGE<<"Render::Render() "<<this<<std::endl;
177
178    _sceneView[0] = new osgUtil::SceneView;
179    _sceneView[1] = new osgUtil::SceneView;
180
181
182    osg::Camera* masterCamera = _camera->getView() ? _camera->getView()->getCamera() : camera;
183    osg::StateSet* stateset = masterCamera->getOrCreateStateSet();
184    osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());
185
186    osg::DisplaySettings* ds = _camera->getDisplaySettings() ?  _camera->getDisplaySettings() :
[7212]187                               ((view && view->getDisplaySettings()) ?  view->getDisplaySettings() :  osg::DisplaySettings::instance());
[7178]188
[9208]189    unsigned int sceneViewOptions = osgUtil::SceneView::HEADLIGHT;
190    if (view)
191    {
192        switch(view->getLightingMode())
193        {
194            case(osg::View::NO_LIGHT): sceneViewOptions = 0; break;
195            case(osg::View::SKY_LIGHT): sceneViewOptions = osgUtil::SceneView::SKY_LIGHT; break;
196            case(osg::View::HEADLIGHT): sceneViewOptions = osgUtil::SceneView::HEADLIGHT; break;
197        }
198    }
199
[7178]200    _sceneView[0]->setGlobalStateSet(stateset);
201    _sceneView[1]->setGlobalStateSet(stateset);
202   
203    _sceneView[0]->setDefaults(sceneViewOptions);
204    _sceneView[1]->setDefaults(sceneViewOptions);
205
206    _sceneView[0]->setDisplaySettings(ds);
207    _sceneView[1]->setDisplaySettings(ds);
208
[7205]209    _sceneView[0]->setCamera(_camera.get(), false);
210    _sceneView[1]->setCamera(_camera.get(), false);
[7178]211
212    // lock the mutex for the current cull SceneView to
213    // prevent the draw traversal from reading from it before the cull traversal has been completed.
[7270]214    _availableQueue.add(_sceneView[0].get());
215    _availableQueue.add(_sceneView[1].get());
216       
217    DEBUG_MESSAGE<<"_availableQueue.size()="<<_availableQueue._queue.size()<<std::endl;
[7178]218
219    _flushOperation = new osg::FlushDeletedGLObjectsOperation(0.1);
220}
221
222Renderer::~Renderer()
223{
224    DEBUG_MESSAGE<<"Render::~Render() "<<this<<std::endl;
225}
226
227void Renderer::setGraphicsThreadDoesCull(bool flag)
228{
229    if (_graphicsThreadDoesCull==flag) return;
230
231    _graphicsThreadDoesCull = flag;
232}
233
234void Renderer::updateSceneView(osgUtil::SceneView* sceneView)
235{
236    osg::Camera* masterCamera = _camera->getView() ? _camera->getView()->getCamera() : _camera.get();
237    osg::StateSet* stateset = masterCamera->getOrCreateStateSet();
238
239    if (sceneView->getGlobalStateSet()!=stateset)
240    {
241        sceneView->setGlobalStateSet(stateset);
242    }
243   
244    osg::GraphicsContext* context = _camera->getGraphicsContext();
245    osg::State* state = context ? context->getState() : 0;
246    if (sceneView->getState()!=state)
247    {
248        sceneView->setState(state);
249    }
250
251    osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());
[8647]252
[7209]253    osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0;
[7178]254    sceneView->getCullVisitor()->setDatabaseRequestHandler(databasePager);
[8647]255
256    osgDB::ImagePager* imagePager = view ? view->getImagePager() : 0;
257    sceneView->getCullVisitor()->setImageRequestHandler(imagePager);
[7178]258   
[7209]259    sceneView->setFrameStamp(view ? view->getFrameStamp() : state->getFrameStamp());
[7178]260   
261    if (databasePager) databasePager->setCompileGLObjectsForContextID(state->getContextID(), true);
262   
263    osg::DisplaySettings* ds = _camera->getDisplaySettings() ?  _camera->getDisplaySettings() :
264                               ((view &&view->getDisplaySettings()) ?  view->getDisplaySettings() :  osg::DisplaySettings::instance());
265
266    sceneView->setDisplaySettings(ds);
267
[7209]268    if (view) _startTick = view->getStartTick();
[7178]269}
270
[8299]271void Renderer::compile()
272{
273    DEBUG_MESSAGE<<"Renderer::compile()"<<std::endl;
[7178]274
[8299]275    _compileOnNextDraw = false;
276   
277    osgUtil::SceneView* sceneView = _sceneView[0].get();
278    if (!sceneView || _done) return;
279
280    if (sceneView->getSceneData())
281    {
282        osgUtil::GLObjectsVisitor glov;
283        glov.setState(sceneView->getState());
284        sceneView->getSceneData()->accept(glov);
285    }
286}
287
[7178]288void Renderer::cull()
289{
290    DEBUG_MESSAGE<<"cull()"<<std::endl;
291
292    if (_done || _graphicsThreadDoesCull) return;
293
[7648]294    // note we assume lock has already been acquired.
[7270]295    osgUtil::SceneView* sceneView = _availableQueue.takeFront();
[7178]296
[7270]297    DEBUG_MESSAGE<<"cull() got SceneView "<<sceneView<<std::endl;
298
[7178]299    if (sceneView)
300    {
301        updateSceneView(sceneView);
302
303        // osg::notify(osg::NOTICE)<<"Culling buffer "<<_currentCull<<std::endl;
304
305        // pass on the fusion distance settings from the View to the SceneView
306        osgViewer::View* view = dynamic_cast<osgViewer::View*>(sceneView->getCamera()->getView());
307        if (view) sceneView->setFusionDistance(view->getFusionDistanceMode(), view->getFusionDistanceValue());
308
309        osg::Stats* stats = sceneView->getCamera()->getStats();
310        osg::State* state = sceneView->getState();
311        const osg::FrameStamp* fs = state->getFrameStamp();
312        int frameNumber = fs ? fs->getFrameNumber() : 0;
313
[7648]314        // do cull traversal
[7178]315        osg::Timer_t beforeCullTick = osg::Timer::instance()->tick();
316
317        sceneView->inheritCullSettings(*(sceneView->getCamera()));
318        sceneView->cull();
319
320        osg::Timer_t afterCullTick = osg::Timer::instance()->tick();
321
322#if 0
323        if (sceneView->getDynamicObjectCount()==0 && state->getDynamicObjectRenderingCompletedCallback())
324        {
325            // osg::notify(osg::NOTICE)<<"Completed in cull"<<std::endl;
326            state->getDynamicObjectRenderingCompletedCallback()->completed(state);
327        }
328#endif
329        if (stats && stats->collectStats("rendering"))
330        {
331            DEBUG_MESSAGE<<"Collecting rendering stats"<<std::endl;
332       
333            stats->setAttribute(frameNumber, "Cull traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeCullTick));
334            stats->setAttribute(frameNumber, "Cull traversal end time", osg::Timer::instance()->delta_s(_startTick, afterCullTick));
335            stats->setAttribute(frameNumber, "Cull traversal time taken", osg::Timer::instance()->delta_s(beforeCullTick, afterCullTick));
336        }
337
[9552]338        if (stats && stats->collectStats("scene"))
339        {
340            osgUtil::Statistics sceneStats;
341            sceneView->getStats(sceneStats);
342           
343            stats->setAttribute(frameNumber, "Visible vertex count", static_cast<double>(sceneStats._vertexCount));
344            stats->setAttribute(frameNumber, "Visible number of drawables", static_cast<double>(sceneStats.numDrawables));
345            stats->setAttribute(frameNumber, "Visible number of lights", static_cast<double>(sceneStats.nlights));
346            stats->setAttribute(frameNumber, "Visible number of render bins", static_cast<double>(sceneStats.nbins));
347            stats->setAttribute(frameNumber, "Visible depth", static_cast<double>(sceneStats.depth));
348            stats->setAttribute(frameNumber, "Visible number of materials", static_cast<double>(sceneStats.nummat));
349            stats->setAttribute(frameNumber, "Visible number of impostors", static_cast<double>(sceneStats.nimpostor));
350
351            osgUtil::Statistics::PrimitiveCountMap& pcm = sceneStats.getPrimitiveCountMap();
352            stats->setAttribute(frameNumber, "Visible number of GL_POINTS", static_cast<double>(pcm[GL_POINTS]));
353            stats->setAttribute(frameNumber, "Visible number of GL_LINES", static_cast<double>(pcm[GL_LINES]));
354            stats->setAttribute(frameNumber, "Visible number of GL_LINE_STRIP", static_cast<double>(pcm[GL_LINE_STRIP]));
355            stats->setAttribute(frameNumber, "Visible number of GL_LINE_LOOP", static_cast<double>(pcm[GL_LINE_LOOP]));
356            stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLES", static_cast<double>(pcm[GL_TRIANGLES]));
357            stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_STRIP", static_cast<double>(pcm[GL_TRIANGLE_STRIP]));
358            stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_FAN", static_cast<double>(pcm[GL_TRIANGLE_FAN]));
359            stats->setAttribute(frameNumber, "Visible number of GL_QUADS", static_cast<double>(pcm[GL_QUADS]));
360            stats->setAttribute(frameNumber, "Visible number of GL_QUAD_STRIP", static_cast<double>(pcm[GL_QUAD_STRIP]));
361            stats->setAttribute(frameNumber, "Visible number of GL_POLYGON", static_cast<double>(pcm[GL_POLYGON]));
362           
363        }
364
[7270]365        _drawQueue.add(sceneView);
[7178]366
[7270]367    }
[7178]368
369    DEBUG_MESSAGE<<"end cull() "<<this<<std::endl;
370}
371
372void Renderer::draw()
373{
374    DEBUG_MESSAGE<<"draw() "<<this<<std::endl;
375
[9385]376    // osg::Timer_t startDrawTick = osg::Timer::instance()->tick();
[7178]377
[7270]378    osgUtil::SceneView* sceneView = _drawQueue.takeFront();
379
380    DEBUG_MESSAGE<<"draw() got SceneView "<<sceneView<<std::endl;
381
[7278]382    osg::GraphicsContext* compileContext = sceneView ? osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID()) : 0;
[7178]383    osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0;
384
[8299]385    if (sceneView && !_done)
[7178]386    {
[8299]387        if (_compileOnNextDraw)
388        {
389            compile();
390        }
391   
[7178]392        osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());
[7209]393        osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0;
[7178]394
395        // osg::notify(osg::NOTICE)<<"Drawing buffer "<<_currentDraw<<std::endl;
396
397        if (_done)
398        {
399            osg::notify(osg::INFO)<<"Renderer::release() causing draw to exit"<<std::endl;
400            return;
401        }
402
403        if (_graphicsThreadDoesCull)
404        {
405            osg::notify(osg::INFO)<<"Renderer::draw() completing early due to change in _graphicsThreadDoesCull flag."<<std::endl;
406            return;
407        }
408
409        // osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
410
411        osg::Stats* stats = sceneView->getCamera()->getStats();
412        osg::State* state = sceneView->getState();
[7270]413        int frameNumber = state->getFrameStamp()->getFrameNumber();
[7178]414
415        if (!_initialized)
416        {
417            initialize(state);
418        }
419
420        state->setDynamicObjectCount(sceneView->getDynamicObjectCount());
421
422        if (sceneView->getDynamicObjectCount()==0 && state->getDynamicObjectRenderingCompletedCallback())
423        {
424            // osg::notify(osg::NOTICE)<<"Completed in cull"<<std::endl;
425            state->getDynamicObjectRenderingCompletedCallback()->completed(state);
426        }
427
[7648]428        bool acquireGPUStats = stats && _timerQuerySupported && stats->collectStats("gpu");
[7178]429
[7648]430        if (acquireGPUStats)
[7178]431        {
432            checkQuery(stats);
433        }
434
[7648]435        // do draw traversal
436        if (acquireGPUStats)
[7178]437        {
438            checkQuery(stats);
439            beginQuery(frameNumber);
440        }
441
[7270]442        osg::Timer_t beforeDrawTick;
[7274]443       
444       
445        bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch();
[7178]446
[7274]447        if (serializeDraw)
[7270]448        {
449            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex);
450            beforeDrawTick = osg::Timer::instance()->tick();
451            sceneView->draw();
452        }
453        else
454        {
455            beforeDrawTick = osg::Timer::instance()->tick();
456            sceneView->draw();
457        }
458
459        _availableQueue.add(sceneView);
460
[8121]461        osg::Timer_t afterDispatchTick = osg::Timer::instance()->tick();
[7178]462
[8121]463        double dispatchTime = osg::Timer::instance()->delta_s(beforeDrawTick, afterDispatchTick);
[7178]464
[8121]465        // now flush delete OpenGL objects and compile any objects as required by the DatabasePager
466        flushAndCompile(dispatchTime, sceneView, databasePager, compileThread);
467   
[7648]468        if (acquireGPUStats)
[7178]469        {
470            endQuery();
471            checkQuery(stats);
472        }
473
[7270]474        //glFlush();
475       
476        osg::Timer_t afterDrawTick = osg::Timer::instance()->tick();
[7178]477
[7270]478//        osg::notify(osg::NOTICE)<<"Time wait for draw = "<<osg::Timer::instance()->delta_m(startDrawTick, beforeDrawTick)<<std::endl;
479//        osg::notify(osg::NOTICE)<<"     time for draw = "<<osg::Timer::instance()->delta_m(beforeDrawTick, afterDrawTick)<<std::endl;
[7178]480
481        if (stats && stats->collectStats("rendering"))
482        {
483            stats->setAttribute(frameNumber, "Draw traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeDrawTick));
484            stats->setAttribute(frameNumber, "Draw traversal end time", osg::Timer::instance()->delta_s(_startTick, afterDrawTick));
485            stats->setAttribute(frameNumber, "Draw traversal time taken", osg::Timer::instance()->delta_s(beforeDrawTick, afterDrawTick));
486        }
[9552]487
[7178]488    }
489
490    DEBUG_MESSAGE<<"end draw() "<<this<<std::endl;
491}
492
493void Renderer::cull_draw()
494{
495    DEBUG_MESSAGE<<"cull_draw() "<<this<<std::endl;
496
[7270]497    osgUtil::SceneView* sceneView = _sceneView[0].get();
[7178]498    if (!sceneView || _done) return;
499
[8324]500    if (_done)
501    {
502        osg::notify(osg::INFO)<<"Render::release() causing cull_draw to exit"<<std::endl;
503        return;
504    }
505   
506    updateSceneView(sceneView);
507
[8299]508    if (_compileOnNextDraw)
509    {
510        compile();
511    }
512
[7178]513    osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView());
[7209]514    osgDB::DatabasePager* databasePager = view ? view->getDatabasePager() : 0;
[7178]515
516    osg::GraphicsContext* compileContext = osg::GraphicsContext::getCompileContext(sceneView->getState()->getContextID());
517    osg::GraphicsThread* compileThread = compileContext ? compileContext->getGraphicsThread() : 0;
518
519
520    // osg::notify(osg::NOTICE)<<"RenderingOperation"<<std::endl;
521
522    // pass on the fusion distance settings from the View to the SceneView
523    if (view) sceneView->setFusionDistance(view->getFusionDistanceMode(), view->getFusionDistanceValue());
524
525    osg::Stats* stats = sceneView->getCamera()->getStats();
526    osg::State* state = sceneView->getState();
527    const osg::FrameStamp* fs = state->getFrameStamp();
528    int frameNumber = fs ? fs->getFrameNumber() : 0;
529
530    if (!_initialized)
531    {
532        initialize(state);
533    }
534
[7648]535    bool acquireGPUStats = stats && _timerQuerySupported && stats->collectStats("gpu");
[7178]536
[7648]537    if (acquireGPUStats)
[7178]538    {
539        checkQuery(stats);
540    }
541
[7648]542    // do cull traversal
[7178]543    osg::Timer_t beforeCullTick = osg::Timer::instance()->tick();
544
545    sceneView->inheritCullSettings(*(sceneView->getCamera()));
546    sceneView->cull();
547
548    osg::Timer_t afterCullTick = osg::Timer::instance()->tick();
549
[9552]550    if (stats && stats->collectStats("scene"))
551    {
552        osgUtil::Statistics sceneStats;
553        sceneView->getStats(sceneStats);
554
555        stats->setAttribute(frameNumber, "Visible vertex count", static_cast<double>(sceneStats._vertexCount));
556        stats->setAttribute(frameNumber, "Visible number of drawables", static_cast<double>(sceneStats.numDrawables));
557        stats->setAttribute(frameNumber, "Visible number of lights", static_cast<double>(sceneStats.nlights));
558        stats->setAttribute(frameNumber, "Visible number of render bins", static_cast<double>(sceneStats.nbins));
559        stats->setAttribute(frameNumber, "Visible depth", static_cast<double>(sceneStats.depth));
560        stats->setAttribute(frameNumber, "Visible number of materials", static_cast<double>(sceneStats.nummat));
561        stats->setAttribute(frameNumber, "Visible number of impostors", static_cast<double>(sceneStats.nimpostor));
562    }
563
[7178]564#if 0
565    if (state->getDynamicObjectCount()==0 && state->getDynamicObjectRenderingCompletedCallback())
566    {
567        state->getDynamicObjectRenderingCompletedCallback()->completed(state);
568    }
569#endif
570
[7270]571
[7648]572    // do draw traversal
573    if (acquireGPUStats)
[7178]574    {
575        checkQuery(stats);
576        beginQuery(frameNumber);
577    }
578
[7270]579    osg::Timer_t beforeDrawTick;
[7178]580
[7274]581    bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch();
582
583    if (serializeDraw)
[7270]584    {
585        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex);
586       
587        beforeDrawTick = osg::Timer::instance()->tick();
588        sceneView->draw();
589    }
590    else
591    {
592        beforeDrawTick = osg::Timer::instance()->tick();
593        sceneView->draw();
594    }
595
[8121]596    osg::Timer_t afterDispatchTick = osg::Timer::instance()->tick();
597    double cullAndDispatchTime = osg::Timer::instance()->delta_s(beforeCullTick, afterDispatchTick);
[7178]598
[8121]599    // now flush delete OpenGL objects and compile any objects as required by the DatabasePager
600    flushAndCompile(cullAndDispatchTime, sceneView, databasePager, compileThread);
[7178]601
[8121]602
[7648]603    if (acquireGPUStats)
[7178]604    {
605        endQuery();
606        checkQuery(stats);
607    }
608
609    osg::Timer_t afterDrawTick = osg::Timer::instance()->tick();
610
611    if (stats && stats->collectStats("rendering"))
612    {
613        DEBUG_MESSAGE<<"Collecting rendering stats"<<std::endl;
614
615        stats->setAttribute(frameNumber, "Cull traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeCullTick));
616        stats->setAttribute(frameNumber, "Cull traversal end time", osg::Timer::instance()->delta_s(_startTick, afterCullTick));
617        stats->setAttribute(frameNumber, "Cull traversal time taken", osg::Timer::instance()->delta_s(beforeCullTick, afterCullTick));
618
[7270]619        stats->setAttribute(frameNumber, "Draw traversal begin time", osg::Timer::instance()->delta_s(_startTick, beforeDrawTick));
[7178]620        stats->setAttribute(frameNumber, "Draw traversal end time", osg::Timer::instance()->delta_s(_startTick, afterDrawTick));
[7270]621        stats->setAttribute(frameNumber, "Draw traversal time taken", osg::Timer::instance()->delta_s(beforeDrawTick, afterDrawTick));
[7178]622    }
623
624    DEBUG_MESSAGE<<"end cull_draw() "<<this<<std::endl;
625
626}
627
[8121]628void Renderer::flushAndCompile(double currentElapsedFrameTime, osgUtil::SceneView* sceneView, osgDB::DatabasePager* databasePager, osg::GraphicsThread* compileThread)
629{
630   
631    double targetFrameRate = _targetFrameRate;
632    double minimumTimeAvailableForGLCompileAndDeletePerFrame = _minimumTimeAvailableForGLCompileAndDeletePerFrame;
633
634    if (databasePager)
635    {
636        targetFrameRate = std::min(targetFrameRate, databasePager->getTargetFrameRate());
637        minimumTimeAvailableForGLCompileAndDeletePerFrame = std::min(minimumTimeAvailableForGLCompileAndDeletePerFrame, databasePager->getMinimumTimeAvailableForGLCompileAndDeletePerFrame());
638    }
639   
640    double targetFrameTime = 1.0/targetFrameRate;
641
642    double availableTime = std::max((targetFrameTime - currentElapsedFrameTime)*_conservativeTimeRatio,
643                                    minimumTimeAvailableForGLCompileAndDeletePerFrame);
644
645    double flushTime = availableTime * _flushTimeRatio;
646    double compileTime = availableTime - flushTime;
647
648#if 0
649    osg::notify(osg::NOTICE)<<"total availableTime = "<<availableTime*1000.0<<std::endl;
650    osg::notify(osg::NOTICE)<<"      flushTime     = "<<flushTime*1000.0<<std::endl;
651    osg::notify(osg::NOTICE)<<"      compileTime   = "<<compileTime*1000.0<<std::endl;
652#endif
653
654    if (compileThread)
655    {
656        compileThread->add(_flushOperation.get());
657    }
658    else
659    {
660        sceneView->flushDeletedGLObjects(flushTime);
661    }
662
663    // if any time left over from flush add this to compile time.       
664    if (flushTime>0.0) compileTime += flushTime;
665
666#if 0
667    osg::notify(osg::NOTICE)<<"      revised compileTime   = "<<compileTime*1000.0<<std::endl;
668#endif
669
670    if (databasePager && databasePager->requiresExternalCompileGLObjects(sceneView->getState()->getContextID()))
671    {
672        databasePager->compileGLObjects(*(sceneView->getState()), compileTime);
673    }
674}
675
[7178]676void Renderer::operator () (osg::Object* object)
677{
678    osg::GraphicsContext* context = dynamic_cast<osg::GraphicsContext*>(object);
679    if (context) operator()(context);
680
681    osg::Camera* camera = dynamic_cast<osg::Camera*>(object);
682    if (camera) cull();
683}
684
685void Renderer::operator () (osg::GraphicsContext* context)
686{
687    if (_graphicsThreadDoesCull)
688    {
689        cull_draw();
690    }
691    else
692    {
693        draw();
694    }
695}
696
697void Renderer::release()
698{
699    osg::notify(osg::INFO)<<"Renderer::release()"<<std::endl;
700    _done = true;
701
[7270]702    _availableQueue.release();
703    _drawQueue.release();
[7178]704}
Note: See TracBrowser for help on using the browser.