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

Revision 10415, 28.4 kB (checked in by robert, 5 years ago)

From Mathias Froehlich, "We are currently getting issues with locale settings and some osg plugins.
Therefore I have changed all the occurances of atof by asciiToFloat or
asciiToDouble.

I believe that it is safe to do so at least for all the plugins.
Included here are also asciiToFloat conversion of environment variables. One
might argue that these should be locale dependent. But IMO these should be
set and interpreted by osg independent of the current locale.
"

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 = osg::asciiToDouble(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.