Added extra controls into osgDB::DatabasePager for customizing how
much time is allocated to compiling and deleting OpenGL objects, also
added support into osgProducer::OsgSceneHandler.cpp for these new parameters.
The new cotrols are:
DatabasePager::s/getTargetFrameRate(..)
DatabasePager::s/getMinimumTimeAvailableForGLCompileAndDeletePerFrame()
DatabasePager::s/getMaximumNumOfObjectsToCompilePerFrame()
This commit is contained in:
@@ -156,6 +156,43 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
virtual void registerPagedLODs(osg::Node* subgraph);
|
||||
|
||||
|
||||
/** 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).
|
||||
*/
|
||||
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.*/
|
||||
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; }
|
||||
|
||||
|
||||
/** Set the amount of time that a subgraph will be kept without being visited in the cull traversal
|
||||
* before being removed.*/
|
||||
void setExpiryDelay(double expiryDelay) { _expiryDelay = expiryDelay; }
|
||||
@@ -327,6 +364,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
double _expiryDelay;
|
||||
|
||||
ActiveGraphicsContexts _activeGraphicsContexts;
|
||||
|
||||
double _targetFrameRate;
|
||||
double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
|
||||
unsigned int _maximumNumOfObjectsToCompilePerFrame;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ DatabasePager::DatabasePager()
|
||||
|
||||
_expiryDelay = 10;
|
||||
|
||||
_targetFrameRate = 100.0;
|
||||
_minimumTimeAvailableForGLCompileAndDeletePerFrame = 0.001; // 1ms.
|
||||
_maximumNumOfObjectsToCompilePerFrame = 8;
|
||||
|
||||
// make sure a SharedStateManager exists.
|
||||
//osgDB::Registry::instance()->getOrCreateSharedStateManager();
|
||||
|
||||
@@ -834,7 +838,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
|
||||
// while there are valid databaseRequest's in the to compile list and there is
|
||||
// sufficient time left compile each databaseRequest's stateset and drawables.
|
||||
while (databaseRequest.valid() && elapsedTime<availableTime && numObjectsCompiled<maxNumObjectsToCompile)
|
||||
while (databaseRequest.valid() && elapsedTime<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)
|
||||
{
|
||||
DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
|
||||
DataToCompile& dtc = dcm[state.getContextID()];
|
||||
|
||||
@@ -84,14 +84,53 @@ void OsgSceneHandler::drawImplementation(Producer::Camera &)
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
if (dp)
|
||||
{
|
||||
|
||||
#if 1
|
||||
double timeForCullAndDraw = osg::Timer::instance()->delta_s(_frameStartTick, osg::Timer::instance()->tick());
|
||||
|
||||
double targeFrameTime = 1.0/dp->getTargetFrameRate();
|
||||
|
||||
double drawCostFactor = 2.0; // must be greater than 1 to account for the extra cost of emptying the OpenGL fifo.
|
||||
double frameFactor = 0.9; // must be less than 1, to compensate for extra time spent in update and swap buffers etc.
|
||||
double timeLeftTillEndOfFrame = targeFrameTime*frameFactor - timeForCullAndDraw*drawCostFactor;
|
||||
double availableTime = timeLeftTillEndOfFrame / drawCostFactor; // account for the fifo when download texture objects.
|
||||
|
||||
// clamp the available time by the prescribed minimum
|
||||
if (availableTime<dp->getMinimumTimeAvailableForGLCompileAndDeletePerFrame())
|
||||
{
|
||||
availableTime = dp->getMinimumTimeAvailableForGLCompileAndDeletePerFrame();
|
||||
}
|
||||
|
||||
static unsigned int _numFramesThatNoTimeAvailable = 0;
|
||||
static unsigned int _maxNumFramesThatNoTimeAvailable = 10;
|
||||
|
||||
if (_numFramesThatNoTimeAvailable>_maxNumFramesThatNoTimeAvailable)
|
||||
{
|
||||
availableTime = 0.0025; // 2.5ms.
|
||||
}
|
||||
|
||||
if (availableTime>0.0)
|
||||
{
|
||||
_numFramesThatNoTimeAvailable = 0;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Time available = "<<availableTime<<std::endl;
|
||||
|
||||
dp->compileGLObjects(*(getSceneView()->getState()),availableTime);
|
||||
|
||||
// flush deleted GL objects.
|
||||
getSceneView()->flushDeletedGLObjects(availableTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
++_numFramesThatNoTimeAvailable;
|
||||
}
|
||||
#else
|
||||
double timeForPreviousFrame = osg::Timer::instance()->delta_s(_previousFrameStartTick, _frameStartTick);
|
||||
double timeForCullAndDraw = osg::Timer::instance()->delta_s(_frameStartTick, osg::Timer::instance()->tick());
|
||||
|
||||
double minimumTargetMaxFrameTime = 0.010; // 10ms.
|
||||
double targetMaxFrameTime = osg::minimum(timeForPreviousFrame, minimumTargetMaxFrameTime);
|
||||
|
||||
// Unused variable warning
|
||||
//double maximumAvailableTime = 0.0025; // 2.5ms.
|
||||
double drawCostFactor = 2.0; // must be greater than 1 to account for the extra cost of emptying the OpenGL fifo.
|
||||
double frameFactor = 0.9; // must be less than 1, to compensate for extra time spent in update and swap buffers etc.
|
||||
double timeLeftTillEndOfFrame = targetMaxFrameTime*frameFactor - timeForCullAndDraw*drawCostFactor;
|
||||
@@ -120,7 +159,7 @@ void OsgSceneHandler::drawImplementation(Producer::Camera &)
|
||||
{
|
||||
++_numFramesThatNoTimeAvailable;
|
||||
}
|
||||
|
||||
#endif
|
||||
dp->signalEndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user