From 0750a19aa669b05c9c66a81b124a7967a69d980e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 19 Sep 2004 20:09:54 +0000 Subject: [PATCH] Added clear(), setDatabasePagerThreadPause() and setAcceptNewDatabaseRequests() methods and new local implementation of cancel(). --- include/osgDB/DatabasePager | 28 +++- src/osgDB/DatabasePager.cpp | 302 +++++++++++++++++------------------- 2 files changed, 171 insertions(+), 159 deletions(-) diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 150deb5a5..d6a087e02 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -92,9 +92,27 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl /** Add a request to load a node file to end the the database request list.*/ virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const osg::FrameStamp* framestamp); - /** run does the database paging.*/ + /** Run does the database paging.*/ virtual void run(); + /** Cancel the database pager thread.*/ + virtual int cancel(); + + /** Clear all internally cached structures.*/ + void clear(); + + /** Set whether the database pager thread should be paused or not.*/ + void setDatabasePagerThreadPause(bool pause); + + /** Get whether the database pager thread should is paused or not.*/ + bool getDatabasePagerThreadPause() const { return _databasePagerThreadPaused; } + + /** Set whether new database request calls are accepted or ignored.*/ + void setAcceptNewDatabaseRequests(bool acceptNewRequests) { _acceptNewRequests = acceptNewRequests; } + + /** Get whether new database request calls are accepted or ignored.*/ + bool getAcceptNewDatabaseRequests() const { return _acceptNewRequests; } + /** Set the use of the frame block which, if enabled, blocks the DatabasePager * from executing which the current frame is being drawn. * When a single processor machine is being used it can be useful to block on @@ -236,10 +254,14 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl inline void updateDatabasePagerThreadBlock() { _databasePagerThreadBlock->set( - !_fileRequestList.empty() || !_childrenToDeleteList.empty()); + (!_fileRequestList.empty() || !_childrenToDeleteList.empty()) && !_databasePagerThreadPaused); } - + + bool _done; + bool _acceptNewRequests; + bool _databasePagerThreadPaused; + bool _useFrameBlock; osg::ref_ptr _frameBlock; int _frameNumber; diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 5ca2d4979..7dc142c7f 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -15,11 +15,16 @@ #endif using namespace osgDB; +using namespace OpenThreads; DatabasePager::DatabasePager() { //osg::notify(osg::INFO)<<"Constructing DatabasePager()"< lock(_fileRequestListMutex); + _fileRequestList.clear(); + } + + { + OpenThreads::ScopedLock lock(_dataToCompileListMutex); + _dataToCompileList.clear(); + } + + { + OpenThreads::ScopedLock lock(_childrenToDeleteListMutex); + _childrenToDeleteList.clear(); + } + + { + OpenThreads::ScopedLock lock(_dataToMergeListMutex); + _dataToMergeList.clear(); + } + + // no mutex?? + _pagedLODList.clear(); + + // ?? + // _activeGraphicsContexts } void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const osg::FrameStamp* framestamp) { + if (!_acceptNewRequests) return; double timestamp = framestamp?framestamp->getReferenceTime():0.0; int frameNumber = framestamp?framestamp->getFrameNumber():_frameNumber; @@ -85,7 +126,8 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou // search to see if filename already exist in the file loaded list. bool foundEntry = false; - _dataToCompileListMutex.lock(); + { + OpenThreads::ScopedLock lock(_dataToCompileListMutex); for(DatabaseRequestList::iterator litr = _dataToCompileList.begin(); litr != _dataToCompileList.end() && !foundEntry; @@ -101,71 +143,67 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou } } - _dataToCompileListMutex.unlock(); + } if (!foundEntry) { - _dataToMergeListMutex.lock(); + OpenThreads::ScopedLock lock(_dataToMergeListMutex); - for(DatabaseRequestList::iterator litr = _dataToMergeList.begin(); - litr != _dataToMergeList.end() && !foundEntry; - ++litr) + for(DatabaseRequestList::iterator litr = _dataToMergeList.begin(); + litr != _dataToMergeList.end() && !foundEntry; + ++litr) + { + if ((*litr)->_fileName==fileName) { - if ((*litr)->_fileName==fileName) - { - foundEntry = true; - (*litr)->_frameNumberLastRequest = frameNumber; - (*litr)->_timestampLastRequest = timestamp; - (*litr)->_priorityLastRequest = priority; - ++((*litr)->_numOfRequests); - } - } - - _dataToMergeListMutex.unlock(); + foundEntry = true; + (*litr)->_frameNumberLastRequest = frameNumber; + (*litr)->_timestampLastRequest = timestamp; + (*litr)->_priorityLastRequest = priority; + ++((*litr)->_numOfRequests); + } + } } if (!foundEntry) { - _fileRequestListMutex.lock(); + OpenThreads::ScopedLock lock(_fileRequestListMutex); - // search to see if entry already in file request list. - bool foundEntry = false; - for(DatabaseRequestList::iterator ritr = _fileRequestList.begin(); - ritr != _fileRequestList.end() && !foundEntry; - ++ritr) + // search to see if entry already in file request list. + bool foundEntry = false; + for(DatabaseRequestList::iterator ritr = _fileRequestList.begin(); + ritr != _fileRequestList.end() && !foundEntry; + ++ritr) + { + if ((*ritr)->_fileName==fileName) { - if ((*ritr)->_fileName==fileName) - { - foundEntry = true; - (*ritr)->_timestampLastRequest = timestamp; - (*ritr)->_priorityLastRequest = priority; - (*ritr)->_frameNumberLastRequest = frameNumber; - ++((*ritr)->_numOfRequests); - } - } - - if (!foundEntry) - { - osg::notify(osg::INFO)<<"In DatabasePager::fileRquest("< databaseRequest = new DatabaseRequest; - - databaseRequest->_fileName = fileName; - databaseRequest->_frameNumberFirstRequest = frameNumber; - databaseRequest->_timestampFirstRequest = timestamp; - databaseRequest->_priorityFirstRequest = priority; - databaseRequest->_frameNumberLastRequest = frameNumber; - databaseRequest->_timestampLastRequest = timestamp; - databaseRequest->_priorityLastRequest = priority; - databaseRequest->_groupForAddingLoadedSubgraph = group; - - _fileRequestList.push_back(databaseRequest); - - updateDatabasePagerThreadBlock(); + foundEntry = true; + (*ritr)->_timestampLastRequest = timestamp; + (*ritr)->_priorityLastRequest = priority; + (*ritr)->_frameNumberLastRequest = frameNumber; + ++((*ritr)->_numOfRequests); } + } - _fileRequestListMutex.unlock(); + if (!foundEntry) + { + osg::notify(osg::INFO)<<"In DatabasePager::fileRquest("< databaseRequest = new DatabaseRequest; + + databaseRequest->_fileName = fileName; + databaseRequest->_frameNumberFirstRequest = frameNumber; + databaseRequest->_timestampFirstRequest = timestamp; + databaseRequest->_priorityFirstRequest = priority; + databaseRequest->_frameNumberLastRequest = frameNumber; + databaseRequest->_timestampLastRequest = timestamp; + databaseRequest->_priorityLastRequest = priority; + databaseRequest->_groupForAddingLoadedSubgraph = group; + + _fileRequestList.push_back(databaseRequest); + + updateDatabasePagerThreadBlock(); + } } if (!isRunning()) @@ -179,6 +217,7 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou if (!s_startThreadCalled) { s_startThreadCalled = true; + _done = false; osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"< obj = 0; - _childrenToDeleteListMutex.lock(); + { + OpenThreads::ScopedLock lock(_childrenToDeleteListMutex); if (!_childrenToDeleteList.empty()) { //osg::notify(osg::NOTICE)<<"In DatabasePager thread deleting "<<_childrenToDeleteList.size()<<" objects"< databaseRequest; // get the front of the file request list. - _fileRequestListMutex.lock(); + { + OpenThreads::ScopedLock lock(_fileRequestListMutex); if (!_fileRequestList.empty()) { std::sort(_fileRequestList.begin(),_fileRequestList.end(),SortFileRequestFunctor()); databaseRequest = _fileRequestList.front(); } - _fileRequestListMutex.unlock(); - + } + if (databaseRequest.valid()) { // check if databaseRequest is still relevant @@ -409,29 +452,26 @@ void DatabasePager::run() // move the databaseRequest from the front of the fileRequest to the end of // dataLoad list. - _fileRequestListMutex.lock(); + + OpenThreads::ScopedLock lock(_fileRequestListMutex); - if (databaseRequest->_loadedModel.valid()) + if (databaseRequest->_loadedModel.valid()) + { + if (loadedObjectsNeedToBeCompiled) { - if (loadedObjectsNeedToBeCompiled) - { - _dataToCompileListMutex.lock(); - _dataToCompileList.push_back(databaseRequest); - _dataToCompileListMutex.unlock(); - } - else - { - _dataToMergeListMutex.lock(); - _dataToMergeList.push_back(databaseRequest); - _dataToMergeListMutex.unlock(); - } - } + OpenThreads::ScopedLock lock(_dataToCompileListMutex); + _dataToCompileList.push_back(databaseRequest); + } + else + { + OpenThreads::ScopedLock lock(_dataToMergeListMutex); + _dataToMergeList.push_back(databaseRequest); + } + } - _fileRequestList.erase(_fileRequestList.begin()); + if (!_fileRequestList.empty()) _fileRequestList.erase(_fileRequestList.begin()); - updateDatabasePagerThreadBlock(); - - _fileRequestListMutex.unlock(); + updateDatabasePagerThreadBlock(); } else @@ -439,13 +479,11 @@ void DatabasePager::run() //std::cout<<"frame number delta for "<_fileName<<" "<<_frameNumber-databaseRequest->_frameNumberLastRequest< lock(_fileRequestListMutex); - _fileRequestList.erase(_fileRequestList.begin()); + if (!_fileRequestList.empty()) _fileRequestList.erase(_fileRequestList.begin()); - updateDatabasePagerThreadBlock(); - - _fileRequestListMutex.unlock(); + updateDatabasePagerThreadBlock(); } } @@ -469,10 +507,11 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp) DatabaseRequestList localFileLoadedList; // get the dat for the _dataToCompileList, leaving it empty via a std::vector<>.swap. - _dataToMergeListMutex.lock(); + { + OpenThreads::ScopedLock lock(_dataToMergeListMutex); localFileLoadedList.swap(_dataToMergeList); - _dataToMergeListMutex.unlock(); - + } + // add the loaded data into the scene graph. for(DatabaseRequestList::iterator itr=localFileLoadedList.begin(); itr!=localFileLoadedList.end(); @@ -566,56 +605,6 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime) } -#if 0 - if (_deleteRemovedSubgraphsInDatabaseThread) - { - - // for all the subgraphs to remove find all the textures and drawables and - // strip them from the display lists. - ReleaseTexturesAndDrawablesVisitor rtadv; - for(osg::NodeList::iterator nitr=childrenRemoved.begin(); - nitr!=childrenRemoved.end(); - ++nitr) - { - (*nitr)->accept(rtadv); - } - - // unref' the children we need to remove, keeping behind the Texture's and Drawables for later deletion - // inside the database thread. - childrenRemoved.clear(); - - // transfer the removed children over to the to delete list so the database thread can delete them. - _childrenToDeleteListMutex.lock(); - - rtadv.releaseGLObjects(_childrenToDeleteList); - - _childrenToDeleteListMutex.unlock(); - } - - // flush all the references from the child removed list. If _deleteRemovedSubgraphsInDatabaseThread - // is false then this will typically resulting in a delete, otherwise this will be left to the - // clean up of the _childrenToDeleteList from within the database paging thread. - childrenRemoved.clear(); - - for(unsigned int i=_pagedLODList.size(); - i>0; - ) - { - --i; - - osg::PagedLOD* plod = _pagedLODList[i].get(); - if (plod->referenceCount()==1) - { - osg::notify(osg::NOTICE)<<"PagedLOD "<referenceCount()<referenceCount()<getSharedStateManager()) osgDB::Registry::instance()->getSharedStateManager()->prune(); @@ -681,7 +670,8 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) osg::ref_ptr databaseRequest; // get the first compileable entry. - _dataToCompileListMutex.lock(); + { + OpenThreads::ScopedLock lock(_dataToCompileListMutex); if (!_dataToCompileList.empty()) { std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor()); @@ -703,7 +693,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) databaseRequest = _dataToCompileList.front(); } - _dataToCompileListMutex.unlock(); + }; // while there are valid databaseRequest's in the to compile list and there is // sufficient time left compile each databaseRequest's stateset and drawables. @@ -785,22 +775,22 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime) // we've compile all of the current databaseRequest so we can now pop it off the // to compile list and place it on the merge list. - _dataToCompileListMutex.lock(); + OpenThreads::ScopedLock lock(_dataToCompileListMutex); - _dataToMergeListMutex.lock(); - _dataToMergeList.push_back(databaseRequest); - _dataToMergeListMutex.unlock(); + { + OpenThreads::ScopedLock lock(_dataToMergeListMutex); + _dataToMergeList.push_back(databaseRequest); + } - _dataToCompileList.erase(_dataToCompileList.begin()); - - if (!_dataToCompileList.empty()) - { - std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor()); - databaseRequest = _dataToCompileList.front(); - } - else databaseRequest = 0; + if (!_dataToCompileList.empty()) _dataToCompileList.erase(_dataToCompileList.begin()); + + if (!_dataToCompileList.empty()) + { + std::sort(_dataToCompileList.begin(),_dataToCompileList.end(),SortFileRequestFunctor()); + databaseRequest = _dataToCompileList.front(); + } + else databaseRequest = 0; - _dataToCompileListMutex.unlock(); } else {