Robert Osfield wrote:
> The DatabasePager does no remove subgraphs and associated OpenGL
> objects straight away, but has adjustable time limits that govern how
> long they live before they are expired.  See the DatabasePager API for
> details.

Robert,

Thanks for pointing this out but this turned out not to be my problem. Instead the issue appears to be in the DatabasePager class itself.

For reasons I don't quite understand the _activePagedLODList and _inactivePagedLODList seem to be named from the wrong perspective. It seems they are named from the POV of an "active PagedLOD candidate that could be paged in" vs. merely an actively paged-in PagedLOD.

Anyways, the removeExpiredChildren() call to each osg::PagedLOD is only done on the _inactivePagedLODList (read: PagedLODs that are in range of the eyepoint). As soon as a PagedLOD moves away from the eyesight it gets immediately added to the _activePagedLODList but removeExpiredChildren() is not called on the _activePagedLODList list for reasons I don't understand.

This is why my memory usage is through the roof and also why calling removeExpiredChildren manually seemed to help (recall my December '06 thread on the issue). The PagedLODs are moving outside of their range but the unused databases are never being expired.

Furthermore, there is an unsigned int called _targetNumOfInActivePagedLODs that I would argue should become a part of the API for osgDB::DatabasePager. This value prevents the calls to removeExpiredChildren unless one reaches the hardcoded value of 100 PagedLODs in the _inactivePagedLODList.

Here's what I did to work-around the problem and make the number of cached pagedLODs configurable. The diff is against OSG 1.2 but applies to the latest CVS.

--
Philip Lowman
Simulation Development Engineer, Modeling and Simulation Technology
General Dynamics Land Systems
http://www.gdls.com
--- OSG_OP_OT-1.2/OpenSceneGraph/include/osgDB/DatabasePager	2006-07-18 11:21:27.000000000 -0400
+++ OSG_OP_OT-1.2-fix/OpenSceneGraph/include/osgDB/DatabasePager	2007-01-11 09:13:01.000000000 -0500
@@ -234,6 +234,13 @@
         /** Report how many items are in the _dataToCompileList queue */
         unsigned int getDataToCompileListSize() const { return _dataToCompileList.size(); }
 
+        /** Set the maximum number of cached PagedLOD nodes to maintain in memory
+         * after they are out of range. */
+        void setTargetNumOfCachedPagedLODs(unsigned int number) { _targetNumOfInActivePagedLODs = number; }
+
+        /** Get the maximum number of cached PagedLOD nodes to maintain in memory
+         * after they are out of range. */
+        unsigned int getTargetNumOfCachedPagedLODs() const { return _targetNumOfInActivePagedLODs; }
 
         typedef std::list< osg::ref_ptr<osg::PagedLOD> >   PagedLODList;
         typedef std::set< osg::ref_ptr<osg::StateSet> >    StateSetList;
@@ -357,6 +364,8 @@
         double                          _targetFrameRate;
         double                          _minimumTimeAvailableForGLCompileAndDeletePerFrame;
         unsigned int                    _maximumNumOfObjectsToCompilePerFrame;
+
+        unsigned int                    _targetNumOfInActivePagedLODs;
 };
 
 }
--- OSG_OP_OT-1.2/OpenSceneGraph/src/osgDB/DatabasePager.cpp	2006-08-03 15:14:52.000000000 -0400
+++ OSG_OP_OT-1.2-fix/OpenSceneGraph/src/osgDB/DatabasePager.cpp	2007-01-11 10:03:07.000000000 -0500
@@ -108,6 +108,8 @@
         _maximumNumOfObjectsToCompilePerFrame = atoi(ptr);
     }
 
+    _targetNumOfInActivePagedLODs = 100;
+
     // make sure a SharedStateManager exists.
     //osgDB::Registry::instance()->getOrCreateSharedStateManager();
     
@@ -678,6 +680,12 @@
 
     osg::NodeList childrenRemoved;
     
