123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSGDB_IMAGEPAGER
- #define OSGDB_IMAGEPAGER 1
- #include <osg/Image>
- #include <osg/NodeVisitor>
- #include <osg/observer_ptr>
- #include <osg/OperationThread>
- #include <osg/FrameStamp>
- #include <OpenThreads/Mutex>
- #include <OpenThreads/Atomic>
- #include <osgDB/ReaderWriter>
- #include <osgDB/Options>
- namespace osgDB
- {
- class OSGDB_EXPORT ImagePager : public osg::NodeVisitor::ImageRequestHandler
- {
- public:
- ImagePager();
- class OSGDB_EXPORT ImageThread : public osg::Referenced, public OpenThreads::Thread
- {
- public:
- enum Mode
- {
- HANDLE_ALL_REQUESTS,
- HANDLE_NON_HTTP,
- HANDLE_ONLY_HTTP
- };
- ImageThread(ImagePager* pager, Mode mode, const std::string& name);
- ImageThread(const ImageThread& dt, ImagePager* pager);
- void setDone(bool done) { _done = done; }
- bool getDone() const { return _done; }
- virtual int cancel();
- virtual void run();
- protected:
- virtual ~ImageThread();
- bool _done;
- Mode _mode;
- ImagePager* _pager;
- std::string _name;
- };
- ImageThread* getImageThread(unsigned int i) { return _imageThreads[i].get(); }
- const ImageThread* getImageThread(unsigned int i) const { return _imageThreads[i].get(); }
- unsigned int getNumImageThreads() const { return static_cast<unsigned int>(_imageThreads.size()); }
- void setPreLoadTime(double preLoadTime) { _preLoadTime=preLoadTime; }
- virtual double getPreLoadTime() const { return _preLoadTime; }
- virtual osg::ref_ptr<osg::Image> readRefImageFile(const std::string& fileName, const osg::Referenced* options=0);
- 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);
- /** Return true if there are pending updates to the scene graph that require a call to updateSceneGraph(double). */
- virtual bool requiresUpdateSceneGraph() const;
- /** Merge the changes to the scene graph. */
- virtual void updateSceneGraph(const osg::FrameStamp &frameStamp);
- /** Signal the image thread that the update, cull and draw has begun for a new frame.
- * 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. */
- virtual void signalBeginFrame(const osg::FrameStamp* framestamp);
- /** Signal the image thread that the update, cull and draw dispatch has completed.
- * 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.*/
- virtual void signalEndFrame();
- int cancel();
- protected:
- virtual ~ImagePager();
- // forward declare
- struct RequestQueue;
- struct SortFileRequestFunctor;
- friend struct SortFileRequestFunctor;
- struct ImageRequest : public osg::Referenced
- {
- ImageRequest():
- osg::Referenced(true),
- _frameNumber(0),
- _timeToMergeBy(0.0),
- _attachmentIndex(-1),
- _requestQueue(0) {}
- unsigned int _frameNumber;
- double _timeToMergeBy;
- std::string _fileName;
- osg::ref_ptr<Options> _loadOptions;
- osg::observer_ptr<osg::Object> _attachmentPoint;
- int _attachmentIndex;
- osg::ref_ptr<osg::Image> _loadedImage;
- RequestQueue* _requestQueue;
- osg::ref_ptr<osgDB::Options> _readOptions;
- };
- struct RequestQueue : public osg::Referenced
- {
- typedef std::vector< osg::ref_ptr<ImageRequest> > RequestList;
- void sort();
- unsigned int size() const;
- RequestList _requestList;
- mutable OpenThreads::Mutex _requestMutex;
- };
- struct ReadQueue : public RequestQueue
- {
- ReadQueue(ImagePager* pager, const std::string& name);
- void block() { _block->block(); }
- void release() { _block->release(); }
- void updateBlock()
- {
- _block->set((!_requestList.empty() && !_pager->_databasePagerThreadPaused));
- }
- void clear();
- void add(ImageRequest* imageRequest);
- void takeFirst(osg::ref_ptr<ImageRequest>& databaseRequest);
- osg::ref_ptr<osg::RefBlock> _block;
- ImagePager* _pager;
- std::string _name;
- };
- OpenThreads::Mutex _run_mutex;
- bool _startThreadCalled;
- bool _done;
- bool _databasePagerThreadPaused;
- OpenThreads::Atomic _frameNumber;
- OpenThreads::Mutex _ir_mutex;
- osg::ref_ptr<ReadQueue> _readQueue;
- typedef std::vector< osg::ref_ptr<ImageThread> > ImageThreads;
- ImageThreads _imageThreads;
- osg::ref_ptr<RequestQueue> _completedQueue;
- double _preLoadTime;
- };
- }
- #endif
|