From 894537a016ee3b172b15f799db0f0b0a86105cdb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 6 Jan 2004 21:18:36 +0000 Subject: [PATCH] Simplified the API for using the DatabasePager, by providing a single DatabasePager::updateSceneGraph(..) method, and added a ref_ptr<> into osDB::Registry for managing a single DatabasePager in a centralised way. --- include/osgDB/DatabasePager | 20 +++++++---- include/osgDB/Registry | 13 +++++++ include/osgProducer/OsgCameraGroup | 11 ------ src/osgDB/DatabasePager.cpp | 14 ++++---- src/osgDB/Registry.cpp | 12 +++++++ src/osgProducer/Viewer.cpp | 54 +++++++++++++----------------- 6 files changed, 69 insertions(+), 55 deletions(-) diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index f1c592ea0..0a6f63351 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -94,10 +94,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl void signalEndFrame(); - /** Add the loaded data to the scene graph.*/ - void addLoadedDataToSceneGraph(double timeStamp); - - /** Find all PagedLOD nodes in a subgraph and register them with * the DatabasePager so it can keep track of expired nodes. * note, should be only be called from the update thread. */ @@ -122,17 +118,27 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl * 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); + + /** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph*/ + void updateSceneGraph(double currentFrameTime) + { + removeExpiredSubgraphs(currentFrameTime); + addLoadedDataToSceneGraph(currentFrameTime); + } /** Turn the compilation of rendering objects for specfied graphics context on (true) or off(false).*/ - void setCompileRenderingObjectsForContexID(unsigned int contextID, bool on); + void setCompileGLObjectsForContexID(unsigned int contextID, bool on); /** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false).*/ - bool getCompileRenderingObjectsForContexID(unsigned int contextID); + bool getCompileGLObjectsForContexID(unsigned int contextID); /** Compile the rendering objects (display lists,texture objects, VBO's) on loaded subgraph. * note, should only be called from the draw thread.*/ - void compileRenderingObjects(osg::State& state,double& availableTime); + void compileGLObjects(osg::State& state,double& availableTime); /** Helper class used internally to force the release of texture objects * and displace lists.*/ diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 1fe5d411a..ba75375fb 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -209,6 +210,16 @@ class OSGDB_EXPORT Registry : public osg::Referenced DynamicLibrary* getLibrary(const std::string& fileName); typedef std::vector< osg::ref_ptr > ReaderWriterList; + + + /** Set the DatabasePager.*/ + void setDatabasePager(DatabasePager* databasePager) { _databasePager = databasePager; } + + /** Get the DatabasePager, creating one if one is not already created.*/ + DatabasePager* getOrCreateDatabasePager(); + + /** Get the DatabasePager. Return 0 if no DatabasePager has been assigned.*/ + DatabasePager* getDatabasePager() { return _databasePager.get(); } protected: @@ -264,6 +275,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced bool _useObjectCacheHint; ObjectCache _objectCache; + + osg::ref_ptr _databasePager; }; diff --git a/include/osgProducer/OsgCameraGroup b/include/osgProducer/OsgCameraGroup index 31c89e841..cb642d97c 100644 --- a/include/osgProducer/OsgCameraGroup +++ b/include/osgProducer/OsgCameraGroup @@ -26,8 +26,6 @@ #include #include -#include - #include namespace osgProducer { @@ -115,13 +113,6 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup void setFusionDistance( osgUtil::SceneView::FusionDistanceMode mode,float value=1.0f); - void setDatabasePager( osgDB::DatabasePager* pager) { _databasePager = pager; } - - osgDB::DatabasePager* getDatabasePager() { return _databasePager.get(); } - - const osgDB::DatabasePager* getDatabasePager() const { return _databasePager.get(); } - - /** RealizeCallback class one should override to provide an the implemention of realize callbacks. * Note, this callback overrides the normal call to OsgSceneHandler::init() so it become the your * responisibility to call this within your callback if required, it is a safe assumption to @@ -197,8 +188,6 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup osg::Timer _timer; osg::Timer_t _start_tick; osg::ref_ptr _frameStamp; - - osg::ref_ptr _databasePager; void _init(); }; diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 6ff04caa5..cb38a5fcc 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -30,6 +30,7 @@ DatabasePager::DatabasePager() DatabasePager::~DatabasePager() { + //std::cout<<"DatabasePager::~DatabasePager()"<release(); } -class FindCompileableRenderingObjectsVisitor : public osg::NodeVisitor +class FindCompileableGLObjectsVisitor : public osg::NodeVisitor { public: - FindCompileableRenderingObjectsVisitor(DatabasePager::DataToCompile& dataToCompile): + FindCompileableGLObjectsVisitor(DatabasePager::DataToCompile& dataToCompile): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _dataToCompile(dataToCompile) { @@ -331,7 +333,7 @@ void DatabasePager::run() ++itr; // find all the compileable rendering objects - FindCompileableRenderingObjectsVisitor frov(dtc); + FindCompileableGLObjectsVisitor frov(dtc); databaseRequest->_loadedModel->accept(frov); if (!dtc.first.empty() || !dtc.second.empty()) @@ -569,7 +571,7 @@ void DatabasePager::registerPagedLODs(osg::Node* subgraph) if (subgraph) subgraph->accept(fplv); } -void DatabasePager::setCompileRenderingObjectsForContexID(unsigned int contextID, bool on) +void DatabasePager::setCompileGLObjectsForContexID(unsigned int contextID, bool on) { if (on) { @@ -581,13 +583,13 @@ void DatabasePager::setCompileRenderingObjectsForContexID(unsigned int contextID } } -bool DatabasePager::getCompileRenderingObjectsForContexID(unsigned int contextID) +bool DatabasePager::getCompileGLObjectsForContexID(unsigned int contextID) { return _activeGraphicsContexts.count(contextID)!=0; } -void DatabasePager::compileRenderingObjects(osg::State& state, double& availableTime) +void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) { const osg::Timer& timer = *osg::Timer::instance(); diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 3cfef076f..bf1468255 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -197,6 +197,11 @@ Registry::Registry() Registry::~Registry() { + // switch off the pager and its associated thread before we clean up + // rest of the Registry. + _databasePager = 0; + + // unload all the plugin before we finally destruct. closeAllLibraries(); } @@ -1835,3 +1840,10 @@ void Registry::clearObjectCache() { _objectCache.clear(); } + +DatabasePager* Registry::getOrCreateDatabasePager() +{ + if (!_databasePager) _databasePager = new DatabasePager; + + return _databasePager.get(); +} diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index 896c2096b..630c3b67e 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -203,6 +203,8 @@ Viewer::Viewer(osg::ArgumentParser& arguments): Viewer::~Viewer() { + // kill the DatabasePager and associated thread if one exists. + osgDB::Registry::instance()->setDatabasePager(0); } void Viewer::setKeyboardMouse(Producer::KeyboardMouse* kbm) @@ -342,20 +344,16 @@ class DatabasePagerStartCullCallback : public OsgSceneHandler::Callback { public: - DatabasePagerStartCullCallback(osgDB::DatabasePager* databasePager): - _databasePager(databasePager) - {} + DatabasePagerStartCullCallback() {} virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera) { - - _databasePager->signalBeginFrame(sh.getSceneView()->getState()->getFrameStamp()); + osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager(); + if (dp) dp->signalBeginFrame(sh.getSceneView()->getState()->getFrameStamp()); sh.cullImplementation(camera); } - - osg::ref_ptr _databasePager; }; class DatabasePagerCompileCallback : public OsgSceneHandler::Callback @@ -371,6 +369,7 @@ public: sh.drawImplementation(camera); + osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager(); #if 0 double availableTime = 0.0025; // 2.5 ms @@ -378,10 +377,10 @@ public: sh.getSceneView()->flushDeletedGLObjects(availableTime); // compile any GL objects that are required. - _databasePager->compileRenderingObjects(*(sh.getSceneView()->getState()),availableTime); + if (dp) dp->compileGLObjects(*(sh.getSceneView()->getState()),availableTime); #endif - _databasePager->signalEndFrame(); + if (dp) dp->signalEndFrame(); } @@ -392,27 +391,26 @@ class PostSwapCompileCallback : public Producer::Camera::Callback { public: - PostSwapCompileCallback(osgUtil::SceneView* sceneView,osgDB::DatabasePager* databasePager): - _sceneView(sceneView), - _databasePager(databasePager) + PostSwapCompileCallback(osgUtil::SceneView* sceneView): + _sceneView(sceneView) {} virtual void operator()(const Producer::Camera&) { + osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager(); + double availableTime = 0.0025; // 5 ms // flush deleted GL objects. _sceneView->flushDeletedGLObjects(availableTime); // compile any GL objects that are required. - _databasePager->compileRenderingObjects(*(_sceneView->getState()),availableTime); - + if (dp) dp->compileGLObjects(*(_sceneView->getState()),availableTime); } osg::ref_ptr _sceneView; - osg::ref_ptr _databasePager; }; bool Viewer::realize() @@ -426,25 +424,25 @@ bool Viewer::realize() // by default set up the DatabasePager. { - _databasePager = new osgDB::DatabasePager; - _databasePager->registerPagedLODs(getTopMostSceneData()); + osgDB::DatabasePager* databasePager = osgDB::Registry::instance()->getOrCreateDatabasePager(); + databasePager->registerPagedLODs(getTopMostSceneData()); for(SceneHandlerList::iterator p=_shvec.begin(); p!=_shvec.end(); ++p) { // pass the database pager to the cull visitor so node can send requests to the pager. - (*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(_databasePager.get()); + (*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(databasePager); - (*p)->setCullCallback(new DatabasePagerStartCullCallback(_databasePager.get())); + (*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(_databasePager.get())); + (*p)->setDrawCallback(new DatabasePagerCompileCallback(databasePager)); // tell the database pager which graphic context the compile of rendering objexts is needed. - _databasePager->setCompileRenderingObjectsForContexID((*p)->getSceneView()->getState()->getContextID(),true); + databasePager->setCompileGLObjectsForContexID((*p)->getSceneView()->getState()->getContextID(),true); } @@ -452,7 +450,7 @@ bool Viewer::realize() for(unsigned int cameraNum=0;cameraNumaddPostSwapCallback(new PostSwapCompileCallback(_shvec[cameraNum]->getSceneView(),_databasePager.get())); + camera->addPostSwapCallback(new PostSwapCompileCallback(_shvec[cameraNum]->getSceneView())); } } @@ -507,16 +505,10 @@ void Viewer::update() } } - if (_databasePager.valid()) + if (osgDB::Registry::instance()->getDatabasePager()) { - - //_databasePager->signalBeginFrame(_frameStamp.get()); - - // removed any children PagedLOD children that havn't been visited in the cull traversal recently. - _databasePager->removeExpiredSubgraphs(_frameStamp->getReferenceTime()); - - // add the newly loaded data into the scene graph. - _databasePager->addLoadedDataToSceneGraph(_frameStamp->getReferenceTime()); + // update the scene graph by remove expired subgraphs and merge newly loaded subgraphs + osgDB::Registry::instance()->getDatabasePager()->updateSceneGraph(_frameStamp->getReferenceTime()); }