root/OpenSceneGraph/trunk/src/osgViewer/ViewerBase.cpp @ 10106

Revision 10106, 28.4 kB (checked in by robert, 6 years ago)

Fixed warning

Line 
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 <stdlib.h>
15#include <string.h>
16
17#include <osgViewer/ViewerBase>
18#include <osgViewer/View>
19#include <osgViewer/Renderer>
20
21#include <osg/io_utils>
22
23#include <osg/TextureCubeMap>
24#include <osg/TextureRectangle>
25#include <osg/TexMat>
26#include <osg/DeleteHandler>
27
28#include <osgUtil/Optimizer>
29#include <osgUtil/IntersectionVisitor>
30#include <osgUtil/Statistics>
31
32static osg::ApplicationUsageProxy ViewerBase_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_CONFIG_FILE <filename>","Specify a viewer configuration file to load by default.");
33static osg::ApplicationUsageProxy ViewerBase_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_THREADING <value>","Set the threading model using by Viewer, <value> can be SingleThreaded, CullDrawThreadPerContext, DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext.");
34static osg::ApplicationUsageProxy ViewerBase_e2(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN <value>","Set the default screen that windows should open up on.");
35static osg::ApplicationUsageProxy ViewerBase_e3(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_WINDOW x y width height","Set the default window dimensions that windows should open up on.");
36static osg::ApplicationUsageProxy ViewerBase_e4(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_FRAME_SCHEME","Frame rate manage scheme that viewer run should use,  ON_DEMAND or CONTINUOUS (default).");
37static osg::ApplicationUsageProxy ViewerBase_e5(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_MAX_FRAME_RATE","Set the maximum number of frame as second that viewer run. 0.0 is default and disables an frame rate capping.");
38
39using namespace osgViewer;
40
41ViewerBase::ViewerBase():
42    osg::Object(true)
43{
44    viewerBaseInit();
45}
46
47ViewerBase::ViewerBase(const ViewerBase& base):
48    osg::Object(true)
49{
50    viewerBaseInit();
51}
52
53void ViewerBase::viewerBaseInit()
54{
55    _firstFrame = true;
56    _done = false;
57    _keyEventSetsDone = osgGA::GUIEventAdapter::KEY_Escape;
58    _quitEventSetsDone = true;
59    _releaseContextAtEndOfFrameHint = true;
60    _threadingModel = AutomaticSelection;
61    _threadsRunning = false;
62    _endBarrierPosition = AfterSwapBuffers;
63    _requestRedraw = true;
64    _requestContinousUpdate = false;
65
66    _runFrameScheme = CONTINUOUS;
67    _runMaxFrameRate = 0.0f;
68
69    const char* str = getenv("OSG_RUN_FRAME_SCHEME");
70    if (str)
71    {
72        if      (strcmp(str, "ON_DEMAND")==0) _runFrameScheme = ON_DEMAND;
73        else if (strcmp(str, "CONTINUOUS")==0) _runFrameScheme = CONTINUOUS;
74    }
75
76    str = getenv("OSG_RUN_MAX_FRAME_RATE");
77    if (str)
78    {
79        _runMaxFrameRate = atof(str);
80    }
81}
82
83void ViewerBase::setThreadingModel(ThreadingModel threadingModel)
84{
85    if (_threadingModel == threadingModel) return;
86   
87    if (_threadsRunning) stopThreading();
88   
89    _threadingModel = threadingModel;
90
91    if (isRealized() && _threadingModel!=SingleThreaded) startThreading();
92}
93
94ViewerBase::ThreadingModel ViewerBase::suggestBestThreadingModel()
95{
96    const char* str = getenv("OSG_THREADING");
97    if (str)
98    {
99        if (strcmp(str,"SingleThreaded")==0) return SingleThreaded;
100        else if (strcmp(str,"CullDrawThreadPerContext")==0) return CullDrawThreadPerContext;
101        else if (strcmp(str,"DrawThreadPerContext")==0) return DrawThreadPerContext;
102        else if (strcmp(str,"CullThreadPerCameraDrawThreadPerContext")==0) return CullThreadPerCameraDrawThreadPerContext;
103    }
104
105    Contexts contexts;
106    getContexts(contexts);
107   
108    if (contexts.empty()) return SingleThreaded;
109
110#if 0
111    // temporary hack to disable multi-threading under Windows till we find good solutions for
112    // crashes that users are seeing.
113    return SingleThreaded;
114#endif
115
116    Cameras cameras;
117    getCameras(cameras);
118
119    if (cameras.empty()) return SingleThreaded;
120
121
122    int numProcessors = OpenThreads::GetNumberOfProcessors();
123
124    if (contexts.size()==1)
125    {
126        if (numProcessors==1) return SingleThreaded;
127        else return DrawThreadPerContext;
128    }
129   
130#if 1
131    if (numProcessors >= static_cast<int>(cameras.size()+contexts.size()))
132    {
133        return CullThreadPerCameraDrawThreadPerContext;
134    }
135#endif
136
137    return DrawThreadPerContext;
138}
139
140void ViewerBase::setUpThreading()
141{
142    Contexts contexts;
143    getContexts(contexts);
144
145    if (_threadingModel==SingleThreaded)
146    {
147        if (_threadsRunning) stopThreading();
148        else
149        {
150            // we'll set processor affinity here to help single threaded apps
151            // with multiple processor cores, and using the database pager.
152            int numProcessors = OpenThreads::GetNumberOfProcessors();
153            bool affinity = numProcessors>1;   
154            if (affinity)
155            {
156                OpenThreads::SetProcessorAffinityOfCurrentThread(0);
157
158                Scenes scenes;
159                getScenes(scenes);
160               
161                for(Scenes::iterator itr = scenes.begin();
162                    itr != scenes.end();
163                    ++itr)
164                {
165                    Scene* scene = *itr;
166                    osgDB::DatabasePager* dp = scene->getDatabasePager();
167                    if (dp)
168                    {
169                        for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
170                        {
171                            osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
172                            dt->setProcessorAffinity(1);
173                        }
174                    }
175                }
176           
177            }
178        }
179    }
180    else
181    {
182        if (!_threadsRunning) startThreading();
183    }
184   
185}
186
187void ViewerBase::setEndBarrierPosition(BarrierPosition bp)
188{
189    if (_endBarrierPosition == bp) return;
190   
191    if (_threadsRunning) stopThreading();
192   
193    _endBarrierPosition = bp;
194
195    if (_threadingModel!=SingleThreaded) startThreading();
196}
197
198
199void ViewerBase::stopThreading()
200{
201    if (!_threadsRunning) return;
202
203    osg::notify(osg::INFO)<<"ViewerBase::stopThreading() - stopping threading"<<std::endl;
204
205    Contexts contexts;
206    getContexts(contexts);
207
208    Cameras cameras;
209    getCameras(cameras);
210
211    Contexts::iterator gcitr;
212    Cameras::iterator citr;
213
214    for(Cameras::iterator camItr = cameras.begin();
215        camItr != cameras.end();
216        ++camItr)
217    {
218        osg::Camera* camera = *camItr;
219        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
220        if (renderer) renderer->release();
221    }
222
223    // delete all the graphics threads.   
224    for(gcitr = contexts.begin();
225        gcitr != contexts.end();
226        ++gcitr)
227    {
228        (*gcitr)->setGraphicsThread(0);
229    }
230
231    // delete all the camera threads.   
232    for(citr = cameras.begin();
233        citr != cameras.end();
234        ++citr)
235    {
236        (*citr)->setCameraThread(0);
237    }
238
239    for(Cameras::iterator camItr = cameras.begin();
240        camItr != cameras.end();
241        ++camItr)
242    {
243        osg::Camera* camera = *camItr;
244        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
245        if (renderer)
246        {
247            renderer->setGraphicsThreadDoesCull( true );
248            renderer->setDone(false);
249        }
250    }
251
252
253    _threadsRunning = false;
254    _startRenderingBarrier = 0;
255    _endRenderingDispatchBarrier = 0;
256    _endDynamicDrawBlock = 0;
257
258    osg::notify(osg::INFO)<<"Viewer::stopThreading() - stopped threading."<<std::endl;
259}
260
261void ViewerBase::startThreading()
262{
263    if (_threadsRunning) return;
264   
265    osg::notify(osg::INFO)<<"Viewer::startThreading() - starting threading"<<std::endl;
266   
267    // release any context held by the main thread.
268    releaseContext();
269
270    _threadingModel = _threadingModel==AutomaticSelection ? suggestBestThreadingModel() : _threadingModel;
271
272    Contexts contexts;
273    getContexts(contexts);
274   
275    osg::notify(osg::INFO)<<"Viewer::startThreading() - contexts.size()="<<contexts.size()<<std::endl;
276
277    Cameras cameras;
278    getCameras(cameras);
279   
280    unsigned int numThreadsOnStartBarrier = 0;
281    unsigned int numThreadsOnEndBarrier = 0;
282    switch(_threadingModel)
283    {
284        case(SingleThreaded):
285            numThreadsOnStartBarrier = 1;
286            numThreadsOnEndBarrier = 1;
287            return;
288        case(CullDrawThreadPerContext):
289            numThreadsOnStartBarrier = contexts.size()+1;
290            numThreadsOnEndBarrier = contexts.size()+1;
291            break;
292        case(DrawThreadPerContext):
293            numThreadsOnStartBarrier = 1;
294            numThreadsOnEndBarrier = 1;
295            break;
296        case(CullThreadPerCameraDrawThreadPerContext):
297            numThreadsOnStartBarrier = cameras.size()+1;
298            numThreadsOnEndBarrier = 1;
299            break;
300        default:
301            osg::notify(osg::NOTICE)<<"Error: Threading model not selected"<<std::endl;
302            return;
303    }
304
305    // using multi-threading so make sure that new objects are allocated with thread safe ref/unref
306    osg::Referenced::setThreadSafeReferenceCounting(true);
307
308    Scenes scenes;
309    getScenes(scenes);
310    for(Scenes::iterator scitr = scenes.begin();
311        scitr != scenes.end();
312        ++scitr)
313    {
314        if ((*scitr)->getSceneData())
315        {
316            osg::notify(osg::INFO)<<"Making scene thread safe"<<std::endl;
317
318            // make sure that existing scene graph objects are allocated with thread safe ref/unref
319            (*scitr)->getSceneData()->setThreadSafeRefUnref(true);
320
321            // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
322            (*scitr)->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
323        }
324    }
325       
326    int numProcessors = OpenThreads::GetNumberOfProcessors();
327    bool affinity = numProcessors>1;   
328   
329    Contexts::iterator citr;
330
331    unsigned int numViewerDoubleBufferedRenderingOperation = 0;
332
333    bool graphicsThreadsDoesCull = _threadingModel == CullDrawThreadPerContext || _threadingModel==SingleThreaded;
334
335    for(Cameras::iterator camItr = cameras.begin();
336        camItr != cameras.end();
337        ++camItr)
338    {
339        osg::Camera* camera = *camItr;
340        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
341        if (renderer)
342        {
343            renderer->setGraphicsThreadDoesCull(graphicsThreadsDoesCull);
344            renderer->setDone(false);
345            ++numViewerDoubleBufferedRenderingOperation;
346        }
347    }
348
349    if (_threadingModel==CullDrawThreadPerContext)
350    {
351        _startRenderingBarrier = 0;
352        _endRenderingDispatchBarrier = 0;
353        _endDynamicDrawBlock = 0;
354    }
355    else if (_threadingModel==DrawThreadPerContext ||
356             _threadingModel==CullThreadPerCameraDrawThreadPerContext)
357    {
358        _startRenderingBarrier = 0;
359        _endRenderingDispatchBarrier = 0;
360        _endDynamicDrawBlock = new osg::EndOfDynamicDrawBlock(numViewerDoubleBufferedRenderingOperation);
361       
362#ifndef OSGUTIL_RENDERBACKEND_USE_REF_PTR
363        if (!osg::Referenced::getDeleteHandler()) osg::Referenced::setDeleteHandler(new osg::DeleteHandler(2));
364        else osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(2);
365#endif
366    }
367   
368    if (numThreadsOnStartBarrier>1)
369    {
370        _startRenderingBarrier = new osg::BarrierOperation(numThreadsOnStartBarrier, osg::BarrierOperation::NO_OPERATION);
371    }
372
373    if (numThreadsOnEndBarrier>1)
374    {
375        _endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsOnEndBarrier, osg::BarrierOperation::NO_OPERATION);
376    }
377
378
379    osg::ref_ptr<osg::BarrierOperation> swapReadyBarrier = contexts.empty() ? 0 : new osg::BarrierOperation(contexts.size(), osg::BarrierOperation::NO_OPERATION);
380
381    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
382
383    typedef std::map<OpenThreads::Thread*, int> ThreadAffinityMap;
384    ThreadAffinityMap threadAffinityMap;
385
386    unsigned int processNum = 1;
387    for(citr = contexts.begin();
388        citr != contexts.end();
389        ++citr, ++processNum)
390    {
391        osg::GraphicsContext* gc = (*citr);
392       
393        if (!gc->isRealized())
394        {
395            osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
396            gc->realize();
397        }
398       
399        gc->getState()->setDynamicObjectRenderingCompletedCallback(_endDynamicDrawBlock.get());
400
401        // create the a graphics thread for this context
402        gc->createGraphicsThread();
403
404        if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
405        threadAffinityMap[gc->getGraphicsThread()] = processNum % numProcessors;
406
407        // add the startRenderingBarrier
408        if (_threadingModel==CullDrawThreadPerContext && _startRenderingBarrier.valid()) gc->getGraphicsThread()->add(_startRenderingBarrier.get());
409
410        // add the rendering operation itself.
411        gc->getGraphicsThread()->add(new osg::RunOperations());
412
413        if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==BeforeSwapBuffers && _endRenderingDispatchBarrier.valid())
414        {
415            // add the endRenderingDispatchBarrier
416            gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
417        }
418
419        if (swapReadyBarrier.valid()) gc->getGraphicsThread()->add(swapReadyBarrier.get());
420
421        // add the swap buffers
422        gc->getGraphicsThread()->add(swapOp.get());
423
424        if (_threadingModel==CullDrawThreadPerContext && _endBarrierPosition==AfterSwapBuffers && _endRenderingDispatchBarrier.valid())
425        {
426            // add the endRenderingDispatchBarrier
427            gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
428        }
429
430    }
431
432    if (_threadingModel==CullThreadPerCameraDrawThreadPerContext && numThreadsOnStartBarrier>1)
433    {
434        Cameras::iterator camItr;
435
436        for(camItr = cameras.begin();
437            camItr != cameras.end();
438            ++camItr, ++processNum)
439        {
440            osg::Camera* camera = *camItr;
441            camera->createCameraThread();
442
443            if (affinity) camera->getCameraThread()->setProcessorAffinity(processNum % numProcessors);
444            threadAffinityMap[camera->getCameraThread()] = processNum % numProcessors;
445
446            osg::GraphicsContext* gc = camera->getGraphicsContext();
447
448            // add the startRenderingBarrier
449            if (_startRenderingBarrier.valid()) camera->getCameraThread()->add(_startRenderingBarrier.get());
450
451            Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
452            renderer->setGraphicsThreadDoesCull(false);
453            camera->getCameraThread()->add(renderer);
454           
455            if (_endRenderingDispatchBarrier.valid())
456            {
457                // add the endRenderingDispatchBarrier
458                gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get());
459            }
460
461        }
462
463        for(camItr = cameras.begin();
464            camItr != cameras.end();
465            ++camItr)
466        {
467            osg::Camera* camera = *camItr;
468            if (camera->getCameraThread() && !camera->getCameraThread()->isRunning())
469            {
470                osg::notify(osg::INFO)<<"  camera->getCameraThread()-> "<<camera->getCameraThread()<<std::endl;
471                camera->getCameraThread()->startThread();
472            }
473        }
474    }
475
476#if 0   
477    if (affinity)
478    {
479        OpenThreads::SetProcessorAffinityOfCurrentThread(0);
480        if (_scene.valid() && _scene->getDatabasePager())
481        {
482#if 0       
483            _scene->getDatabasePager()->setProcessorAffinity(1);
484#else
485            _scene->getDatabasePager()->setProcessorAffinity(0);
486#endif
487        }
488    }
489#endif
490
491#if 0
492    if (affinity)
493    {
494        for(ThreadAffinityMap::iterator titr = threadAffinityMap.begin();
495            titr != threadAffinityMap.end();
496            ++titr)
497        {
498            titr->first->setProcessorAffinity(titr->second);
499        }
500    }
501#endif
502
503
504    for(citr = contexts.begin();
505        citr != contexts.end();
506        ++citr)
507    {
508        osg::GraphicsContext* gc = (*citr);
509        if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning())
510        {
511            osg::notify(osg::INFO)<<"  gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl;
512            gc->getGraphicsThread()->startThread();
513            // OpenThreads::Thread::YieldCurrentThread();
514        }
515    }
516
517    _threadsRunning = true;
518
519    osg::notify(osg::INFO)<<"Set up threading"<<std::endl;
520}
521
522void ViewerBase::getWindows(Windows& windows, bool onlyValid)
523{
524    windows.clear();
525
526    Contexts contexts;
527    getContexts(contexts, onlyValid);
528   
529    for(Contexts::iterator itr = contexts.begin();
530        itr != contexts.end();
531        ++itr)
532    {
533        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*itr);
534        if (gw) windows.push_back(gw);
535    }
536}
537
538void ViewerBase::checkWindowStatus()
539{
540    Contexts contexts;
541    getContexts(contexts);
542   
543    // osg::notify(osg::NOTICE)<<"Viewer::checkWindowStatus() - "<<contexts.size()<<std::endl;
544   
545    if (contexts.size()==0)
546    {
547        _done = true;
548        if (areThreadsRunning()) stopThreading();
549    }
550}
551
552void ViewerBase::addUpdateOperation(osg::Operation* operation)
553{
554    if (!operation) return;
555
556    if (!_updateOperations) _updateOperations = new osg::OperationQueue;
557   
558    _updateOperations->add(operation);
559}
560
561void ViewerBase::removeUpdateOperation(osg::Operation* operation)
562{
563    if (!operation) return;
564
565    if (_updateOperations.valid())
566    {
567        _updateOperations->remove(operation);
568    }
569}
570
571void ViewerBase::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico)
572{
573    if (_incrementalCompileOperation == ico) return;
574   
575    Contexts contexts;
576    getContexts(contexts, false);
577   
578    if (_incrementalCompileOperation.valid()) _incrementalCompileOperation->removeContexts(contexts);
579
580    // assign new operation       
581    _incrementalCompileOperation = ico;
582
583    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
584}
585
586int ViewerBase::run()
587{
588    if (!isRealized())
589    {
590        realize();
591    }
592
593    const char* str = getenv("OSG_RUN_FRAME_COUNT");
594    int runTillFrameNumber = str==0 ? -1 : atoi(str);
595
596    while(!done() || (runTillFrameNumber>=0 && getViewerFrameStamp()->getFrameNumber()>runTillFrameNumber))
597    {
598        double minFrameTime = _runMaxFrameRate>0.0 ? 1.0/_runMaxFrameRate : 0.0;
599        osg::Timer_t startFrameTick = osg::Timer::instance()->tick();
600        if (_runFrameScheme==ON_DEMAND)
601        {
602            if (checkNeedToDoFrame()) frame();
603        }
604        else
605        {
606            frame();
607        }
608
609        // work out if we need to force a sleep to hold back the frame rate
610        osg::Timer_t endFrameTick = osg::Timer::instance()->tick();
611        double frameTime = osg::Timer::instance()->delta_s(startFrameTick, endFrameTick);
612        if (frameTime < minFrameTime) OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*(minFrameTime-frameTime)));
613    }
614
615    return 0;
616}
617
618void ViewerBase::frame(double simulationTime)
619{
620    if (_done) return;
621
622    // osg::notify(osg::NOTICE)<<std::endl<<"CompositeViewer::frame()"<<std::endl<<std::endl;
623
624    if (_firstFrame)
625    {
626        viewerInit();
627       
628        if (!isRealized())
629        {
630            realize();
631        }
632       
633        _firstFrame = false;
634    }
635    advance(simulationTime);
636   
637    eventTraversal();
638    updateTraversal();
639    renderingTraversals();
640}
641
642
643void ViewerBase::renderingTraversals()
644{
645    bool _outputMasterCameraLocation = false;
646    if (_outputMasterCameraLocation)
647    {
648        Views views;
649        getViews(views);
650
651        for(Views::iterator itr = views.begin();
652            itr != views.end();
653            ++itr)
654        {
655            osgViewer::View* view = *itr;
656            if (view)
657            {
658                const osg::Matrixd& m = view->getCamera()->getInverseViewMatrix();
659                osg::notify(osg::NOTICE)<<"View "<<view<<", Master Camera position("<<m.getTrans()<<"), rotation("<<m.getRotate()<<")"<<std::endl;
660            }
661        }
662    }
663       
664    // check to see if windows are still valid
665    checkWindowStatus();
666
667    if (_done) return;
668
669    double beginRenderingTraversals = elapsedTime();
670
671    osg::FrameStamp* frameStamp = getViewerFrameStamp();
672
673    if (getViewerStats() && getViewerStats()->collectStats("scene"))
674    {
675        int frameNumber = frameStamp ? frameStamp->getFrameNumber() : 0;
676   
677        Views views;
678        getViews(views);
679        for(Views::iterator vitr = views.begin();
680            vitr != views.end();
681            ++vitr)
682        {
683            View* view = *vitr;
684            osg::Stats* stats = view->getStats();           
685            osg::Node* sceneRoot = view->getSceneData();
686            if (sceneRoot && stats)
687            {
688                osgUtil::StatsVisitor statsVisitor;
689                sceneRoot->accept(statsVisitor);
690                statsVisitor.totalUpStats();
691               
692                unsigned int unique_primitives = 0;
693                osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr;
694                for(pcmitr = statsVisitor._uniqueStats.GetPrimitivesBegin();
695                    pcmitr != statsVisitor._uniqueStats.GetPrimitivesEnd();
696                    ++pcmitr)
697                {
698                    unique_primitives += pcmitr->second;
699                }
700
701                stats->setAttribute(frameNumber, "Number of unique StateSet", static_cast<double>(statsVisitor._statesetSet.size()));
702                stats->setAttribute(frameNumber, "Number of unique Group", static_cast<double>(statsVisitor._groupSet.size()));
703                stats->setAttribute(frameNumber, "Number of unique Transform", static_cast<double>(statsVisitor._transformSet.size()));
704                stats->setAttribute(frameNumber, "Number of unique LOD", static_cast<double>(statsVisitor._lodSet.size()));
705                stats->setAttribute(frameNumber, "Number of unique Switch", static_cast<double>(statsVisitor._switchSet.size()));
706                stats->setAttribute(frameNumber, "Number of unique Geode", static_cast<double>(statsVisitor._geodeSet.size()));
707                stats->setAttribute(frameNumber, "Number of unique Drawable", static_cast<double>(statsVisitor._drawableSet.size()));
708                stats->setAttribute(frameNumber, "Number of unique Geometry", static_cast<double>(statsVisitor._geometrySet.size()));
709                stats->setAttribute(frameNumber, "Number of unique Vertices", static_cast<double>(statsVisitor._uniqueStats._vertexCount));
710                stats->setAttribute(frameNumber, "Number of unique Primitives", static_cast<double>(unique_primitives));
711
712                unsigned int instanced_primitives = 0;
713                for(pcmitr = statsVisitor._instancedStats.GetPrimitivesBegin();
714                    pcmitr != statsVisitor._instancedStats.GetPrimitivesEnd();
715                    ++pcmitr)
716                {
717                    instanced_primitives += pcmitr->second;
718                }
719
720                stats->setAttribute(frameNumber, "Number of instanced Stateset", static_cast<double>(statsVisitor._numInstancedStateSet));
721                stats->setAttribute(frameNumber, "Number of instanced Group", static_cast<double>(statsVisitor._numInstancedGroup));
722                stats->setAttribute(frameNumber, "Number of instanced Transform", static_cast<double>(statsVisitor._numInstancedTransform));
723                stats->setAttribute(frameNumber, "Number of instanced LOD", static_cast<double>(statsVisitor._numInstancedLOD));
724                stats->setAttribute(frameNumber, "Number of instanced Switch", static_cast<double>(statsVisitor._numInstancedSwitch));
725                stats->setAttribute(frameNumber, "Number of instanced Geode", static_cast<double>(statsVisitor._numInstancedGeode));
726                stats->setAttribute(frameNumber, "Number of instanced Drawable", static_cast<double>(statsVisitor._numInstancedDrawable));
727                stats->setAttribute(frameNumber, "Number of instanced Geometry", static_cast<double>(statsVisitor._numInstancedGeometry));
728                stats->setAttribute(frameNumber, "Number of instanced Vertices", static_cast<double>(statsVisitor._instancedStats._vertexCount));
729                stats->setAttribute(frameNumber, "Number of instanced Primitives", static_cast<double>(instanced_primitives));
730           }
731        }
732    }
733
734    Scenes scenes;
735    getScenes(scenes);
736   
737    for(Scenes::iterator sitr = scenes.begin();
738        sitr != scenes.end();
739        ++sitr)
740    {
741        Scene* scene = *sitr;
742        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
743        if (dp)
744        {
745            dp->signalBeginFrame(frameStamp);
746        }
747       
748        if (scene->getSceneData())
749        {
750            // fire off a build of the bounding volumes while we
751            // are still running single threaded.
752            scene->getSceneData()->getBound();
753        }
754    }
755
756    // osg::notify(osg::NOTICE)<<std::endl<<"Start frame"<<std::endl;
757   
758
759    Contexts contexts;
760    getContexts(contexts);
761
762    Cameras cameras;
763    getCameras(cameras);
764   
765    Contexts::iterator itr;
766   
767    bool doneMakeCurrentInThisThread = false;
768
769    if (_endDynamicDrawBlock.valid())
770    {
771        _endDynamicDrawBlock->reset();
772    }
773   
774    // dispatch the rendering threads
775    if (_startRenderingBarrier.valid()) _startRenderingBarrier->block();
776
777    // reset any double buffer graphics objects
778    for(Cameras::iterator camItr = cameras.begin();
779        camItr != cameras.end();
780        ++camItr)
781    {
782        osg::Camera* camera = *camItr;
783        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
784        if (renderer)
785        {
786            if (!renderer->getGraphicsThreadDoesCull() && !(camera->getCameraThread()))
787            {
788                renderer->cull();
789            }
790        }
791    }
792
793    for(itr = contexts.begin();
794        itr != contexts.end();
795        ++itr)
796    {
797        if (_done) return;
798        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
799        {
800            doneMakeCurrentInThisThread = true;
801            makeCurrent(*itr);
802            (*itr)->runOperations();
803        }
804    }
805
806    // osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block "<<_endRenderingDispatchBarrier.get()<<std::endl;
807
808    // wait till the rendering dispatch is done.
809    if (_endRenderingDispatchBarrier.valid()) _endRenderingDispatchBarrier->block();
810
811    for(itr = contexts.begin();
812        itr != contexts.end();
813        ++itr)
814    {
815        if (_done) return;
816
817        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
818        {
819            doneMakeCurrentInThisThread = true;
820            makeCurrent(*itr);
821            (*itr)->swapBuffers();
822        }
823    }
824
825    for(Scenes::iterator sitr = scenes.begin();
826        sitr != scenes.end();
827        ++sitr)
828    {
829        Scene* scene = *sitr;
830        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
831        if (dp)
832        {
833            dp->signalEndFrame();
834        }
835    }
836
837    // wait till the dynamic draw is complete.
838    if (_endDynamicDrawBlock.valid())
839    {
840        // osg::Timer_t startTick = osg::Timer::instance()->tick();
841        _endDynamicDrawBlock->block();
842        // osg::notify(osg::NOTICE)<<"Time waiting "<<osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick())<<std::endl;;
843    }
844   
845    if (_releaseContextAtEndOfFrameHint && doneMakeCurrentInThisThread)
846    {
847        //osg::notify(osg::NOTICE)<<"Doing release context"<<std::endl;
848        releaseContext();
849    }
850
851    if (getViewerStats() && getViewerStats()->collectStats("update"))
852    {
853        double endRenderingTraversals = elapsedTime();
854
855        // update current frames stats
856        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals begin time ", beginRenderingTraversals);
857        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals end time ", endRenderingTraversals);
858        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals);
859    }
860
861    _requestRedraw = false;
862}
Note: See TracBrowser for help on using the browser.