4d7b2edd4c
avoid threading issues associated with compile running in a parallel with update/cull on the first frame. Also added automatic recompile when a new SceneData is applied to a View.
181 lines
7.7 KiB
C++
181 lines
7.7 KiB
C++
/* -*-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 OSGVIEWER_RENDERER
|
|
#define OSGVIEWER_RENDERER 1
|
|
|
|
#include <osg/Timer>
|
|
#include <osgDB/DatabasePager>
|
|
#include <osgUtil/SceneView>
|
|
#include <osgViewer/Export>
|
|
|
|
namespace osgViewer {
|
|
|
|
class OSGVIEWER_EXPORT OpenGLQuerySupport
|
|
{
|
|
public:
|
|
OpenGLQuerySupport();
|
|
|
|
typedef std::pair<GLuint, int> QueryFrameNumberPair;
|
|
typedef std::list<QueryFrameNumberPair> QueryFrameNumberList;
|
|
typedef std::vector<GLuint> QueryList;
|
|
|
|
void setStartTick(osg::Timer_t startTick) { _startTick = startTick; }
|
|
osg::Timer_t getStartTick() const { return _startTick; }
|
|
|
|
void checkQuery(osg::Stats* stats);
|
|
|
|
GLuint createQueryObject();
|
|
void beginQuery(int frameNumber);
|
|
void endQuery();
|
|
void initialize(osg::State* state);
|
|
|
|
protected:
|
|
|
|
osg::Timer_t _startTick;
|
|
bool _initialized;
|
|
bool _timerQuerySupported;
|
|
const osg::Drawable::Extensions* _extensions;
|
|
QueryFrameNumberList _queryFrameNumberList;
|
|
QueryList _availableQueryObjects;
|
|
double _previousQueryTime;
|
|
|
|
};
|
|
|
|
class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation, public OpenGLQuerySupport
|
|
{
|
|
public:
|
|
|
|
Renderer(osg::Camera* camera);
|
|
|
|
osgUtil::SceneView* getSceneView(unsigned int i) { return _sceneView[i].get(); }
|
|
|
|
void setDone(bool done) { _done = done; }
|
|
bool getDone() { return _done; }
|
|
|
|
void setGraphicsThreadDoesCull(bool flag);
|
|
bool getGraphicsThreadDoesCull() const { return _graphicsThreadDoesCull; }
|
|
|
|
|
|
virtual void cull();
|
|
virtual void draw();
|
|
virtual void cull_draw();
|
|
|
|
virtual void compile();
|
|
|
|
void setCompileOnNextDraw(bool flag) { _compileOnNextDraw = flag; }
|
|
bool getCompileOnNextDraw() const { return _compileOnNextDraw; }
|
|
|
|
virtual void operator () (osg::Object* object);
|
|
|
|
virtual void operator () (osg::GraphicsContext* context);
|
|
|
|
virtual void release();
|
|
|
|
|
|
/** Set the target frame rate that the DatabasePager 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 DatabasePager, but are should be used as a guide for how
|
|
* long to set aside per frame for compiling and deleting OpenGL objects - ie. the value to use
|
|
* when calling DatabasePager::compileGLObjectgs(state,availableTime,). The longer amount of
|
|
* time to set aside cthe 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).
|
|
*
|
|
* Note, the actual TargetFrameRate used is the minimum of this value and that set in the DatabasePager. */
|
|
void setTargetFrameRate(double tfr) { _targetFrameRate = tfr; }
|
|
|
|
/** Get the target frame rate that the DatabasePager 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.
|
|
*
|
|
* Note, the actual TargetFrameRate used is the minimum of this value and that set in the DatabasePager. */
|
|
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; }
|
|
|
|
/** 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 reduse the chances of frame drop.*/
|
|
void setConservativeTimeRatio(double ratio) { _conservativeTimeRatio = ratio; }
|
|
double getConservativeTimeRatio() const { return _conservativeTimeRatio; }
|
|
|
|
protected:
|
|
|
|
virtual ~Renderer();
|
|
|
|
virtual void updateSceneView(osgUtil::SceneView* sceneView);
|
|
virtual void flushAndCompile(double currentElapsedFrameTime, osgUtil::SceneView* sceneView, osgDB::DatabasePager* databasePager, osg::GraphicsThread* compileThread);
|
|
|
|
double _targetFrameRate;
|
|
double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
|
|
double _flushTimeRatio;
|
|
double _conservativeTimeRatio;
|
|
|
|
osg::observer_ptr<osg::Camera> _camera;
|
|
|
|
bool _done;
|
|
bool _graphicsThreadDoesCull;
|
|
bool _compileOnNextDraw;
|
|
|
|
osg::ref_ptr<osgUtil::SceneView> _sceneView[2];
|
|
|
|
osg::ref_ptr<osg::FlushDeletedGLObjectsOperation> _flushOperation;
|
|
|
|
|
|
struct OSGVIEWER_EXPORT TheadSafeQueue
|
|
{
|
|
OpenThreads::Mutex _mutex;
|
|
OpenThreads::Block _block;
|
|
typedef std::list<osgUtil::SceneView*> SceneViewList;
|
|
SceneViewList _queue;
|
|
|
|
TheadSafeQueue();
|
|
~TheadSafeQueue();
|
|
|
|
void release()
|
|
{
|
|
_block.release();
|
|
}
|
|
|
|
osgUtil::SceneView* takeFront();
|
|
|
|
void add(osgUtil::SceneView* sv);
|
|
};
|
|
|
|
|
|
TheadSafeQueue _availableQueue;
|
|
TheadSafeQueue _drawQueue;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|