Changeset 8325
- Timestamp:
- 05/21/08 23:09:45
- Files:
-
- OpenSceneGraph/trunk/include/osg/NodeVisitor (modified) (1 diff)
- OpenSceneGraph/trunk/include/osg/PagedLOD (modified) (2 diffs)
- OpenSceneGraph/trunk/include/osg/ProxyNode (modified) (2 diffs)
- OpenSceneGraph/trunk/include/osgDB/DatabasePager (modified) (10 diffs)
- OpenSceneGraph/trunk/include/osgDB/ReaderWriter (modified) (4 diffs)
- OpenSceneGraph/trunk/src/osg/PagedLOD.cpp (modified) (3 diffs)
- OpenSceneGraph/trunk/src/osg/ProxyNode.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgDB/DatabasePager.cpp (modified) (10 diffs)
- OpenSceneGraph/trunk/src/osgDB/Registry.cpp (modified) (2 diffs)
- OpenSceneGraph/trunk/src/osgPlugins/curl/CMakeLists.txt (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgPlugins/curl/ReaderWriterCURL.cpp (modified) (3 diffs)
- OpenSceneGraph/trunk/src/osgPlugins/osg/PagedLOD.cpp (modified) (2 diffs)
- OpenSceneGraph/trunk/src/osgPlugins/txp/TXPPagedLOD.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgViewer/CompositeViewer.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgViewer/Viewer.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgViewer/ViewerBase.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgWrappers/osg/NodeVisitor.cpp (modified) (1 diff)
- OpenSceneGraph/trunk/src/osgWrappers/osg/PagedLOD.cpp (modified) (3 diffs)
- OpenSceneGraph/trunk/src/osgWrappers/osg/ProxyNode.cpp (modified) (3 diffs)
- OpenSceneGraph/trunk/src/osgWrappers/osgDB/DatabasePager.cpp (modified) (8 diffs)
- OpenSceneGraph/trunk/src/osgWrappers/osgDB/ReaderWriter.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
OpenSceneGraph/trunk/include/osg/NodeVisitor
r7731 r8325 269 269 Referenced(true) {} 270 270 271 virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const FrameStamp* framestamp ) = 0;271 virtual void requestNodeFile(const std::string& fileName,osg::Group* group, float priority, const FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& databaseRequest) = 0; 272 272 273 273 protected: OpenSceneGraph/trunk/include/osg/PagedLOD
r5328 r8325 59 59 PerRangeData& operator = (const PerRangeData& prd); 60 60 61 std::string _filename; 62 float _priorityOffset; 63 float _priorityScale; 64 double _timeStamp; 61 std::string _filename; 62 float _priorityOffset; 63 float _priorityScale; 64 double _timeStamp; 65 osg::ref_ptr<osg::Referenced> _databaseRequest; 65 66 }; 66 67 … … 84 85 double getTimeStamp(unsigned int childNo) const { return _perRangeDataList[childNo]._timeStamp; } 85 86 unsigned int getNumTimeStamps() const { return _perRangeDataList.size(); } 87 88 89 /** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests 90 * being carried on behalf of the DatabasePager. 91 * Note, in normal OSG usage you should not set this value yourself, as this will be managed by 92 * the osgDB::DatabasePager.*/ 93 osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) { return _perRangeDataList[childNo]._databaseRequest; } 94 95 /** Return the const DatabaseRequest object.*/ 96 const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _perRangeDataList[childNo]._databaseRequest; } 86 97 87 98 OpenSceneGraph/trunk/include/osg/ProxyNode
r8038 r8325 47 47 inline const std::string& getDatabasePath() const { return _databasePath; } 48 48 49 typedef std::vector<std::string> FileNameList; 49 void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo].first=filename; } 50 const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo].first; } 51 unsigned int getNumFileNames() const { return _filenameList.size(); } 52 53 /** Return the DatabaseRequest object used by the DatabasePager to keep track of file load requests 54 * being carried on behalf of the DatabasePager. 55 * Note, in normal OSG usage you should not set this value yourself, as this will be managed by 56 * the osgDB::DatabasePager.*/ 57 osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) { return _filenameList[childNo].second; } 50 58 51 void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo]=filename; }52 const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo]; }53 unsigned int getNumFileNames() const { return _filenameList.size(); } 59 /** Return the const DatabaseRequest object.*/ 60 const osg::ref_ptr<osg::Referenced>& getDatabaseRequest(unsigned int childNo) const { return _filenameList[childNo].second; } 61 54 62 55 63 /** Modes which control how the center of object should be determined when computed which child is active.*/ … … 103 111 void expandFileNameListTo(unsigned int pos); 104 112 105 FileNameList _filenameList; 106 std::string _databasePath; 113 typedef std::pair< std::string, osg::ref_ptr<osg::Referenced> > FileNameDatabaseRequestPair; 114 typedef std::vector<FileNameDatabaseRequestPair> FileNameDatabaseRequestList; 115 116 FileNameDatabaseRequestList _filenameList; 117 std::string _databasePath; 107 118 108 LoadingExternalReferenceMode _loadingExtReference;119 LoadingExternalReferenceMode _loadingExtReference; 109 120 110 CenterMode _centerMode;111 vec_type _userDefinedCenter;112 value_type _radius;121 CenterMode _centerMode; 122 vec_type _userDefinedCenter; 123 value_type _radius; 113 124 114 125 }; OpenSceneGraph/trunk/include/osgDB/DatabasePager
r8007 r8325 38 38 39 39 40 40 41 /** Database paging class which manages the loading of files in a background thread, 41 42 * and synchronizing of loaded models with the main scene graph.*/ 42 class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandler , public OpenThreads::Thread43 class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandler 43 44 { 44 45 public : … … 63 64 /** Add a request to load a node file to end the the database request list.*/ 64 65 virtual void requestNodeFile(const std::string& fileName,osg::Group* group, 65 float priority, const osg::FrameStamp* framestamp); 66 float priority, const osg::FrameStamp* framestamp, 67 osg::ref_ptr<osg::Referenced>& databaseRequest); 66 68 67 69 virtual void requestNodeFile(const std::string& fileName,osg::Group* group, 68 70 float priority, const osg::FrameStamp* framestamp, 71 osg::ref_ptr<osg::Referenced>& databaseRequest, 69 72 ReaderWriter::Options* loadOptions); 70 73 71 /** Run does the database paging.*/72 virtual void run();73 74 /** Cancel the database pager thread .*/74 /** Set the priority of the database pager thread(s).*/ 75 int setSchedulePriority(OpenThreads::Thread::ThreadPriority priority); 76 77 /** Cancel the database pager thread(s).*/ 75 78 virtual int cancel(); 79 80 virtual bool isRunning() const; 76 81 77 82 /** Clear all internally cached structures.*/ 78 83 virtual void clear(); 84 85 class DatabaseThread : public osg::Referenced, public OpenThreads::Thread 86 { 87 public: 88 89 enum Mode 90 { 91 HANDLE_ALL_REQUESTS, 92 HANDLE_NON_HTTP, 93 HANDLE_ONLY_HTTP 94 }; 95 96 DatabaseThread(DatabasePager* pager, Mode mode, const std::string& name); 97 98 DatabaseThread(const DatabaseThread& dt, DatabasePager* pager); 99 100 void setDone(bool done) { _done = done; } 101 bool getDone() const { return _done; } 102 103 virtual int cancel(); 104 105 virtual void run(); 106 107 protected: 108 109 virtual ~DatabaseThread(); 110 111 bool _done; 112 DatabasePager* _pager; 113 Mode _mode; 114 std::string _name; 115 }; 116 117 DatabaseThread* getDatabaseThread(unsigned int i) { return _databaseThreads[i].get(); } 118 119 const DatabaseThread* getDatabaseThread(unsigned int i) const { return _databaseThreads[i].get(); } 120 121 unsigned int getNumDatabaseThreads() const { return _databaseThreads.size(); } 79 122 80 123 /** Set whether the database pager thread should be paused or not.*/ … … 233 276 234 277 /** Report how many items are in the _fileRequestList queue */ 235 unsigned int getFileRequestListSize() const { return _fileRequest List.size(); }278 unsigned int getFileRequestListSize() const { return _fileRequestQueue._requestList.size() + _httpRequestQueue._requestList.size(); } 236 279 237 280 /** Report how many items are in the _dataToCompileList queue */ … … 264 307 virtual ~DatabasePager(); 265 308 309 friend class DatabaseThread; 310 266 311 267 312 friend struct DatabaseRequest; … … 270 315 { 271 316 DatabaseRequest(): 317 osg::Referenced(true), 318 _frameNumberFirstRequest(0), 319 _timestampFirstRequest(0.0), 320 _priorityFirstRequest(0.f), 321 _frameNumberLastRequest(0), 322 _timestampLastRequest(0.0), 323 _priorityLastRequest(0.0f), 272 324 _numOfRequests(0) 273 325 {} … … 291 343 } 292 344 }; 293 294 typedef std::vector< osg::ref_ptr<DatabaseRequest> > DatabaseRequestList; 345 346 typedef std::vector< osg::ref_ptr<DatabaseThread> > DatabaseThreadList; 347 typedef std::list< osg::ref_ptr<DatabaseRequest> > DatabaseRequestList; 295 348 typedef std::vector< osg::ref_ptr<osg::Object> > ObjectList; 349 350 struct RequestQueue : public osg::Referenced 351 { 352 RequestQueue(DatabasePager* pager, const std::string& name); 353 354 void block() { _block->block(); } 355 356 void release() { _block->release(); } 357 358 void updateBlock() 359 { 360 _block->set((!_requestList.empty() || !_childrenToDeleteList.empty()) && 361 !_pager->_databasePagerThreadPaused); 362 } 363 364 void clear(); 365 366 void add(DatabaseRequest* databaseRequest); 367 368 void takeFirst(osg::ref_ptr<DatabaseRequest>& databaseRequest); 369 370 osg::ref_ptr<osg::RefBlock> _block; 371 372 DatabasePager* _pager; 373 std::string _name; 374 375 OpenThreads::Mutex _requestMutex; 376 DatabaseRequestList _requestList; 377 378 OpenThreads::Mutex _childrenToDeleteListMutex; 379 ObjectList _childrenToDeleteList; 380 }; 296 381 297 382 // forward declare inner helper classes … … 310 395 OpenThreads::Mutex _run_mutex; 311 396 bool _startThreadCalled; 312 313 314 osg::ref_ptr<osg::RefBlock> _databasePagerThreadBlock;315 316 inline void updateDatabasePagerThreadBlock()317 {318 _databasePagerThreadBlock->set(319 (!_fileRequestList.empty() || !_childrenToDeleteList.empty()) && !_databasePagerThreadPaused);320 }321 397 322 398 // Helper functions for determining if objects need to be … … 411 487 bool _databasePagerThreadPaused; 412 488 489 DatabaseThreadList _databaseThreads; 490 413 491 int _numFramesActive; 414 492 mutable OpenThreads::Mutex _numFramesActiveMutex; 415 493 int _frameNumber; 416 494 417 DatabaseRequestList _fileRequestList; 418 mutable OpenThreads::Mutex _fileRequestListMutex; 495 RequestQueue _fileRequestQueue; 496 RequestQueue _httpRequestQueue; 497 498 //DatabaseRequestList _fileRequestList; 499 //mutable OpenThreads::Mutex _fileRequestListMutex; 419 500 420 501 DatabaseRequestList _dataToCompileList; … … 429 510 430 511 bool _deleteRemovedSubgraphsInDatabaseThread; 431 ObjectList _childrenToDeleteList;432 mutable OpenThreads::Mutex _childrenToDeleteListMutex;512 //ObjectList _childrenToDeleteList; 513 //mutable OpenThreads::Mutex _childrenToDeleteListMutex; 433 514 434 515 DatabaseRequestList _dataToMergeList; … … 452 533 unsigned int _numTilesMerges; 453 534 454 455 535 struct CompileOperation : public osg::GraphicsOperation 456 536 { OpenSceneGraph/trunk/include/osgDB/ReaderWriter
r8322 r8325 91 91 Options(): 92 92 osg::Object(true), 93 _objectCacheHint(CACHE_ARCHIVES), 94 _asynchronousFileReadHint(false) {} 93 _objectCacheHint(CACHE_ARCHIVES) {} 95 94 96 95 Options(const std::string& str): 97 96 osg::Object(true), 98 97 _str(str), 99 _objectCacheHint(CACHE_ARCHIVES), 100 _asynchronousFileReadHint(false) {} 98 _objectCacheHint(CACHE_ARCHIVES) {} 101 99 102 100 Options(const Options& options,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): … … 104 102 _str(options._str), 105 103 _databasePaths(options._databasePaths), 106 _objectCacheHint(options._objectCacheHint), 107 _asynchronousFileReadHint(options._asynchronousFileReadHint) {} 104 _objectCacheHint(options._objectCacheHint) {} 108 105 109 106 META_Object(osgDB,Options); … … 130 127 /** Get whether the Registry::ObjectCache should be used by default.*/ 131 128 CacheHintOptions getObjectCacheHint() const { return _objectCacheHint; } 132 133 134 /** Set Asynchrnous file read hint.135 * This hint is used by plugins like the libcurl http reader plugin to inform them that136 * they should make an internal file read requests to their background threads to load files,137 * with the plugin returning immediately with a ReadResult::FILE_REQUESTED status. It is138 * assumed that calls will continue to be made to the plugin until the background threads139 * have read or failed to read the request file, at which point the return status which change140 * to FILE_LOADED and the objects will be returned.141 * Note, this facility is particular useful when using DatabasePager in conjunction with142 * internet based databases where file load latency is relatively high.*/143 void setAsynchronousFileReadHint(bool flag) { _asynchronousFileReadHint = flag; }144 145 /** Get Asynchrnous file read hint. */146 bool getAsynchronousFileReadHint() const { return _asynchronousFileReadHint; }147 129 148 130 … … 170 152 FilePathList _databasePaths; 171 153 CacheHintOptions _objectCacheHint; 172 bool _asynchronousFileReadHint;173 154 174 155 typedef std::map<std::string,void*> PluginDataMap; OpenSceneGraph/trunk/src/osg/PagedLOD.cpp
r7343 r8325 29 29 _priorityOffset(prd._priorityOffset), 30 30 _priorityScale(prd._priorityScale), 31 _timeStamp(prd._timeStamp) {} 31 _timeStamp(prd._timeStamp), 32 _databaseRequest(prd._databaseRequest) {} 32 33 33 34 PagedLOD::PerRangeData& PagedLOD::PerRangeData::operator = (const PerRangeData& prd) … … 38 39 _priorityScale = prd._priorityScale; 39 40 _timeStamp = prd._timeStamp; 41 _databaseRequest = prd._databaseRequest; 40 42 return *this; 41 43 } … … 189 191 if (_databasePath.empty()) 190 192 { 191 nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp() );193 nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp(), _perRangeDataList[numChildren]._databaseRequest); 192 194 } 193 195 else 194 196 { 195 197 // prepend the databasePath to the child's filename. 196 nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp() );198 nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp(), _perRangeDataList[numChildren]._databaseRequest); 197 199 } 198 200 } OpenSceneGraph/trunk/src/osg/ProxyNode.cpp
r7881 r8325 63 63 for(unsigned int i=_children.size(); i<_filenameList.size(); ++i) 64 64 { 65 nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_filenameList[i] , this, 1.0f, nv.getFrameStamp());65 nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_filenameList[i].first, this, 1.0f, nv.getFrameStamp(), _filenameList[i].second); 66 66 } 67 67 } OpenSceneGraph/trunk/src/osgDB/DatabasePager.cpp
r8322 r8325 1 1 #include <osgDB/DatabasePager> 2 2 #include <osgDB/ReadFile> 3 #include <osgDB/WriteFile> 3 4 #include <osgDB/FileNameUtils> 5 #include <osgDB/FileUtils> 4 6 5 7 #include <osg/Geode> … … 7 9 #include <osg/Texture> 8 10 #include <osg/Notify> 11 #include <osg/ProxyNode> 9 12 #include <osg/ApplicationUsage> 10 13 … … 81 84 } 82 85 83 DatabasePager::DatabasePager() 84 { 85 //osg::notify(osg::INFO)<<"Constructing DatabasePager()"<<std::endl; 86 87 _startThreadCalled = false; 88 89 _done = false; 90 _acceptNewRequests = true; 91 _databasePagerThreadPaused = false; 92 93 _numFramesActive = 0; 94 _frameNumber = 0; 95 _databasePagerThreadBlock = new osg::RefBlock; 96 97 const char* str = getenv("OSG_DATABASE_PAGER_PRIORITY"); 98 if (str) 99 { 100 if (strcmp(str,"DEFAULT")==0) 101 { 102 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_DEFAULT); 103 } 104 else if (strcmp(str,"MIN")==0) 105 { 106 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_MIN); 107 } 108 else if (strcmp(str,"LOW")==0) 109 { 110 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_LOW); 111 } 112 else if (strcmp(str,"NOMINAL")==0) 113 { 114 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_NOMINAL); 115 } 116 else if (strcmp(str,"HIGH")==0) 117 { 118 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_HIGH); 119 } 120 else if (strcmp(str,"MAX")==0) 121 { 122 setSchedulePriority(OpenThreads::Thread::THREAD_PRIORITY_MAX); 123 } 124 } 125 126 #if __APPLE__ 127 // OSX really doesn't like compiling display lists, and performs poorly when they are used, 128 // so apply this hack to make up for its short comings. 129 _drawablePolicy = USE_VERTEX_ARRAYS; 130 #else 131 _drawablePolicy = DO_NOT_MODIFY_DRAWABLE_SETTINGS; 132 #endif 133 134 str = getenv("OSG_DATABASE_PAGER_GEOMETRY"); 135 if (!str) str = getenv("OSG_DATABASE_PAGER_DRAWABLE"); 136 if (str) 137 { 138 if (strcmp(str,"DoNotModify")==0) 139 { 140 _drawablePolicy = DO_NOT_MODIFY_DRAWABLE_SETTINGS; 141 } 142 else if (strcmp(str,"DisplayList")==0 || strcmp(str,"DL")==0) 143 { 144 _drawablePolicy = USE_DISPLAY_LISTS; 145 } 146 else if (strcmp(str,"VBO")==0) 147 { 148 _drawablePolicy = USE_VERTEX_BUFFER_OBJECTS; 149 } 150 else if (strcmp(str,"VertexArrays")==0 || strcmp(str,"VA")==0 ) 151 { 152 _drawablePolicy = USE_VERTEX_ARRAYS; 153 } 154 } 155 156 _changeAutoUnRef = true; 157 _valueAutoUnRef = true; 158 _changeAnisotropy = false; 159 _valueAnisotropy = 1.0f; 160 161 162 163 const char* ptr=0; 164 165 _deleteRemovedSubgraphsInDatabaseThread = true; 166 if( (ptr = getenv("OSG_DELETE_IN_DATABASE_THREAD")) != 0) 167 { 168 _deleteRemovedSubgraphsInDatabaseThread = strcmp(ptr,"yes")==0 || strcmp(ptr,"YES")==0 || 169 strcmp(ptr,"on")==0 || strcmp(ptr,"ON")==0; 170 171 } 172 173 _expiryDelay = 10.0; 174 if( (ptr = getenv("OSG_EXPIRY_DELAY")) != 0) 175 { 176 _expiryDelay = atof(ptr); 177 osg::notify(osg::NOTICE)<<"Expiry delay = "<<_expiryDelay<<std::endl; 178 } 179 180 _doPreCompile = true; 181 if( (ptr = getenv("OSG_DO_PRE_COMPILE")) != 0) 182 { 183 _doPreCompile = strcmp(ptr,"yes")==0 || strcmp(ptr,"YES")==0 || 184 strcmp(ptr,"on")==0 || strcmp(ptr,"ON")==0; 185 } 186 187 _targetFrameRate = 100.0; 188 _minimumTimeAvailableForGLCompileAndDeletePerFrame = 0.001; // 1ms. 189 _maximumNumOfObjectsToCompilePerFrame = 4; 190 if( (ptr = getenv("OSG_MINIMUM_COMPILE_TIME_PER_FRAME")) != 0) 191 { 192 _minimumTimeAvailableForGLCompileAndDeletePerFrame = atof(ptr); 193 } 194 195 if( (ptr = getenv("OSG_MAXIMUM_OBJECTS_TO_COMPILE_PER_FRAME")) != 0) 196 { 197 _maximumNumOfObjectsToCompilePerFrame = atoi(ptr); 198 } 199 200 // initialize the stats variables 201 resetStats(); 202 203 // make sure a SharedStateManager exists. 204 //osgDB::Registry::instance()->getOrCreateSharedStateManager(); 205 206 //if (osgDB::Registry::instance()->getSharedStateManager()) 207 //osgDB::Registry::instance()->setUseObjectCacheHint(true); 208 } 209 210 DatabasePager::DatabasePager(const DatabasePager& rhs) 211 { 212 //osg::notify(osg::INFO)<<"Constructing DatabasePager(const DatabasePager& )"<<std::endl; 213 214 _startThreadCalled = false; 215 216 _done = false; 217 _acceptNewRequests = true; 218 _databasePagerThreadPaused = false; 219 220 _numFramesActive = 0; 221 _frameNumber = 0; 222 _databasePagerThreadBlock = new osg::RefBlock; 223 224 _drawablePolicy = rhs._drawablePolicy; 225 226 _changeAutoUnRef = rhs._changeAutoUnRef; 227 _valueAutoUnRef = rhs._valueAutoUnRef; 228 _changeAnisotropy = rhs._changeAnisotropy; 229 _valueAnisotropy = rhs._valueAnisotropy; 230 231 232 _deleteRemovedSubgraphsInDatabaseThread = rhs._deleteRemovedSubgraphsInDatabaseThread; 233 234 _expiryDelay = rhs._expiryDelay; 235 _doPreCompile = rhs._doPreCompile; 236 _targetFrameRate = rhs._targetFrameRate; 237 _minimumTimeAvailableForGLCompileAndDeletePerFrame = rhs._minimumTimeAvailableForGLCompileAndDeletePerFrame; 238 _maximumNumOfObjectsToCompilePerFrame = rhs._maximumNumOfObjectsToCompilePerFrame; 239 240 // initialize the stats variables 241 resetStats(); 242 } 243 244 245 DatabasePager::~DatabasePager() 246 { 247 cancel(); 248 } 249 250 osg::ref_ptr<DatabasePager>& DatabasePager::prototype() 251 { 252 static osg::ref_ptr<DatabasePager> s_DatabasePager = new DatabasePager; 253 return s_DatabasePager; 254 } 255 256 DatabasePager* DatabasePager::create() 257 { 258 return DatabasePager::prototype().valid() ? 259 DatabasePager::prototype()->clone() : 260 new DatabasePager; 261 } 262 263 264 int DatabasePager::cancel() 265 { 266 int result = 0; 267 if( isRunning() ) 268 { 269 270 _done = true; 271 272 // cancel the thread.. 273 // result = Thread::cancel(); 274 //join(); 275 276 // release the frameBlock and _databasePagerThreadBlock in case its holding up thread cancellation. 277 _databasePagerThreadBlock->release(); 278 279 // then wait for the the thread to stop running. 280 while(isRunning()) 281 { 282 // commenting out debug info as it was cashing crash on exit, presumable 283 // due to osg::notify or std::cout destructing earlier than this destructor. 284 // osg::notify(osg::DEBUG_INFO)<<"Waiting for DatabasePager to cancel"<<std::endl; 285 OpenThreads::Thread::YieldCurrentThread(); 286 } 287 288 _startThreadCalled = false; 289 } 290 //std::cout<<"DatabasePager::~DatabasePager() stopped running"<<std::endl; 291 return result; 292 } 293 294 void DatabasePager::clear() 295 { 296 { 297 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex); 298 _fileRequestList.clear(); 299 } 300 301 { 302 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex); 303 _dataToCompileList.clear(); 304 } 305 306 { 307 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_childrenToDeleteListMutex); 308 _childrenToDeleteList.clear(); 309 } 310 311 { 312 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex); 313 _dataToMergeList.clear(); 314 } 315 316 // note, no need to use a mutex as the list is only accessed from the update thread. 317 _pagedLODList.clear(); 318 319 // ?? 320 // _activeGraphicsContexts 321 } 322 323 void DatabasePager::resetStats() 324 { 325 // initialize the stats variables 326 _minimumTimeToMergeTile = DBL_MAX; 327 _maximumTimeToMergeTile = -DBL_MAX; 328 _totalTimeToMergeTiles = 0.0; 329 _numTilesMerges = 0; 330 } 331 332 void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* group, 333 float priority, const osg::FrameStamp* framestamp) 334 { 335 requestNodeFile(fileName,group,priority,framestamp,Registry::instance()->getOptions()); 336 } 337 338 void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* group, 339 float priority, const osg::FrameStamp* framestamp, 340 ReaderWriter::Options* loadOptions) 341 { 342 if (!_acceptNewRequests) return; 343 344 double timestamp = framestamp?framestamp->getReferenceTime():0.0; 345 int frameNumber = framestamp?framestamp->getFrameNumber():_frameNumber; 346 347 // search to see if filename already exist in the file loaded list. 348 bool foundEntry = false; 349 350 { 351 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex); 352 353 for(DatabaseRequestList::iterator litr = _dataToCompileList.begin(); 354 litr != _dataToCompileList.end() && !foundEntry; 355 ++litr) 356 { 357 if ((*litr)->_fileName==fileName) 358 { 359 foundEntry = true; 360 (*litr)->_frameNumberLastRequest = frameNumber; 361 (*litr)->_timestampLastRequest = timestamp; 362 (*litr)->_priorityLastRequest = priority; 363 ++((*litr)->_numOfRequests); 364 } 365 } 366 367 } 368 369 if (!foundEntry) 370 { 371 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex); 372 373 for(DatabaseRequestList::iterator litr = _dataToMergeList.begin(); 374 litr != _dataToMergeList.end() && !foundEntry; 375 ++litr) 376 { 377 if ((*litr)->_fileName==fileName) 378 { 379 foundEntry = true; 380 (*litr)->_frameNumberLastRequest = frameNumber; 381 (*litr)->_timestampLastRequest = timestamp; 382 (*litr)->_priorityLastRequest = priority; 383 ++((*litr)->_numOfRequests); 384 } 385 } 386 } 387 388 if (!foundEntry) 389 { 390 391 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex); 392 393 // search to see if entry already in file request list. 394 bool foundEntry = false; 395 for(DatabaseRequestList::iterator ritr = _fileRequestList.begin(); 396 ritr != _fileRequestList.end() && !foundEntry; 397 ++ritr) 398 { 399 if ((*ritr)->_fileName==fileName) 400 { 401 foundEntry = true; 402 (*ritr)->_timestampLastRequest = timestamp; 403 (*ritr)->_priorityLastRequest = priority; 404 (*ritr)->_frameNumberLastRequest = frameNumber; 405 ++((*ritr)->_numOfRequests); 406 } 407 } 408 409 if (!foundEntry) 410 { 411 osg::notify(osg::INFO)<<"In DatabasePager::fileRquest("<<fileName<<")"<<std::endl; 412 413 osg::ref_ptr<DatabaseRequest> databaseRequest = new DatabaseRequest; 414 415 databaseRequest->_fileName = fileName; 416 databaseRequest->_frameNumberFirstRequest = frameNumber; 417 databaseRequest->_timestampFirstRequest = timestamp; 418 databaseRequest->_priorityFirstRequest = priority; 419 databaseRequest->_frameNumberLastRequest = frameNumber; 420 databaseRequest->_timestampLastRequest = timestamp; 421 databaseRequest->_priorityLastRequest = priority; 422 databaseRequest->_groupForAddingLoadedSubgraph = group; 423 424 if ((Registry::instance()->getOptions()==loadOptions) && 425 (loadOptions ? !loadOptions->getAsynchronousFileReadHint() : true) && 426 osgDB::containsServerAddress(fileName)) 427 { 428 // we need to enable asynchronous file reading. 429 databaseRequest->_loadOptions = loadOptions ? 430 dynamic_cast<osgDB::ReaderWriter::Options*>(loadOptions->clone(osg::CopyOp::SHALLOW_COPY)) : 431 new osgDB::ReaderWriter::Options; 432 433 databaseRequest->_loadOptions->setAsynchronousFileReadHint(true); 434 } 435 else 436 { 437 databaseRequest->_loadOptions = loadOptions; 438 } 439 440 _fileRequestList.push_back(databaseRequest); 441 442 updateDatabasePagerThreadBlock(); 443 } 444 } 445 446 if (!isRunning()) 447 { 448 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_run_mutex); 449 450 if (!_startThreadCalled) 451 { 452 _startThreadCalled = true; 453 _done = false; 454 osg::notify(osg::DEBUG_INFO)<<"DatabasePager::startThread()"<<std::endl; 455 startThread(); 456 } 457 } 458 } 459 460 void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp) 461 { 462 if (framestamp) 463 { 464 //osg::notify(osg::INFO) << "signalBeginFrame "<<framestamp->getFrameNumber()<<">>>>>>>>>>>>>>>>"<<std::endl; 465 _frameNumber = framestamp->getFrameNumber(); 466 467 } //else osg::notify(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<<std::endl; 468 } 469 470 void DatabasePager::signalEndFrame() 471 { 472 //osg::notify(osg::INFO) << "signalEndFrame <<<<<<<<<<<<<<<<<<<< "<<std::endl; 473 } 474 86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 87 // 88 // SortFileRequestFunctor 89 // 90 struct DatabasePager::SortFileRequestFunctor 91 { 92 bool operator() (const osg::ref_ptr<DatabasePager::DatabaseRequest>& lhs,const osg::ref_ptr<DatabasePager::DatabaseRequest>& rhs) const 93 { 94 if (lhs->_timestampLastRequest>rhs->_timestampLastRequest) return true; 95 else if (lhs->_timestampLastRequest<rhs->_timestampLastRequest) return false; 96 else return (lhs->_priorityLastRequest>rhs->_priorityLastRequest); 97 } 98 }; 99 100 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 101 // 102 // FindCompileableGLObjectsVisitor 103 // 475 104 class DatabasePager::FindCompileableGLObjectsVisitor : public osg::NodeVisitor 476 105 { … … 608 237 609 238 610 struct DatabasePager::SortFileRequestFunctor 611 { 612 bool operator() (const osg::ref_ptr<DatabasePager::DatabaseRequest>& lhs,const osg::ref_ptr<DatabasePager::DatabaseRequest>& rhs) const 613 { 614 if (lhs->_timestampLastRequest>rhs->_timestampLastRequest) return true; 615 else if (lhs->_timestampLastRequest<rhs->_timestampLastRequest) return false; 616 else return (lhs->_priorityLastRequest>rhs->_priorityLastRequest); 617 } 618 }; 619 620 621 void DatabasePager::setDatabasePagerThreadPause(bool pause) 622 { 623 _databasePagerThreadPaused = pause; 624 updateDatabasePagerThreadBlock(); 625 } 626 627 void DatabasePager::run() 628 { 629 osg::notify(osg::INFO)<<"DatabasePager::run()"<<std::endl; 630 239 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 240 // 241 // RequestQueue 242 // 243 DatabasePager::RequestQueue::RequestQueue(DatabasePager* pager, const std::string& name): 244 _pager(pager), 245 _name(name) 246 { 247 _block = new osg::RefBlock; 248 } 249 250 void DatabasePager::RequestQueue::clear() 251 { 252 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_requestMutex); 253 _requestList.clear(); 254 255 updateBlock(); 256 } 257 258 void DatabasePager::RequestQueue::add(DatabasePager::DatabaseRequest* databaseRequest) 259 { 260 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_requestMutex); 261 _requestList.push_back(databaseRequest); 262 263 updateBlock(); 264 } 265 266 void DatabasePager::RequestQueue::takeFirst(osg::ref_ptr<DatabaseRequest>& databaseRequest) 267 { 268 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_requestMutex); 269 270 if (!_requestList.empty()) 271 { 272 _requestList.sort(SortFileRequestFunctor()); 273 databaseRequest = _requestList.front(); 274 _requestList.erase(_requestList.begin()); 275 } 276 } 277 278 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// 279 // 280 // DatabaseThread 281 // 282 DatabasePager::DatabaseThread::DatabaseThread(DatabasePager* pager, Mode mode, const std::string& name): 283 _done(false), 284 _pager(pager), 285 _mode(mode), 286 _name(name) 287 { 288 } 289 290 DatabasePager::DatabaseThread::DatabaseThread(const DatabaseThread& dt, DatabasePager* pager): 291 _done(false), 292 _pager(pager), 293 _mode(dt._mode), 294 _name(dt._name) 295 { 296 297 } 298 299 DatabasePager::DatabaseThread::~DatabaseThread() 300 { 301 cancel(); 302 } 303 304 int DatabasePager::DatabaseThread::cancel() 305 { 306 int result = 0; 307 308 if( isRunning() ) 309 { 310 311 _done = true; 312 313 // release the frameBlock and _databasePagerThreadBlock in case its holding up thread cancellation. 314 // _databasePagerThreadBlock->release(); 315 316 // then wait for the the thread to stop running. 317 while(isRunning()) 318 { 319 // commenting out debug info as it was cashing crash on exit, presumable 320 // due to osg::notify or std::cout destructing earlier than this destructor. 321 // osg::notify(osg::DEBUG_INFO)<<"Waiting for DatabasePager to cancel"<&l
