diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index fb9bb5304..63f17846e 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -279,11 +280,7 @@ 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(const osg::FrameStamp& frameStamp) - { - removeExpiredSubgraphs(frameStamp); - addLoadedDataToSceneGraph(frameStamp); - } + virtual void updateSceneGraph(const osg::FrameStamp& frameStamp); /** Turn the compilation of rendering objects for specified graphics context on (true) or off(false). */ void setCompileGLObjectsForContextID(unsigned int contextID, bool on); @@ -332,7 +329,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl /** Reset the Stats variables.*/ void resetStats(); - typedef std::list< osg::ref_ptr > PagedLODList; typedef std::set< osg::ref_ptr > StateSetList; typedef std::vector< osg::ref_ptr > DrawableList; typedef std::pair DataToCompile; @@ -349,6 +345,28 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl struct RequestQueue; + struct PagedLODObserver : public osg::observer_ptr + { + typedef osg::observer_ptr BaseClass; + + PagedLODObserver(osg::PagedLOD* plod):BaseClass(plod) {} + PagedLODObserver(const PagedLODObserver& plodObserver):BaseClass(plodObserver) {} + + PagedLODObserver& operator = (const PagedLODObserver& rhs) + { + (*static_cast(this)) = rhs; + return *this; + } + + virtual void objectDeleted(void* ptr) + { + BaseClass::objectDeleted(ptr); + } + }; + + typedef std::list< PagedLODObserver > PagedLODList; + + struct DatabaseRequest : public osg::Referenced { DatabaseRequest(): @@ -442,8 +460,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl class FindCompileableGLObjectsVisitor; friend class FindCompileableGLObjectsVisitor; - class MarkPagedLODsVisitor; - + class CountPagedLODsVisitor; class FindPagedLODsVisitor; friend class FindPagedLODsVisitor; @@ -547,12 +564,6 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl * note, should be only be called from the update thread. */ virtual void removeExpiredSubgraphs(const osg::FrameStamp &frameStamp); - /** Old expiry delay based removeExpiredSubgraphs. */ - virtual void expiry_removeExpiredSubgraphs(const osg::FrameStamp &frameStamp); - - /** New capped based removeExpiredSubgraphs. */ - virtual void capped_removeExpiredSubgraphs(const osg::FrameStamp &frameStamp); - /** Add the loaded data to the scene graph.*/ void addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp); diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index f1b285f11..b74e0aa13 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -217,7 +217,7 @@ public: { case DatabasePager::DO_NOT_MODIFY_DRAWABLE_SETTINGS: // do nothing, leave settings as they came in from loaded database. - // OSG_NOTIFY(osg::NOTICE)<<"DO_NOT_MODIFY_DRAWABLE_SETTINGS"<setUseDisplayList(true); @@ -226,12 +226,12 @@ public: case DatabasePager::USE_VERTEX_BUFFER_OBJECTS: drawable->setUseDisplayList(true); drawable->setUseVertexBufferObjects(true); - // OSG_NOTIFY(osg::NOTICE)<<"USE_VERTEX_BUFFER_OBJECTS"<setUseDisplayList(false); drawable->setUseVertexBufferObjects(false); - // OSG_NOTIFY(osg::NOTICE)<<"USE_VERTEX_ARRAYS"<_requestList.size()= "<_requestList.size()<<" to delete = "<_childrenToDeleteList.size()<_requestList.size()= "<_requestList.size()<<" to delete = "<_childrenToDeleteList.size()<_fileName<_fileName<add(databaseRequest.get()); databaseRequest = 0; } @@ -608,7 +608,7 @@ void DatabasePager::DatabaseThread::run() // load the data, note safe to write to the databaseRequest since once // it is created this thread is the only one to write to the _loadedModel pointer. - //OSG_NOTIFY(osg::NOTICE)<<"In DatabasePager thread readNodeFile("<_fileName<<")"<_fileName<<")"<tick(); @@ -630,7 +630,7 @@ void DatabasePager::DatabaseThread::run() if ((_pager->_frameNumber-databaseRequest->_frameNumberLastRequest)>1) { - OSG_NOTIFY(osg::INFO)<<_name<<": Warning DatabaseRquest no longer required."<_loadedModel = 0; } @@ -638,12 +638,12 @@ void DatabasePager::DatabaseThread::run() osg::RefNodePath refNodePath; if (!databaseRequest->_observerNodePath.getRefNodePath(refNodePath)) { - OSG_NOTICE<<_name<<": Warning node in parental chain has been deleted, discarding load."<_loadedModel = 0; } - //OSG_NOTIFY(osg::NOTICE)<<" node read in "<delta_m(before,osg::Timer::instance()->tick())<<" ms"<delta_m(before,osg::Timer::instance()->tick())<<" ms"<_dataToCompileList->_requestList.end(); ++citr) { - OSG_NOTIFY(osg::INFO)<<_name<<": pruning from compile list"<_loadedModel = 0; (*citr)->_requestQueue = 0; } @@ -778,7 +778,7 @@ void DatabasePager::DatabaseThread::run() } } - // OSG_NOTIFY(osg::NOTICE)<<"Done compiling in paging thread"<getOptions(); - // OSG_NOTIFY(osg::NOTICE)<<"Using options from Registry "<_requestQueue; if (requestQueue) @@ -1312,7 +1312,7 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou if (databaseRequestRef->referenceCount()==1) { - OSG_NOTIFY(osg::INFO)<<"DatabasePager::requestNodeFile("<_frameNumberFirstRequest = frameNumber; databaseRequest->_timestampFirstRequest = timestamp; @@ -1333,7 +1333,7 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou if (!foundEntry) { - OSG_NOTIFY(osg::INFO)<<"In DatabasePager::requestNodeFile("< lock(_fileRequestQueue->_requestMutex); @@ -1397,15 +1397,15 @@ void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp) { if (framestamp) { - //OSG_NOTIFY(osg::INFO) << "signalBeginFrame "<getFrameNumber()<<">>>>>>>>>>>>>>>>"<getFrameNumber()<<">>>>>>>>>>>>>>>>"<getFrameNumber(); - } //else OSG_NOTIFY(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<>>>>>>>>>>>>>>>"< lock(*osg::Observer::getGlobalObserverMutex()); + + removeExpiredSubgraphs(frameStamp); + +#ifdef UPDATE_TIMING + timeFor_removeExpiredSubgraphs = timer.elapsedTime_m(); +#endif + + addLoadedDataToSceneGraph(frameStamp); + +#ifdef UPDATE_TIMING + timeFor_addLoadedDataToSceneGraph = timer.elapsedTime_m() - timeFor_removeExpiredSubgraphs; +#endif + + } + +#ifdef UPDATE_TIMING + double elapsedTime = timer.elapsedTime_m(); + if (elapsedTime>0.2) + { + OSG_NOTICE<<"DatabasePager::updateSceneGraph() total time = "<tick(); + osg::Timer_t before = osg::Timer::instance()->tick(), mid, last; RequestQueue::RequestList localFileLoadedList; @@ -1445,7 +1481,7 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) localFileLoadedList.swap(_dataToMergeList->_requestList); } - osg::Timer_t mid = osg::Timer::instance()->tick(); + mid = osg::Timer::instance()->tick(); // add the loaded data into the scene graph. for(RequestQueue::RequestList::iterator itr=localFileLoadedList.begin(); @@ -1457,13 +1493,12 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) osg::RefNodePath refNodePath; if (databaseRequest->_observerNodePath.getRefNodePath(refNodePath)) { - // OSG_NOTIFY(osg::NOTICE)<<"Merging "<<_frameNumber-(*itr)->_frameNumberLastRequest<_frameNumberLastRequest<_groupForAddingLoadedSubgraph; if (osgDB::Registry::instance()->getSharedStateManager()) osgDB::Registry::instance()->getSharedStateManager()->share(databaseRequest->_loadedModel.get()); - registerPagedLODs(databaseRequest->_loadedModel.get(), frameStamp.getFrameNumber()); osg::PagedLOD* plod = dynamic_cast(group); if (plod) @@ -1483,7 +1518,9 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) group->addChild(databaseRequest->_loadedModel.get()); - // OSG_NOTIFY(osg::NOTICE)<<"merged subgraph"<_fileName<<" after "<_numOfRequests<<" requests and time="<<(timeStamp-databaseRequest->_timestampFirstRequest)*1000.0<_fileName<<" after "<_numOfRequests<<" requests and time="<<(timeStamp-databaseRequest->_timestampFirstRequest)*1000.0<_timestampFirstRequest; @@ -1501,10 +1538,10 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) // reset the loadedModel pointer databaseRequest->_loadedModel = 0; - // OSG_NOTIFY(osg::NOTICE)<<"curr = "<delta_m(mid,last)<<"ms"<< " objects"<0) - { - capped_removeExpiredSubgraphs(frameStamp); - } - else - { - expiry_removeExpiredSubgraphs(frameStamp); - } -} - -void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameStamp) { static double s_total_iter_stage_a = 0.0; static double s_total_time_stage_a = 0.0; @@ -1571,32 +1590,34 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt osg::Timer_t startTick = osg::Timer::instance()->tick(); - unsigned int numPagedLODs = _activePagedLODList.size() + _inactivePagedLODList.size(); - - PagedLODList::iterator itr = _activePagedLODList.begin(); for(PagedLODList::iterator itr = _activePagedLODList.begin(); itr != _activePagedLODList.end(); ) { osg::PagedLOD* plod = itr->get(); - - int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); - if (delta>1) + if (plod) { - if (_releaseDelay!=DBL_MAX) + int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); + if (delta>1) { - plod->releaseGLObjects(); - OSG_NOTIFY(osg::INFO)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<releaseGLObjects(); + } - _inactivePagedLODList.push_back(plod); - - itr = _activePagedLODList.erase(itr); + _inactivePagedLODList.push_back(plod); + + itr = _activePagedLODList.erase(itr); + } + else + { + ++itr; + } } else { - ++itr; + itr = _activePagedLODList.erase(itr); } } @@ -1605,21 +1626,28 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt ) { osg::PagedLOD* plod = itr->get(); - - int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); - if (delta>1) + if (plod) { - ++itr; + int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); + if (delta>1) + { + ++itr; + } + else + { + _activePagedLODList.push_back(plod); + + itr = _inactivePagedLODList.erase(itr); + } } else { - _activePagedLODList.push_back(plod); - itr = _inactivePagedLODList.erase(itr); } } int inactivePLOD = _inactivePagedLODList.size(); + unsigned int numPagedLODs = _activePagedLODList.size() + _inactivePagedLODList.size(); osg::Timer_t end_a_Tick = osg::Timer::instance()->tick(); @@ -1648,47 +1676,51 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt double expiryTime = frameStamp.getReferenceTime() - 0.1; int expiryFrame = frameStamp.getFrameNumber() - 1; - MarkPagedLODsVisitor markerVistor("NeedToRemove"); + CountPagedLODsVisitor countPagedLODsVisitor; for(PagedLODList::iterator itr = _inactivePagedLODList.begin(); - itr!=_inactivePagedLODList.end() && markerVistor._numPagedLODsMarkedget(); - - osg::NodeList localChildrenRemoved; - plod->removeExpiredChildren(expiryTime, expiryFrame, localChildrenRemoved); - if (!localChildrenRemoved.empty()) + if (plod) { - for(osg::NodeList::iterator critr = localChildrenRemoved.begin(); - critr!=localChildrenRemoved.end(); - ++critr) + osg::NodeList localChildrenRemoved; + plod->removeExpiredChildren(expiryTime, expiryFrame, localChildrenRemoved); + if (!localChildrenRemoved.empty()) { - (*critr)->accept(markerVistor); + for(osg::NodeList::iterator critr = localChildrenRemoved.begin(); + critr!=localChildrenRemoved.end(); + ++critr) + { + (*critr)->accept(countPagedLODsVisitor); + } + + std::copy(localChildrenRemoved.begin(),localChildrenRemoved.end(),std::back_inserter(childrenRemoved)); } - - std::copy(localChildrenRemoved.begin(),localChildrenRemoved.end(),std::back_inserter(childrenRemoved)); } } for(PagedLODList::iterator itr = _activePagedLODList.begin(); - itr!=_activePagedLODList.end() && markerVistor._numPagedLODsMarkedget(); - - osg::NodeList localChildrenRemoved; - plod->removeExpiredChildren(expiryTime, expiryFrame, localChildrenRemoved); - if (!localChildrenRemoved.empty()) + if (plod) { - for(osg::NodeList::iterator critr = localChildrenRemoved.begin(); - critr!=localChildrenRemoved.end(); - ++critr) + osg::NodeList localChildrenRemoved; + plod->removeExpiredChildren(expiryTime, expiryFrame, localChildrenRemoved); + if (!localChildrenRemoved.empty()) { - (*critr)->accept(markerVistor); + for(osg::NodeList::iterator critr = localChildrenRemoved.begin(); + critr!=localChildrenRemoved.end(); + ++critr) + { + (*critr)->accept(countPagedLODsVisitor); + } + + std::copy(localChildrenRemoved.begin(),localChildrenRemoved.end(),std::back_inserter(childrenRemoved)); } - - std::copy(localChildrenRemoved.begin(),localChildrenRemoved.end(),std::back_inserter(childrenRemoved)); } } @@ -1701,7 +1733,7 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt - //OSG_NOTIFY(osg::NOTICE)<<"numToPrune "<delta_m(before,osg::Timer::instance()->tick())<<" ms "<get(); - if (plod && plod->getName() != markerVistor._marker) - { - ++itr; - - ++numSkipped; - - // OSG_NOTIFY(osg::NOTICE)<<"skipping"<updateBlock(); @@ -1772,108 +1768,12 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt s_total_time_stage_c += time_c; if (s_total_max_stage_ctick(); - - double expiryTime = frameStamp.getReferenceTime() - _expiryDelay; - int expiryFrame = frameStamp.getFrameNumber() - _expiryFrames; - - double releaseTime = frameStamp.getReferenceTime() - _releaseDelay; - int releaseFrame = frameStamp.getFrameNumber() - _releaseFrames; - - osg::NodeList childrenRemoved; - - for(PagedLODList::iterator itr = _activePagedLODList.begin(); - itr!=_activePagedLODList.end(); - ++itr) - { - osg::PagedLOD* plod = itr->get(); - - - if (_releaseDelay!=DBL_MAX && plod->releaseGLObjectsOnExpiredChildren(releaseTime, releaseFrame)) - { - OSG_NOTIFY(osg::INFO)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<removeExpiredChildren(expiryTime, expiryFrame, childrenRemoved); - } - - if (!childrenRemoved.empty()) - { - MarkPagedLODsVisitor markerVistor("NeedToRemove"); - for(osg::NodeList::iterator critr = childrenRemoved.begin(); - critr!=childrenRemoved.end(); - ++critr) - { - (*critr)->accept(markerVistor); - } - - // OSG_NOTIFY(osg::NOTICE)<<"Children to remove "< lock(_fileRequestQueue->_childrenToDeleteListMutex); - for (osg::NodeList::iterator critr = childrenRemoved.begin(); - critr!=childrenRemoved.end(); - ++critr) - { - _fileRequestQueue->_childrenToDeleteList.push_back(critr->get()); - } - - _fileRequestQueue->updateBlock(); - } - - // OSG_NOTIFY(osg::NOTICE)<<" time 2 "<delta_m(before,osg::Timer::instance()->tick())<<" ms "<get(); - if (plod && plod->getName() != markerVistor._marker) - { - ++itr; - } - else - { - PagedLODList::iterator itr_to_erase = itr; - ++itr; - - _activePagedLODList.erase(itr_to_erase); - } - } - - childrenRemoved.clear(); - - - } - - osg::Timer_t endTick = osg::Timer::instance()->tick(); - double time = osg::Timer::instance()->delta_m(startTick,endTick); - - s_total_iter += 1.0; - s_total_time += time; - if (s_total_maxgetObservers(); + for(osg::ObserverSet::Observers::const_iterator itr = observers.begin(); + itr != observers.end() && needsToBeInserted; + ++itr) + { + if (dynamic_cast(*itr)) + { + needsToBeInserted = false; + } + } + } + + if (needsToBeInserted) + { + _activePagedLODList.push_back(&plod); + } + traverse(plod); } - + DatabasePager::PagedLODList& _activePagedLODList; int _frameNumber; - + protected: - + FindPagedLODsVisitor& operator = (const FindPagedLODsVisitor&) { return *this; } }; void DatabasePager::registerPagedLODs(osg::Node* subgraph, int frameNumber) { if (!subgraph) return; - FindPagedLODsVisitor fplv(_activePagedLODList, frameNumber); subgraph->accept(fplv); } @@ -1944,7 +1863,7 @@ DatabasePager::CompileOperation::CompileOperation(osgDB::DatabasePager* database void DatabasePager::CompileOperation::operator () (osg::GraphicsContext* context) { - // OSG_NOTIFY(osg::NOTICE)<<"Background thread compiling"<compileAllGLObjects(*(context->getState())); @@ -1965,7 +1884,7 @@ void DatabasePager::compileAllGLObjects(osg::State& state) void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) { - // OSG_NOTIFY(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<get(), state.getContextID()) || (sharedManager && sharedManager->isShared(itr->get()))) { @@ -2052,7 +1971,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) if (!dtc.second.empty() && (compileAll || ((elapsedTime+estimatedDrawableDuration)get(), state.getContextID())) { elapsedTime = timer.delta_s(start_tick,timer.tick()); @@ -2085,7 +2004,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) dwlist.erase(dwlist.begin(),itr); } - //OSG_NOTIFY(osg::INFO)<<"Checking if compiled"< 0) - //OSG_NOTIFY(osg::NOTICE)<< _frameNumber << "compiled " << numObjectsCompiled << " objects" << std::endl; + //OSG_NOTICE<< _frameNumber << "compiled " << numObjectsCompiled << " objects" << std::endl; if (allCompiled) { // we've compiled all of the current databaseRequest so we can now pop it off the // to compile list and place it on the merge list. - // OSG_NOTIFY(osg::NOTICE)<<"All compiled"< lock(_dataToCompileList->_requestMutex); @@ -2140,7 +2059,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) } else { - // OSG_NOTIFY(osg::NOTICE)<<"Not all compiled"<