Cleaned up the thread priority management in DatabasePager and added
support for paging stats.
This commit is contained in:
@@ -34,14 +34,11 @@ DatabasePager::DatabasePager()
|
||||
_acceptNewRequests = true;
|
||||
_databasePagerThreadPaused = false;
|
||||
|
||||
_useFrameBlock = false;
|
||||
_numFramesActive = 0;
|
||||
_frameNumber = 0;
|
||||
_frameBlock = new osg::RefBlock;
|
||||
_databasePagerThreadBlock = new osg::RefBlock;
|
||||
|
||||
_threadPriorityDuringFrame = THREAD_PRIORITY_MIN;
|
||||
_threadPriorityOutwithFrame = THREAD_PRIORITY_MIN;
|
||||
|
||||
setSchedulePriority(THREAD_PRIORITY_MIN);
|
||||
|
||||
#if __APPLE__
|
||||
// OSX really doesn't like compiling display lists, and performs poorly when they are used,
|
||||
@@ -108,6 +105,10 @@ DatabasePager::DatabasePager()
|
||||
_maximumNumOfObjectsToCompilePerFrame = atoi(ptr);
|
||||
}
|
||||
|
||||
|
||||
// initialize the stats variables
|
||||
resetStats();
|
||||
|
||||
// make sure a SharedStateManager exists.
|
||||
//osgDB::Registry::instance()->getOrCreateSharedStateManager();
|
||||
|
||||
@@ -125,15 +126,10 @@ DatabasePager::DatabasePager(const DatabasePager& rhs)
|
||||
_acceptNewRequests = true;
|
||||
_databasePagerThreadPaused = false;
|
||||
|
||||
_useFrameBlock = rhs._useFrameBlock;
|
||||
_numFramesActive = 0;
|
||||
_frameNumber = 0;
|
||||
_frameBlock = new osg::RefBlock;
|
||||
_databasePagerThreadBlock = new osg::RefBlock;
|
||||
|
||||
_threadPriorityDuringFrame = rhs._threadPriorityDuringFrame;
|
||||
_threadPriorityOutwithFrame = rhs._threadPriorityOutwithFrame;
|
||||
|
||||
_drawablePolicy = rhs._drawablePolicy;
|
||||
|
||||
_changeAutoUnRef = rhs._changeAutoUnRef;
|
||||
@@ -149,6 +145,9 @@ DatabasePager::DatabasePager(const DatabasePager& rhs)
|
||||
_targetFrameRate = rhs._targetFrameRate;
|
||||
_minimumTimeAvailableForGLCompileAndDeletePerFrame = rhs._minimumTimeAvailableForGLCompileAndDeletePerFrame;
|
||||
_maximumNumOfObjectsToCompilePerFrame = rhs._maximumNumOfObjectsToCompilePerFrame;
|
||||
|
||||
// initialize the stats variables
|
||||
resetStats();
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +183,6 @@ int DatabasePager::cancel()
|
||||
//join();
|
||||
|
||||
// release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation.
|
||||
_frameBlock->release();
|
||||
_databasePagerThreadBlock->release();
|
||||
|
||||
// then wait for the the thread to stop running.
|
||||
@@ -232,6 +230,15 @@ void DatabasePager::clear()
|
||||
// _activeGraphicsContexts
|
||||
}
|
||||
|
||||
void DatabasePager::resetStats()
|
||||
{
|
||||
// initialize the stats variables
|
||||
_minimumTimeToMergeTile = DBL_MAX;
|
||||
_maximumTimeToMergeTile = -DBL_MAX;
|
||||
_totalTimeToMergeTiles = 0.0;
|
||||
_numTilesMerges = 0;
|
||||
}
|
||||
|
||||
void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* group,
|
||||
float priority, const osg::FrameStamp* framestamp)
|
||||
{
|
||||
@@ -340,7 +347,6 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
|
||||
_startThreadCalled = true;
|
||||
_done = false;
|
||||
osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"<<std::endl;
|
||||
setSchedulePriority(_threadPriorityDuringFrame);
|
||||
startThread();
|
||||
}
|
||||
}
|
||||
@@ -348,28 +354,17 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
|
||||
|
||||
void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
|
||||
{
|
||||
|
||||
if (framestamp)
|
||||
{
|
||||
//osg::notify(osg::INFO) << "signalBeginFrame "<<framestamp->getFrameNumber()<<">>>>>>>>>>>>>>>>"<<std::endl;
|
||||
_frameNumber = framestamp->getFrameNumber();
|
||||
|
||||
} //else osg::notify(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<<std::endl;
|
||||
|
||||
updateFrameBlock(1);
|
||||
|
||||
if (_numFramesActive>0 && _threadPriorityDuringFrame!=getSchedulePriority())
|
||||
setSchedulePriority(_threadPriorityDuringFrame);
|
||||
}
|
||||
|
||||
void DatabasePager::signalEndFrame()
|
||||
{
|
||||
//osg::notify(osg::INFO) << "signalEndFrame <<<<<<<<<<<<<<<<<<<< "<<std::endl;
|
||||
updateFrameBlock(-1);
|
||||
|
||||
if (_numFramesActive<=0 && _threadPriorityOutwithFrame!=getSchedulePriority())
|
||||
setSchedulePriority(_threadPriorityOutwithFrame);
|
||||
|
||||
}
|
||||
|
||||
class DatabasePager::FindCompileableGLObjectsVisitor : public osg::NodeVisitor
|
||||
@@ -508,11 +503,6 @@ void DatabasePager::run()
|
||||
|
||||
_databasePagerThreadBlock->block();
|
||||
|
||||
if (_useFrameBlock)
|
||||
{
|
||||
_frameBlock->block();
|
||||
}
|
||||
|
||||
//
|
||||
// delete any children if required.
|
||||
//
|
||||
@@ -749,8 +739,18 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
|
||||
plod->setTimeStamp(plod->getNumChildren(),timeStamp);
|
||||
}
|
||||
group->addChild(databaseRequest->_loadedModel.get());
|
||||
osg::notify(osg::INFO)<<"merged subgraph"<<databaseRequest->_fileName<<" after "<<databaseRequest->_numOfRequests<<" requests."<<std::endl;
|
||||
|
||||
osg::notify(osg::INFO)<<"merged subgraph"<<databaseRequest->_fileName<<" after "<<databaseRequest->_numOfRequests<<" requests and time="<<(timeStamp-databaseRequest->_timestampFirstRequest)*1000.0<<std::endl;
|
||||
|
||||
double timeToMerge = timeStamp-databaseRequest->_timestampFirstRequest;
|
||||
|
||||
if (timeToMerge<_minimumTimeToMergeTile) _minimumTimeToMergeTile = timeToMerge;
|
||||
if (timeToMerge>_maximumTimeToMergeTile) _maximumTimeToMergeTile = timeToMerge;
|
||||
|
||||
_totalTimeToMergeTiles += timeToMerge;
|
||||
++_numTilesMerges;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"curr = "<<timeToMerge<<" min "<<getMinimumTimeToMergeTile()*1000.0<<" max = "<<getMaximumTimeToMergeTile()*1000.0<<" average = "<<getAverageTimToMergeTiles()*1000.0<<std::endl;
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Done DatabasePager::addLoadedDataToSceneGraph"<<osg::Timer::instance()->delta_m(before,osg::Timer::instance()->tick())<<" ms objects"<<localFileLoadedList.size()<<std::endl;
|
||||
|
||||
@@ -103,6 +103,11 @@ bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdap
|
||||
}
|
||||
case(VIEWER_STATS):
|
||||
{
|
||||
if (viewer->getDatabasePager() && viewer->getDatabasePager()->isRunning())
|
||||
{
|
||||
viewer->getDatabasePager()->resetStats();
|
||||
}
|
||||
|
||||
viewer->getStats()->collectStats("event",true);
|
||||
viewer->getStats()->collectStats("update",true);
|
||||
|
||||
@@ -410,6 +415,69 @@ struct FrameMarkerDrawCallback : public virtual osg::Drawable::DrawCallback
|
||||
int _numFrames;
|
||||
};
|
||||
|
||||
struct PagerCallback : public virtual osg::NodeCallback
|
||||
{
|
||||
|
||||
PagerCallback(osgDB::DatabasePager* dp, osgText::Text* minValue, osgText::Text* maxValue, osgText::Text* averageValue, double multiplier):
|
||||
_dp(dp),
|
||||
_minValue(minValue),
|
||||
_maxValue(maxValue),
|
||||
_averageValue(averageValue),
|
||||
_multiplier(multiplier)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (_dp.valid())
|
||||
{
|
||||
double value = _dp->getAverageTimeToMergeTiles();
|
||||
if (value>= 0.0 && value <= 1000)
|
||||
{
|
||||
sprintf(_tmpText,"%4.0f",value * _multiplier);
|
||||
_averageValue->setText(_tmpText);
|
||||
}
|
||||
else
|
||||
{
|
||||
_averageValue->setText("");
|
||||
}
|
||||
|
||||
value = _dp->getMinimumTimeToMergeTile();
|
||||
if (value>= 0.0 && value <= 1000)
|
||||
{
|
||||
sprintf(_tmpText,"%4.0f",value * _multiplier);
|
||||
_minValue->setText(_tmpText);
|
||||
}
|
||||
else
|
||||
{
|
||||
_minValue->setText("");
|
||||
}
|
||||
|
||||
value = _dp->getMaximumTimeToMergeTile();
|
||||
if (value>= 0.0 && value <= 1000)
|
||||
{
|
||||
sprintf(_tmpText,"%4.0f",value * _multiplier);
|
||||
_maxValue->setText(_tmpText);
|
||||
}
|
||||
else
|
||||
{
|
||||
_maxValue->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
osg::observer_ptr<osgDB::DatabasePager> _dp;
|
||||
|
||||
osg::ref_ptr<osgText::Text> _minValue;
|
||||
osg::ref_ptr<osgText::Text> _maxValue;
|
||||
osg::ref_ptr<osgText::Text> _averageValue;
|
||||
double _multiplier;
|
||||
char _tmpText[128];
|
||||
osg::Timer_t _tickLastUpdated;
|
||||
};
|
||||
|
||||
|
||||
osg::Geometry* StatsHandler::createFrameMarkers(const osg::Vec3& pos, float height, const osg::Vec4& colour, unsigned int numBlocks)
|
||||
{
|
||||
@@ -523,6 +591,8 @@ void StatsHandler::setUpScene(osgViewer::Viewer* viewer)
|
||||
osg::Vec4 colorUpdate( 0.0f,1.0f,0.0f,1.0f);
|
||||
osg::Vec4 colorUpdateAlpha( 0.0f,1.0f,0.0f,0.5f);
|
||||
|
||||
osg::Vec4 colorDP( 1.0f,1.0f,0.5f,1.0f);
|
||||
|
||||
|
||||
// frame rate stats
|
||||
{
|
||||
@@ -683,6 +753,87 @@ void StatsHandler::setUpScene(osgViewer::Viewer* viewer)
|
||||
geode->addDrawable(frameMarkers);
|
||||
}
|
||||
|
||||
|
||||
osgDB::DatabasePager* dp = viewer->getDatabasePager();
|
||||
if (dp && dp->isRunning())
|
||||
{
|
||||
pos.y() -= characterSize*1.5f;
|
||||
|
||||
pos.x() = leftPos;
|
||||
|
||||
osg::ref_ptr<osgText::Text> averageLabel = new osgText::Text;
|
||||
geode->addDrawable( averageLabel.get() );
|
||||
|
||||
averageLabel->setColor(colorDP);
|
||||
averageLabel->setFont(font);
|
||||
averageLabel->setCharacterSize(characterSize);
|
||||
averageLabel->setPosition(pos);
|
||||
averageLabel->setText("DatabasePager time to merge new tiles - average: ");
|
||||
|
||||
pos.x() = averageLabel->getBound().xMax();
|
||||
|
||||
osg::ref_ptr<osgText::Text> averageValue = new osgText::Text;
|
||||
geode->addDrawable( averageValue.get() );
|
||||
|
||||
averageValue->setColor(colorDP);
|
||||
averageValue->setFont(font);
|
||||
averageValue->setCharacterSize(characterSize);
|
||||
averageValue->setPosition(pos);
|
||||
averageValue->setText("1000");
|
||||
|
||||
pos.x() = averageValue->getBound().xMax() + 2.0f*characterSize;
|
||||
|
||||
|
||||
osg::ref_ptr<osgText::Text> minLabel = new osgText::Text;
|
||||
geode->addDrawable( minLabel.get() );
|
||||
|
||||
minLabel->setColor(colorDP);
|
||||
minLabel->setFont(font);
|
||||
minLabel->setCharacterSize(characterSize);
|
||||
minLabel->setPosition(pos);
|
||||
minLabel->setText("min: ");
|
||||
|
||||
pos.x() = minLabel->getBound().xMax();
|
||||
|
||||
osg::ref_ptr<osgText::Text> minValue = new osgText::Text;
|
||||
geode->addDrawable( minValue.get() );
|
||||
|
||||
minValue->setColor(colorDP);
|
||||
minValue->setFont(font);
|
||||
minValue->setCharacterSize(characterSize);
|
||||
minValue->setPosition(pos);
|
||||
minValue->setText("1000");
|
||||
|
||||
pos.x() = minValue->getBound().xMax() + 2.0f*characterSize;
|
||||
|
||||
|
||||
osg::ref_ptr<osgText::Text> maxLabel = new osgText::Text;
|
||||
geode->addDrawable( maxLabel.get() );
|
||||
|
||||
maxLabel->setColor(colorDP);
|
||||
maxLabel->setFont(font);
|
||||
maxLabel->setCharacterSize(characterSize);
|
||||
maxLabel->setPosition(pos);
|
||||
maxLabel->setText("max: ");
|
||||
|
||||
pos.x() = maxLabel->getBound().xMax();
|
||||
|
||||
osg::ref_ptr<osgText::Text> maxValue = new osgText::Text;
|
||||
geode->addDrawable( maxValue.get() );
|
||||
|
||||
maxValue->setColor(colorDP);
|
||||
maxValue->setFont(font);
|
||||
maxValue->setCharacterSize(characterSize);
|
||||
maxValue->setPosition(pos);
|
||||
maxValue->setText("1000");
|
||||
|
||||
pos.x() = maxLabel->getBound().xMax();
|
||||
|
||||
geode->setCullCallback(new PagerCallback(dp, minValue.get(), maxValue.get(), averageValue.get(), 1000.0));
|
||||
}
|
||||
|
||||
pos.x() = leftPos;
|
||||
|
||||
}
|
||||
#if 0
|
||||
// scene stats
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/Group>
|
||||
#include <osg/Node>
|
||||
#include <osg/OperationThread>
|
||||
#include <osg/PagedLOD>
|
||||
#include <osg/State>
|
||||
#include <osgDB/DatabasePager>
|
||||
@@ -114,41 +113,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
|
||||
__bool__getAcceptNewDatabaseRequests,
|
||||
"Get whether new database request calls are accepted or ignored. ",
|
||||
"");
|
||||
I_Method1(void, setUseFrameBlock, IN, bool, useFrameBlock,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setUseFrameBlock__bool,
|
||||
"Set the use of the frame block which, if enabled, blocks the DatabasePager from executing which the current frame is being drawn. ",
|
||||
"When a single processor machine is being used it can be useful to block on frame to help prevent the database paging thread from slowing the cull and draw traversals which in turn can cause frame drops. ");
|
||||
I_Method0(bool, getUseFrameBlock,
|
||||
Properties::NON_VIRTUAL,
|
||||
__bool__getUseFrameBlock,
|
||||
"Get the whether UseFrameBlock is on or off. ",
|
||||
"");
|
||||
I_Method0(osg::RefBlock *, getFrameBlock,
|
||||
Properties::NON_VIRTUAL,
|
||||
__osg_RefBlock_P1__getFrameBlock,
|
||||
"",
|
||||
"");
|
||||
I_Method1(void, setThreadPriorityDuringFrame, IN, osgDB::DatabasePager::ThreadPriority, duringFrame,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setThreadPriorityDuringFrame__ThreadPriority,
|
||||
"Set the priority of the database pager thread during the frame (i.e. ",
|
||||
"while cull and draw are running.) ");
|
||||
I_Method0(osgDB::DatabasePager::ThreadPriority, getThreadPriorityDuringFrame,
|
||||
Properties::NON_VIRTUAL,
|
||||
__ThreadPriority__getThreadPriorityDuringFrame,
|
||||
"Get the priority of the database pager thread during the frame. ",
|
||||
"");
|
||||
I_Method1(void, setThreadPriorityOutwithFrame, IN, osgDB::DatabasePager::ThreadPriority, outwithFrame,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setThreadPriorityOutwithFrame__ThreadPriority,
|
||||
"Set the priority of the database pager thread when the frame is not being exectuted (i.e. ",
|
||||
"before or after cull and draw have run.) ");
|
||||
I_Method0(osgDB::DatabasePager::ThreadPriority, getThreadPriorityOutwithFrame,
|
||||
Properties::NON_VIRTUAL,
|
||||
__ThreadPriority__getThreadPriorityOutwithFrame,
|
||||
"Get the priority of the database pager thread when the frame is not being exectuted. ",
|
||||
"");
|
||||
I_Method0(int, getNumFramesActive,
|
||||
Properties::NON_VIRTUAL,
|
||||
__int__getNumFramesActive,
|
||||
@@ -309,6 +273,26 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
|
||||
__unsigned_int__getDataToCompileListSize,
|
||||
"Report how many items are in the _dataToCompileList queue. ",
|
||||
"");
|
||||
I_Method0(double, getMinimumTimeToMergeTile,
|
||||
Properties::NON_VIRTUAL,
|
||||
__double__getMinimumTimeToMergeTile,
|
||||
"Get the minimum time between the first request for a tile to be loaded and the time of its merge into the main scene graph. ",
|
||||
"");
|
||||
I_Method0(double, getMaximumTimeToMergeTile,
|
||||
Properties::NON_VIRTUAL,
|
||||
__double__getMaximumTimeToMergeTile,
|
||||
"Get the maximum time between the first request for a tile to be loaded and the time of its merge into the main scene graph. ",
|
||||
"");
|
||||
I_Method0(double, getAverageTimeToMergeTiles,
|
||||
Properties::NON_VIRTUAL,
|
||||
__double__getAverageTimeToMergeTiles,
|
||||
"Get the average time between the first request for a tile to be loaded and the time of its merge into the main scene graph. ",
|
||||
"");
|
||||
I_Method0(void, resetStats,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__resetStats,
|
||||
"Reset the Stats variables. ",
|
||||
"");
|
||||
I_StaticMethod0(osg::ref_ptr< osgDB::DatabasePager > &, prototype,
|
||||
__osg_ref_ptrT1_DatabasePager__R1__prototype_S,
|
||||
"get the prototype singleton used by DatabasePager::create(). ",
|
||||
@@ -323,12 +307,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
|
||||
__void__updateDatabasePagerThreadBlock,
|
||||
"",
|
||||
"");
|
||||
I_ProtectedMethod1(void, updateFrameBlock, IN, int, delta,
|
||||
Properties::NON_VIRTUAL,
|
||||
Properties::NON_CONST,
|
||||
__void__updateFrameBlock__int,
|
||||
"",
|
||||
"");
|
||||
I_ProtectedMethod1(void, removeExpiredSubgraphs, IN, double, currentFrameTime,
|
||||
Properties::VIRTUAL,
|
||||
Properties::NON_CONST,
|
||||
@@ -344,6 +322,9 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
|
||||
I_SimpleProperty(bool, AcceptNewDatabaseRequests,
|
||||
__bool__getAcceptNewDatabaseRequests,
|
||||
__void__setAcceptNewDatabaseRequests__bool);
|
||||
I_SimpleProperty(double, AverageTimeToMergeTiles,
|
||||
__double__getAverageTimeToMergeTiles,
|
||||
0);
|
||||
I_IndexedProperty(bool, CompileGLObjectsForContextID,
|
||||
__bool__getCompileGLObjectsForContextID__unsigned_int,
|
||||
__void__setCompileGLObjectsForContextID__unsigned_int__bool,
|
||||
@@ -369,27 +350,21 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
|
||||
I_SimpleProperty(unsigned int, FileRequestListSize,
|
||||
__unsigned_int__getFileRequestListSize,
|
||||
0);
|
||||
I_SimpleProperty(osg::RefBlock *, FrameBlock,
|
||||
__osg_RefBlock_P1__getFrameBlock,
|
||||
0);
|
||||
I_SimpleProperty(unsigned int, MaximumNumOfObjectsToCompilePerFrame,
|
||||
__unsigned_int__getMaximumNumOfObjectsToCompilePerFrame,
|
||||
__void__setMaximumNumOfObjectsToCompilePerFrame__unsigned_int);
|
||||
I_SimpleProperty(double, MaximumTimeToMergeTile,
|
||||
__double__getMaximumTimeToMergeTile,
|
||||
0);
|
||||
I_SimpleProperty(double, MinimumTimeAvailableForGLCompileAndDeletePerFrame,
|
||||
__double__getMinimumTimeAvailableForGLCompileAndDeletePerFrame,
|
||||
__void__setMinimumTimeAvailableForGLCompileAndDeletePerFrame__double);
|
||||
I_SimpleProperty(double, MinimumTimeToMergeTile,
|
||||
__double__getMinimumTimeToMergeTile,
|
||||
0);
|
||||
I_SimpleProperty(double, TargetFrameRate,
|
||||
__double__getTargetFrameRate,
|
||||
__void__setTargetFrameRate__double);
|
||||
I_SimpleProperty(osgDB::DatabasePager::ThreadPriority, ThreadPriorityDuringFrame,
|
||||
__ThreadPriority__getThreadPriorityDuringFrame,
|
||||
__void__setThreadPriorityDuringFrame__ThreadPriority);
|
||||
I_SimpleProperty(osgDB::DatabasePager::ThreadPriority, ThreadPriorityOutwithFrame,
|
||||
__ThreadPriority__getThreadPriorityOutwithFrame,
|
||||
__void__setThreadPriorityOutwithFrame__ThreadPriority);
|
||||
I_SimpleProperty(bool, UseFrameBlock,
|
||||
__bool__getUseFrameBlock,
|
||||
__void__setUseFrameBlock__bool);
|
||||
END_REFLECTOR
|
||||
|
||||
BEGIN_OBJECT_REFLECTOR(osg::observer_ptr< osg::GraphicsContext >)
|
||||
|
||||
Reference in New Issue
Block a user