Introduce new run frame rate management support to allow control of maximum frame rate and to support on demand rendering of frames
This commit is contained in:
@@ -37,7 +37,17 @@ CompositeViewer::CompositeViewer(const CompositeViewer& cv,const osg::CopyOp& co
|
||||
CompositeViewer::CompositeViewer(osg::ArgumentParser& arguments)
|
||||
{
|
||||
constructorInit();
|
||||
|
||||
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--CullDrawThreadPerContext","Select CullDrawThreadPerContext threading model for viewer.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--DrawThreadPerContext","Select DrawThreadPerContext threading model for viewer.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--CullThreadPerCameraDrawThreadPerContext","Select CullThreadPerCameraDrawThreadPerContext threading model for viewer.");
|
||||
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-max-frame-rate","Set the run methods maximum permissable frame rate, 0.0 is default and switching off frame rate capping.");
|
||||
|
||||
|
||||
std::string filename;
|
||||
bool readConfig = false;
|
||||
while (arguments.read("-c",filename))
|
||||
@@ -50,6 +60,14 @@ CompositeViewer::CompositeViewer(osg::ArgumentParser& arguments)
|
||||
while (arguments.read("--DrawThreadPerContext")) setThreadingModel(DrawThreadPerContext);
|
||||
while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) setThreadingModel(CullThreadPerCameraDrawThreadPerContext);
|
||||
|
||||
|
||||
while(arguments.read("--run-on-demand")) { setRunFrameScheme(ON_DEMAND); }
|
||||
while(arguments.read("--run-continuous")) { setRunFrameScheme(CONTINUOUS); }
|
||||
|
||||
double runMaxFrameRate;
|
||||
while(arguments.read("--run-max-frame-rate", runMaxFrameRate)) { setRunMaxFrameRate(runMaxFrameRate); }
|
||||
|
||||
|
||||
osg::DisplaySettings::instance()->readCommandLine(arguments);
|
||||
osgDB::readCommandLine(arguments);
|
||||
}
|
||||
@@ -222,6 +240,34 @@ bool CompositeViewer::isRealized() const
|
||||
return numRealizedWindows > 0;
|
||||
}
|
||||
|
||||
bool CompositeViewer::checkNeedToDoFrame()
|
||||
{
|
||||
if (_requestRedraw) return true;
|
||||
if (_requestContinousUpdate) return true;
|
||||
|
||||
for(RefViews::iterator itr = _views.begin();
|
||||
itr != _views.end();
|
||||
++itr)
|
||||
{
|
||||
osgViewer::View* view = itr->get();
|
||||
if (view)
|
||||
{
|
||||
// If the database pager is going to update the scene the render flag is
|
||||
// set so that the updates show up
|
||||
if (view->getDatabasePager()->requiresUpdateSceneGraph() ||
|
||||
view->getDatabasePager()->getRequestsInProgress()) return true;
|
||||
}
|
||||
}
|
||||
|
||||
// now do a eventTraversal to see if any events might require a new frame.
|
||||
eventTraversal();
|
||||
|
||||
if (_requestRedraw) return true;
|
||||
if (_requestContinousUpdate) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CompositeViewer::run()
|
||||
{
|
||||
for(RefViews::iterator itr = _views.begin();
|
||||
|
||||
@@ -183,7 +183,7 @@ bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdap
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
aa.requestRedraw();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1696,10 +1696,12 @@ void View::assignSceneDataToCameras()
|
||||
|
||||
void View::requestRedraw()
|
||||
{
|
||||
getViewerBase()->_requestRedraw = true;
|
||||
}
|
||||
|
||||
void View::requestContinuousUpdate(bool)
|
||||
void View::requestContinuousUpdate(bool flag)
|
||||
{
|
||||
getViewerBase()->_requestContinousUpdate = flag;
|
||||
}
|
||||
|
||||
void View::requestWarpPointer(float x,float y)
|
||||
|
||||
@@ -53,6 +53,11 @@ Viewer::Viewer(osg::ArgumentParser& arguments)
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--clear-color <color>","Set the background color of the viewer in the form \"r,g,b[,a]\".");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--screen <num>","Set the screen to use when multiple screens are present.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--window <x y w h>","Set the position (x,y) and size (w,h) of the viewer window.");
|
||||
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--run-max-frame-rate","Set the run methods maximum permissable frame rate, 0.0 is default and switching off frame rate capping.");
|
||||
|
||||
// FIXME: Uncomment these lines when the options have been documented properly
|
||||
//arguments.getApplicationUsage()->addCommandLineOption("--3d-sd","");
|
||||
//arguments.getApplicationUsage()->addCommandLineOption("--panoramic-sd","");
|
||||
@@ -84,13 +89,21 @@ Viewer::Viewer(osg::ArgumentParser& arguments)
|
||||
if( cnt==3 || cnt==4 ) getCamera()->setClearColor( osg::Vec4(r,g,b,a) );
|
||||
else osg::notify(osg::WARN)<<"Invalid clear color \""<<colorStr<<"\""<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
while(arguments.read("--run-on-demand")) { setRunFrameScheme(ON_DEMAND); }
|
||||
while(arguments.read("--run-continuous")) { setRunFrameScheme(CONTINUOUS); }
|
||||
|
||||
double runMaxFrameRate;
|
||||
while(arguments.read("--run-max-frame-rate", runMaxFrameRate)) { setRunMaxFrameRate(runMaxFrameRate); }
|
||||
|
||||
|
||||
int screenNum = -1;
|
||||
while (arguments.read("--screen",screenNum)) {}
|
||||
|
||||
|
||||
int x = -1, y = -1, width = -1, height = -1;
|
||||
while (arguments.read("--window",x,y,width,height)) {}
|
||||
|
||||
|
||||
bool ss3d = false;
|
||||
bool wowvx20 = false;
|
||||
bool wowvx42 = false;
|
||||
@@ -309,22 +322,40 @@ bool Viewer::isRealized() const
|
||||
return numRealizedWindows > 0;
|
||||
}
|
||||
|
||||
bool Viewer::checkNeedToDoFrame()
|
||||
{
|
||||
if (_requestRedraw) return true;
|
||||
if (_requestContinousUpdate) return true;
|
||||
|
||||
// If the database pager is going to update the scene the render flag is
|
||||
// set so that the updates show up
|
||||
if(getDatabasePager()->requiresUpdateSceneGraph() || getDatabasePager()->getRequestsInProgress()) return true;
|
||||
|
||||
// now do a eventTraversal to see if any events might require a new frame.
|
||||
eventTraversal();
|
||||
|
||||
if (_requestRedraw) return true;
|
||||
if (_requestContinousUpdate) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Viewer::run()
|
||||
{
|
||||
if (!getCameraManipulator() && getCamera()->getAllowEventFocus())
|
||||
{
|
||||
setCameraManipulator(new osgGA::TrackballManipulator());
|
||||
}
|
||||
|
||||
|
||||
setReleaseContextAtEndOfFrameHint(false);
|
||||
|
||||
|
||||
return ViewerBase::run();
|
||||
}
|
||||
|
||||
void Viewer::setStartTick(osg::Timer_t tick)
|
||||
{
|
||||
View::setStartTick(tick);
|
||||
|
||||
|
||||
Contexts contexts;
|
||||
getContexts(contexts,false);
|
||||
|
||||
|
||||
@@ -33,25 +33,24 @@ static osg::ApplicationUsageProxy ViewerBase_e0(osg::ApplicationUsage::ENVIRONME
|
||||
static osg::ApplicationUsageProxy ViewerBase_e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_THREADING <value>","Set the threading model using by Viewer, <value> can be SingleThreaded, CullDrawThreadPerContext, DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext.");
|
||||
static osg::ApplicationUsageProxy ViewerBase_e2(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN <value>","Set the default screen that windows should open up on.");
|
||||
static osg::ApplicationUsageProxy ViewerBase_e3(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_WINDOW x y width height","Set the default window dimensions that windows should open up on.");
|
||||
|
||||
static osg::ApplicationUsageProxy ViewerBase_e4(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_FRAME_SCHEME","Frame rate manage scheme that viewer run should use, ON_DEMAND or CONTINUOUS (default).");
|
||||
static osg::ApplicationUsageProxy ViewerBase_e5(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_RUN_MAX_FRAME_RATE","Set the maximum number of frame as second that viewer run. 0.0 is default and disables an frame rate capping.");
|
||||
|
||||
using namespace osgViewer;
|
||||
|
||||
ViewerBase::ViewerBase():
|
||||
osg::Object(true)
|
||||
{
|
||||
_firstFrame = true;
|
||||
_done = false;
|
||||
_keyEventSetsDone = osgGA::GUIEventAdapter::KEY_Escape;
|
||||
_quitEventSetsDone = true;
|
||||
_releaseContextAtEndOfFrameHint = true;
|
||||
_threadingModel = AutomaticSelection;
|
||||
_threadsRunning = false;
|
||||
_endBarrierPosition = AfterSwapBuffers;
|
||||
viewerBaseInit();
|
||||
}
|
||||
|
||||
ViewerBase::ViewerBase(const ViewerBase& base):
|
||||
osg::Object(true)
|
||||
{
|
||||
viewerBaseInit();
|
||||
}
|
||||
|
||||
void ViewerBase::viewerBaseInit()
|
||||
{
|
||||
_firstFrame = true;
|
||||
_done = false;
|
||||
@@ -61,6 +60,24 @@ ViewerBase::ViewerBase(const ViewerBase& base):
|
||||
_threadingModel = AutomaticSelection;
|
||||
_threadsRunning = false;
|
||||
_endBarrierPosition = AfterSwapBuffers;
|
||||
_requestRedraw = true;
|
||||
_requestContinousUpdate = false;
|
||||
|
||||
_runFrameScheme = CONTINUOUS;
|
||||
_runMaxFrameRate = 0.0f;
|
||||
|
||||
const char* str = getenv("OSG_RUN_FRAME_SCHEME");
|
||||
if (str)
|
||||
{
|
||||
if (strcmp(str, "ON_DEMAND")==0) _runFrameScheme = ON_DEMAND;
|
||||
else if (strcmp(str, "CONTINUOUS")==0) _runFrameScheme = CONTINUOUS;
|
||||
}
|
||||
|
||||
str = getenv("OSG_RUN_MAX_FRAME_RATE");
|
||||
if (str)
|
||||
{
|
||||
_runMaxFrameRate = atof(str);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerBase::setThreadingModel(ThreadingModel threadingModel)
|
||||
@@ -573,30 +590,28 @@ int ViewerBase::run()
|
||||
realize();
|
||||
}
|
||||
|
||||
#if 0
|
||||
while (!done())
|
||||
{
|
||||
frame();
|
||||
}
|
||||
#else
|
||||
|
||||
const char* str = getenv("OSG_RUN_FRAME_COUNT");
|
||||
if (str)
|
||||
int runTillFrameNumber = str==0 ? -1 : atoi(str);
|
||||
|
||||
while(!done() || (runTillFrameNumber>=0 && getViewerFrameStamp()->getFrameNumber()>runTillFrameNumber))
|
||||
{
|
||||
int runTillFrameNumber = atoi(str);
|
||||
while (!done() && getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber)
|
||||
double minFrameTime = _runMaxFrameRate>0.0 ? 1.0/_runMaxFrameRate : 0.0;
|
||||
osg::Timer_t startFrameTick = osg::Timer::instance()->tick();
|
||||
if (_runFrameScheme==ON_DEMAND)
|
||||
{
|
||||
if (checkNeedToDoFrame()) frame();
|
||||
}
|
||||
else
|
||||
{
|
||||
frame();
|
||||
}
|
||||
|
||||
// work out if we need to force a sleep to hold back the frame rate
|
||||
osg::Timer_t endFrameTick = osg::Timer::instance()->tick();
|
||||
double frameTime = osg::Timer::instance()->delta_s(startFrameTick, endFrameTick);
|
||||
if (frameTime < minFrameTime) OpenThreads::Thread::microSleep(1000000.0*(minFrameTime-frameTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!done())
|
||||
{
|
||||
frame();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -842,5 +857,7 @@ void ViewerBase::renderingTraversals()
|
||||
getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals end time ", endRenderingTraversals);
|
||||
getViewerStats()->setAttribute(frameStamp->getFrameNumber(), "Rendering traversals time taken", endRenderingTraversals-beginRenderingTraversals);
|
||||
}
|
||||
|
||||
_requestRedraw = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ bool WindowSizeHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActio
|
||||
{
|
||||
toggleFullscreen(*itr);
|
||||
}
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
else if (_changeWindowedResolution == true && ea.getKey() == _keyEventWindowedResolutionUp)
|
||||
@@ -114,6 +116,8 @@ bool WindowSizeHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActio
|
||||
{
|
||||
changeWindowedResolution(*itr, true);
|
||||
}
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
else if (_changeWindowedResolution == true && ea.getKey() == _keyEventWindowedResolutionDown)
|
||||
@@ -128,6 +132,8 @@ bool WindowSizeHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActio
|
||||
{
|
||||
changeWindowedResolution(*itr, false);
|
||||
}
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -317,6 +323,7 @@ bool ThreadingHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIAction
|
||||
|
||||
if (_changeThreadingModel == true && ea.getKey() == _keyEventChangeThreadingModel && delta > 1.0)
|
||||
{
|
||||
|
||||
_tickOrLastKeyPress = osg::Timer::instance()->tick();
|
||||
|
||||
switch(viewerBase->getThreadingModel())
|
||||
@@ -348,6 +355,8 @@ bool ThreadingHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIAction
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
if (viewer && _changeEndBarrierPosition == true && ea.getKey() == _keyEventChangeEndBarrierPosition)
|
||||
@@ -363,6 +372,8 @@ bool ThreadingHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIAction
|
||||
osg::notify(osg::NOTICE)<<"Threading model 'BeforeSwapBuffers' selected."<<std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -575,6 +586,8 @@ bool LODScaleHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA
|
||||
{
|
||||
camera->setLODScale(camera->getLODScale()*1.1);
|
||||
osg::notify(osg::NOTICE)<<"LODScale = "<<camera->getLODScale()<<std::endl;
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -582,8 +595,10 @@ bool LODScaleHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA
|
||||
{
|
||||
camera->setLODScale(camera->getLODScale()/1.1);
|
||||
osg::notify(osg::NOTICE)<<"LODScale = "<<camera->getLODScale()<<std::endl;
|
||||
|
||||
aa.requestRedraw();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user