Clean up of new DatabasePager code, and change of osgProducer so that

DatabasePager support is now integrated into the OsgSceneHandler.
This commit is contained in:
Robert Osfield 2004-09-23 18:50:38 +00:00
parent fc68ccacb7
commit 1b31024cd5
6 changed files with 103 additions and 169 deletions

View File

@ -182,15 +182,11 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
void getMaxAnisotropyPolicy(bool& changeAnisotropy, float& valueAnisotropy) const { changeAnisotropy = _changeAnisotropy; valueAnisotropy = _valueAnisotropy; }
/** Iterate through the active PagedLOD nodes children removing
* children which havn't been visited since specified expiryTime.
* note, should be only be called from the update thread. */
void removeExpiredSubgraphs(double currentFrameTime);
/** Add the loaded data to the scene graph.*/
void addLoadedDataToSceneGraph(double currentFrameTime);
/** Return trye if there are pending updates to the scene graph that require a call to updateSceneGraph(double). */
bool requiresUpdateSceneGraph() const;
/** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph*/
/** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph.
* Note, must only be called from single thread update phase. */
void updateSceneGraph(double currentFrameTime)
{
removeExpiredSubgraphs(currentFrameTime);
@ -204,8 +200,13 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
/** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false). */
bool getCompileGLObjectsForContextID(unsigned int contextID);
/** Return true if there are pending compile operations that are required.
* If requiresCompileGLObjects() return true the application should call compileGLObjects() .*/
bool requiresCompileGLObjects() const;
/** Compile the rendering objects (display lists,texture objects, VBO's) on loaded subgraph.
* note, should only be called from the draw thread.*/
* note, should only be called from the draw thread.
* Note, must only be called from a valid graphics context. */
void compileGLObjects(osg::State& state,double& availableTime);
@ -213,7 +214,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
typedef std::list< osg::ref_ptr<osg::PagedLOD> > PagedLODList;
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::set< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
typedef std::pair<StateSetList,DrawableList> DataToCompile;
typedef std::map< unsigned int, DataToCompile > DataToCompileMap;
@ -262,6 +263,15 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
}
/** Iterate through the active PagedLOD nodes children removing
* children which havn't been visited since specified expiryTime.
* note, should be only be called from the update thread. */
void removeExpiredSubgraphs(double currentFrameTime);
/** Add the loaded data to the scene graph.*/
void addLoadedDataToSceneGraph(double currentFrameTime);
bool _done;
bool _acceptNewRequests;
bool _databasePagerThreadPaused;
@ -274,10 +284,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
ThreadPriority _threadPriorityOutwithFrame;
DatabaseRequestList _fileRequestList;
OpenThreads::Mutex _fileRequestListMutex;
mutable OpenThreads::Mutex _fileRequestListMutex;
DatabaseRequestList _dataToCompileList;
OpenThreads::Mutex _dataToCompileListMutex;
mutable OpenThreads::Mutex _dataToCompileListMutex;
bool _changeAutoUnRef;
bool _valueAutoUnRef;
@ -286,10 +296,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
bool _deleteRemovedSubgraphsInDatabaseThread;
ObjectList _childrenToDeleteList;
OpenThreads::Mutex _childrenToDeleteListMutex;
mutable OpenThreads::Mutex _childrenToDeleteListMutex;
DatabaseRequestList _dataToMergeList;
OpenThreads::Mutex _dataToMergeListMutex;
mutable OpenThreads::Mutex _dataToMergeListMutex;
PagedLODList _activePagedLODList;

View File

