123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSGUTIL_INCREMENTALCOMPILEOPERATOR
- #define OSGUTIL_INCREMENTALCOMPILEOPERATOR
- #include <osgUtil/GLObjectsVisitor>
- #include <osg/Geometry>
- namespace osgUtil {
- class OSGUTIL_EXPORT StateToCompile : public osg::NodeVisitor
- {
- public:
- StateToCompile(GLObjectsVisitor::Mode mode, osg::Object* markerObject);
- typedef std::set<osg::Drawable*> DrawableSet;
- typedef std::set<osg::StateSet*> StateSetSet;
- typedef std::set<osg::Texture*> TextureSet;
- typedef std::set<osg::Program*> ProgramSet;
- DrawableSet _drawablesHandled;
- StateSetSet _statesetsHandled;
- GLObjectsVisitor::Mode _mode;
- DrawableSet _drawables;
- TextureSet _textures;
- ProgramSet _programs;
- bool _assignPBOToImages;
- osg::ref_ptr<osg::PixelBufferObject> _pbo;
- osg::ref_ptr<osg::Object> _markerObject;
- bool empty() const { return _textures.empty() && _programs.empty() && _drawables.empty(); }
- virtual void apply(osg::Node& node);
- virtual void apply(osg::Drawable& drawable);
- virtual void apply(osg::StateSet& stateset);
- virtual void apply(osg::Texture& texture);
- };
- class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation
- {
- public:
- IncrementalCompileOperation();
- /** Return true if the IncrementCompileOperation is active.*/
- bool isActive() const { return !_contexts.empty(); }
- bool requiresCompile(StateToCompile& stateToCompile);
- /** Set the target frame rate that the IncrementalCompileOperation should assume.
- * Typically one would set this to the value refresh rate of your display system i.e. 60Hz.
- * Default value is 100.
- * Usage notes. The TargetFrameRate and the MinimumTimeAvailableForGLCompileAndDeletePerFrame
- * parameters are not directly used by IncrementalCompileOperation, but are should be used as a guide for how
- * long to set aside per frame for compiling and deleting OpenGL objects. The longer amount of
- * time to set aside the faster databases will be paged in but with increased chance of frame drops,
- * the lower the amount of time the set aside the slower databases will paged it but with better
- * chance of avoid any frame drops. The default values are chosen to achieve the later when running
- * on a modern mid to high end PC.
- * The way to compute the amount of available time use a scheme such as :
- * availableTime = maximum(1.0/targetFrameRate - timeTakenDuringUpdateCullAndDraw, minimumTimeAvailableForGLCompileAndDeletePerFrame).
- */
- void setTargetFrameRate(double tfr) { _targetFrameRate = tfr; }
- /** Get the target frame rate that the IncrementalCompileOperation should assume.*/
- double getTargetFrameRate() const { return _targetFrameRate; }
- /** Set the minimum amount of time (in seconds) that should be made available for compiling and delete OpenGL objects per frame.
- * Default value is 0.001 (1 millisecond).
- * For usage see notes in setTargetFrameRate.*/
- void setMinimumTimeAvailableForGLCompileAndDeletePerFrame(double ta) { _minimumTimeAvailableForGLCompileAndDeletePerFrame = ta; }
- /** Get the minimum amount of time that should be made available for compiling and delete OpenGL objects per frame.
- * For usage see notes in setTargetFrameRate.*/
- double getMinimumTimeAvailableForGLCompileAndDeletePerFrame() const { return _minimumTimeAvailableForGLCompileAndDeletePerFrame; }
- /** Set the maximum number of OpenGL objects that the page should attempt to compile per frame.
- * Note, Lower values reduces chances of a frame drop but lower the rate that database will be paged in at.
- * Default value is 8. */
- void setMaximumNumOfObjectsToCompilePerFrame(unsigned int num) { _maximumNumOfObjectsToCompilePerFrame = num; }
- /** Get the maximum number of OpenGL objects that the page should attempt to compile per frame.*/
- unsigned int getMaximumNumOfObjectsToCompilePerFrame() const { return _maximumNumOfObjectsToCompilePerFrame; }
- /** FlushTimeRatio governs how much of the spare time in each frame is used for flushing deleted OpenGL objects.
- * Default value is 0.5, valid range is 0.1 to 0.9.*/
- void setFlushTimeRatio(double ratio) { _flushTimeRatio = ratio; }
- double getFlushTimeRatio() const { return _flushTimeRatio; }
- /** ConservativeTimeRatio governs how much of the measured spare time in each frame is used for flushing deleted and compile new OpenGL objects.
- * Default value is 0.5, valid range is 0.1 to 1.0.
- * A ratio near 1.0 will lead to paged databases being compiled and merged quicker but increase the chances of frame drop.
- * A ratio near 0.1 will lead to paged databases being compiled and merged closer but reduce the chances of frame drop.*/
- 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(); }
- typedef std::vector<osg::GraphicsContext*> Contexts;
- void assignContexts(Contexts& contexts);
- void removeContexts(Contexts& contexts);
- void addGraphicsContext(osg::GraphicsContext* gc);
- void removeGraphicsContext(osg::GraphicsContext* gc);
- typedef std::set<osg::GraphicsContext*> ContextSet;
- ContextSet& getContextSet() { return _contexts; }
- const ContextSet& getContextSet() const { return _contexts; }
- /** Merge subgraphs that have been compiled.*/
- void mergeCompiledSubgraphs(const osg::FrameStamp* frameStamp);
- /** Set the current frame number that the IncrementalCompileOperation should use as a reference
- * value for calculations based on current frame number.
- * Note, this value is set by the mergeCompiledSubgraphs(..) method so one won't normally need to call
- * set the CurrentFrameNumber manually.*/
- void setCurrentFrameNumber(unsigned int fn) { _currentFrameNumber = fn; }
- unsigned int getCurrentFrameNumber() const { return _currentFrameNumber; }
- /** tell the IncrementalCompileOperation to compile all pending objects during next draw traversal,
- * for specified number of frames.*/
- void compileAllForNextFrame(unsigned int numFramesToDoCompileAll=1);
- /** tell the IncrementalCompileOperation to compile all pending objects during next draw traversal,
- * till specified frame number.*/
- void setCompileAllTillFrameNumber(unsigned int fn) { _compileAllTillFrameNumber = fn; }
- unsigned int getCompileAllTillFrameNumber() const { return _compileAllTillFrameNumber; }
- virtual void operator () (osg::GraphicsContext* context);
- struct OSGUTIL_EXPORT CompileInfo : public osg::RenderInfo
- {
- CompileInfo(osg::GraphicsContext* context, IncrementalCompileOperation* ico);
- bool okToCompile(double estimatedTimeForCompile=0.0) const
- {
- if (compileAll) return true;
- if (maxNumObjectsToCompile==0) return false;
- return (allocatedTime - timer.elapsedTime()) >= estimatedTimeForCompile;
- }
- IncrementalCompileOperation* incrementalCompileOperation;
- bool compileAll;
- unsigned int maxNumObjectsToCompile;
- double allocatedTime;
- osg::ElapsedTime timer;
- };
- 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<osg::Drawable> _drawable;
- };
- struct OSGUTIL_EXPORT CompileTextureOp : public CompileOp
- {
- CompileTextureOp(osg::Texture* texture);
- double estimatedTimeForCompile(CompileInfo& compileInfo) const;
- bool compile(CompileInfo& compileInfo);
- osg::ref_ptr<osg::Texture> _texture;
- };
- struct OSGUTIL_EXPORT CompileProgramOp : public CompileOp
- {
- CompileProgramOp(osg::Program* program);
- double estimatedTimeForCompile(CompileInfo& compileInfo) const;
- bool compile(CompileInfo& compileInfo);
- osg::ref_ptr<osg::Program> _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<CompileOp> > CompileOps;
- CompileOps _compileOps;
- };
- class CompileSet;
- struct CompileCompletedCallback : public virtual osg::Referenced
- {
- /// return true if the callback assumes responsibility for merging any associated subgraphs with the main scene graph
- /// return false if callback doesn't handle the merge, and instead requires the IncrementalCompileOperation to handle this for us
- virtual bool compileCompleted(CompileSet* compileSet) = 0;
- };
- class OSGUTIL_EXPORT CompileSet : public osg::Referenced
- {
- public:
- CompileSet() {}
- CompileSet(osg::Node*subgraphToCompile):
- _subgraphToCompile(subgraphToCompile) {}
- CompileSet(osg::Group* attachmentPoint, osg::Node* subgraphToCompile):
- _attachmentPoint(attachmentPoint),
- _subgraphToCompile(subgraphToCompile) {}
- void buildCompileMap(ContextSet& contexts, StateToCompile& stateToCompile);
- void buildCompileMap(ContextSet& contexts, GLObjectsVisitor::Mode mode=GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES);
- bool compile(CompileInfo& compileInfo);
- bool compiled() const { return _numberCompileListsToCompile==0; }
- OpenThreads::Atomic _numberCompileListsToCompile;
- osg::observer_ptr<osg::Group> _attachmentPoint;
- osg::ref_ptr<osg::Node> _subgraphToCompile;
- osg::ref_ptr<CompileCompletedCallback> _compileCompletedCallback;
- typedef std::map<osg::GraphicsContext*, CompileList > CompileMap;
- CompileMap _compileMap;
- osg::ref_ptr<osg::Object> _markerObject;
- protected:
- virtual ~CompileSet() {}
- };
- typedef std::list< osg::ref_ptr<CompileSet> > CompileSets;
- /** Add a subgraph to be compiled.*/
- void add(osg::Node* subgraphToCompile);
- /** Add a subgraph to be compiled and add automatically to attachPoint on call to mergeCompiledSubgraphs.*/
- void add(osg::Group* attachmentPoint, osg::Node* subgraphToCompile);
- /** Add a CompileSet to be compiled.*/
- void add(CompileSet* compileSet, bool callBuildCompileMap=true);
- /** Remove CompileSet from list.*/
- void remove(CompileSet* compileSet);
- OpenThreads::Mutex* getToCompiledMutex() { return &_toCompileMutex; }
- CompileSets& getToCompile() { return _toCompile; }
- OpenThreads::Mutex* getCompiledMutex() { return &_compiledMutex; }
- CompileSets& getCompiled() { return _compiled; }
- void setMarkerObject(osg::Object* mo) { _markerObject = mo; }
- osg::Object* getMarkerObject() { return _markerObject.get(); }
- const osg::Object* getMarkerObject() const { return _markerObject.get(); }
- protected:
- virtual ~IncrementalCompileOperation();
- void compileSets(CompileSets& toCompile, CompileInfo& compileInfo);
- double _targetFrameRate;
- double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
- unsigned int _maximumNumOfObjectsToCompilePerFrame;
- double _flushTimeRatio;
- double _conservativeTimeRatio;
- unsigned int _currentFrameNumber;
- unsigned int _compileAllTillFrameNumber;
- osg::ref_ptr<osg::Geometry> _forceTextureDownloadGeometry;
- OpenThreads::Mutex _toCompileMutex;
- CompileSets _toCompile;
- OpenThreads::Mutex _compiledMutex;
- CompileSets _compiled;
- ContextSet _contexts;
- osg::ref_ptr<osg::Object> _markerObject;
- };
- }
- #endif
|