diff --git a/include/osg/PagedLOD b/include/osg/PagedLOD index c4d95e7cc..bf3cdc138 100644 --- a/include/osg/PagedLOD +++ b/include/osg/PagedLOD @@ -62,6 +62,7 @@ class OSG_EXPORT PagedLOD : public LOD float _priorityOffset; float _priorityScale; double _timeStamp; + int _frameNumber; osg::ref_ptr _databaseRequest; }; @@ -85,6 +86,10 @@ class OSG_EXPORT PagedLOD : public LOD double getTimeStamp(unsigned int childNo) const { return _perRangeDataList[childNo]._timeStamp; } unsigned int getNumTimeStamps() const { return _perRangeDataList.size(); } + void setFrameNumber(unsigned int childNo, int frameNumber) { expandPerRangeDataTo(childNo); _perRangeDataList[childNo]._frameNumber=frameNumber; } + double getFrameNumber(unsigned int childNo) const { return _perRangeDataList[childNo]._frameNumber; } + unsigned int getNumFrameNumbers() const { return _perRangeDataList.size(); } + /** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests * being carried on behalf of the DatabasePager. @@ -111,13 +116,11 @@ class OSG_EXPORT PagedLOD : public LOD /** Get the number of children that the PagedLOD must keep around, even if they are older than their expiry time.*/ unsigned int getNumChildrenThatCannotBeExpired() const { return _numChildrenThatCannotBeExpired; } - /** Remove the children from the PagedLOD which haven't been visited since specified expiry time. + /** Remove the children from the PagedLOD which haven't been visited since specified expiry time and expiry frame number. * The removed children are added to the removeChildren list passed into the method, * this allows the children to be deleted later at the caller's discretion. * Return true if children are removed, false otherwise. */ - virtual bool removeExpiredChildren(double expiryTime,NodeList& removedChildren); - - + virtual bool removeExpiredChildren(double expiryTime, int expiryFrame, NodeList& removedChildren); protected : diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index bf31cef9e..d0567484c 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -207,6 +208,14 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl * before being removed.*/ double getExpiryDelay() const { return _expiryDelay; } + /** Set the number of frames that a subgraph will be kept without being visited in the cull traversal + * before being removed.*/ + void setExpiryFrames(int expiryFrames) { _expiryFrames = expiryFrames; } + + /** Get the number of frames that a subgraph will be kept without being visited in the cull traversal + * before being removed.*/ + int getExpiryFrames() const { return _expiryFrames; } + /** Set whether the removed subgraphs should be deleted in the database thread or not.*/ void setDeleteRemovedSubgraphsInDatabaseThread(bool flag) { _deleteRemovedSubgraphsInDatabaseThread = flag; } @@ -247,12 +256,12 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl /** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph. * Note, must only be called from single thread update phase. */ - virtual void updateSceneGraph(double currentFrameTime) + virtual void updateSceneGraph(const osg::FrameStamp &frameStamp) { - removeExpiredSubgraphs(currentFrameTime); - addLoadedDataToSceneGraph(currentFrameTime); + removeExpiredSubgraphs(frameStamp); + addLoadedDataToSceneGraph(frameStamp); } - + /** Turn the compilation of rendering objects for specified graphics context on (true) or off(false). */ void setCompileGLObjectsForContextID(unsigned int contextID, bool on); @@ -487,10 +496,10 @@ 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. */ - virtual void removeExpiredSubgraphs(double currentFrameTime); + virtual void removeExpiredSubgraphs(const osg::FrameStamp &frameStamp); /** Add the loaded data to the scene graph.*/ - void addLoadedDataToSceneGraph(double currentFrameTime); + void addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp); bool _done; @@ -523,6 +532,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl PagedLODList _pagedLODList; double _expiryDelay; + int _expiryFrames; ActiveGraphicsContexts _activeGraphicsContexts; // CompileGraphicsContexts _compileGraphicsContexts; diff --git a/include/osgDB/ImagePager b/include/osgDB/ImagePager index 588fa83f8..943031ee4 100644 --- a/include/osgDB/ImagePager +++ b/include/osgDB/ImagePager @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -84,7 +85,7 @@ class OSGDB_EXPORT ImagePager : public osg::NodeVisitor::ImageRequestHandler virtual bool requiresUpdateSceneGraph() const; /** Merge the changes to the scene graph. */ - virtual void updateSceneGraph(double currentFrameTime); + virtual void updateSceneGraph(const osg::FrameStamp &frameStamp); int cancel(); diff --git a/src/osg/PagedLOD.cpp b/src/osg/PagedLOD.cpp index 04906216c..f75746d3c 100644 --- a/src/osg/PagedLOD.cpp +++ b/src/osg/PagedLOD.cpp @@ -22,13 +22,15 @@ using namespace osg; PagedLOD::PerRangeData::PerRangeData(): _priorityOffset(0.0f), _priorityScale(1.0f), - _timeStamp(0.0f) {} + _timeStamp(0.0f), + _frameNumber(0) {} PagedLOD::PerRangeData::PerRangeData(const PerRangeData& prd): _filename(prd._filename), _priorityOffset(prd._priorityOffset), _priorityScale(prd._priorityScale), _timeStamp(prd._timeStamp), + _frameNumber(prd._frameNumber), _databaseRequest(prd._databaseRequest) {} PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd) @@ -38,6 +40,7 @@ PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& _priorityOffset = prd._priorityOffset; _priorityScale = prd._priorityScale; _timeStamp = prd._timeStamp; + _frameNumber = prd._frameNumber; _databaseRequest = prd._databaseRequest; return *this; } @@ -114,6 +117,7 @@ void PagedLOD::traverse(NodeVisitor& nv) if (nv.getFrameStamp()) setFrameNumberOfLastTraversal(nv.getFrameStamp()->getFrameNumber()); double timeStamp = nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0; + int frameNumber = nv.getFrameStamp()?nv.getFrameStamp()->getFrameNumber():0; bool updateTimeStamp = nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR; switch(nv.getTraversalMode()) @@ -154,7 +158,11 @@ void PagedLOD::traverse(NodeVisitor& nv) { if (i<_children.size()) { - if (updateTimeStamp) _perRangeDataList[i]._timeStamp=timeStamp; + if (updateTimeStamp) + { + _perRangeDataList[i]._timeStamp=timeStamp; + _perRangeDataList[i]._frameNumber=frameNumber; + } _children[i]->accept(nv); lastChildTraversed = (int)i; @@ -173,7 +181,11 @@ void PagedLOD::traverse(NodeVisitor& nv) // select the last valid child. if (numChildren>0 && ((int)numChildren-1)!=lastChildTraversed) { - if (updateTimeStamp) _perRangeDataList[numChildren-1]._timeStamp=timeStamp; + if (updateTimeStamp) + { + _perRangeDataList[numChildren-1]._timeStamp=timeStamp; + _perRangeDataList[numChildren-1]._frameNumber=frameNumber; + } _children[numChildren-1]->accept(nv); } @@ -261,12 +273,14 @@ bool PagedLOD::removeChildren( unsigned int pos,unsigned int numChildrenToRemove return Group::removeChildren(pos,numChildrenToRemove); } -bool PagedLOD::removeExpiredChildren(double expiryTime,NodeList& removedChildren) +bool PagedLOD::removeExpiredChildren(double expiryTime, int expiryFrame, NodeList& removedChildren) { if (_children.size()>_numChildrenThatCannotBeExpired) { - if (!_perRangeDataList[_children.size()-1]._filename.empty() && _perRangeDataList[_children.size()-1]._timeStamp","Set the drawable policy for setting of loaded drawable to specified type. mode can be one of DoNotModify, DisplayList, VBO or VertexArrays>."); static osg::ApplicationUsageProxy DatabasePager_e4(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DATABASE_PAGER_PRIORITY ", "Set the thread priority to DEFAULT, MIN, LOW, NOMINAL, HIGH or MAX."); static osg::ApplicationUsageProxy DatabasePager_e7(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EXPIRY_DELAY ","Set the length of time a PagedLOD child is kept in memory, without being used, before its tagged as expired, and ear marked to deletion."); +static osg::ApplicationUsageProxy DatabasePager_e8(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EXPIRY_FRAMES ","Set number of frames a PagedLOD child is kept in memory, without being used, before its tagged as expired, and ear marked to deletion."); // Convert function objects that take pointer args into functions that a // reference to an osg::ref_ptr. This is quite useful for doing STL // operations on lists of ref_ptr. This code assumes that a function @@ -901,6 +902,13 @@ DatabasePager::DatabasePager() osg::notify(osg::NOTICE)<<"Expiry delay = "<<_expiryDelay<tick(); @@ -1321,7 +1332,8 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp) osg::PagedLOD* plod = dynamic_cast(group.get()); if (plod) { - plod->setTimeStamp(plod->getNumChildren(),timeStamp); + plod->setTimeStamp(plod->getNumChildren(), timeStamp); + plod->setFrameNumber(plod->getNumChildren(), frameNumber); plod->getDatabaseRequest(plod->getNumChildren()) = 0; } else @@ -1375,11 +1387,12 @@ public: std::string _marker; }; -void DatabasePager::removeExpiredSubgraphs(double currentFrameTime) +void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp &frameStamp) { // osg::notify(osg::NOTICE)<<"DatabasePager::new_removeExpiredSubgraphs()"<get(); - plod->removeExpiredChildren(expiryTime,childrenRemoved); + plod->removeExpiredChildren(expiryTime, expiryFrame, childrenRemoved); } if (!childrenRemoved.empty()) @@ -1445,7 +1458,7 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime) osgDB::Registry::instance()->getSharedStateManager()->prune(); // update the Registry object cache. - osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(currentFrameTime); + osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(frameStamp.getReferenceTime()); osgDB::Registry::instance()->removeExpiredObjectsInCache(expiryTime); diff --git a/src/osgDB/ImagePager.cpp b/src/osgDB/ImagePager.cpp index ce68631d3..ff00f9639 100644 --- a/src/osgDB/ImagePager.cpp +++ b/src/osgDB/ImagePager.cpp @@ -326,7 +326,7 @@ bool ImagePager::requiresUpdateSceneGraph() const return !(_completedQueue->_requestList.empty()); } -void ImagePager::updateSceneGraph(double currentFrameTime) +void ImagePager::updateSceneGraph(const osg::FrameStamp &frameStamp) { OpenThreads::ScopedLock lock(_completedQueue->_requestMutex); diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index f40792783..c8ad1025c 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -971,13 +971,13 @@ void CompositeViewer::updateTraversal() if (scene->getDatabasePager()) { // synchronize changes required by the DatabasePager thread to the scene graph - scene->getDatabasePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + scene->getDatabasePager()->updateSceneGraph(*_frameStamp); } if (scene->getImagePager()) { // synchronize changes required by the DatabasePager thread to the scene graph - scene->getImagePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + scene->getImagePager()->updateSceneGraph(*_frameStamp); } } diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 6c832e708..f83fbf15f 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -889,13 +889,13 @@ void Viewer::updateTraversal() if (_scene->getDatabasePager()) { // synchronize changes required by the DatabasePager thread to the scene graph - _scene->getDatabasePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + _scene->getDatabasePager()->updateSceneGraph(*_frameStamp); } if (_scene->getImagePager()) { // synchronize changes required by the DatabasePager thread to the scene graph - _scene->getImagePager()->updateSceneGraph(_frameStamp->getReferenceTime()); + _scene->getImagePager()->updateSceneGraph(*_frameStamp); } if (_updateOperations.valid())