@ -14,10 +14,14 @@
#ifndef OSGPRODUCER_OSGSCENEHANDLER
#define OSGPRODUCER_OSGSCENEHANDLER 1
#include <osgProducer/Export>
#include <osg/Timer>
#include <osgUtil/SceneView>
#include <Producer/Camera>
#include <osgUtil/SceneView>
#include <osgProducer/Export>
namespace osgProducer {
@ -99,6 +103,8 @@ class OSGPRODUCER_EXPORT OsgSceneHandler : public Producer::Camera::SceneHandler
osg::ref_ptr<Callback> _clearCallback;
osg::ref_ptr<Callback> _cullCallback;
osg::ref_ptr<Callback> _drawCallback;
osg::Timer_t _frameStartTick;
};
}

View File

@ -257,7 +257,7 @@ void TextureObjectManager::flushTextureObjects(unsigned int contextID,double cur
itr!=tol.end() && elapsedTime<availableTime && tol.size()>s_minimumNumberOfTextureObjectsToRetainInCache && numObjectsDeleted<maxNumObjectsToDelete;
)
{
if ((*itr)->_timeStamp<expiryTime)
if ((*itr)->_timeStamp<=expiryTime)
{
--s_number;
++Texture::s_numberDeletedTextureInLastFrame;

View File

@ -47,7 +47,7 @@ DatabasePager::DatabasePager()
_deleteRemovedSubgraphsInDatabaseThread = false;
#endif
_expiryDelay = 30;
_expiryDelay = 10;
// make sure a SharedStateManager exists.
//osgDB::Registry::instance()->getOrCreateSharedStateManager();
@ -226,11 +226,6 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
}
}
static double s_start_frame = 0;
static double s_before_compile = 0;
static double s_after_compile = 0;
static osg::Timer_t startTick = 0;
void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
{
@ -239,58 +234,8 @@ void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
//osg::notify(osg::INFO) << "signalBeginFrame "<<framestamp->getFrameNumber()<<">>>>>>>>>>>>>>>>"<<std::endl;
_frameNumber = framestamp->getFrameNumber();
} //else osg::notify(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<<std::endl;
if (startTick==0) startTick = osg::Timer::instance()->tick();
double timeStamp = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
double drawTime = s_before_compile-s_start_frame;
double compileTime = s_after_compile-s_before_compile;
double timeDelta = timeStamp-s_start_frame;
unsigned int numFrames = (timeDelta*60.0074);
/*
if (timeDelta>0.02)
{
std::string str;
if (osg::Texture::s_numberTextureReusedLastInLastFrame > 0) str += " RT ";
if (osg::Texture::s_numberNewTextureInLastFrame > 0) str += " NT ";
if (osg::Texture::s_numberDeletedTextureInLastFrame > 0) str += " DT ";
if (osg::Drawable::s_numberDrawablesReusedLastInLastFrame > 0) str += " RD ";
if (osg::Drawable::s_numberNewDrawablesInLastFrame > 0) str += " ND ";
if (osg::Drawable::s_numberDeletedDrawablesInLastFrame > 0) str += " DD ";
if (str.empty()) str += " ?? ";
osg::notify(osg::NOTICE)<<" ************* frame="<<timeDelta<<"\tdraw="<<drawTime<<"\tcompile="<<compileTime<<" ***** FRAMES DROPPED ********** "<<str<<std::dec<<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberTextureReusedLastInLastFrame = "<<osg::Texture::s_numberTextureReusedLastInLastFrame<<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberNewTextureInLastFrame = "<<osg::Texture::s_numberNewTextureInLastFrame <<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberDeletedTextureInLastFrame = "<<osg::Texture::s_numberDeletedTextureInLastFrame <<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDrawablesReusedLastInLastFrame = "<<osg::Drawable::s_numberDrawablesReusedLastInLastFrame <<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberNewDrawablesInLastFrame = "<<osg::Drawable::s_numberNewDrawablesInLastFrame <<std::endl;
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDeletedDrawablesInLastFrame = "<<osg::Drawable::s_numberDeletedDrawablesInLastFrame <<std::endl;
}
*/
s_start_frame = timeStamp;
osg::Texture::s_numberTextureReusedLastInLastFrame = 0;
osg::Texture::s_numberNewTextureInLastFrame = 0;
osg::Texture::s_numberDeletedTextureInLastFrame = 0;
osg::Drawable::s_numberDrawablesReusedLastInLastFrame = 0;
osg::Drawable::s_numberNewDrawablesInLastFrame = 0;
osg::Drawable::s_numberDeletedDrawablesInLastFrame = 0;
_frameBlock->reset();
@ -362,7 +307,7 @@ public:
if (foundTextureState)
{
//osg::notify(osg::DEBUG_INFO)<<"Found compilable texture state"<<std::endl;
_dataToCompile.first.push_back(stateset);
_dataToCompile.first.insert(stateset);
}
}
}
@ -580,6 +525,19 @@ void DatabasePager::run()
}
bool DatabasePager::requiresUpdateSceneGraph() const
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
if (!_dataToMergeList.empty()) return true;
}
return false;
}
void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
{
@ -623,6 +581,7 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
}
void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
{
//osg::notify(osg::NOTICE)<<"DatabasePager::removeExpiredSubgraphs()"<<std::endl;
@ -711,8 +670,7 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
if (childrenRemoved.size()<targetNumOfRemovedChildPagedLODs)
{
// check for removing expired children.
if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(currentFrameTime,childrenRemoved))
// if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
{
//osg::notify(osg::NOTICE)<<"Some children removed from PLod"<<std::endl;
}
@ -794,6 +752,12 @@ void DatabasePager::registerPagedLODs(osg::Node* subgraph)
if (subgraph) subgraph->accept(fplv);
}
bool DatabasePager::requiresCompileGLObjects() const
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
return !_dataToCompileList.empty();
}
void DatabasePager::setCompileGLObjectsForContextID(unsigned int contextID, bool on)
{
if (on)
@ -816,19 +780,14 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
{
// osg::notify(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<<std::endl;
s_before_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
double drawTime = s_before_compile-s_start_frame;
if (drawTime<0.01)
if (availableTime>0.0)
{
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
double estimatedTextureDuration = 0.0;
double estimatedDrawableDuration = 0.0;
double estimatedTextureDuration = 0.0001;
double estimatedDrawableDuration = 0.0001;
osg::ref_ptr<DatabaseRequest> databaseRequest;
@ -930,8 +889,6 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
// estimate the duration of the compile based on current compile duration.
estimatedDrawableDuration = (elapsedTime-startCompileTime);
// osg::notify(osg::NOTICE)<<" Compiling drawable "<<estimatedDrawableDuration<<std::endl;
++numObjectsCompiled;
}
@ -955,8 +912,6 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
if (allCompiled)
{
osg::notify(osg::INFO)<<"All compiled"<<std::endl;
// we've compile all of the current databaseRequest so we can now pop it off the
// to compile list and place it on the merge list.
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
@ -985,9 +940,9 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
// availableTime -= elapsedTime;
availableTime -= elapsedTime;
// osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<" time remaining ="<<availableTime<<std::endl;
//osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<"\ttime remaining ="<<availableTime<<"\tnumObjectsCompiled = "<<numObjectsCompiled<<std::endl;
//osg::notify(osg::NOTICE)<<"estimatedTextureDuration="<<estimatedTextureDuration;
//osg::notify(osg::NOTICE)<<"\testimatedDrawableDuration="<<estimatedDrawableDuration<<std::endl;
}
@ -995,8 +950,5 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
{
availableTime = 0.0f;
}
s_after_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
}

View File

@ -13,6 +13,8 @@
#include <OpenThreads/Mutex>
#include <osgDB/Registry>
#include <osgProducer/OsgSceneHandler>
using namespace osgUtil;
@ -39,6 +41,14 @@ void OsgSceneHandler::init()
void OsgSceneHandler::clearImplementation(Producer::Camera& /*camera*/)
{
_frameStartTick = osg::Timer::instance()->tick();
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
if (dp)
{
dp->signalBeginFrame(getSceneView()->getState()->getFrameStamp());
}
// no-op right now as scene view manages its own clear.
}
@ -63,7 +73,31 @@ void OsgSceneHandler::cullImplementation(Producer::Camera &cam)
void OsgSceneHandler::drawImplementation(Producer::Camera &)
{
// dipatch the draw traversal of the scene graph
_sceneView->SceneView::draw();
// for the database pager now manage any GL object operations that are required.
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
if (dp)
{
double timeForCullAndDraw = osg::Timer::instance()->delta_s(_frameStartTick, osg::Timer::instance()->tick());
double targetMaxFrameTime = 0.010; // 10ms.
double availableTime = targetMaxFrameTime-timeForCullAndDraw;
// availableTime = 0.1; // 2.5 ms
if (availableTime>0.0)
{
dp->compileGLObjects(*(getSceneView()->getState()),availableTime);
// flush deleted GL objects.
getSceneView()->flushDeletedGLObjects(availableTime);
}
dp->signalEndFrame();
}
}
void OsgSceneHandler::setContextID( int id )

View File

@ -478,77 +478,16 @@ bool Viewer::realize( ThreadingModel thread_model )
return realize();
}
class DatabasePagerStartCullCallback : public OsgSceneHandler::Callback
class PostSwapFinishCallback : public Producer::Camera::Callback
{
public:
DatabasePagerStartCullCallback() {}
PostSwapFinishCallback() {}
virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera)
{
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
if (dp) dp->signalBeginFrame(sh.getSceneView()->getState()->getFrameStamp());
sh.cullImplementation(camera);
}
};
class DatabasePagerCompileCallback : public OsgSceneHandler::Callback
{
public:
DatabasePagerCompileCallback() {}
virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera)
{
sh.drawImplementation(camera);
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
#if 1
double availableTime = 0.0025; // 2.5 ms
// compile any GL objects that are required.
if (dp) dp->compileGLObjects(*(sh.getSceneView()->getState()),availableTime);
// flush deleted GL objects.
sh.getSceneView()->flushDeletedGLObjects(availableTime);
#endif
if (dp) dp->signalEndFrame();
}
};
class PostSwapCompileCallback : public Producer::Camera::Callback
{
public:
PostSwapCompileCallback(osgUtil::SceneView* sceneView):
_sceneView(sceneView)
{}
virtual void operator()(const Producer::Camera&)
{
#if 0
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
double availableTime = 0.0025; // 2.5 ms
// flush deleted GL objects.
_sceneView->flushDeletedGLObjects(availableTime);
// compile any GL objects that are required.
if (dp) dp->compileGLObjects(*(_sceneView->getState()),availableTime);
#endif
// glFinish();
}
osg::ref_ptr<osgUtil::SceneView> _sceneView;
virtual void operator()(const Producer::Camera&)
{
// glFinish();
}
};
bool Viewer::realize()
@ -571,14 +510,7 @@ bool Viewer::realize()
{
// pass the database pager to the cull visitor so node can send requests to the pager.
(*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(databasePager);
(*p)->setCullCallback(new DatabasePagerStartCullCallback());
// set up a draw callback to pre compile any rendering object of database has loaded,
// but not yet merged with the main scene graph.
(*p)->setDrawCallback(new DatabasePagerCompileCallback());
// tell the database pager which graphic context the compile of rendering objexts is needed.
databasePager->setCompileGLObjectsForContextID((*p)->getSceneView()->getState()->getContextID(),true);
}
@ -588,7 +520,7 @@ bool Viewer::realize()
for(unsigned int cameraNum=0;cameraNum<getNumberOfCameras();++cameraNum)
{
Producer::Camera* camera=getCamera(cameraNum);
camera->addPostSwapCallback(new PostSwapCompileCallback(_shvec[cameraNum]->getSceneView()));
camera->addPostSwapCallback(new PostSwapFinishCallback());
}
}