root/OpenSceneGraph/trunk/src/osgUtil/IncrementalCompileOperation.cpp @ 13041

Revision 13041, 23.1 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
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#include <osgUtil/IncrementalCompileOperation>
14
15#include <osg/Drawable>
16#include <osg/Notify>
17#include <osg/Timer>
18#include <osg/GLObjects>
19#include <osg/Depth>
20#include <osg/ColorMask>
21#include <osg/ApplicationUsage>
22
23#include <OpenThreads/ScopedLock>
24
25#include <algorithm>
26#include <iterator>
27#include <stdlib.h>
28#include <string.h>
29
30namespace osgUtil
31{
32
33
34// TODO
35// priority of CompileSets
36// isCompiled
37// time estimation
38// early completion
39// needs compile given time slot
40// custom CompileData elements
41// pruneOldRequestsAndCheckIfEmpty()
42// Use? :
43//                     #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
44//                        GLint p;
45//                        glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_RESIDENT, &p);
46//                    #endif
47
48static osg::ApplicationUsageProxy ICO_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MINIMUM_COMPILE_TIME_PER_FRAME <float>","minimum compile time alloted to compiling OpenGL objects per frame in database pager.");
49static osg::ApplicationUsageProxy UCO_e2(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAXIMUM_OBJECTS_TO_COMPILE_PER_FRAME <int>","maximum number of OpenGL objects to compile per frame in database pager.");
50static osg::ApplicationUsageProxy UCO_e3(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_FORCE_TEXTURE_DOWNLOAD <ON/OFF>","should the texture compiles be forced to download using a dummy Geometry.");
51
52/////////////////////////////////////////////////////////////////
53//
54// CollectStateToCompile
55//
56StateToCompile::StateToCompile(GLObjectsVisitor::Mode mode):
57    osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
58    _mode(mode),
59    _assignPBOToImages(false)
60{
61}
62
63void StateToCompile::apply(osg::Node& node)
64{
65    if (node.getStateSet())
66    {
67        apply(*(node.getStateSet()));
68    }
69
70    traverse(node);
71}
72
73void StateToCompile::apply(osg::Geode& node)
74{
75    if (node.getStateSet())
76    {
77        apply(*(node.getStateSet()));
78    }
79
80    for(unsigned int i=0;i<node.getNumDrawables();++i)
81    {
82        osg::Drawable* drawable = node.getDrawable(i);
83        if (drawable)
84        {
85            apply(*drawable);
86            if (drawable->getStateSet())
87            {
88                apply(*(drawable->getStateSet()));
89            }
90        }
91    }
92}
93
94void StateToCompile::apply(osg::Drawable& drawable)
95{
96    if (_drawablesHandled.count(&drawable)!=0) return;
97
98    _drawablesHandled.insert(&drawable);
99
100    if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS)
101    {
102        drawable.setUseDisplayList(false);
103    }
104
105    if (_mode&GLObjectsVisitor::SWITCH_ON_DISPLAY_LISTS)
106    {
107        drawable.setUseDisplayList(true);
108    }
109
110    if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS)
111    {
112        drawable.setUseVertexBufferObjects(true);
113    }
114
115    if (_mode&GLObjectsVisitor::SWITCH_OFF_VERTEX_BUFFER_OBJECTS)
116    {
117        drawable.setUseVertexBufferObjects(false);
118    }
119
120    if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS &&
121        (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects()))
122    {
123        _drawables.insert(&drawable);
124    }
125}
126
127void StateToCompile::apply(osg::StateSet& stateset)
128{
129    if (_statesetsHandled.count(&stateset)!=0) return;
130
131    _statesetsHandled.insert(&stateset);
132
133    if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES)
134    {
135        osg::Program* program = dynamic_cast<osg::Program*>(stateset.getAttribute(osg::StateAttribute::PROGRAM));
136        if (program)
137        {
138            _programs.insert(program);
139        }
140
141        osg::StateSet::TextureAttributeList& tal = stateset.getTextureAttributeList();
142
143#if 0
144        if (tal.size()>1)
145        {
146            tal.erase(tal.begin()+1,tal.end());
147        }
148#endif
149        for(osg::StateSet::TextureAttributeList::iterator itr = tal.begin();
150            itr != tal.end();
151            ++itr)
152        {
153            osg::StateSet::AttributeList& al = *itr;
154            osg::StateAttribute::TypeMemberPair tmp(osg::StateAttribute::TEXTURE,0);
155            osg::StateSet::AttributeList::iterator texItr = al.find(tmp);
156            if (texItr != al.end())
157            {
158                osg::Texture* texture = dynamic_cast<osg::Texture*>(texItr->second.first.get());
159                if (texture)
160                {
161                    if (_textures.count(texture)==0)
162                    {
163                        apply(*texture);
164                    }
165                }
166            }
167        }
168    }
169}
170
171void StateToCompile::apply(osg::Texture& texture)
172{
173    if (_assignPBOToImages)
174    {
175        unsigned int numRequringPBO = 0;
176        osg::ref_ptr<osg::PixelBufferObject> pbo = 0;
177        for(unsigned int i=0; i<texture.getNumImages(); ++i)
178        {
179            osg::Image* image = texture.getImage(i);
180            if (image)
181            {
182                if (image->getPixelBufferObject())
183                {
184                    pbo = image->getPixelBufferObject();
185                }
186                else
187                {
188                    ++numRequringPBO;
189                }
190            }
191        }
192        if (numRequringPBO>0)
193        {
194            // assign pbo
195            if (!pbo)
196            {
197                if (!_pbo) _pbo = new osg::PixelBufferObject;
198                pbo = _pbo;
199            }
200
201            for(unsigned int i=0; i<texture.getNumImages(); ++i)
202            {
203                osg::Image* image = texture.getImage(i);
204                if (image)
205                {
206                    if (!image->getPixelBufferObject())
207                    {
208                        //OSG_NOTICE<<"Assigning PBO"<<std::endl;
209                        pbo->setCopyDataAndReleaseGLBufferObject(true);
210                        pbo->setUsage(GL_DYNAMIC_DRAW_ARB);
211                        image->setPixelBufferObject(pbo.get());
212                    }
213                }
214            }
215        }
216    }
217
218    _textures.insert(&texture);
219}
220
221/////////////////////////////////////////////////////////////////
222//
223// CompileOps
224//
225IncrementalCompileOperation::CompileDrawableOp::CompileDrawableOp(osg::Drawable* drawable):
226    _drawable(drawable)
227{
228}
229
230double IncrementalCompileOperation::CompileDrawableOp::estimatedTimeForCompile(CompileInfo& compileInfo) const
231{
232    osg::GraphicsCostEstimator* gce = compileInfo.getState()->getGraphicsCostEstimator();
233    osg::Geometry* geometry = _drawable->asGeometry();
234    if (gce && geometry)
235    {
236        return gce->estimateCompileCost(geometry).first;
237    }
238    else return 0.0;
239}
240
241bool IncrementalCompileOperation::CompileDrawableOp::compile(CompileInfo& compileInfo)
242{
243    //OSG_NOTICE<<"CompileDrawableOp::compile(..)"<<std::endl;
244    _drawable->compileGLObjects(compileInfo);
245    return true;
246}
247
248IncrementalCompileOperation::CompileTextureOp::CompileTextureOp(osg::Texture* texture):
249    _texture(texture)
250{
251}
252
253double IncrementalCompileOperation::CompileTextureOp::estimatedTimeForCompile(CompileInfo& compileInfo) const
254{
255    osg::GraphicsCostEstimator* gce = compileInfo.getState()->getGraphicsCostEstimator();
256    if (gce) return gce->estimateCompileCost(_texture.get()).first;
257    else return 0.0;
258}
259
260bool IncrementalCompileOperation::CompileTextureOp::compile(CompileInfo& compileInfo)
261{
262    //OSG_NOTICE<<"CompileTextureOp::compile(..)"<<std::endl;
263    osg::Geometry* forceDownloadGeometry = compileInfo.incrementalCompileOperation->getForceTextureDownloadGeometry();
264    if (forceDownloadGeometry)
265    {
266
267        //OSG_NOTICE<<"Force texture download"<<std::endl;
268        if (forceDownloadGeometry->getStateSet())
269        {
270            compileInfo.getState()->apply(forceDownloadGeometry->getStateSet());
271        }
272
273        compileInfo.getState()->applyTextureMode(0, _texture->getTextureTarget(), true);
274        compileInfo.getState()->applyTextureAttribute(0, _texture.get());
275
276        forceDownloadGeometry->draw(compileInfo);
277    }
278    else
279    {
280        _texture->apply(*compileInfo.getState());
281    }
282    return true;
283}
284
285IncrementalCompileOperation::CompileProgramOp::CompileProgramOp(osg::Program* program):
286    _program(program)
287{
288}
289
290double IncrementalCompileOperation::CompileProgramOp::estimatedTimeForCompile(CompileInfo& compileInfo) const
291{
292    osg::GraphicsCostEstimator* gce = compileInfo.getState()->getGraphicsCostEstimator();
293    if (gce) return gce->estimateCompileCost(_program.get()).first;
294    else return 0.0;
295}
296
297bool IncrementalCompileOperation::CompileProgramOp::compile(CompileInfo& compileInfo)
298{
299    //OSG_NOTICE<<"CompileProgramOp::compile(..)"<<std::endl;
300    _program->apply(*compileInfo.getState());
301    return true;
302}
303
304IncrementalCompileOperation::CompileInfo::CompileInfo(osg::GraphicsContext* context, IncrementalCompileOperation* ico):
305    compileAll(false),
306    maxNumObjectsToCompile(0),
307    allocatedTime(0)
308{
309    setState(context->getState());
310    incrementalCompileOperation = ico;
311}
312
313
314/////////////////////////////////////////////////////////////////
315//
316// CompileList
317//
318IncrementalCompileOperation::CompileList::CompileList()
319{
320}
321
322IncrementalCompileOperation::CompileList::~CompileList()
323{
324}
325
326void IncrementalCompileOperation::CompileList::add(CompileOp* compileOp)
327{
328    _compileOps.push_back(compileOp);
329}
330
331double IncrementalCompileOperation::CompileList::estimatedTimeForCompile(CompileInfo& compileInfo) const
332{
333    double estimateTime = 0.0;
334    for(CompileOps::const_iterator itr = _compileOps.begin();
335        itr != _compileOps.begin();
336        ++itr)
337    {
338        estimateTime += (*itr)->estimatedTimeForCompile(compileInfo);
339    }
340    return estimateTime;
341}
342
343bool IncrementalCompileOperation::CompileList::compile(CompileInfo& compileInfo)
344{
345//#define USE_TIME_ESTIMATES
346
347    for(CompileOps::iterator itr = _compileOps.begin();
348        itr != _compileOps.end() && compileInfo.okToCompile();
349    )
350    {
351        #ifdef USE_TIME_ESTIMATES
352        double estimatedCompileCost = (*itr)->estimatedTimeForCompile(compileInfo);
353        #endif
354
355        --compileInfo.maxNumObjectsToCompile;
356
357        #ifdef USE_TIME_ESTIMATES
358        osg::ElapsedTime timer;
359        #endif
360
361        CompileOps::iterator saved_itr(itr);
362        ++itr;
363        if ((*saved_itr)->compile(compileInfo))
364        {
365            _compileOps.erase(saved_itr);
366        }
367
368        #ifdef USE_TIME_ESTIMATES
369        double actualCompileCost = timer.elapsedTime();
370        OSG_NOTICE<<"IncrementalCompileOperation::CompileList::compile() estimatedTimForCompile = "<<estimatedCompileCost*1000.0<<"ms, actual = "<<actualCompileCost*1000.0<<"ms";
371        if (estimatedCompileCost>0.0) OSG_NOTICE<<", ratio="<<(actualCompileCost/estimatedCompileCost);
372        OSG_NOTICE<<std::endl;
373        #endif
374    }
375    return empty();
376}
377
378/////////////////////////////////////////////////////////////////
379//
380// CompileSet
381//
382void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, StateToCompile& stc)
383{
384    if (contexts.empty() || stc.empty()) return;
385
386    if (stc.empty()) return;
387
388    for(ContextSet::iterator itr = contexts.begin();
389        itr != contexts.end();
390        ++itr)
391    {
392        // increment the number of compile lists that will need to compile
393        ++_numberCompileListsToCompile;
394
395        CompileList& cl = _compileMap[*itr];
396        for(StateToCompile::DrawableSet::iterator ditr = stc._drawables.begin();
397            ditr != stc._drawables.end();
398            ++ditr)
399        {
400            cl.add(*ditr);
401        }
402
403        for(StateToCompile::TextureSet::iterator titr = stc._textures.begin();
404            titr != stc._textures.end();
405            ++titr)
406        {
407            cl.add(*titr);
408        }
409
410        for(StateToCompile::ProgramSet::iterator pitr = stc._programs.begin();
411            pitr != stc._programs.end();
412            ++pitr)
413        {
414            cl.add(*pitr);
415        }
416    }
417}
418
419void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode)
420{
421    if (contexts.empty() || !_subgraphToCompile) return;
422
423    StateToCompile stc(mode);
424    _subgraphToCompile->accept(stc);
425
426    buildCompileMap(contexts, stc);
427}
428
429bool IncrementalCompileOperation::CompileSet::compile(CompileInfo& compileInfo)
430{
431    CompileList& compileList = _compileMap[compileInfo.getState()->getGraphicsContext()];
432    if (!compileList.empty())
433    {
434        if (compileList.compile(compileInfo))
435        {
436            --_numberCompileListsToCompile;
437            return _numberCompileListsToCompile==0;
438        }
439    }
440    return _numberCompileListsToCompile==0;
441}
442
443/////////////////////////////////////////////////////////////////
444//
445// IncrementalCompileOperation
446//
447IncrementalCompileOperation::IncrementalCompileOperation():
448    osg::GraphicsOperation("IncrementalCompileOperation",true),
449    _flushTimeRatio(0.5),
450    _conservativeTimeRatio(0.5),
451    _currentFrameNumber(0),
452    _compileAllTillFrameNumber(0)
453{
454    _targetFrameRate = 100.0;
455    _minimumTimeAvailableForGLCompileAndDeletePerFrame = 0.001; // 1ms.
456    _maximumNumOfObjectsToCompilePerFrame = 20;
457    const char* ptr = 0;
458    if( (ptr = getenv("OSG_MINIMUM_COMPILE_TIME_PER_FRAME")) != 0)
459    {
460        _minimumTimeAvailableForGLCompileAndDeletePerFrame = osg::asciiToDouble(ptr);
461    }
462
463    if( (ptr = getenv("OSG_MAXIMUM_OBJECTS_TO_COMPILE_PER_FRAME")) != 0)
464    {
465        _maximumNumOfObjectsToCompilePerFrame = atoi(ptr);
466    }
467
468    bool useForceTextureDownload = false;
469    if( (ptr = getenv("OSG_FORCE_TEXTURE_DOWNLOAD")) != 0)
470    {
471        useForceTextureDownload = strcmp(ptr,"yes")==0 || strcmp(ptr,"YES")==0 ||
472                                  strcmp(ptr,"on")==0 || strcmp(ptr,"ON")==0;
473
474        OSG_NOTICE<<"OSG_FORCE_TEXTURE_DOWNLOAD set to "<<useForceTextureDownload<<std::endl;
475    }
476
477    if (useForceTextureDownload)
478    {
479        assignForceTextureDownloadGeometry();
480    }
481
482}
483
484IncrementalCompileOperation::~IncrementalCompileOperation()
485{
486}
487
488void IncrementalCompileOperation::assignForceTextureDownloadGeometry()
489{
490    osg::Geometry* geometry = new osg::Geometry;
491
492    osg::Vec3Array* vertices = new osg::Vec3Array;
493    vertices->push_back(osg::Vec3(0.0f,0.0f,0.0f));
494    geometry->setVertexArray(vertices);
495
496    osg::Vec4Array* texcoords = new osg::Vec4Array;
497    texcoords->push_back(osg::Vec4(0.0f,0.0f,0.0f,0.0f));
498    geometry->setTexCoordArray(0, texcoords);
499
500    geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,1));
501
502    osg::StateSet* stateset = geometry->getOrCreateStateSet();
503    stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
504
505    osg::Depth* depth = new osg::Depth;
506    depth->setWriteMask(false);
507    stateset->setAttribute(depth);
508
509    osg::ColorMask* colorMask = new osg::ColorMask(false,false,false,false);
510    stateset->setAttribute(colorMask);
511
512    _forceTextureDownloadGeometry = geometry;
513}
514
515void IncrementalCompileOperation::assignContexts(Contexts& contexts)
516{
517    for(Contexts::iterator itr = contexts.begin();
518        itr != contexts.end();
519        ++itr)
520    {
521        osg::GraphicsContext* gc = *itr;
522        addGraphicsContext(gc);
523    }
524}
525
526void IncrementalCompileOperation::removeContexts(Contexts& contexts)
527{
528    for(Contexts::iterator itr = contexts.begin();
529        itr != contexts.end();
530        ++itr)
531    {
532        osg::GraphicsContext* gc = *itr;
533        removeGraphicsContext(gc);
534    }
535}
536
537
538void IncrementalCompileOperation::addGraphicsContext(osg::GraphicsContext* gc)
539{
540    if (_contexts.count(gc)==0)
541    {
542        gc->add(this);
543        _contexts.insert(gc);
544    }
545}
546
547void IncrementalCompileOperation::removeGraphicsContext(osg::GraphicsContext* gc)
548{
549    if (_contexts.count(gc)!=0)
550    {
551        gc->remove(this);
552        _contexts.erase(gc);
553    }
554}
555
556bool IncrementalCompileOperation::requiresCompile(StateToCompile& stateToCompile)
557{
558    return isActive() && !stateToCompile.empty();
559}
560
561void IncrementalCompileOperation::add(osg::Node* subgraphToCompile)
562{
563    OSG_INFO<<"IncrementalCompileOperation::add("<<subgraphToCompile<<")"<<std::endl;
564    add(new CompileSet(subgraphToCompile));
565}
566
567void IncrementalCompileOperation::add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile)
568{
569    OSG_INFO<<"IncrementalCompileOperation::add("<<attachmentPoint<<", "<<subgraphToCompile<<")"<<std::endl;
570    add(new CompileSet(attachmentPoint, subgraphToCompile));
571}
572
573
574void IncrementalCompileOperation::add(CompileSet* compileSet, bool callBuildCompileMap)
575{
576    if (!compileSet) return;
577
578    if (compileSet->_subgraphToCompile.valid())
579    {
580        // force a compute of the bound of the subgraph to avoid the update traversal from having to do this work
581        // and reducing the change of frame drop.
582        compileSet->_subgraphToCompile->getBound();
583    }
584
585    if (callBuildCompileMap) compileSet->buildCompileMap(_contexts);
586
587    OSG_INFO<<"IncrementalCompileOperation::add(CompileSet = "<<compileSet<<", "<<", "<<callBuildCompileMap<<")"<<std::endl;
588
589    OpenThreads::ScopedLock<OpenThreads::Mutex>  lock(_toCompileMutex);
590    _toCompile.push_back(compileSet);
591}
592
593void IncrementalCompileOperation::remove(CompileSet* compileSet)
594{
595    // OSG_NOTICE<<"IncrementalCompileOperation::remove(CompileSet* compileSet)"<<std::endl;
596
597    if (!compileSet) return;
598
599    // remove CompileSet from _toCompile list if it's present.
600    {
601        OpenThreads::ScopedLock<OpenThreads::Mutex>  lock(_toCompileMutex);
602        for(CompileSets::iterator itr = _toCompile.begin();
603            itr != _toCompile.end();
604            ++itr)
605        {
606            if (*itr == compileSet)
607            {
608                _toCompile.erase(itr);
609                return;
610            }
611        }
612    }
613
614    // remove CompileSet from _compiled list if it's present.
615    {
616        OpenThreads::ScopedLock<OpenThreads::Mutex>  lock(_compiledMutex);
617        for(CompileSets::iterator itr = _compiled.begin();
618            itr != _compiled.end();
619            ++itr)
620        {
621            if (*itr == compileSet)
622            {
623                _toCompile.erase(itr);
624                return;
625            }
626        }
627    }
628}
629
630
631void IncrementalCompileOperation::mergeCompiledSubgraphs(const osg::FrameStamp* frameStamp)
632{
633    // OSG_INFO<<"IncrementalCompileOperation::mergeCompiledSubgraphs()"<<std::endl;
634
635    OpenThreads::ScopedLock<OpenThreads::Mutex>  compilded_lock(_compiledMutex);
636
637    if (frameStamp) _currentFrameNumber = frameStamp->getFrameNumber();
638
639    for(CompileSets::iterator itr = _compiled.begin();
640        itr != _compiled.end();
641        ++itr)
642    {
643        CompileSet* cs = itr->get();
644        osg::ref_ptr<osg::Group> group;
645        if (cs->_attachmentPoint.lock(group))
646        {
647            group->addChild(cs->_subgraphToCompile.get());
648        }
649    }
650
651    _compiled.clear();
652}
653
654
655void IncrementalCompileOperation::operator () (osg::GraphicsContext* context)
656{
657    osg::NotifySeverity level = osg::INFO;
658
659    //glFinish();
660    //glFlush();
661
662    double targetFrameRate = _targetFrameRate;
663    double minimumTimeAvailableForGLCompileAndDeletePerFrame = _minimumTimeAvailableForGLCompileAndDeletePerFrame;
664
665    double targetFrameTime = 1.0/targetFrameRate;
666
667    const osg::FrameStamp* fs = context->getState()->getFrameStamp();
668    double currentTime = fs ? fs->getReferenceTime() : 0.0;
669
670    double currentElapsedFrameTime = context->getTimeSinceLastClear();
671
672    OSG_NOTIFY(level)<<"IncrementalCompileOperation()"<<std::endl;
673    OSG_NOTIFY(level)<<"    currentTime = "<<currentTime<<std::endl;
674    OSG_NOTIFY(level)<<"    currentElapsedFrameTime = "<<currentElapsedFrameTime<<std::endl;
675
676    double _flushTimeRatio(0.5);
677    double _conservativeTimeRatio(0.5);
678
679    double availableTime = std::max((targetFrameTime - currentElapsedFrameTime)*_conservativeTimeRatio,
680                                    minimumTimeAvailableForGLCompileAndDeletePerFrame);
681
682    double flushTime = availableTime * _flushTimeRatio;
683    double compileTime = availableTime - flushTime;
684
685#if 1
686    OSG_NOTIFY(level)<<"    availableTime = "<<availableTime*1000.0<<std::endl;
687    OSG_NOTIFY(level)<<"    flushTime     = "<<flushTime*1000.0<<std::endl;
688    OSG_NOTIFY(level)<<"    compileTime   = "<<compileTime*1000.0<<std::endl;
689#endif
690
691    //level = osg::NOTICE;
692
693    CompileInfo compileInfo(context, this);
694    compileInfo.maxNumObjectsToCompile = _maximumNumOfObjectsToCompilePerFrame;
695    compileInfo.allocatedTime = compileTime;
696    compileInfo.compileAll = (_compileAllTillFrameNumber > _currentFrameNumber);
697
698    CompileSets toCompileCopy;
699    {
700        OpenThreads::ScopedLock<OpenThreads::Mutex>  toCompile_lock(_toCompileMutex);
701        std::copy(_toCompile.begin(),_toCompile.end(),std::back_inserter<CompileSets>(toCompileCopy));
702    }
703
704    if (!toCompileCopy.empty())
705    {
706        compileSets(toCompileCopy, compileInfo);
707    }
708
709    osg::flushDeletedGLObjects(context->getState()->getContextID(), currentTime, flushTime);
710
711    if (!toCompileCopy.empty() && compileInfo.maxNumObjectsToCompile>0)
712    {
713        compileInfo.allocatedTime += flushTime;
714
715        // if any time left over from flush add on this remaining time to a second pass of compiling.
716        if (compileInfo.okToCompile())
717        {
718            OSG_NOTIFY(level)<<"    Passing on "<<flushTime<<" to second round of compileSets(..)"<<std::endl;
719            compileSets(toCompileCopy, compileInfo);
720        }
721    }
722
723    //glFush();
724    //glFinish();
725}
726
727void IncrementalCompileOperation::compileSets(CompileSets& toCompile, CompileInfo compileInfo)
728{
729    osg::NotifySeverity level = osg::INFO;
730
731    for(CompileSets::iterator itr = toCompile.begin();
732        itr != toCompile.end() && compileInfo.okToCompile();
733        )
734    {
735        CompileSet* cs = itr->get();
736        if (cs->compile(compileInfo))
737        {
738            {
739                OpenThreads::ScopedLock<OpenThreads::Mutex>  toCompile_lock(_toCompileMutex);
740
741                CompileSets::iterator cs_itr = std::find(_toCompile.begin(), _toCompile.end(), *itr);
742                if (cs_itr != _toCompile.end())
743                {
744                    OSG_NOTIFY(level)<<"    Erasing from list"<<std::endl;
745
746                    // remove from the _toCompile list, note cs won't be deleted here as the tempoary
747                    // toCompile_Copy list will retain a reference.
748                    _toCompile.erase(cs_itr);
749                }
750            }
751            if (cs->_compileCompletedCallback.valid() && cs->_compileCompletedCallback->compileCompleted(cs))
752            {
753                // callback will handle merging of subgraph so no need to place CompileSet in merge.
754            }
755            else
756            {
757                OpenThreads::ScopedLock<OpenThreads::Mutex>  compilded_lock(_compiledMutex);
758                _compiled.push_back(cs);
759            }
760
761            // remove entry from list.
762            itr = toCompile.erase(itr);
763        }
764        else
765        {
766            ++itr;
767        }
768    }
769
770}
771
772
773void IncrementalCompileOperation::compileAllForNextFrame(unsigned int numFramesToDoCompileAll)
774{
775    _compileAllTillFrameNumber = _currentFrameNumber+numFramesToDoCompileAll;
776}
777
778
779} // end of namespace osgUtil
Note: See TracBrowser for help on using the browser.