Changeset 11573

Show
Ignore:
Timestamp:
06/03/10 16:14:40 (5 years ago)
Author:
robert
Message:

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.

Location:
OpenSceneGraph/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgmultiviewpaging/osgmultiviewpaging.cpp

    r10829 r11573  
    5555     osgDB::DatabasePager::updateSceneGraph(frameStamp); 
    5656     double d = osg::Timer::instance()->delta_m(start, osg::Timer::instance()->tick()); 
    57      std::cout << "DatabasePager update took " << d << " ms. Length of active nodes = " << _activePagedLODList.size() << std::endl; 
     57     std::cout << "DatabasePager update took " << d << " ms. Length of active nodes = " << _activePagedLODList->size() << std::endl; 
    5858   } 
    5959 } 
  • OpenSceneGraph/trunk/include/osgDB/DatabasePager

    r11430 r11573  
    337337        typedef std::vector< osg::observer_ptr<osg::GraphicsContext> >  CompileGraphicsContexts; 
    338338 
     339        class CountPagedLODsVisitor; 
     340 
     341        struct PagedLODList : public osg::Referenced 
     342        { 
     343            virtual PagedLODList* clone() = 0; 
     344            virtual void clear() = 0; 
     345            virtual unsigned int size() = 0; 
     346            virtual void moveInactivePagedLODTo(PagedLODList& inactivePagedLODList, const osg::FrameStamp& framestamp) = 0; 
     347            virtual void moveActivePagedLODTo(PagedLODList& activePagedLODList, const osg::FrameStamp& framestamp) = 0; 
     348            virtual void removeExpiredChildren(int& numberChildrenToRemove, double expiryTime, int expiryFrame, osg::NodeList& childrenRemoved) = 0; 
     349            virtual void insertPagedLOD(osg::PagedLOD* plod) = 0; 
     350        }; 
     351 
    339352    protected: 
    340353 
     
    345358 
    346359        struct RequestQueue; 
    347  
    348         typedef osg::observer_ptr<osg::PagedLOD> PagedLODObserver; 
    349         typedef std::list< PagedLODObserver >                PagedLODList; 
    350360 
    351361        struct DatabaseRequest : public osg::Referenced 
     
    445455        friend class FindCompileableGLObjectsVisitor; 
    446456         
    447         class CountPagedLODsVisitor; 
    448457        class FindPagedLODsVisitor; 
    449458        friend class FindPagedLODsVisitor; 
     
    580589        osg::ref_ptr<RequestQueue>      _dataToMergeList; 
    581590         
    582         PagedLODList                    _activePagedLODList; 
    583         PagedLODList                    _inactivePagedLODList; 
     591        osg::ref_ptr<PagedLODList>      _activePagedLODList; 
     592        osg::ref_ptr<PagedLODList>      _inactivePagedLODList; 
    584593         
    585594        unsigned int                    _targetMaximumNumberOfPageLOD; 
  • OpenSceneGraph/trunk/src/osgDB/DatabasePager.cpp

    r11562 r11573  
    105105} 
    106106} 
     107 
     108class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor 
     109{ 
     110public: 
     111    CountPagedLODsVisitor(): 
     112        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), 
     113        _numPagedLODs(0) 
     114    { 
     115    } 
     116 
     117    META_NodeVisitor("osgDB","CountPagedLODsVisitor") 
     118 
     119    virtual void apply(osg::PagedLOD& plod) 
     120    { 
     121        ++_numPagedLODs; 
     122        _pagedLODs.insert(&plod); 
     123        traverse(plod); 
     124    } 
     125 
     126    bool removeExpiredChildrenAndCountPagedLODs(osg::PagedLOD* plod, double expiryTime, int expiryFrame, osg::NodeList& removedChildren) 
     127    { 
     128        size_t sizeBefore = removedChildren.size(); 
     129        plod->removeExpiredChildren(expiryTime, expiryFrame, removedChildren); 
     130        for(size_t i = sizeBefore; i<removedChildren.size(); ++i) 
     131        { 
     132            removedChildren[i]->accept(*this); 
     133        } 
     134        return sizeBefore!=removedChildren.size(); 
     135    } 
     136 
     137 
     138    typedef std::set<osg::PagedLOD*> PagedLODset; 
     139    PagedLODset         _pagedLODs; 
     140    int                 _numPagedLODs; 
     141}; 
     142 
     143 
     144///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     145// 
     146//  SetBasedPagedLODList 
     147// 
     148class SetBasedPagedLODList : public DatabasePager::PagedLODList 
     149{ 
     150public: 
     151 
     152    typedef std::set< osg::observer_ptr<osg::PagedLOD> > PagedLODs; 
     153    PagedLODs _pagedLODs; 
     154 
     155 
     156    virtual PagedLODList* clone() { return new SetBasedPagedLODList(); } 
     157    virtual void clear() { _pagedLODs.clear(); } 
     158    virtual unsigned int size() { return _pagedLODs.size(); } 
     159    virtual void moveInactivePagedLODTo(PagedLODList& inactivePagedLODList, const osg::FrameStamp& frameStamp) 
     160    { 
     161        for(PagedLODs::iterator itr = _pagedLODs.begin(); 
     162            itr != _pagedLODs.end(); 
     163            ) 
     164        { 
     165            osg::ref_ptr<osg::PagedLOD> plod; 
     166            if (itr->lock(plod)) 
     167            { 
     168                int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); 
     169                if (delta>1) 
     170                { 
     171#if 0 
     172                    if (_releaseDelay!=DBL_MAX) 
     173                    { 
     174                        plod->releaseGLObjects(); 
     175                    } 
     176#endif 
     177                    inactivePagedLODList.insertPagedLOD(plod); 
     178 
     179                    PagedLODs::iterator pitr = itr; 
     180                    ++itr; 
     181                    _pagedLODs.erase(pitr); 
     182                } 
     183                else 
     184                { 
     185                    ++itr; 
     186                } 
     187            } 
     188            else 
     189            { 
     190                OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _activePagedLODLists"<<std::endl; 
     191                PagedLODs::iterator pitr = itr; 
     192                ++itr; 
     193                _pagedLODs.erase(pitr); 
     194            } 
     195        } 
     196    } 
     197 
     198    virtual void moveActivePagedLODTo(PagedLODList& activePagedLODList, const osg::FrameStamp& frameStamp) 
     199    { 
     200        for(PagedLODs::iterator itr = _pagedLODs.begin(); 
     201            itr != _pagedLODs.end(); 
     202            ) 
     203        { 
     204            osg::ref_ptr<osg::PagedLOD> plod; 
     205            if (itr->lock(plod)) 
     206            { 
     207                int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); 
     208                if (delta>1) 
     209                { 
     210                    ++itr; 
     211                } 
     212                else 
     213                { 
     214                    activePagedLODList.insertPagedLOD(plod); 
     215 
     216                    PagedLODs::iterator pitr = itr; 
     217                    ++itr; 
     218                    _pagedLODs.erase(pitr); 
     219                } 
     220            } 
     221            else 
     222            { 
     223                OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _inactivePagedLODLists"<<std::endl; 
     224                PagedLODs::iterator pitr = itr; 
     225                ++itr; 
     226                _pagedLODs.erase(pitr); 
     227            } 
     228        } 
     229    } 
     230 
     231    virtual void removeExpiredChildren(int& numberChildrenToRemove, double expiryTime, int expiryFrame, osg::NodeList& childrenRemoved) 
     232    { 
     233        DatabasePager::CountPagedLODsVisitor countPagedLODsVisitor; 
     234 
     235        for(PagedLODs::iterator itr = _pagedLODs.begin(); 
     236            itr!=_pagedLODs.end() && numberChildrenToRemove > countPagedLODsVisitor._numPagedLODs; 
     237            ) 
     238        { 
     239            osg::ref_ptr<osg::PagedLOD> plod; 
     240            if (itr->lock(plod) && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) 
     241            { 
     242                countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); 
     243 
     244                // advance the iterator to the next element 
     245                ++itr; 
     246            } 
     247            else 
     248            { 
     249                PagedLODs::iterator pitr = itr; 
     250                ++itr; 
     251                _pagedLODs.erase(pitr); 
     252                OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _inactivePagedLOD has been invalidated, but ignored"<<std::endl; 
     253            } 
     254        } 
     255        numberChildrenToRemove -= countPagedLODsVisitor._numPagedLODs; 
     256    } 
     257 
     258    virtual void insertPagedLOD(osg::PagedLOD* plod) 
     259    { 
     260        if (_pagedLODs.count(plod)!=0) 
     261        { 
     262            OSG_NOTICE<<"Warning: SetBasedPagedLODList::insertPagedLOD("<<plod<<") already inserted"<<std::endl; 
     263            // abort(); 
     264            return; 
     265        } 
     266 
     267        _pagedLODs.insert(plod); 
     268    } 
     269}; 
     270 
    107271 
    108272///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     
    10021166        } 
    10031167    } 
     1168 
     1169    _activePagedLODList = new SetBasedPagedLODList; 
     1170    _inactivePagedLODList = new SetBasedPagedLODList; 
    10041171} 
    10051172 
     
    10531220    } 
    10541221 
     1222    _activePagedLODList = rhs._activePagedLODList->clone(); 
     1223    _inactivePagedLODList = rhs._inactivePagedLODList->clone(); 
     1224 
    10551225    // initialize the stats variables 
    10561226    resetStats(); 
     
    12021372 
    12031373    // note, no need to use a mutex as the list is only accessed from the update thread. 
    1204     _activePagedLODList.clear(); 
    1205     _inactivePagedLODList.clear(); 
     1374    _activePagedLODList->clear(); 
     1375    _inactivePagedLODList->clear(); 
    12061376 
    12071377    // ?? 
     
    14341604} 
    14351605 
    1436 //#define UPDATE_TIMING 1 
     1606#define UPDATE_TIMING 0 
    14371607void DatabasePager::updateSceneGraph(const osg::FrameStamp& frameStamp) 
    14381608{ 
    1439 #ifdef UPDATE_TIMING 
     1609#if UPDATE_TIMING 
    14401610    osg::ElapsedTime timer; 
    14411611    double timeFor_removeExpiredSubgraphs, timeFor_addLoadedDataToSceneGraph; 
     
    14451615        removeExpiredSubgraphs(frameStamp); 
    14461616 
    1447 #ifdef UPDATE_TIMING 
     1617#if UPDATE_TIMING 
    14481618        timeFor_removeExpiredSubgraphs = timer.elapsedTime_m(); 
    14491619#endif 
     
    14511621        addLoadedDataToSceneGraph(frameStamp); 
    14521622 
    1453 #ifdef UPDATE_TIMING 
     1623#if UPDATE_TIMING 
    14541624        timeFor_addLoadedDataToSceneGraph = timer.elapsedTime_m() - timeFor_removeExpiredSubgraphs; 
    14551625#endif 
     
    14571627    } 
    14581628 
    1459 #ifdef UPDATE_TIMING 
     1629#if UPDATE_TIMING 
    14601630    double elapsedTime = timer.elapsedTime_m(); 
    1461     if (elapsedTime>1.0) 
     1631    if (elapsedTime>0.4) 
    14621632    { 
    14631633        OSG_NOTICE<<"DatabasePager::updateSceneGraph() total time = "<<elapsedTime<<"ms"<<std::endl; 
    14641634        OSG_NOTICE<<"   timeFor_removeExpiredSubgraphs    = "<<timeFor_removeExpiredSubgraphs<<"ms"<<std::endl; 
    14651635        OSG_NOTICE<<"   timeFor_addLoadedDataToSceneGraph = "<<timeFor_addLoadedDataToSceneGraph<<"ms"<<std::endl; 
     1636        OSG_NOTICE<<"   _activePagedLODList.size()        = "<<_activePagedLODList->size()<<std::endl; 
     1637        OSG_NOTICE<<"   _inactivePagedLODList.size()      = "<<_inactivePagedLODList->size()<<std::endl; 
     1638        OSG_NOTICE<<"   total                             = "<<_activePagedLODList->size() + _inactivePagedLODList->size()<<std::endl; 
    14661639    } 
    14671640#endif 
     
    15561729} 
    15571730 
    1558 class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor 
    1559 { 
    1560 public: 
    1561     CountPagedLODsVisitor(): 
    1562         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), 
    1563         _numPagedLODs(0) 
    1564     { 
    1565     } 
    1566  
    1567     META_NodeVisitor("osgDB","CountPagedLODsVisitor") 
    1568  
    1569     virtual void apply(osg::PagedLOD& plod) 
    1570     { 
    1571         ++_numPagedLODs; 
    1572         _pagedLODs.insert(&plod); 
    1573         traverse(plod); 
    1574     } 
    1575  
    1576     bool removeExpiredChildrenAndCountPagedLODs(osg::PagedLOD* plod, double expiryTime, int expiryFrame, osg::NodeList& removedChildren) 
    1577     { 
    1578         size_t sizeBefore = removedChildren.size(); 
    1579         plod->removeExpiredChildren(expiryTime, expiryFrame, removedChildren); 
    1580         for(size_t i = sizeBefore; i<removedChildren.size(); ++i) 
    1581         { 
    1582             removedChildren[i]->accept(*this); 
    1583         } 
    1584         return sizeBefore!=removedChildren.size(); 
    1585     } 
    1586  
    1587  
    1588     typedef std::set<osg::PagedLOD*> PagedLODset; 
    1589     PagedLODset         _pagedLODs; 
    1590     int                 _numPagedLODs; 
    1591 }; 
     1731 
    15921732 
    15931733void DatabasePager::removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) 
    15941734{ 
     1735 
    15951736    static double s_total_iter_stage_a = 0.0; 
    15961737    static double s_total_time_stage_a = 0.0; 
     
    16071748    osg::Timer_t startTick = osg::Timer::instance()->tick(); 
    16081749 
    1609  
    1610     PagedLODList::iterator itr = _activePagedLODList.begin(); 
    1611     for(PagedLODList::iterator itr = _activePagedLODList.begin(); 
    1612         itr != _activePagedLODList.end(); 
    1613         ) 
    1614     { 
    1615         osg::ref_ptr<osg::PagedLOD> plod(*itr); 
    1616         if (plod.valid()) 
    1617         { 
    1618             int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); 
    1619             if (delta>1) 
    1620             { 
    1621                 if (_releaseDelay!=DBL_MAX) 
    1622                 { 
    1623                     plod->releaseGLObjects(); 
    1624                 } 
    1625  
    1626                 _inactivePagedLODList.push_back(plod); 
    1627  
    1628                 itr = _activePagedLODList.erase(itr); 
    1629             } 
    1630             else 
    1631             { 
    1632                 ++itr; 
    1633             } 
    1634         } 
    1635         else 
    1636         { 
    1637             OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _activePagedLODLists"<<std::endl; 
    1638             itr = _activePagedLODList.erase(itr); 
    1639         } 
    1640     } 
    1641  
    1642     for(PagedLODList::iterator itr = _inactivePagedLODList.begin(); 
    1643         itr != _inactivePagedLODList.end(); 
    1644         ) 
    1645     { 
    1646         osg::ref_ptr<osg::PagedLOD> plod(*itr); 
    1647         if (plod.valid()) 
    1648         { 
    1649             int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); 
    1650             if (delta>1) 
    1651             { 
    1652                 ++itr; 
    1653             } 
    1654             else 
    1655             { 
    1656                 _activePagedLODList.push_back(plod); 
    1657  
    1658                 itr = _inactivePagedLODList.erase(itr); 
    1659             } 
    1660         } 
    1661         else 
    1662         { 
    1663             OSG_INFO<<"DatabasePager::removeExpiredSubgraphs(), removing PagedLOD from _inactivePagedLODLists"<<std::endl; 
    1664             itr = _inactivePagedLODList.erase(itr); 
    1665         } 
    1666     } 
    1667  
    1668     int inactivePLOD = _inactivePagedLODList.size(); 
    1669     unsigned int numPagedLODs = _activePagedLODList.size() + _inactivePagedLODList.size(); 
     1750    _activePagedLODList->moveInactivePagedLODTo(*_inactivePagedLODList, frameStamp); 
     1751 
     1752    _inactivePagedLODList->moveActivePagedLODTo(*_activePagedLODList, frameStamp); 
     1753 
     1754    int inactivePLOD = _inactivePagedLODList->size(); 
     1755    unsigned int numPagedLODs = _activePagedLODList->size() + inactivePLOD; 
    16701756 
    16711757     
     
    16971783    int expiryFrame = frameStamp.getFrameNumber() - 1; 
    16981784 
    1699     CountPagedLODsVisitor countPagedLODsVisitor; 
    1700  
    1701     for(PagedLODList::iterator itr = _inactivePagedLODList.begin(); 
    1702         itr!=_inactivePagedLODList.end() && countPagedLODsVisitor._numPagedLODs<numToPrune; 
    1703         ) 
    1704     { 
    1705         osg::ref_ptr<osg::PagedLOD> plod(*itr); 
    1706         if (plod.valid() && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) 
    1707         { 
    1708             countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); 
    1709  
    1710             // advance the iterator to the next element 
    1711             ++itr; 
    1712         } 
    1713         else 
    1714         { 
    1715             itr = _inactivePagedLODList.erase(itr); 
    1716             OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _inactivePagedLOD has been invalidated, but ignored"<<std::endl; 
    1717         } 
    1718     } 
    1719  
    1720     for(PagedLODList::iterator itr = _activePagedLODList.begin(); 
    1721         itr!=_activePagedLODList.end() && countPagedLODsVisitor._numPagedLODs<numToPrune; 
    1722         ) 
    1723     { 
    1724         osg::ref_ptr<osg::PagedLOD> plod(*itr); 
    1725         if (plod.valid() && countPagedLODsVisitor._pagedLODs.count(plod.get())==0) 
    1726         { 
    1727             countPagedLODsVisitor.removeExpiredChildrenAndCountPagedLODs(plod.get(), expiryTime, expiryFrame, childrenRemoved); 
    1728  
    1729             // advance the iterator to the next element 
    1730             ++itr; 
    1731         } 
    1732         else 
    1733         { 
    1734             itr = _activePagedLODList.erase(itr); 
    1735             OSG_INFO<<"DatabasePager::removeExpiredSubgraphs() _activePagedLOD has been invalidated, but ignored"<<std::endl; 
    1736         } 
    1737     } 
    1738      
     1785    if (numToPrune>0) _inactivePagedLODList->removeExpiredChildren(numToPrune, expiryTime, expiryFrame, childrenRemoved); 
     1786    if (numToPrune>0) _activePagedLODList->removeExpiredChildren(numToPrune, expiryTime, expiryFrame, childrenRemoved); 
     1787 
    17391788    osg::Timer_t end_b_Tick = osg::Timer::instance()->tick(); 
    17401789    double time_b = osg::Timer::instance()->delta_m(end_a_Tick,end_b_Tick); 
     
    17431792    s_total_time_stage_b += time_b; 
    17441793    if (s_total_max_stage_b<time_b) s_total_max_stage_b = time_b; 
    1745  
    1746  
    17471794 
    17481795    //OSG_NOTICE<<"numToPrune "<<numToPrune<< " countPagedLODsVisitor._numPagedLODsMarked="<<countPagedLODsVisitor._numPagedLODsMarked<< " childrenRemoved.size()="<<childrenRemoved.size()<<std::endl; 
     
    17811828    if (s_total_max_stage_c<time_c) s_total_max_stage_c = time_c; 
    17821829 
    1783     OSG_INFO<<"active="<<_activePagedLODList.size()<<" inactive="<<_inactivePagedLODList.size()<<" overall = "<<osg::Timer::instance()->delta_m(startTick,end_c_Tick)<< 
     1830    OSG_INFO<<"active="<<_activePagedLODList->size()<<" inactive="<<_inactivePagedLODList->size()<<" overall = "<<osg::Timer::instance()->delta_m(startTick,end_c_Tick)<< 
    17841831                              " A="<<time_a<<" avg="<<s_total_time_stage_a/s_total_iter_stage_a<<" max = "<<s_total_max_stage_a<< 
    17851832                              " B="<<time_b<<" avg="<<s_total_time_stage_b/s_total_iter_stage_b<<" max = "<<s_total_max_stage_b<< 
     
    18031850    { 
    18041851        plod.setFrameNumberOfLastTraversal(_frameNumber); 
    1805  
    1806         bool needsToBeInserted = true; 
    1807  
    1808         osg::ObserverSet* observerSet = plod.getObserverSet(); 
    1809         if (observerSet) 
    1810         { 
    1811             const osg::ObserverSet::Observers& observers = observerSet->getObservers(); 
    1812             for(osg::ObserverSet::Observers::const_iterator itr = observers.begin(); 
    1813                 itr != observers.end() && needsToBeInserted; 
    1814                 ++itr) 
    1815             { 
    1816                 if (dynamic_cast<PagedLODObserver*>(*itr)) 
    1817                 { 
    1818                     needsToBeInserted = false; 
    1819                 } 
    1820             } 
    1821         } 
    1822  
    1823         if (needsToBeInserted) 
    1824         { 
    1825             _activePagedLODList.push_back(&plod); 
    1826         } 
     1852        _activePagedLODList.insertPagedLOD(&plod); 
    18271853 
    18281854        traverse(plod); 
     
    18401866{ 
    18411867    if (!subgraph) return; 
    1842     FindPagedLODsVisitor fplv(_activePagedLODList, frameNumber); 
     1868    FindPagedLODsVisitor fplv(*_activePagedLODList, frameNumber); 
    18431869    subgraph->accept(fplv); 
    18441870}