diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index d0e6c558f..faf874395 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -271,7 +271,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl typedef std::set< osg::ref_ptr > StateSetList; typedef std::vector< osg::ref_ptr > DrawableList; - class CountPagedLODsVisitor; + class ExpirePagedLODsVisitor; typedef std::list< osg::ref_ptr > ObjectList; @@ -307,7 +307,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl _frameNumberLastRequest(0), _timestampLastRequest(0.0), _priorityLastRequest(0.0f), - _numOfRequests(0) + _numOfRequests(0), + _groupExpired(false) {} void invalidate(); @@ -331,6 +332,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl osg::ref_ptr _loadOptions; osg::observer_ptr _compileSet; + bool _groupExpired; // flag used only in update thread bool isRequestCurrent (int frameNumber) const { diff --git a/src/osg/PagedLOD.cpp b/src/osg/PagedLOD.cpp index 0c7f4ada1..306dddca9 100644 --- a/src/osg/PagedLOD.cpp +++ b/src/osg/PagedLOD.cpp @@ -288,13 +288,14 @@ bool PagedLOD::removeExpiredChildren(double expiryTime, unsigned int expiryFrame { if (_children.size()>_numChildrenThatCannotBeExpired) { - if (!_perRangeDataList[_children.size()-1]._filename.empty() && - _perRangeDataList[_children.size()-1]._timeStampadd(databaseRequest); } -///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// CountPagedLODList -// -class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor +// This class is a helper for the management of SetBasedPagedLODList. +class DatabasePager::ExpirePagedLODsVisitor : public osg::NodeVisitor { public: - CountPagedLODsVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _numPagedLODs(0) + ExpirePagedLODsVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { } - META_NodeVisitor("osgDB","CountPagedLODsVisitor") + META_NodeVisitor("osgDB","ExpirePagedLODsVisitor") virtual void apply(osg::PagedLOD& plod) { - ++_numPagedLODs; - _pagedLODs.insert(&plod); + _childPagedLODs.insert(&plod); + markRequestsExpired(&plod); traverse(plod); } - bool removeExpiredChildrenAndCountPagedLODs(osg::PagedLOD* plod, double expiryTime, unsigned int expiryFrame, osg::NodeList& removedChildren) + // Remove expired children from a PagedLOD. On return + // removedChildren contains the nodes removed by the call to + // PagedLOD::removeExpiredChildren, and the _childPagedLODs member + // contains all the PagedLOD objects found in those children's + // subgraphs. + bool removeExpiredChildrenAndFindPagedLODs(osg::PagedLOD* plod, double expiryTime, unsigned int expiryFrame, osg::NodeList& removedChildren) { size_t sizeBefore = removedChildren.size(); @@ -161,24 +162,25 @@ public: { removedChildren[i]->accept(*this); } - - for(PagedLODset::iterator itr = _pagedLODs.begin(); - itr != _pagedLODs.end(); - ++itr) - { - removedChildren.push_back(*itr); - } - return sizeBefore!=removedChildren.size(); } - typedef std::set > PagedLODset; - PagedLODset _pagedLODs; - int _numPagedLODs; + PagedLODset _childPagedLODs; +private: + void markRequestsExpired(osg::PagedLOD* plod) + { + unsigned numFiles = plod->getNumFileNames(); + for (unsigned i = 0; i < numFiles; ++i) + { + DatabasePager::DatabaseRequest* request + = dynamic_cast(plod->getDatabaseRequest(i).get()); + if (request) + request->_groupExpired = true; + } + } }; - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SetBasedPagedLODList @@ -201,7 +203,7 @@ public: { int leftToRemove = numberChildrenToRemove; for(PagedLODs::iterator itr = _pagedLODs.begin(); - itr!=_pagedLODs.end() && leftToRemove >= 0; + itr!=_pagedLODs.end() && leftToRemove > 0; ) { osg::ref_ptr plod; @@ -210,14 +212,14 @@ public: bool plodActive = expiryFrame < plod->getFrameNumberOfLastTraversal(); if (visitActive==plodActive) // true if (visitActive && plodActive) OR (!visitActive &&!plodActive) { - DatabasePager::CountPagedLODsVisitor countPagedLODsVisitor; + DatabasePager::ExpirePagedLODsVisitor expirePagedLODsVisitor; osg::NodeList expiredChildren; // expired PagedLODs - countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs( + expirePagedLODsVisitor.removeExpiredChildrenAndFindPagedLODs( plod.get(), expiryTime, expiryFrame, expiredChildren); // Clear any expired PagedLODs out of the set - for (DatabasePager::CountPagedLODsVisitor::PagedLODset::iterator - citr = countPagedLODsVisitor._pagedLODs.begin(), - end = countPagedLODsVisitor._pagedLODs.end(); + for (DatabasePager::ExpirePagedLODsVisitor::PagedLODset::iterator + citr = expirePagedLODsVisitor._childPagedLODs.begin(), + end = expirePagedLODsVisitor._childPagedLODs.end(); citr != end; ++citr) { @@ -1588,7 +1590,7 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) // the request; the cull traversal -- which might redispatch // the request -- can't run at the sametime as this update traversal. osg::ref_ptr group; - if (databaseRequest->_group.lock(group)) + if (!databaseRequest->_groupExpired && databaseRequest->_group.lock(group)) { if (osgDB::Registry::instance()->getSharedStateManager()) osgDB::Registry::instance()->getSharedStateManager()->share(databaseRequest->_loadedModel.get());