You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.4 KiB
175 lines
5.4 KiB
/* -*-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 <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 _imageThreads.size(); } |
|
|
|
|
|
void setPreLoadTime(double preLoadTime) { _preLoadTime=preLoadTime; } |
|
virtual double getPreLoadTime() const { return _preLoadTime; } |
|
|
|
virtual osg::Image* readImageFile(const std::string& fileName); |
|
|
|
virtual void requestImageFile(const std::string& fileName,osg::Object* attachmentPoint, int attachmentIndex, double timeToMergeBy, const osg::FrameStamp* framestamp); |
|
|
|
|
|
/** 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); |
|
|
|
int cancel(); |
|
|
|
protected: |
|
|
|
virtual ~ImagePager(); |
|
// forward declare |
|
struct RequestQueue; |
|
|
|
struct SortFileRequestFunctor; |
|
friend struct SortFileRequestFunctor; |
|
|
|
struct ImageRequest : public osg::Referenced |
|
{ |
|
ImageRequest(): |
|
osg::Referenced(true), |
|
_timeToMergeBy(0.0), |
|
_attachmentIndex(-1) {} |
|
|
|
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; |
|
|
|
}; |
|
|
|
struct RequestQueue : public osg::Referenced |
|
{ |
|
typedef std::vector< osg::ref_ptr<ImageRequest> > RequestList; |
|
|
|
void sort(); |
|
|
|
RequestList _requestList; |
|
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; |
|
|
|
osg::ref_ptr<ReadQueue> _readQueue; |
|
|
|
typedef std::vector< osg::ref_ptr<ImageThread> > ImageThreads; |
|
ImageThreads _imageThreads; |
|
|
|
osg::ref_ptr<RequestQueue> _completedQueue; |
|
|
|
double _preLoadTime; |
|
}; |
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|