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

Revision 9886, 27.2 kB (checked in by robert, 6 years ago)

From Roland Smeenk, "While working on the Collada plugin I noticed that all geometry created by the dae reader result in slow path geometry.
Because there already exists the option to convert slow path geometry to the fast path by computing an internal fast path alternative, I added a new optimizer option that automatically does this. To check the results I also made some changes to the statistics gathering and rendering.

Somewhat unrelated, but also part of the optimizer I disabled removal of CameraView? nodes during RemoveRedundantNodes? optimization.
As discussed on the ML, CameraViews? were removed from the scenegraph. This solves that issue.

Summary:
-Geometry::areFastPathsUsed now also looks at internalOptimizedGeometry
-Added Optimize option to make all slow path geometry compute their internal fast path alternative
-Added fast geometry counter to the statistics
-Disabled removel of CameraViews? in optimizer
"

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