diff --git a/include/osgUtil/IncrementalCompileOperation b/include/osgUtil/IncrementalCompileOperation index b2f7bbc5d..2b4c9b7d2 100644 --- a/include/osgUtil/IncrementalCompileOperation +++ b/include/osgUtil/IncrementalCompileOperation @@ -19,29 +19,6 @@ namespace osgUtil { -class CompileData : public osg::Referenced -{ - public: - - CompileData() {} - - typedef std::set< osg::ref_ptr > Drawables; - typedef std::set< osg::ref_ptr > Textures; - typedef std::set< osg::ref_ptr > Programs; - - bool empty() const { return _drawables.empty() && _textures.empty() && _programs.empty(); } - - void reset() - { - _drawables.clear(); - _textures.clear(); - _programs.clear(); - } - - Drawables _drawables; - Textures _textures; - Programs _programs; -}; class OSGUTIL_EXPORT CompileStats : public osg::Referenced { @@ -111,52 +88,6 @@ class OSGUTIL_EXPORT CompileStats : public osg::Referenced StatsMap _statsMap; }; -class OSGUTIL_EXPORT CompileOperator : public osg::Referenced -{ - public: - - CompileOperator(); - - /** Assign a geometry and associated StateSet than is applied after each texture compile to atttempt to force the OpenGL - * drive to download the texture object to OpenGL graphics card.*/ - void assignForceTextureDownloadGeometry(); - - /** Set the osg::Geometry to apply after each texture compile to atttempt to force the OpenGL - * drive to download the texture object to OpenGL graphics card.*/ - void setForceTextureDownloadGeometry(osg::Geometry* geom) { _forceTextureDownloadGeometry = geom; } - osg::Geometry* getForceTextureDownloadGeometry() { return _forceTextureDownloadGeometry.get(); } - const osg::Geometry* getForceTextureDownloadGeometry() const { return _forceTextureDownloadGeometry.get(); } - - /** Compile as many elements in the CompileData container as possible within specified time. - * return true if all have been compiled. */ - virtual bool compile(osg::RenderInfo& renderInfo, CompileData& compileData, unsigned int& maxNumObjectsToCompile, double& availableTime); - - /** Compile all the elements in the CompileData container. */ - void compileAll(osg::RenderInfo& renderInfo, CompileData& compileData) - { - unsigned int maxNumObjectsToCompile = 32768; - double availableTime = DBL_MAX; - compile(renderInfo, compileData, maxNumObjectsToCompile, availableTime); - } - - CompileStats* getCompileStats() { return _compileStats.get(); } - const CompileStats* getCompileStats() const { return _compileStats.get(); } - - protected: - - void runTimingTests(osg::RenderInfo& renderInfo); - - double timeCompile(osg::RenderInfo& renderInfo, osg::Geometry* geometry) const; - double timeCompile(osg::RenderInfo& renderInfo, osg::StateSet* stateset) const; - osg::Geometry* createTestGeometry(unsigned int numVertices, bool vbo) const; - osg::StateSet* createTestStateSet(unsigned int imageSize, bool mipmapped) const; - - osg::ref_ptr _forceTextureDownloadGeometry; - osg::ref_ptr _compileStats; - bool _timingTestsCompleted; -}; - - class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation { public: @@ -211,6 +142,18 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation void setConservativeTimeRatio(double ratio) { _conservativeTimeRatio = ratio; } double getConservativeTimeRatio() const { return _conservativeTimeRatio; } + /** Assign a geometry and associated StateSet than is applied after each texture compile to atttempt to force the OpenGL + * drive to download the texture object to OpenGL graphics card.*/ + void assignForceTextureDownloadGeometry(); + + /** Set the osg::Geometry to apply after each texture compile to atttempt to force the OpenGL + * drive to download the texture object to OpenGL graphics card.*/ + void setForceTextureDownloadGeometry(osg::Geometry* geom) { _forceTextureDownloadGeometry = geom; } + osg::Geometry* getForceTextureDownloadGeometry() { return _forceTextureDownloadGeometry.get(); } + const osg::Geometry* getForceTextureDownloadGeometry() const { return _forceTextureDownloadGeometry.get(); } + + CompileStats* getCompileStats() { return _compileStats.get(); } + const CompileStats* getCompileStats() const { return _compileStats.get(); } typedef std::vector Contexts; @@ -225,12 +168,74 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation void mergeCompiledSubgraphs(); virtual void operator () (osg::GraphicsContext* context); + + struct OSGUTIL_EXPORT CompileInfo : public osg::RenderInfo + { + CompileInfo(osg::GraphicsContext* context, IncrementalCompileOperation* ico); + + double availableTime() { return allocatedTime - timer.elapsedTime(); } + + IncrementalCompileOperation* incrementalCompileOperation; + unsigned int maxNumObjectsToCompile; + osg::ElapsedTime timer; + double allocatedTime; + }; + struct CompileOp : public osg::Referenced + { + /** return an estimate for how many seconds the compile will take.*/ + virtual double estimatedTimeForCompile(CompileInfo& compileInfo) const = 0; + /** compile associated objects, return true if object as been fully compiled and this CompileOp can be removed from the to compile list.*/ + virtual bool compile(CompileInfo& compileInfo) = 0; + }; + + struct OSGUTIL_EXPORT CompileDrawableOp : public CompileOp + { + CompileDrawableOp(osg::Drawable* drawable); + double estimatedTimeForCompile(CompileInfo& compileInfo) const; + bool compile(CompileInfo& compileInfo); + osg::ref_ptr _drawable; + }; + + struct OSGUTIL_EXPORT CompileTextureOp : public CompileOp + { + CompileTextureOp(osg::Texture* texture); + double estimatedTimeForCompile(CompileInfo& compileInfo) const; + bool compile(CompileInfo& compileInfo); + osg::ref_ptr _texture; + }; + + struct OSGUTIL_EXPORT CompileProgramOp : public CompileOp + { + CompileProgramOp(osg::Program* program); + double estimatedTimeForCompile(CompileInfo& compileInfo) const; + bool compile(CompileInfo& compileInfo); + osg::ref_ptr _program; + }; + + class OSGUTIL_EXPORT CompileList + { + public: + CompileList(); + ~CompileList(); + + bool empty() const { return _compileOps.empty(); } + void add(CompileOp* compileOp); + void add(osg::Drawable* drawable) { add(new CompileDrawableOp(drawable)); } + void add(osg::Texture* texture) { add(new CompileTextureOp(texture)); } + void add(osg::Program* program) { add(new CompileProgramOp(program)); } + + double estimatedTimeForCompile(CompileInfo& compileInfo) const; + bool compile(CompileInfo& compileInfo); + + + typedef std::list< osg::ref_ptr > CompileOps; + CompileOps _compileOps; + }; class CompileSet; typedef std::set ContextSet; - typedef std::map CompileMap; struct CompileCompletedCallback : public virtual osg::Referenced { @@ -242,36 +247,29 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation class OSGUTIL_EXPORT CompileSet : public osg::Referenced { public: - - CompileSet() {} - + CompileSet(osg::Node*subgraphToCompile): _subgraphToCompile(subgraphToCompile) {} - CompileSet(osg::Group* attachmentPoint, osg::Node*subgraphToCompile): + CompileSet(osg::Group* attachmentPoint, osg::Node* subgraphToCompile): _attachmentPoint(attachmentPoint), _subgraphToCompile(subgraphToCompile) {} - + void buildCompileMap(ContextSet& context, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES); - bool compileCompleted() const - { - for(CompileMap::const_iterator itr = _compileMap.begin(); - itr != _compileMap.end(); - ++itr) - { - if (!(itr->second.empty())) return false; - } - return true; - } + bool compile(CompileInfo& compileInfo); + + OpenThreads::Atomic _numberCompileListsToCompile; osg::observer_ptr _attachmentPoint; osg::ref_ptr _subgraphToCompile; osg::ref_ptr _compileCompletedCallback; + + typedef std::map CompileMap; CompileMap _compileMap; - // protected: + protected: virtual ~CompileSet() {} }; @@ -297,14 +295,6 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; } CompileSets& getCompiled() { return _compiled; } - void setCompileOperator(CompileOperator* compileOperator) { _compileOperator = compileOperator; } - CompileOperator* getCompileOperator() { return _compileOperator.get(); } - const CompileOperator* getCompileOperator() const { return _compileOperator.get(); } - - /** Assign a geometry and associated StateSet than is applied after each texture compile to atttempt to force the OpenGL - * drive to download the texture object to OpenGL graphics card.*/ - void assignForceTextureDownloadGeometry(); - protected: virtual ~IncrementalCompileOperation(); @@ -318,7 +308,8 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation double _flushTimeRatio; double _conservativeTimeRatio; - osg::ref_ptr _compileOperator; + osg::ref_ptr _forceTextureDownloadGeometry; + osg::ref_ptr _compileStats; OpenThreads::Mutex _toCompileMutex; CompileSets _toCompile; diff --git a/src/osgUtil/IncrementalCompileOperation.cpp b/src/osgUtil/IncrementalCompileOperation.cpp index c1269c4bb..45640d3b2 100644 --- a/src/osgUtil/IncrementalCompileOperation.cpp +++ b/src/osgUtil/IncrementalCompileOperation.cpp @@ -47,6 +47,130 @@ namespace osgUtil static osg::ApplicationUsageProxy ICO_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MINIMUM_COMPILE_TIME_PER_FRAME ","minimum compile time alloted to compiling OpenGL objects per frame in database pager."); static osg::ApplicationUsageProxy UCO_e2(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAXIMUM_OBJECTS_TO_COMPILE_PER_FRAME ","maximum number of OpenGL objects to compile per frame in database pager."); +///////////////////////////////////////////////////////////////// +// +// CollectStateToCompile +// +class IncrementalCompileOperation::CollectStateToCompile : public osg::NodeVisitor +{ +public: + + CollectStateToCompile(GLObjectsVisitor::Mode mode): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _mode(mode) {} + + GLObjectsVisitor::Mode _mode; + + typedef std::set DrawableSet; + typedef std::set StateSetSet; + typedef std::set TextureSet; + typedef std::set ProgramSet; + + DrawableSet _drawablesHandled; + StateSetSet _statesetsHandled; + + DrawableSet _drawables; + TextureSet _textures; + ProgramSet _programs; + + void apply(osg::Node& node) + { + if (node.getStateSet()) + { + apply(*(node.getStateSet())); + } + + traverse(node); + } + + void apply(osg::Geode& node) + { + if (node.getStateSet()) + { + apply(*(node.getStateSet())); + } + + for(unsigned int i=0;igetStateSet()) + { + apply(*(drawable->getStateSet())); + } + } + } + } + + void apply(osg::Drawable& drawable) + { + if (_drawablesHandled.count(&drawable)!=0) return; + + _drawablesHandled.insert(&drawable); + + if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS) + { + drawable.setUseDisplayList(false); + } + + if (_mode&GLObjectsVisitor::SWITCH_ON_DISPLAY_LISTS) + { + drawable.setUseDisplayList(true); + } + + if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS) + { + drawable.setUseVertexBufferObjects(true); + } + + if (_mode&GLObjectsVisitor::SWITCH_OFF_VERTEX_BUFFER_OBJECTS) + { + drawable.setUseVertexBufferObjects(false); + } + + if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && + (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) + { + _drawables.insert(&drawable); + } + + } + + void apply(osg::StateSet& stateset) + { + if (_statesetsHandled.count(&stateset)!=0) return; + + _statesetsHandled.insert(&stateset); + + if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES) + { + osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); + if (program) + { + _programs.insert(program); + } + + osg::StateSet::TextureAttributeList& tal = stateset.getTextureAttributeList(); + for(osg::StateSet::TextureAttributeList::iterator itr = tal.begin(); + itr != tal.end(); + ++itr) + { + osg::StateSet::AttributeList& al = *itr; + osg::StateAttribute::TypeMemberPair tmp(osg::StateAttribute::TEXTURE,0); + osg::StateSet::AttributeList::iterator texItr = al.find(tmp); + if (texItr != al.end()) + { + osg::Texture* texture = dynamic_cast(texItr->second.first.get()); + if (texture) _textures.insert(texture); + } + } + } + } + +}; + ///////////////////////////////////////////////////////////////// // // CompileStats @@ -140,329 +264,185 @@ void CompileStats::Values::add(double size, double time) ///////////////////////////////////////////////////////////////// // -// CompileOperator +// CompileOps // -CompileOperator::CompileOperator(): - _timingTestsCompleted(false) +IncrementalCompileOperation::CompileDrawableOp::CompileDrawableOp(osg::Drawable* drawable): + _drawable(drawable) { - _compileStats = new CompileStats; } -void CompileOperator::assignForceTextureDownloadGeometry() +double IncrementalCompileOperation::CompileDrawableOp::estimatedTimeForCompile(CompileInfo& compileInfo) const { - osg::Geometry* geometry = new osg::Geometry; - - osg::Vec3Array* vertices = new osg::Vec3Array; - vertices->push_back(osg::Vec3(0.0f,0.0f,0.0f)); - geometry->setVertexArray(vertices); - - osg::Vec4Array* texcoords = new osg::Vec4Array; - texcoords->push_back(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); - geometry->setTexCoordArray(0, texcoords); - - geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,1)); - - osg::StateSet* stateset = geometry->getOrCreateStateSet(); - stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); - - osg::Depth* depth = new osg::Depth; - depth->setWriteMask(false); - stateset->setAttribute(depth); - - osg::ColorMask* colorMask = new osg::ColorMask(false,false,false,false); - stateset->setAttribute(colorMask); - - _forceTextureDownloadGeometry = geometry; + return 0.0; } -double CompileOperator::timeCompile(osg::RenderInfo& renderInfo, osg::Geometry* geometry) const +bool IncrementalCompileOperation::CompileDrawableOp::compile(CompileInfo& compileInfo) { - osg::ElapsedTime timer; - geometry->compileGLObjects(renderInfo); - return timer.elapsedTime(); + //OSG_NOTICE<<"CompileDrawableOp::compile(..)"<compileGLObjects(compileInfo); + return true; } -double CompileOperator::timeCompile(osg::RenderInfo& renderInfo, osg::StateSet* stateset) const +IncrementalCompileOperation::CompileTextureOp::CompileTextureOp(osg::Texture* texture): + _texture(texture) { - osg::ElapsedTime timer; - stateset->compileGLObjects(*renderInfo.getState()); - return timer.elapsedTime(); } -osg::Geometry* CompileOperator::createTestGeometry(unsigned int numVertices, bool vbo) const +double IncrementalCompileOperation::CompileTextureOp::estimatedTimeForCompile(CompileInfo& compileInfo) const { - osg::ref_ptr geometry = new osg::Geometry; - osg::ref_ptr vertices = new osg::Vec3Array(numVertices); - osg::ref_ptr normals = new osg::Vec3Array(numVertices); - osg::ref_ptr colours = new osg::Vec4Array(numVertices); - osg::ref_ptr texcoords = new osg::Vec2Array(numVertices); + return 0.0; +} - geometry->setVertexArray(vertices.get()); - geometry->setNormalArray(normals.get()); - geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - geometry->setColorArray(colours.get()); - geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); - geometry->setTexCoordArray(0, texcoords.get()); - - for(unsigned int i=0; igetForceTextureDownloadGeometry(); + if (forceDownloadGeometry) { - (*vertices)[i] = osg::Vec3(0.0f,0.0f,0.0f); - (*normals)[i] = osg::Vec3(0.0f,0.0f,0.0f); - (*colours)[i] = osg::Vec4(1.0f,1.0f,1.0f,1.0f); - (*texcoords)[i] = osg::Vec2(0.0f,0.0f); - } - - geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0,numVertices)); - - geometry->setUseDisplayList(true); - geometry->setUseVertexBufferObjects(vbo); - - return geometry.release(); -} - -osg::StateSet* CompileOperator::createTestStateSet(unsigned int imageSize, bool mipmapped) const -{ - return 0; -} - -void CompileOperator::runTimingTests(osg::RenderInfo& renderInfo) -{ - _timingTestsCompleted = true; - - return; - - OSG_NOTICE<<"runTimingTests()"<getStateSet()) { - unsigned int numVertices = pow(2.0,double(i)); - osg::ref_ptr geometry = createTestGeometry(numVertices, useVBO); - double size = geometry->getGLObjectSizeHint(); - double time = timeCompile(renderInfo, geometry.get()); - OSG_NOTICE<<" numVertices = "<apply(forceDownloadGeometry->getStateSet()); + } + + compileInfo.getState()->applyTextureMode(0, _texture->getTextureTarget(), true); + compileInfo.getState()->applyTextureAttribute(0, _texture.get()); + + forceDownloadGeometry->draw(compileInfo); + } + else + { + _texture->apply(*compileInfo.getState()); + } + return true; +} + +IncrementalCompileOperation::CompileProgramOp::CompileProgramOp(osg::Program* program): + _program(program) +{ +} + +double IncrementalCompileOperation::CompileProgramOp::estimatedTimeForCompile(CompileInfo& compileInfo) const +{ + return 0.0; +} + +bool IncrementalCompileOperation::CompileProgramOp::compile(CompileInfo& compileInfo) +{ + //OSG_NOTICE<<"CompileProgramOp::compile(..)"<apply(*compileInfo.getState()); + return true; +} + +IncrementalCompileOperation::CompileInfo::CompileInfo(osg::GraphicsContext* context, IncrementalCompileOperation* ico) +{ + setState(context->getState()); + incrementalCompileOperation = ico; +} + + +///////////////////////////////////////////////////////////////// +// +// CompileList +// +IncrementalCompileOperation::CompileList::CompileList() +{ +} + +IncrementalCompileOperation::CompileList::~CompileList() +{ +} + +void IncrementalCompileOperation::CompileList::add(CompileOp* compileOp) +{ + _compileOps.push_back(compileOp); +} + +double IncrementalCompileOperation::CompileList::estimatedTimeForCompile(CompileInfo& compileInfo) const +{ + double estimateTime = 0.0; + for(CompileOps::const_iterator itr = _compileOps.begin(); + itr != _compileOps.begin(); + ++itr) + { + estimateTime += (*itr)->estimatedTimeForCompile(compileInfo); + } + return estimateTime; +} + +bool IncrementalCompileOperation::CompileList::compile(CompileInfo& compileInfo) +{ + for(CompileOps::iterator itr = _compileOps.begin(); + itr != _compileOps.end() && compileInfo.availableTime()>0.0 && compileInfo.maxNumObjectsToCompile>0; + ) + { + --compileInfo.maxNumObjectsToCompile; + + CompileOps::iterator saved_itr(itr); + ++itr; + if ((*saved_itr)->compile(compileInfo)) + { + _compileOps.erase(saved_itr); } } - for(unsigned int j=0; j<4; ++j) + return empty(); +} + +///////////////////////////////////////////////////////////////// +// +// CompileSet +// +void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode) +{ + if (contexts.empty() || !_subgraphToCompile) return; + + CollectStateToCompile cstc(mode); + _subgraphToCompile->accept(cstc); + + if (cstc._textures.empty() && cstc._programs.empty() && cstc._drawables.empty()) return; + + for(ContextSet::iterator itr = contexts.begin(); + itr != contexts.end(); + ++itr) { - OSG_NOTICE<<"Using VBOs"< geometry = createTestGeometry(numVertices, useVBO); - double size = geometry->getGLObjectSizeHint(); - double time = timeCompile(renderInfo, geometry.get()); - OSG_NOTICE<<" numVertices = "<tick(); - - if (!_timingTestsCompleted) + CompileList& compileList = _compileMap[compileInfo.getState()->getGraphicsContext()]; + if (!compileList.empty()) { - runTimingTests(renderInfo); - } - - - unsigned int totalDataSizeCompiled = 0; - unsigned int drawablesCompiled = 0; - unsigned int texturesCompiled = 0; - unsigned int programsCompiled = 0; - - if (!cd.empty() && compileTime>0.0) - { - - osg::Timer_t previousTick = osg::Timer::instance()->tick(); - - const std::string vboDrawablesName("VBO Drawables"); - const std::string dlDawablesName("DisplayList Drawables"); - - while(!cd._drawables.empty() && - maxNumObjectsToCompile>0 && - osg::Timer::instance()->delta_s(startTick, previousTick) < compileTime) + if (compileList.compile(compileInfo)) { - CompileData::Drawables::iterator itr = cd._drawables.begin(); - const osg::Drawable* drawable = itr->get(); - unsigned int size = drawable->getGLObjectSizeHint(); - const std::string& nameOfDrawableType = drawable->getUseVertexBufferObjects() ? vboDrawablesName : dlDawablesName; - -#if 0 - double estimatedTime = _compileStats->estimateTime(nameOfDrawableType, double(size)); - double estimatedTime2 = _compileStats->estimateTime2(nameOfDrawableType, double(size)); - double estimatedTime3 = _compileStats->estimateTime3(nameOfDrawableType, double(size)); - double estimatedTime4 = _compileStats->estimateTime4(nameOfDrawableType, double(size)); -#endif - drawable->compileGLObjects(renderInfo); - osg::Timer_t currTick = osg::Timer::instance()->tick(); - double timeForCompile = osg::Timer::instance()->delta_s(previousTick, currTick); - previousTick = currTick; - -#if 0 - OSG_NOTIFY(level)<<"Drawable size = "<isCompressedInternalFormat()="<getNumImages();++i) - { - osg::Image* image = texture->getImage(i); - if (image) - { - totalDataSizeCompiled += texture->getImage(i)->getTotalSizeInBytesIncludingMipmaps(); - if (textureMipmapped && !image->isMipmap()) needtoBuildMipmaps = true; - if (textureCompressedFormat && !image->isCompressed()) needtoCompress = true; - } - } - - - OSG_NOTIFY(level)<<"compiling texture, textureMipmapped="<assignForceTextureDownloadGeometry(); + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array* vertices = new osg::Vec3Array; + vertices->push_back(osg::Vec3(0.0f,0.0f,0.0f)); + geometry->setVertexArray(vertices); + + osg::Vec4Array* texcoords = new osg::Vec4Array; + texcoords->push_back(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); + geometry->setTexCoordArray(0, texcoords); + + geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS,0,1)); + + osg::StateSet* stateset = geometry->getOrCreateStateSet(); + stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + + osg::Depth* depth = new osg::Depth; + depth->setWriteMask(false); + stateset->setAttribute(depth); + + osg::ColorMask* colorMask = new osg::ColorMask(false,false,false,false); + stateset->setAttribute(colorMask); + + _forceTextureDownloadGeometry = geometry; } void IncrementalCompileOperation::assignContexts(Contexts& contexts) @@ -634,147 +636,6 @@ void IncrementalCompileOperation::mergeCompiledSubgraphs() _compiled.clear(); } -class IncrementalCompileOperation::CollectStateToCompile : public osg::NodeVisitor -{ -public: - - CollectStateToCompile(GLObjectsVisitor::Mode mode): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _mode(mode) {} - - GLObjectsVisitor::Mode _mode; - - typedef std::set DrawableSet; - typedef std::set StateSetSet; - typedef std::set TextureSet; - typedef std::set ProgramSet; - - DrawableSet _drawablesHandled; - StateSetSet _statesetsHandled; - - DrawableSet _drawables; - TextureSet _textures; - ProgramSet _programs; - - void apply(osg::Node& node) - { - if (node.getStateSet()) - { - apply(*(node.getStateSet())); - } - - traverse(node); - } - - void apply(osg::Geode& node) - { - if (node.getStateSet()) - { - apply(*(node.getStateSet())); - } - - for(unsigned int i=0;igetStateSet()) - { - apply(*(drawable->getStateSet())); - } - } - } - } - - void apply(osg::Drawable& drawable) - { - if (_drawablesHandled.count(&drawable)!=0) return; - - _drawablesHandled.insert(&drawable); - - if (_mode&GLObjectsVisitor::SWITCH_OFF_DISPLAY_LISTS) - { - drawable.setUseDisplayList(false); - } - - if (_mode&GLObjectsVisitor::SWITCH_ON_DISPLAY_LISTS) - { - drawable.setUseDisplayList(true); - } - - if (_mode&GLObjectsVisitor::SWITCH_ON_VERTEX_BUFFER_OBJECTS) - { - drawable.setUseVertexBufferObjects(true); - } - - if (_mode&GLObjectsVisitor::SWITCH_OFF_VERTEX_BUFFER_OBJECTS) - { - drawable.setUseVertexBufferObjects(false); - } - - if (_mode&GLObjectsVisitor::COMPILE_DISPLAY_LISTS && - (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects())) - { - _drawables.insert(&drawable); - } - - } - - void apply(osg::StateSet& stateset) - { - if (_statesetsHandled.count(&stateset)!=0) return; - - _statesetsHandled.insert(&stateset); - - if (_mode & GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES) - { - osg::Program* program = dynamic_cast(stateset.getAttribute(osg::StateAttribute::PROGRAM)); - if (program) - { - _programs.insert(program); - } - - osg::StateSet::TextureAttributeList& tal = stateset.getTextureAttributeList(); - for(osg::StateSet::TextureAttributeList::iterator itr = tal.begin(); - itr != tal.end(); - ++itr) - { - osg::StateSet::AttributeList& al = *itr; - osg::StateAttribute::TypeMemberPair tmp(osg::StateAttribute::TEXTURE,0); - osg::StateSet::AttributeList::iterator texItr = al.find(tmp); - if (texItr != al.end()) - { - osg::Texture* texture = dynamic_cast(texItr->second.first.get()); - if (texture) _textures.insert(texture); - } - } - } - } - -}; - - -void IncrementalCompileOperation::CompileSet::buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode) -{ - if (contexts.empty() || !_subgraphToCompile) return; - - CollectStateToCompile cstc(mode); - _subgraphToCompile->accept(cstc); - - if (cstc._textures.empty() && cstc._programs.empty() && cstc._drawables.empty()) return; - - for(ContextSet::iterator itr = contexts.begin(); - itr != contexts.end(); - ++itr) - { - CompileData& cd = _compileMap[*itr]; - std::copy(cstc._drawables.begin(), cstc._drawables.end(), std::inserter(cd._drawables, cd._drawables.end())); - std::copy(cstc._textures.begin(), cstc._textures.end(), std::inserter(cd._textures, cd._textures.end())); - std::copy(cstc._programs.begin(), cstc._programs.end(), std::inserter(cd._programs, cd._programs.end())); - } - -} void IncrementalCompileOperation::operator () (osg::GraphicsContext* context) { @@ -821,8 +682,9 @@ void IncrementalCompileOperation::operator () (osg::GraphicsContext* context) //level = osg::NOTICE; - osg::RenderInfo renderInfo; - renderInfo.setState(context->getState()); + CompileInfo compileInfo(context, this); + compileInfo.maxNumObjectsToCompile = _maximumNumOfObjectsToCompilePerFrame; + compileInfo.allocatedTime = compileTime; CompileSets toCompileCopy; { @@ -835,43 +697,29 @@ void IncrementalCompileOperation::operator () (osg::GraphicsContext* context) ++itr) { CompileSet* cs = itr->get(); - CompileMap& cm = cs->_compileMap; - CompileData& cd = cm[context]; - - if (_compileOperator->compile(renderInfo, cd, maxNumOfObjectsToCompilePerFrame, compileTime)) + if (cs->compile(compileInfo)) { - bool csCompleted = false; { OpenThreads::ScopedLock toCompile_lock(_toCompileMutex); - if (cs->compileCompleted()) - { - CompileSets::iterator cs_itr = std::find(_toCompile.begin(), _toCompile.end(), *itr); - if (cs_itr != _toCompile.end()) - { - OSG_NOTIFY(level)<<"Erasing from list"<_compileCompletedCallback.valid() && cs->_compileCompletedCallback->compileCompleted(cs)) { - if (cs->_compileCompletedCallback.valid() && cs->_compileCompletedCallback->compileCompleted(cs)) - { - // callback will handle merging of subgraph so no need to place CompileSet in merge. - } - else - { - OpenThreads::ScopedLock compilded_lock(_compiledMutex); - _compiled.push_back(cs); - } + // callback will handle merging of subgraph so no need to place CompileSet in merge. + } + else + { + OpenThreads::ScopedLock compilded_lock(_compiledMutex); + _compiled.push_back(cs); } } }