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

Revision 9554, 26.7 kB (checked in by robert, 5 years ago)

Refactored the view stats.

RevLine 
[7507]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
[7566]14#include <stdlib.h>
15#include <string.h>
16
[7507]17#include <osgViewer/ViewerBase>
[8348]18#include <osgViewer/View>
[7535]19#include <osgViewer/Renderer>
[7507]20
21#include <osg/io_utils>
22
23#include <osg/TextureCubeMap>
24#include <osg/TextureRectangle>
25#include <osg/TexMat>
[7837]26#include <osg/DeleteHandler>
[7507]27
28#include <osgUtil/Optimizer>
29#include <osgUtil/IntersectionVisitor>
[9554]30#include <osgUtil/Statistics>
[7507]31
[7535]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
[7507]38using namespace osgViewer;
39
40ViewerBase::ViewerBase():
41    osg::Object(true)
42{
[7535]43    _firstFrame = true;
[7507]44    _done = false;
45    _keyEventSetsDone = osgGA::GUIEventAdapter::KEY_Escape;
46    _quitEventSetsDone = true;
[8406]47    _releaseContextAtEndOfFrameHint = true;
[7507]48    _threadingModel = AutomaticSelection;
49    _threadsRunning = false;
[7535]50    _endBarrierPosition = AfterSwapBuffers;
[7507]51}
52
53ViewerBase::ViewerBase(const ViewerBase& base):
54    osg::Object(true)
55{
[7535]56    _firstFrame = true;
57    _done = false;
58    _keyEventSetsDone = osgGA::GUIEventAdapter::KEY_Escape;
59    _quitEventSetsDone = true;
[8406]60    _releaseContextAtEndOfFrameHint = true;
[7535]61    _threadingModel = AutomaticSelection;
62    _threadsRunning = false;
63    _endBarrierPosition = AfterSwapBuffers;
[7507]64}
65
[7535]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;
[8325]149                    osgDB::DatabasePager* dp = scene->getDatabasePager();
150                    if (dp)
[7535]151                    {
[8325]152                        for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
153                        {
154                            osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
155                            dt->setProcessorAffinity(1);
156                        }
[7535]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       
[8512]376        if (!gc->isRealized())
377        {
378            osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
379            gc->realize();
380        }
381       
[7535]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
[8893]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
[7535]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
[7507]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}
[7535]553
554int ViewerBase::run()
555{
556    if (!isRealized())
557    {
558        realize();
559    }
560
561#if 0
562    while (!done())
563    {
564        frame();
565    }
566#else
567
568    const char* str = getenv("OSG_RUN_FRAME_COUNT");
569    if (str)
570    {
571        int runTillFrameNumber = atoi(str);
572        while (!done() && getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber)
573        {
574            frame();
575        }
576    }
577    else
578    {
579        while (!done())
580        {
581            frame();
582        }
583    }
584#endif   
[7541]585    return 0;
[7535]586}
587
588void ViewerBase::frame(double simulationTime)
589{
590    if (_done) return;
591
592    // osg::notify(osg::NOTICE)<<std::endl<<"CompositeViewer::frame()"<<std::endl<<std::endl;
593
594    if (_firstFrame)
595    {
596        viewerInit();
597       
598        if (!isRealized())
599        {
600            realize();
601        }
602       
603        _firstFrame = false;
604    }
605    advance(simulationTime);
606   
607    eventTraversal();
608    updateTraversal();
609    renderingTraversals();
610}
611
612
613void ViewerBase::renderingTraversals()
614{
[8348]615    bool _outputMasterCameraLocation = false;
616    if (_outputMasterCameraLocation)
617    {
618        Views views;
619        getViews(views);
620
621        for(Views::iterator itr = views.begin();
622            itr != views.end();
623            ++itr)
624        {
625            osgViewer::View* view = *itr;
626            if (view)
627            {
628                const osg::Matrixd& m = view->getCamera()->getInverseViewMatrix();
629                osg::notify(osg::NOTICE)<<"View "<<view<<", Master Camera position("<<m.getTrans()<<"), rotation("<<m.getRotate()<<")"<<std::endl;
630            }
631        }
632    }
633       
[7535]634    // check to see if windows are still valid
635    checkWindowStatus();
636
637    if (_done) return;
638
639    double beginRenderingTraversals = elapsedTime();
640
641    osg::FrameStamp* frameStamp = getViewerFrameStamp();
642
[9554]643    if (getViewerStats() && getViewerStats()->collectStats("scene"))
644    {
645        int frameNumber = frameStamp ? frameStamp->getFrameNumber() : 0;
646   
647        Views views;
648        getViews(views);
649        for(Views::iterator vitr = views.begin();
650            vitr != views.end();
651            ++vitr)
652        {
653            View* view = *vitr;
654            osg::Stats* stats = view->getStats();           
655            osg::Node* sceneRoot = view->getSceneData();
656            if (sceneRoot)
657            {
658                osgUtil::StatsVisitor statsVisitor;
659                sceneRoot->accept(statsVisitor);
660               
661                unsigned int unique_primitives = 0;
662                osgUtil::Statistics::PrimitiveCountMap::iterator pcmitr;
663                for(pcmitr = statsVisitor._uniqueStats.GetPrimitivesBegin();
664                    pcmitr != statsVisitor._uniqueStats.GetPrimitivesEnd();
665                    ++pcmitr)
666                {
667                    unique_primitives += pcmitr->second;
668                }
669
670                stats->setAttribute(frameNumber, "Number of unique StateSet", static_cast<double>(statsVisitor._statesetSet.size()));
671                stats->setAttribute(frameNumber, "Number of unique Group", static_cast<double>(statsVisitor._groupSet.size()));
672                stats->setAttribute(frameNumber, "Number of unique Transform", static_cast<double>(statsVisitor._transformSet.size()));
673                stats->setAttribute(frameNumber, "Number of unique LOD", static_cast<double>(statsVisitor._lodSet.size()));
674                stats->setAttribute(frameNumber, "Number of unique Switch", static_cast<double>(statsVisitor._switchSet.size()));
675                stats->setAttribute(frameNumber, "Number of unique Geode", static_cast<double>(statsVisitor._geodeSet.size()));
676                stats->setAttribute(frameNumber, "Number of unique Drawable", static_cast<double>(statsVisitor._drawableSet.size()));
677                stats->setAttribute(frameNumber, "Number of unique Geometry", static_cast<double>(statsVisitor._geometrySet.size()));
678                stats->setAttribute(frameNumber, "Number of unique Vertices", static_cast<double>(statsVisitor._uniqueStats._vertexCount));
679                stats->setAttribute(frameNumber, "Number of unique Primitives", static_cast<double>(unique_primitives));
680
681                unsigned int instanced_primitives = 0;
682                for(pcmitr = statsVisitor._instancedStats.GetPrimitivesBegin();
683                    pcmitr != statsVisitor._instancedStats.GetPrimitivesEnd();
684                    ++pcmitr)
685                {
686                    instanced_primitives += pcmitr->second;
687                }
688
689                stats->setAttribute(frameNumber, "Number of instanced Stateset", static_cast<double>(statsVisitor._numInstancedStateSet));
690                stats->setAttribute(frameNumber, "Number of instanced Group", static_cast<double>(statsVisitor._numInstancedGroup));
691                stats->setAttribute(frameNumber, "Number of instanced Transform", static_cast<double>(statsVisitor._numInstancedTransform));
692                stats->setAttribute(frameNumber, "Number of instanced LOD", static_cast<double>(statsVisitor._numInstancedLOD));
693                stats->setAttribute(frameNumber, "Number of instanced Switch", static_cast<double>(statsVisitor._numInstancedSwitch));
694                stats->setAttribute(frameNumber, "Number of instanced Geode", static_cast<double>(statsVisitor._numInstancedGeode));
695                stats->setAttribute(frameNumber, "Number of instanced Drawable", static_cast<double>(statsVisitor._numInstancedDrawable));
696                stats->setAttribute(frameNumber, "Number of instanced Geometry", static_cast<double>(statsVisitor._numInstancedGeometry));
697                stats->setAttribute(frameNumber, "Number of instanced Vertices", static_cast<double>(statsVisitor._instancedStats._vertexCount));
698                stats->setAttribute(frameNumber, "Number of instanced Primitives", static_cast<double>(instanced_primitives));
699           }
700        }
701    }
702
[7535]703    Scenes scenes;
704    getScenes(scenes);
705   
706    for(Scenes::iterator sitr = scenes.begin();
707        sitr != scenes.end();
708        ++sitr)
709    {
710        Scene* scene = *sitr;
711        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
712        if (dp)
713        {
714            dp->signalBeginFrame(frameStamp);
715        }
[8312]716       
717        if (scene->getSceneData())
718        {
719            // fire off a build of the bounding volumes while we
720            // are still running single threaded.
721            scene->getSceneData()->getBound();
722        }
[7535]723    }
724
725    // osg::notify(osg::NOTICE)<<std::endl<<"Start frame"<<std::endl;
726   
727
728    Contexts contexts;
729    getContexts(contexts);
730
731    Cameras cameras;
732    getCameras(cameras);
733   
734    Contexts::iterator itr;
[8413]735   
736    bool doneMakeCurrentInThisThread = false;
[7535]737
738    if (_endDynamicDrawBlock.valid())
739    {
740        _endDynamicDrawBlock->reset();
741    }
742   
[9131]743    // dispatch the rendering threads
744    if (_startRenderingBarrier.valid()) _startRenderingBarrier->block();
745
[7535]746    // reset any double buffer graphics objects
747    for(Cameras::iterator camItr = cameras.begin();
748        camItr != cameras.end();
749        ++camItr)
750    {
751        osg::Camera* camera = *camItr;
752        Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
753        if (renderer)
754        {
755            if (!renderer->getGraphicsThreadDoesCull() && !(camera->getCameraThread()))
756            {
757                renderer->cull();
758            }
759        }
760    }
761
762    for(itr = contexts.begin();
763        itr != contexts.end();
764        ++itr)
765    {
766        if (_done) return;
767        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
[8413]768        {
769            doneMakeCurrentInThisThread = true;
[7535]770            makeCurrent(*itr);
771            (*itr)->runOperations();
772        }
773    }
774
775    // osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block "<<_endRenderingDispatchBarrier.get()<<std::endl;
776
777    // wait till the rendering dispatch is done.
778    if (_endRenderingDispatchBarrier.valid()) _endRenderingDispatchBarrier->block();
779
780    for(itr = contexts.begin();
781        itr != contexts.end();
782        ++itr)
783    {
784        if (_done) return;
785
786        if (!((*itr)->getGraphicsThread()) && (*itr)->valid())
787        {
[8413]788            doneMakeCurrentInThisThread = true;
[7535]789            makeCurrent(*itr);
790            (*itr)->swapBuffers();
791        }
792    }
793
794    for(Scenes::iterator sitr = scenes.begin();
795        sitr != scenes.end();
796        ++sitr)
797    {
798        Scene* scene = *sitr;
799        osgDB::DatabasePager* dp = scene ? scene->getDatabasePager() : 0;
800        if (dp)
801        {
802            dp->signalEndFrame();
803        }
804    }
805
806    // wait till the dynamic draw is complete.
807    if (_endDynamicDrawBlock.valid())
808    {
809        // osg::Timer_t startTick = osg::Timer::instance()->tick();
810        _endDynamicDrawBlock->block();
811        // osg::notify(osg::NOTICE)<<"Time waiting "<<osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick())<<std::endl;;
812    }
[8406]813   
[8413]814    if (_releaseContextAtEndOfFrameHint && doneMakeCurrentInThisThread)
[8406]815    {
[8413]816        //osg::notify(osg::NOTICE)<<"Doing release context"<<std::endl;
[8406]817        releaseContext();
818    }
[7535]819
[9554]820    if (getViewerStats() && getViewerStats()->collectStats("update"))
[7535]821    {
822        double endRenderingTraversals = elapsedTime();
823
824        // update current frames stats
[9554]825        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals begin time ", beginRenderingTraversals);
826        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals end time ", endRenderingTraversals);
827        getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals);
[7535]828    }
829}
Note: See TracBrowser for help on using the browser.