ImagePager 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGDB_IMAGEPAGER
  14. #define OSGDB_IMAGEPAGER 1
  15. #include <osg/Image>
  16. #include <osg/NodeVisitor>
  17. #include <osg/observer_ptr>
  18. #include <osg/OperationThread>
  19. #include <osg/FrameStamp>
  20. #include <OpenThreads/Mutex>
  21. #include <OpenThreads/Atomic>
  22. #include <osgDB/ReaderWriter>
  23. #include <osgDB/Options>
  24. namespace osgDB
  25. {
  26. class OSGDB_EXPORT ImagePager : public osg::NodeVisitor::ImageRequestHandler
  27. {
  28. public:
  29. ImagePager();
  30. class OSGDB_EXPORT ImageThread : public osg::Referenced, public OpenThreads::Thread
  31. {
  32. public:
  33. enum Mode
  34. {
  35. HANDLE_ALL_REQUESTS,
  36. HANDLE_NON_HTTP,
  37. HANDLE_ONLY_HTTP
  38. };
  39. ImageThread(ImagePager* pager, Mode mode, const std::string& name);
  40. ImageThread(const ImageThread& dt, ImagePager* pager);
  41. void setDone(bool done) { _done = done; }
  42. bool getDone() const { return _done; }
  43. virtual int cancel();
  44. virtual void run();
  45. protected:
  46. virtual ~ImageThread();
  47. bool _done;
  48. Mode _mode;
  49. ImagePager* _pager;
  50. std::string _name;
  51. };
  52. ImageThread* getImageThread(unsigned int i) { return _imageThreads[i].get(); }
  53. const ImageThread* getImageThread(unsigned int i) const { return _imageThreads[i].get(); }
  54. unsigned int getNumImageThreads() const { return static_cast<unsigned int>(_imageThreads.size()); }
  55. void setPreLoadTime(double preLoadTime) { _preLoadTime=preLoadTime; }
  56. virtual double getPreLoadTime() const { return _preLoadTime; }
  57. virtual osg::ref_ptr<osg::Image> readRefImageFile(const std::string& fileName, const osg::Referenced* options=0);
  58. virtual void requestImageFile(const std::string& fileName, osg::Object* attachmentPoint, int attachmentIndex, double timeToMergeBy, const osg::FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& imageRequest, const osg::Referenced* options);
  59. /** Return true if there are pending updates to the scene graph that require a call to updateSceneGraph(double). */
  60. virtual bool requiresUpdateSceneGraph() const;
  61. /** Merge the changes to the scene graph. */
  62. virtual void updateSceneGraph(const osg::FrameStamp &frameStamp);
  63. /** Signal the image thread that the update, cull and draw has begun for a new frame.
  64. * Note, this is called by the application so that the image pager can go to sleep while the CPU is busy on the main rendering threads. */
  65. virtual void signalBeginFrame(const osg::FrameStamp* framestamp);
  66. /** Signal the image thread that the update, cull and draw dispatch has completed.
  67. * Note, this is called by the application so that the image pager can go to wake back up now the main rendering threads are iddle waiting for the next frame.*/
  68. virtual void signalEndFrame();
  69. int cancel();
  70. protected:
  71. virtual ~ImagePager();
  72. // forward declare
  73. struct RequestQueue;
  74. struct SortFileRequestFunctor;
  75. friend struct SortFileRequestFunctor;
  76. struct ImageRequest : public osg::Referenced
  77. {
  78. ImageRequest():
  79. osg::Referenced(true),
  80. _frameNumber(0),
  81. _timeToMergeBy(0.0),
  82. _attachmentIndex(-1),
  83. _requestQueue(0) {}
  84. unsigned int _frameNumber;
  85. double _timeToMergeBy;
  86. std::string _fileName;
  87. osg::ref_ptr<Options> _loadOptions;
  88. osg::observer_ptr<osg::Object> _attachmentPoint;
  89. int _attachmentIndex;
  90. osg::ref_ptr<osg::Image> _loadedImage;
  91. RequestQueue* _requestQueue;
  92. osg::ref_ptr<osgDB::Options> _readOptions;
  93. };
  94. struct RequestQueue : public osg::Referenced
  95. {
  96. typedef std::vector< osg::ref_ptr<ImageRequest> > RequestList;
  97. void sort();
  98. unsigned int size() const;
  99. RequestList _requestList;
  100. mutable OpenThreads::Mutex _requestMutex;
  101. };
  102. struct ReadQueue : public RequestQueue
  103. {
  104. ReadQueue(ImagePager* pager, const std::string& name);
  105. void block() { _block->block(); }
  106. void release() { _block->release(); }
  107. void updateBlock()
  108. {
  109. _block->set((!_requestList.empty() && !_pager->_databasePagerThreadPaused));
  110. }
  111. void clear();
  112. void add(ImageRequest* imageRequest);
  113. void takeFirst(osg::ref_ptr<ImageRequest>& databaseRequest);
  114. osg::ref_ptr<osg::RefBlock> _block;
  115. ImagePager* _pager;
  116. std::string _name;
  117. };
  118. OpenThreads::Mutex _run_mutex;
  119. bool _startThreadCalled;
  120. bool _done;
  121. bool _databasePagerThreadPaused;
  122. OpenThreads::Atomic _frameNumber;
  123. OpenThreads::Mutex _ir_mutex;
  124. osg::ref_ptr<ReadQueue> _readQueue;
  125. typedef std::vector< osg::ref_ptr<ImageThread> > ImageThreads;
  126. ImageThreads _imageThreads;
  127. osg::ref_ptr<RequestQueue> _completedQueue;
  128. double _preLoadTime;
  129. };
  130. }
  131. #endif