| | 107 | |
| | 108 | class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor |
| | 109 | { |
| | 110 | public: |
| | 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 | // |
| | 148 | class SetBasedPagedLODList : public DatabasePager::PagedLODList |
| | 149 | { |
| | 150 | public: |
| | 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 | |
| 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 | |
| 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; |
| 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 | |