From 0ff3f486938f73a00c06aac57e6c05b7acab396f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 26 Oct 2008 22:22:38 +0000 Subject: [PATCH] Improved the support for no pre compile, and configuring the number of threads in the DatabasePager. --- include/osg/DisplaySettings | 15 ++ include/osgDB/DatabasePager | 4 + src/osg/BufferObject.cpp | 16 +- src/osg/DisplaySettings.cpp | 23 ++- src/osgDB/DatabasePager.cpp | 187 +++++++++++++++--------- src/osgWrappers/osg/DisplaySettings.cpp | 26 ++++ src/osgWrappers/osgDB/DatabasePager.cpp | 10 ++ 7 files changed, 205 insertions(+), 76 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index d7cedaa54..63a418d3d 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -183,6 +183,18 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced void setSerializeDrawDispatch(bool serializeDrawDispatch) { _serializeDrawDispatch = serializeDrawDispatch; } bool getSerializeDrawDispatch() const { return _serializeDrawDispatch; } + + /** Set the hint for the total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/ + void setNumOfDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; } + + /** Get the hint for total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/ + unsigned int getNumOfDatabaseThreadsHint() const { return _numDatabaseThreadsHint; } + + /** Set the hint for number of threads in the DatbasePager to dedicate to reading http requests.*/ + void setNumOfHttpDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; } + + /** Get the hint for number of threads in the DatbasePager dedicated to reading http requests.*/ + unsigned int getNumOfHttpDatabaseThreadsHint() const { return _numHttpDatabaseThreadsHint; } protected: @@ -220,6 +232,9 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced bool _compileContextsHint; bool _serializeDrawDispatch; + unsigned int _numDatabaseThreadsHint; + unsigned int _numHttpDatabaseThreadsHint; + }; } diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 3294356dd..a58b091b9 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -114,6 +114,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl Mode _mode; std::string _name; }; + + void setUpThreads(unsigned int totalNumThreads=2, unsigned int numHttpThreads=1); + + unsigned int addDatabaseThread(DatabaseThread::Mode mode, const std::string& name); DatabaseThread* getDatabaseThread(unsigned int i) { return _databaseThreads[i].get(); } diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index ddb7ff281..bea417475 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -30,9 +30,9 @@ using namespace osg; // static cache of deleted buffer object lists which can only // by completely deleted once the appropriate OpenGL context -// is set. Used osg::BufferObject::deleteDisplayList(..) and flushDeletedBufferObjects(..) below. -typedef std::multimap DisplayListMap; -typedef osg::buffered_object DeletedBufferObjectCache; +// is set. Used osg::BufferObject::deleteBufferObject(..) and flushDeletedBufferObjects(..) below. +typedef std::multimap BufferObjectMap; +typedef osg::buffered_object DeletedBufferObjectCache; static OpenThreads::Mutex s_mutex_deletedBufferObjectCache; static DeletedBufferObjectCache s_deletedBufferObjectCache; @@ -44,7 +44,7 @@ void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj) OpenThreads::ScopedLock lock(s_mutex_deletedBufferObjectCache); // insert the globj into the cache for the appropriate context. - s_deletedBufferObjectCache[contextID].insert(DisplayListMap::value_type(0,globj)); + s_deletedBufferObjectCache[contextID].insert(BufferObjectMap::value_type(0,globj)); } } @@ -65,9 +65,9 @@ void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*cur unsigned int noDeleted = 0; - DisplayListMap& dll = s_deletedBufferObjectCache[contextID]; + BufferObjectMap& dll = s_deletedBufferObjectCache[contextID]; - DisplayListMap::iterator ditr=dll.begin(); + BufferObjectMap::iterator ditr=dll.begin(); for(; ditr!=dll.end() && elapsedTime lock(s_mutex_deletedBufferObjectCache); - DisplayListMap& dll = s_deletedBufferObjectCache[contextID]; + BufferObjectMap& dll = s_deletedBufferObjectCache[contextID]; dll.clear(); } diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 8f4851b8d..91ff5ebf8 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -74,6 +74,9 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs) _compileContextsHint = vs._compileContextsHint; _serializeDrawDispatch = vs._serializeDrawDispatch; + + _numDatabaseThreadsHint = vs._numDatabaseThreadsHint; + _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; } void DisplaySettings::merge(const DisplaySettings& vs) @@ -92,6 +95,9 @@ void DisplaySettings::merge(const DisplaySettings& vs) if (vs._compileContextsHint) _compileContextsHint = vs._compileContextsHint; if (vs._serializeDrawDispatch) _serializeDrawDispatch = vs._serializeDrawDispatch; + + if (vs._numDatabaseThreadsHint>_numDatabaseThreadsHint) _numDatabaseThreadsHint = vs._numDatabaseThreadsHint; + if (vs._numHttpDatabaseThreadsHint>_numHttpDatabaseThreadsHint) _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; } void DisplaySettings::setDefaults() @@ -133,6 +139,9 @@ void DisplaySettings::setDefaults() _compileContextsHint = false; _serializeDrawDispatch = true; + + _numDatabaseThreadsHint = 2; + _numHttpDatabaseThreadsHint = 1; } void DisplaySettings::setMaxNumberOfGraphicsContexts(unsigned int num) @@ -169,6 +178,8 @@ static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_ static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS ","maximum number of graphics contexts to be used with applications."); static ApplicationUsageProxy DisplaySetting_e13(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_COMPIlE_CONTEXTS ","OFF | ON Enable/disable the use a backgrouind compile contexts and threads."); static ApplicationUsageProxy DisplaySetting_e14(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SERIALIZE_DRAW_DISPATCH ","OFF | ON Enable/disable the use a muetx to serialize the draw dispatch when there are multiple graphics threads."); +static ApplicationUsageProxy DisplaySetting_e15(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_NUM_DATABASE_THREADS ","Set the hint for the total number of threads to set up in the DatabasePager."); +static ApplicationUsageProxy DisplaySetting_e16(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_NUM_HTTP_DATABASE_THREADS ","Set the hint for the total number of threads dedicated to http requests to set up in the DatabasePager."); void DisplaySettings::readEnvironmentalVariables() { @@ -351,7 +362,15 @@ void DisplaySettings::readEnvironmentalVariables() } } - + if( (ptr = getenv("OSG_NUM_DATABASE_THREADS")) != 0) + { + _numDatabaseThreadsHint = atoi(ptr); + } + + if( (ptr = getenv("OSG_NUM_HTTP_DATABASE_THREADS")) != 0) + { + _numHttpDatabaseThreadsHint = atoi(ptr); + } } void DisplaySettings::readCommandLine(ArgumentParser& arguments) @@ -435,4 +454,6 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments) else if (str=="OFF") _serializeDrawDispatch = false; } + while(arguments.read("--num-db-threads",_numDatabaseThreadsHint)) {} + while(arguments.read("--num-http-threads",_numHttpDatabaseThreadsHint)) {} } diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index f19caadc4..a3299b779 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -537,7 +537,7 @@ void DatabasePager::DatabaseThread::run() Registry::instance()->readNode(databaseRequest->_fileName, databaseRequest->_loadOptions.get(), false); if (rr.validNode()) databaseRequest->_loadedModel = rr.getNode(); - if (rr.error()) osg::notify(osg::WARN) << rr.message() << std::endl; + if (rr.error()) osg::notify(osg::WARN)<<"Error in reading file "<_fileName<<" : "<_loadedModel.valid() && osgDB::containsServerAddress(databaseRequest->_fileName) && @@ -566,21 +566,62 @@ void DatabasePager::DatabaseThread::run() bool loadedObjectsNeedToBeCompiled = false; if (databaseRequest->_loadedModel.valid()) - { - + { + databaseRequest->_loadedModel->getBound(); + osg::NodePath nodePath; osg::NodePathList nodePathList = groupForAddingLoadedSubgraph->getParentalNodePaths(); if (!nodePathList.empty()) nodePath = nodePathList.front(); nodePath.push_back(groupForAddingLoadedSubgraph.get()); +#if 1 + // force a compute of the loaded model's bounding volume, so that when the subgraph + // merged with the main scene graph and large computeBound() isn't incurred. + ActiveGraphicsContexts::iterator itr = _pager->_activeGraphicsContexts.begin(); + + DataToCompile& dtc = databaseRequest->_dataToCompileMap[*itr]; + ++itr; + + // find all the compileable rendering objects + DatabasePager::FindCompileableGLObjectsVisitor frov(dtc, + _pager->_changeAutoUnRef, _pager->_valueAutoUnRef, + _pager->_changeAnisotropy, _pager->_valueAnisotropy, + _pager->_drawablePolicy, + _pager); + + // push the soon to be parent on the nodepath of the NodeVisitor so that + // during traversal one can test for where it'll be in the overall scene graph + for(osg::NodePath::iterator nitr = nodePath.begin(); + nitr != nodePath.end(); + ++nitr) + { + frov.pushOntoNodePath(*nitr); + } + + databaseRequest->_loadedModel->accept(frov); + + if (_pager->_doPreCompile && + !_pager->_activeGraphicsContexts.empty()) + { + if (!dtc.first.empty() || !dtc.second.empty()) + { + loadedObjectsNeedToBeCompiled = true; + + // copy the objects from the compile list to the other graphics context list. + for(; + itr != _pager->_activeGraphicsContexts.end(); + ++itr) + { + databaseRequest->_dataToCompileMap[*itr] = dtc; + } + } + } +#else if (_pager->_doPreCompile && !_pager->_activeGraphicsContexts.empty()) { // force a compute of the loaded model's bounding volume, so that when the subgraph // merged with the main scene graph and large computeBound() isn't incurred. - databaseRequest->_loadedModel->getBound(); - - ActiveGraphicsContexts::iterator itr = _pager->_activeGraphicsContexts.begin(); DataToCompile& dtc = databaseRequest->_dataToCompileMap[*itr]; @@ -639,6 +680,7 @@ void DatabasePager::DatabaseThread::run() //osg::notify(osg::NOTICE)<<"KdTree build time "<delta_m(before, after)<getNumOfDatabaseThreadsHint(), + osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint()); -#if 0 - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ALL_REQUESTS,"HANDLE_ALL_REQUESTS")); -#else - - #if 1 - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 0")); - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 1")); - #else - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 0")); - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_NON_HTTP, "HANDLE_NON_HTTP 1")); - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 2")); - _databaseThreads.push_back(new DatabaseThread(this, DatabaseThread::HANDLE_ONLY_HTTP, "HANDLE_ONLY_HTTP 3")); - #endif -#endif } DatabasePager::DatabasePager(const DatabasePager& rhs) @@ -1000,6 +1028,53 @@ DatabasePager* DatabasePager::create() new DatabasePager; } +void DatabasePager::setUpThreads(unsigned int totalNumThreads, unsigned int numHttpThreads) +{ + _databaseThreads.clear(); + + unsigned int numGeneralThreads = numHttpThreads < totalNumThreads ? + totalNumThreads - numHttpThreads : + 1; + + if (numHttpThreads==0) + { + for(unsigned int i=0; istartThread(); + } + + return pos; +} + void DatabasePager::setReleaseDelay(double releaseDelay) { _releaseDelay = releaseDelay; @@ -1238,6 +1313,13 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou _done = false; osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"<getNumOfDatabaseThreadsHint(), + osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint()); + } + for(DatabaseThreadList::const_iterator dt_itr = _databaseThreads.begin(); dt_itr != _databaseThreads.end(); ++dt_itr) @@ -1292,16 +1374,18 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) double timeStamp = frameStamp.getReferenceTime(); int frameNumber = frameStamp.getFrameNumber(); - // osg::Timer_t before = osg::Timer::instance()->tick(); + osg::Timer_t before = osg::Timer::instance()->tick(); RequestQueue::RequestList localFileLoadedList; - // get the dat for the _dataToCompileList, leaving it empty via a std::vector<>.swap. + // get the data for the _dataToCompileList, leaving it empty via a std::vector<>.swap. { OpenThreads::ScopedLock lock(_dataToMergeList->_requestMutex); localFileLoadedList.swap(_dataToMergeList->_requestList); } + osg::Timer_t mid = osg::Timer::instance()->tick(); + // add the loaded data into the scene graph. for(RequestQueue::RequestList::iterator itr=localFileLoadedList.begin(); itr!=localFileLoadedList.end(); @@ -1338,7 +1422,7 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) group->addChild(databaseRequest->_loadedModel.get()); - osg::notify(osg::INFO)<<"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; @@ -1355,7 +1439,12 @@ void DatabasePager::addLoadedDataToSceneGraph(const osg::FrameStamp &frameStamp) // osg::notify(osg::NOTICE)<<"curr = "<delta_m(before,osg::Timer::instance()->tick())<<" ms objects"<tick(); + + osg::notify(osg::INFO)<<"Done DatabasePager::addLoadedDataToSceneGraph"<< + osg::Timer::instance()->delta_m(before,mid)<<"ms,\t"<< + osg::Timer::instance()->delta_m(mid,last)<<"ms"<< + " objects"<tick(); -#if 1 - unsigned int numPagedLODs = _activePagedLODList.size() + _inactivePagedLODList.size(); @@ -1431,7 +1518,7 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt if (_releaseDelay!=DBL_MAX) { plod->releaseGLObjects(); - osg::notify(osg::INFO)<<"DatabasePager::removeExpiredSubgraphs(), releasing gl objects"<get(); - - int delta = frameStamp.getFrameNumber() - plod->getFrameNumberOfLastTraversal(); - if (delta>1) - { - ++inactivePLOD; - ++itr; - } - else - { - ++activePLOD; - - _activePagedLODList.push_back(plod); - - itr = _activePagedLODList.erase(itr); - } - } - - PagedLODList& pagedLODList = _activePagedLODList; -#endif - osg::Timer_t end_a_Tick = osg::Timer::instance()->tick(); double time_a = osg::Timer::instance()->delta_m(startTick,end_a_Tick); @@ -1559,11 +1611,12 @@ void DatabasePager::capped_removeExpiredSubgraphs(const osg::FrameStamp& frameSt s_total_time_stage_b += time_b; if (s_total_max_stage_b