From 2ea6aa050ec10aa37198c40ffda4d37b2ac5c5ce Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 3 Jun 2010 14:14:40 +0000 Subject: [PATCH] Refactored the PagedLODList implementation so that it's now done via a base class that enables different implementations to be easily tried. Initial concrete PagedLODList is the SetBasedPagedLODList. --- .../osgmultiviewpaging/osgmultiviewpaging.cpp | 2 +- include/osgDB/DatabasePager | 21 +- src/osgDB/DatabasePager.cpp | 356 ++++++++++-------- 3 files changed, 207 insertions(+), 172 deletions(-) diff --git a/examples/osgmultiviewpaging/osgmultiviewpaging.cpp b/examples/osgmultiviewpaging/osgmultiviewpaging.cpp index 7ed666b93..267a3f971 100644 --- a/examples/osgmultiviewpaging/osgmultiviewpaging.cpp +++ b/examples/osgmultiviewpaging/osgmultiviewpaging.cpp @@ -54,7 +54,7 @@ public: osg::Timer_t start = osg::Timer::instance()->tick(); osgDB::DatabasePager::updateSceneGraph(frameStamp); double d = osg::Timer::instance()->delta_m(start, osg::Timer::instance()->tick()); - std::cout << "DatabasePager update took " << d << " ms. Length of active nodes = " << _activePagedLODList.size() << std::endl; + std::cout << "DatabasePager update took " << d << " ms. Length of active nodes = " << _activePagedLODList->size() << std::endl; } } }; diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index a5bc4d323..f48d26f03 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -336,6 +336,19 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl typedef std::set ActiveGraphicsContexts; typedef std::vector< osg::observer_ptr > CompileGraphicsContexts; + class CountPagedLODsVisitor; + + struct PagedLODList : public osg::Referenced + { + virtual PagedLODList* clone() = 0; + virtual void clear() = 0; + virtual unsigned int size() = 0; + virtual void moveInactivePagedLODTo(PagedLODList& inactivePagedLODList, const osg::FrameStamp& framestamp) = 0; + virtual void moveActivePagedLODTo(PagedLODList& activePagedLODList, const osg::FrameStamp& framestamp) = 0; + virtual void removeExpiredChildren(int& numberChildrenToRemove, double expiryTime, int expiryFrame, osg::NodeList& childrenRemoved) = 0; + virtual void insertPagedLOD(osg::PagedLOD* plod) = 0; + }; + protected: virtual ~DatabasePager(); @@ -345,9 +358,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl struct RequestQueue; - typedef osg::observer_ptr PagedLODObserver; - typedef std::list< PagedLODObserver > PagedLODList; - struct DatabaseRequest : public osg::Referenced { DatabaseRequest(): @@ -444,7 +454,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl class FindCompileableGLObjectsVisitor; friend class FindCompileableGLObjectsVisitor; - class CountPagedLODsVisitor; class FindPagedLODsVisitor; friend class FindPagedLODsVisitor; @@ -579,8 +588,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl osg::ref_ptr _dataToMergeList; - PagedLODList _activePagedLODList; - PagedLODList _inactivePagedLODList; + osg::ref_ptr _activePagedLODList; + osg::ref_ptr _inactivePagedLODList; unsigned int _targetMaximumNumberOfPageLOD; diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 36fdfba26..e53b6d7c2 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -105,6 +105,170 @@ RefPtrAdapter refPtrAdapt(const FuncObj& func) } } +class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor +{ +public: + CountPagedLODsVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _numPagedLODs(0) + { + } + + META_NodeVisitor("osgDB","CountPagedLODsVisitor") + + virtual void apply(osg::PagedLOD& plod) + { + ++_numPagedLODs; + _pagedLODs.insert(&plod); + traverse(plod); + } + + bool removeExpiredChildrenAndCountPagedLODs(osg::PagedLOD* plod, double expiryTime, int expiryFrame, osg::NodeList& removedChildren) + { + size_t sizeBefore = removedChildren.size(); + plod->removeExpiredChildren(expiryTime, expiryFrame, removedChildren); + for(size_t i = sizeBefore; iaccept(*this); + } + return sizeBefore!=removedChildren.size(); + } + + + typedef std::set PagedLODset; + PagedLODset _pagedLODs; + int _numPagedLODs; +}; + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// SetBasedPagedLODList +// +class SetBasedPagedLODList : public DatabasePager::PagedLODList +{ +public: + + typedef std::set< osg::observer_ptr > PagedLODs; + PagedLODs _pagedLODs; + + + virtual PagedLODList* clone() { return new SetBasedPagedLODList(); } + virtual void clear() { _pagedLODs.clear(); } + virtual unsigned int size() { return _pagedLODs.size(); } + virtual void moveInactivePagedLODTo(PagedLODList& inactivePagedLODList, const osg::FrameStamp& frameStamp) + { + for(PagedLODs::iterator itr = _pagedLODs.begin(); + itr != _pagedLODs.end(); + ) + { + osg::ref_ptr plod; + if (itr->lock(plod)) + { + int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); + if (delta>1) + { +#if 0 + if (_releaseDelay!=DBL_MAX) + { + plod->releaseGLObjects(); + } +#endif + inactivePagedLODList.insertPagedLOD(plod); + + PagedLODs::iterator pitr = itr; + ++itr; + _pagedLODs.erase(pitr); + } + else + { + ++itr; + } + } + else + { + OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _activePagedLODLists"< plod; + if (itr->lock(plod)) + { + int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); + if (delta>1) + { + ++itr; + } + else + { + activePagedLODList.insertPagedLOD(plod); + + PagedLODs::iterator pitr = itr; + ++itr; + _pagedLODs.erase(pitr); + } + } + else + { + OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _inactivePagedLODLists"< countPagedLODsVisitor._numPagedLODs; + ) + { + osg::ref_ptr plod; + if (itr->lock(plod) && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) + { + countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); + + // advance the iterator to the next element + ++itr; + } + else + { + PagedLODs::iterator pitr = itr; + ++itr; + _pagedLODs.erase(pitr); + OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _inactivePagedLOD has been invalidated, but ignored"<clone(); + _inactivePagedLODList = rhs._inactivePagedLODList->clone(); + // initialize the stats variables resetStats(); } @@ -1201,8 +1371,8 @@ void DatabasePager::clear() _dataToMergeList->clear(); // note, no need to use a mutex as the list is only accessed from the update thread. - _activePagedLODList.clear(); - _inactivePagedLODList.clear(); + _activePagedLODList->clear(); + _inactivePagedLODList->clear(); // ?? // _activeGraphicsContexts @@ -1433,10 +1603,10 @@ bool DatabasePager::requiresUpdateSceneGraph() const return !(_dataToMergeList->_requestList.empty()); } -//#define UPDATE_TIMING 1 +#define UPDATE_TIMING 0 void DatabasePager::updateSceneGraph(const osg::FrameStamp& frameStamp) { -#ifdef UPDATE_TIMING +#if UPDATE_TIMING osg::ElapsedTime timer; double timeFor_removeExpiredSubgraphs, timeFor_addLoadedDataToSceneGraph; #endif @@ -1444,25 +1614,28 @@ void DatabasePager::updateSceneGraph(const osg::FrameStamp& frameStamp) { removeExpiredSubgraphs(frameStamp); -#ifdef UPDATE_TIMING +#if UPDATE_TIMING timeFor_removeExpiredSubgraphs = timer.elapsedTime_m(); #endif addLoadedDataToSceneGraph(frameStamp); -#ifdef UPDATE_TIMING +#if UPDATE_TIMING timeFor_addLoadedDataToSceneGraph = timer.elapsedTime_m() - timeFor_removeExpiredSubgraphs; #endif } -#ifdef UPDATE_TIMING +#if UPDATE_TIMING double elapsedTime = timer.elapsedTime_m(); - if (elapsedTime>1.0) + if (elapsedTime>0.4) { OSG_NOTICE<<"DatabasePager::updateSceneGraph() total time = "<removeExpiredChildren(expiryTime, expiryFrame, removedChildren); - for(size_t i = sizeBefore; iaccept(*this); - } - return sizeBefore!=removedChildren.size(); - } - - - typedef std::set PagedLODset; - PagedLODset _pagedLODs; - int _numPagedLODs; -}; void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) { + static double s_total_iter_stage_a = 0.0; static double s_total_time_stage_a = 0.0; static double s_total_max_stage_a = 0.0; @@ -1606,67 +1747,12 @@ void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) osg::Timer_t startTick = osg::Timer::instance()->tick(); + _activePagedLODList->moveInactivePagedLODTo(*_inactivePagedLODList, frameStamp); - PagedLODList::iterator itr = _activePagedLODList.begin(); - for(PagedLODList::iterator itr = _activePagedLODList.begin(); - itr != _activePagedLODList.end(); - ) - { - osg::ref_ptr plod(*itr); - if (plod.valid()) - { - int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); - if (delta>1) - { - if (_releaseDelay!=DBL_MAX) - { - plod->releaseGLObjects(); - } + _inactivePagedLODList->moveActivePagedLODTo(*_activePagedLODList, frameStamp); - _inactivePagedLODList.push_back(plod); - - itr = _activePagedLODList.erase(itr); - } - else - { - ++itr; - } - } - else - { - OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _activePagedLODLists"< plod(*itr); - if (plod.valid()) - { - int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); - if (delta>1) - { - ++itr; - } - else - { - _activePagedLODList.push_back(plod); - - itr = _inactivePagedLODList.erase(itr); - } - } - else - { - OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _inactivePagedLODLists"<size(); + unsigned int numPagedLODs = _activePagedLODList->size() + inactivePLOD; osg::Timer_t end_a_Tick = osg::Timer::instance()->tick(); @@ -1696,46 +1782,9 @@ void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) double expiryTime = frameStamp.getReferenceTime() - 0.1; int expiryFrame = frameStamp.getFrameNumber() - 1; - CountPagedLODsVisitor countPagedLODsVisitor; + if (numToPrune>0) _inactivePagedLODList->removeExpiredChildren(numToPrune, expiryTime, expiryFrame, childrenRemoved); + if (numToPrune>0) _activePagedLODList->removeExpiredChildren(numToPrune, expiryTime, expiryFrame, childrenRemoved); - for(PagedLODList::iterator itr = _inactivePagedLODList.begin(); - itr!=_inactivePagedLODList.end() && countPagedLODsVisitor._numPagedLODs plod(*itr); - if (plod.valid() && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) - { - countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); - - // advance the iterator to the next element - ++itr; - } - else - { - itr = _inactivePagedLODList.erase(itr); - OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _inactivePagedLOD has been invalidated, but ignored"< plod(*itr); - if (plod.valid() && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) - { - countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); - - // advance the iterator to the next element - ++itr; - } - else - { - itr = _activePagedLODList.erase(itr); - OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _activePagedLOD has been invalidated, but ignored"<tick(); double time_b = osg::Timer::instance()->delta_m(end_a_Tick,end_b_Tick); @@ -1743,8 +1792,6 @@ void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) s_total_time_stage_b += time_b; if (s_total_max_stage_b