+    unsigned int targetNumOfRemovedChildPagedLODs = 0;
+    if(_targetNumOfInActivePagedLODs == 0 ||
+          _inactivePagedLODList.size() > _targetNumOfInActivePagedLODs)
+    {
+       targetNumOfRemovedChildPagedLODs = 1;
+    }
 
     for(PagedLODList::iterator active_itr = _activePagedLODList.begin();
         active_itr!=_activePagedLODList.end();
@@ -694,7 +702,7 @@
         }
         else if (plod->getFrameNumberOfLastTraversal()<_frameNumber)
         {                
-            // osg::notify(osg::NOTICE)<<"_activePagedLODList : moving PageLOD to inactive list"<<std::endl;
+            //osg::notify(osg::NOTICE)<<"_activePagedLODList : moving PageLOD to inactive list"<<std::endl;
             _inactivePagedLODList.push_back(*active_itr);
             remove_plod = true;
         }
@@ -708,18 +716,17 @@
         }
         else
         {
+            if (childrenRemoved.size()<targetNumOfRemovedChildPagedLODs)
+            {
+                // check for removing expired children.
+                if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
+                {
+                    //osg::notify(osg::NOTICE)<<"_activePagedLODList : Some children removed from PLod"<<std::endl;
+                }
+            }
             ++active_itr;
         }
     }
-    
-    unsigned int i = 0;
-    // unsigned int numberOfPagedLODToTest = _inactivePagedLODList.size();
-    unsigned int targetNumOfInActivePagedLODs = 100;
-    unsigned int targetNumOfRemovedChildPagedLODs = 0;
-    if (_inactivePagedLODList.size()>targetNumOfInActivePagedLODs) targetNumOfRemovedChildPagedLODs = _inactivePagedLODList.size()-targetNumOfInActivePagedLODs;
-    
-    if (targetNumOfRemovedChildPagedLODs>1) targetNumOfRemovedChildPagedLODs=1;
-    
 
     // filter out singly referenced PagedLOD and move reactivated PagedLOD into the active list
     for(PagedLODList::iterator inactive_itr = _inactivePagedLODList.begin();
@@ -732,12 +739,12 @@
         {
             // prune PageLOD's that are no longer externally referenced
             childrenRemoved.push_back(const_cast<osg::PagedLOD*>(plod));
-            //osg::notify(osg::NOTICE)<<"_activePagedLODList : pruning no longer externally referenced"<<std::endl;
+            //osg::notify(osg::NOTICE)<<"_inactivePagedLODList : pruning no longer externally referenced"<<std::endl;
             remove_plod = true;
         }
         else if (plod->getFrameNumberOfLastTraversal()>=_frameNumber)
         {
-            // osg::notify(osg::NOTICE)<<"_inactivePagedLODList : moving PageLOD to active list"<<std::endl;
+            //osg::notify(osg::NOTICE)<<"_inactivePagedLODList : moving PageLOD to active list"<<std::endl;
             // found a reactivated pagedLOD's need to put it back in the active list.                
             _activePagedLODList.push_back(*inactive_itr);
             remove_plod = true;
@@ -752,27 +759,23 @@
         }
         else
         {
-//            if (i<numberOfPagedLODToTest)
             if (childrenRemoved.size()<targetNumOfRemovedChildPagedLODs)
             {
                 // check for removing expired children.
                 if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
                 {
-                    //osg::notify(osg::NOTICE)<<"Some children removed from PLod"<<std::endl;
-                }
-                else
-                {
-                    // osg::notify(osg::NOTICE)<<"no children removed from PLod"<<std::endl;
+                    //osg::notify(osg::NOTICE)<<"_inactivePagedLODList : Some children removed from PLod"<<std::endl;
                 }
             }
-        
             ++inactive_itr;
-            ++i;
         }
     }
 
-    //osg::notify(osg::NOTICE)<<"_activePagedLODList.size()="<<_activePagedLODList.size()<<"\t_inactivePagedLODList.size()="<<_inactivePagedLODList.size()<<std::endl;
-
+    //double foo = currentFrameTime - int(currentFrameTime);
+    //if(foo >= 0.0 && foo < 0.01)
+    //{
+    //    osg::notify(osg::NOTICE)<<"_activePagedLODList.size()="<<_activePagedLODList.size()<<"\t_inactivePagedLODList.size()="<<_inactivePagedLODList.size()<<std::endl;
+    //}
 
     // osg::notify(osg::NOTICE)<<"   number stale "<<numberStale<<"  number active "<<_pagedLODList.size()-numberStale<<std::endl;
 
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to