diff --git a/include/osg/GraphicsThread b/include/osg/GraphicsThread index 95ad33dbe..ff976d30d 100644 --- a/include/osg/GraphicsThread +++ b/include/osg/GraphicsThread @@ -14,153 +14,10 @@ #ifndef OSG_GRAPHICSTHREAD #define OSG_GRAPHICSTHREAD 1 -#include -#include - -#include -#include -#include -#include - -#include +#include namespace osg { -class RefBlock: virtual public osg::Referenced, public OpenThreads::Block -{ - public: - - RefBlock() {} - -}; - -/** Base class for implementing graphics operations.*/ -class Operation : virtual public Referenced -{ - public: - Operation(const std::string& name, bool keep): - _name(name), - _keep(keep) {} - - - /** Set the human readable name of the operation.*/ - void setName(const std::string& name) { _name = name; } - - /** Get the human readable name of the operation.*/ - const std::string& getName() const { return _name; } - - /** Set whether the operation should be kept once its been applied.*/ - void setKeep(bool keep) { _keep = keep; } - - /** Get whether the operation should be kept once its been applied.*/ - bool getKeep() const { return _keep; } - - /** if this operation is a barrier then release it.*/ - virtual void release() {} - - /** Do the actual task of this operation.*/ - virtual void operator () (Object*) = 0; - - protected: - - virtual ~Operation() {} - - std::string _name; - bool _keep; -}; - -class OSG_EXPORT OperationQueue : public Referenced -{ - public: - - OperationQueue(); - - RefBlock* getOperationsBlock() { return _operationsBlock.get(); } - - const RefBlock* getOperationsBlock() const { return _operationsBlock.get(); } - - /** Add operation to end of OperationQueue, this will be - * executed by the operation thread once this operation gets to the head of the queue.*/ - void add(Operation* operation); - - /** Remove operation from OperationQueue.*/ - void remove(Operation* operation); - - /** Remove named operation from OperationQueue.*/ - void remove(const std::string& name); - - /** Remove all operations from OperationQueue.*/ - void removeAllOperations(); - - protected: - - virtual ~OperationQueue(); - - typedef std::list< ref_ptr > Operations; - - OpenThreads::Mutex _operationsMutex; - osg::ref_ptr _operationsBlock; - Operations _operations; - -}; - -/** GraphicsThread is a helper class for running OpenGL GraphicsOperation within a single thread assigned to a specific GraphicsContext.*/ -class OSG_EXPORT OperationsThread : public Referenced, public OpenThreads::Thread -{ - public: - OperationsThread(); - - void setParent(Object* parent) { _parent = parent; } - - Object* getParent() { return _parent.get(); } - - const Object* getParent() const { return _parent.get(); } - - - /** Add operation to end of OperationQueue, this will be - * executed by the graphics thread once this operation gets to the head of the queue.*/ - void add(Operation* operation, bool waitForCompletion=false); - - /** Remove operation from OperationQueue.*/ - void remove(Operation* operation); - - /** Remove named operation from OperationQueue.*/ - void remove(const std::string& name); - - /** Remove all operations from OperationQueue.*/ - void removeAllOperations(); - - /** Get the operation currently being run.*/ - osg::ref_ptr getCurrentOperation() { return _currentOperation; } - - /** Run does the graphics thread run loop.*/ - virtual void run(); - - void setDone(bool done); - - bool getDone() const { return _done; } - - /** Cancel this graphics thread.*/ - virtual int cancel(); - - protected: - - virtual ~OperationsThread(); - - observer_ptr _parent; - - typedef std::list< ref_ptr > Operations; - - bool _done; - - OpenThreads::Mutex _operationsMutex; - osg::ref_ptr _operationsBlock; - Operations _operations; - osg::ref_ptr _currentOperation; - -}; - - /** SwapBufferOperation calls swap buffers on the GraphicsContext.*/ struct OSG_EXPORT SwapBuffersOperation : public Operation { @@ -204,6 +61,15 @@ struct OSG_EXPORT ReleaseContext_Block_MakeCurrentOperation : public Operation, virtual void operator () (Object* context); }; +struct OSG_EXPORT BlockAndFlushOperation : public Operation, public OpenThreads::Block +{ + BlockAndFlushOperation(); + + virtual void release(); + + virtual void operator () (Object*); +}; + } #endif diff --git a/include/osg/OperationsThread b/include/osg/OperationsThread new file mode 100644 index 000000000..2df1a9324 --- /dev/null +++ b/include/osg/OperationsThread @@ -0,0 +1,173 @@ +/* -*-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 OSG_OPERATIONSTHREAD +#define OSG_OPERATIONSTHREAD 1 + +#include +#include + +#include +#include +#include +#include + +#include + +namespace osg { + +class RefBlock: virtual public osg::Referenced, public OpenThreads::Block +{ + public: + + RefBlock() {} + +}; + +/** Base class for implementing graphics operations.*/ +class Operation : virtual public Referenced +{ + public: + Operation(const std::string& name, bool keep): + _name(name), + _keep(keep) {} + + + /** Set the human readable name of the operation.*/ + void setName(const std::string& name) { _name = name; } + + /** Get the human readable name of the operation.*/ + const std::string& getName() const { return _name; } + + /** Set whether the operation should be kept once its been applied.*/ + void setKeep(bool keep) { _keep = keep; } + + /** Get whether the operation should be kept once its been applied.*/ + bool getKeep() const { return _keep; } + + /** if this operation is a barrier then release it.*/ + virtual void release() {} + + /** Do the actual task of this operation.*/ + virtual void operator () (Object*) = 0; + + protected: + + virtual ~Operation() {} + + std::string _name; + bool _keep; +}; + +class OSG_EXPORT OperationQueue : public Referenced +{ + public: + + OperationQueue(); + + RefBlock* getOperationsBlock() { return _operationsBlock.get(); } + + const RefBlock* getOperationsBlock() const { return _operationsBlock.get(); } + + /** Get the next operation from the operation queue. + * Return null ref_ptr<> if no operations are left in queue. */ + osg::ref_ptr getNextOperation(); + + /** Add operation to end of OperationQueue, this will be + * executed by the operation thread once this operation gets to the head of the queue.*/ + void add(Operation* operation); + + /** Remove operation from OperationQueue.*/ + void remove(Operation* operation); + + /** Remove named operation from OperationQueue.*/ + void remove(const std::string& name); + + /** Remove all operations from OperationQueue.*/ + void removeAllOperations(); + + /** Call release on all operations. */ + void releaseAllOperations(); + + protected: + + virtual ~OperationQueue(); + + typedef std::list< ref_ptr > Operations; + + OpenThreads::Mutex _operationsMutex; + osg::ref_ptr _operationsBlock; + Operations _operations; + Operations::iterator _currentOperationIterator; + +}; + +/** GraphicsThread is a helper class for running OpenGL GraphicsOperation within a single thread assigned to a specific GraphicsContext.*/ +class OSG_EXPORT OperationsThread : public Referenced, public OpenThreads::Thread +{ + public: + OperationsThread(); + + void setParent(Object* parent) { _parent = parent; } + + Object* getParent() { return _parent.get(); } + + const Object* getParent() const { return _parent.get(); } + + + /** Add operation to end of OperationQueue, this will be + * executed by the graphics thread once this operation gets to the head of the queue.*/ + void add(Operation* operation); + + /** Remove operation from OperationQueue.*/ + void remove(Operation* operation); + + /** Remove named operation from OperationQueue.*/ + void remove(const std::string& name); + + /** Remove all operations from OperationQueue.*/ + void removeAllOperations(); + + /** Get the operation currently being run.*/ + osg::ref_ptr getCurrentOperation() { return _currentOperation; } + + /** Run does the graphics thread run loop.*/ + virtual void run(); + + void setDone(bool done); + + bool getDone() const { return _done; } + + /** Cancel this graphics thread.*/ + virtual int cancel(); + + protected: + + virtual ~OperationsThread(); + + observer_ptr _parent; + + typedef std::list< ref_ptr > Operations; + + bool _done; + + OpenThreads::Mutex _operationsMutex; + osg::ref_ptr _operationsBlock; + Operations _operations; + osg::ref_ptr _currentOperation; + +}; + +} + +#endif diff --git a/include/osgParticle/range b/include/osgParticle/range index a6687d5ce..2984a9abf 100644 --- a/include/osgParticle/range +++ b/include/osgParticle/range @@ -18,18 +18,12 @@ // include Export simply to disable Visual Studio silly warnings. #include -#ifndef __sgi -#include -#else #include -#endif #include #include #include -//using std::rand; - namespace osgParticle { diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index c898d9a8e..da7eeed93 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -91,6 +91,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/Notify ${HEADER_PATH}/Object ${HEADER_PATH}/OccluderNode + ${HEADER_PATH}/OperationsThread ${HEADER_PATH}/PagedLOD ${HEADER_PATH}/Plane ${HEADER_PATH}/Point @@ -245,6 +246,7 @@ ADD_LIBRARY(${LIB_NAME} Notify.cpp Object.cpp OccluderNode.cpp + OperationsThread.cpp PagedLOD.cpp Point.cpp PointSprite.cpp diff --git a/src/osg/GraphicsThread.cpp b/src/osg/GraphicsThread.cpp index 1748ba269..c7dabc708 100644 --- a/src/osg/GraphicsThread.cpp +++ b/src/osg/GraphicsThread.cpp @@ -39,364 +39,6 @@ struct BlockOperation : public Operation, public Block } }; -///////////////////////////////////////////////////////////////////////////// -// -// OperationsQueue -// - -OperationQueue::OperationQueue() -{ -} - -OperationQueue::~OperationQueue() -{ -} - -void OperationQueue::add(Operation* operation) -{ - osg::notify(osg::INFO)<<"Doing add"< lock(_operationsMutex); - - // add the operation to the end of the list - _operations.push_back(operation); - - _operationsBlock->set(true); - } -} - -void OperationQueue::remove(Operation* operation) -{ - osg::notify(osg::INFO)<<"Doing remove operation"< lock(_operationsMutex); - - for(Operations::iterator itr = _operations.begin(); - itr!=_operations.end();) - { - if ((*itr)==operation) itr = _operations.erase(itr); - else ++itr; - } -} - -void OperationQueue::remove(const std::string& name) -{ - osg::notify(osg::INFO)<<"Doing remove named operation"< lock(_operationsMutex); - - // find the remove all operations with specificed name - for(Operations::iterator itr = _operations.begin(); - itr!=_operations.end();) - { - if ((*itr)->getName()==name) itr = _operations.erase(itr); - else ++itr; - } - - if (_operations.empty()) - { - _operationsBlock->set(false); - } -} - -void OperationQueue::removeAllOperations() -{ - osg::notify(osg::INFO)<<"Doing remove all operations"< lock(_operationsMutex); - _operations.clear(); - - if (_operations.empty()) - { - _operationsBlock->set(false); - } -} - - -///////////////////////////////////////////////////////////////////////////// -// -// OperationsThread -// - -OperationsThread::OperationsThread(): - _parent(0), - _done(false) -{ - _operationsBlock = new RefBlock; -} - -OperationsThread::~OperationsThread() -{ - //osg::notify(osg::NOTICE)<<"Destructing graphics thread "< lock(_operationsMutex); - if (_currentOperation.valid()) - { - osg::notify(osg::INFO)<<"releasing "<<_currentOperation.get()<release(); - } - } - - _operationsBlock->release(); - } - -} - -int OperationsThread::cancel() -{ - osg::notify(osg::INFO)<<"Cancelling OperationsThred "<release(); - } - - // release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation. - _operationsBlock->release(); - - // then wait for the the thread to stop running. - while(isRunning()) - { - _operationsBlock->release(); - - { - OpenThreads::ScopedLock lock(_operationsMutex); - - for(Operations::iterator itr = _operations.begin(); - itr != _operations.end(); - ++itr) - { - (*itr)->release(); - } - - if (_currentOperation.valid()) _currentOperation->release(); - } - - // commenting out debug info as it was cashing crash on exit, presumable - // due to osg::notify or std::cout destructing earlier than this destructor. - osg::notify(osg::INFO)<<" Waiting for OperationsThread to cancel "< block = 0; - - { - // aquire the lock on the operations queue to prevent anyone else for modifying it at the same time - OpenThreads::ScopedLock lock(_operationsMutex); - - // add the operation to the end of the list - _operations.push_back(operation); - - if (waitForCompletion) - { - block = new BlockOperation; - _operations.push_back(block.get()); - } - - _operationsBlock->set(true); - } - - if (block.valid()) - { - // now we wait till the barrier is joined by the graphics thread. - block->block(); - } -} - -void OperationsThread::remove(Operation* operation) -{ - osg::notify(osg::INFO)<<"Doing remove operation"< lock(_operationsMutex); - - for(Operations::iterator itr = _operations.begin(); - itr!=_operations.end();) - { - if ((*itr)==operation) itr = _operations.erase(itr); - else ++itr; - } -} - -void OperationsThread::remove(const std::string& name) -{ - osg::notify(osg::INFO)<<"Doing remove named operation"< lock(_operationsMutex); - - // find the remove all operations with specificed name - for(Operations::iterator itr = _operations.begin(); - itr!=_operations.end();) - { - if ((*itr)->getName()==name) itr = _operations.erase(itr); - else ++itr; - } - - if (_operations.empty()) - { - _operationsBlock->set(false); - } -} - -void OperationsThread::removeAllOperations() -{ - osg::notify(osg::INFO)<<"Doing remove all operations"< lock(_operationsMutex); - _operations.clear(); - - if (_operations.empty()) - { - _operationsBlock->set(false); - } -} - - -void OperationsThread::run() -{ - // make the graphics context current. - GraphicsContext* graphicsContext = dynamic_cast(_parent.get()); - if (graphicsContext) - { - graphicsContext->makeCurrent(); - } - - osg::notify(osg::INFO)<<"Doing run "<block(); - - // exit from loop if _done is set. - if (_done) break; - - itr = _operations.begin(); - } - else - { - if (itr == _operations.end()) itr = _operations.begin(); - } - - // osg::notify(osg::INFO)<<"get op "<<_done<<" "< lock(_operationsMutex); - if (!_operations.empty()) - { - // get the next item - _currentOperation = *itr; - - if (!_currentOperation->getKeep()) - { - // osg::notify(osg::INFO)<<"removing "<<_currentOperation->getName()<set(false); - } - } - else - { - // osg::notify(osg::INFO)<<"increment "<<_currentOperation->getName()<getName()<<" "< lock(_operationsMutex); - _currentOperation = 0; - } - } - - if (firstTime) - { - // do a yield to get round a peculiar thread hang when testCancel() is called - // in certain cirumstances - of which there is no particular pattern. - YieldCurrentThread(); - firstTime = false; - } - - // osg::notify(osg::NOTICE)<<"operations.size()="<<_operations.size()<<" done="<<_done<<" testCancel()"<releaseContext(); - } - - osg::notify(osg::INFO)<<"exit loop "< +#include +#include + +using namespace osg; +using namespace OpenThreads; + +struct BlockOperation : public Operation, public Block +{ + BlockOperation(): + Operation("Block",false) + { + reset(); + } + + virtual void release() + { + Block::release(); + } + + virtual void operator () (Object*) + { + glFlush(); + Block::release(); + } +}; + +///////////////////////////////////////////////////////////////////////////// +// +// OperationsQueue +// + +OperationQueue::OperationQueue() +{ + _currentOperationIterator = _operations.begin(); + _operationsBlock = new RefBlock; +} + +OperationQueue::~OperationQueue() +{ +} + +osg::ref_ptr OperationQueue::getNextOperation() +{ + return osg::ref_ptr(); +} + +void OperationQueue::add(Operation* operation) +{ + osg::notify(osg::INFO)<<"Doing add"< lock(_operationsMutex); + + // add the operation to the end of the list + _operations.push_back(operation); + + _operationsBlock->set(true); +} + +void OperationQueue::remove(Operation* operation) +{ + osg::notify(osg::INFO)<<"Doing remove operation"< lock(_operationsMutex); + + for(Operations::iterator itr = _operations.begin(); + itr!=_operations.end();) + { + if ((*itr)==operation) itr = _operations.erase(itr); + else ++itr; + } +} + +void OperationQueue::remove(const std::string& name) +{ + osg::notify(osg::INFO)<<"Doing remove named operation"< lock(_operationsMutex); + + // find the remove all operations with specificed name + for(Operations::iterator itr = _operations.begin(); + itr!=_operations.end();) + { + if ((*itr)->getName()==name) itr = _operations.erase(itr); + else ++itr; + } + + if (_operations.empty()) + { + _operationsBlock->set(false); + } +} + +void OperationQueue::removeAllOperations() +{ + osg::notify(osg::INFO)<<"Doing remove all operations"< lock(_operationsMutex); + _operations.clear(); + + if (_operations.empty()) + { + _operationsBlock->set(false); + } +} + +void OperationQueue::releaseAllOperations() +{ + OpenThreads::ScopedLock lock(_operationsMutex); + + for(Operations::iterator itr = _operations.begin(); + itr!=_operations.end(); + ++itr) + { + (*itr)->release(); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// +// OperationsThread +// + +OperationsThread::OperationsThread(): + _parent(0), + _done(false) +{ + _operationsBlock = new RefBlock; +} + +OperationsThread::~OperationsThread() +{ + //osg::notify(osg::NOTICE)<<"Destructing graphics thread "< lock(_operationsMutex); + if (_currentOperation.valid()) + { + osg::notify(osg::INFO)<<"releasing "<<_currentOperation.get()<release(); + } + } + + _operationsBlock->release(); + } + +} + +int OperationsThread::cancel() +{ + osg::notify(osg::INFO)<<"Cancelling OperationsThred "<release(); + } + + // release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation. + _operationsBlock->release(); + + // then wait for the the thread to stop running. + while(isRunning()) + { + _operationsBlock->release(); + + { + OpenThreads::ScopedLock lock(_operationsMutex); + + for(Operations::iterator itr = _operations.begin(); + itr != _operations.end(); + ++itr) + { + (*itr)->release(); + } + + if (_currentOperation.valid()) _currentOperation->release(); + } + + // commenting out debug info as it was cashing crash on exit, presumable + // due to osg::notify or std::cout destructing earlier than this destructor. + osg::notify(osg::INFO)<<" Waiting for OperationsThread to cancel "< lock(_operationsMutex); + + // add the operation to the end of the list + _operations.push_back(operation); + + _operationsBlock->set(true); +} + +void OperationsThread::remove(Operation* operation) +{ + osg::notify(osg::INFO)<<"Doing remove operation"< lock(_operationsMutex); + + for(Operations::iterator itr = _operations.begin(); + itr!=_operations.end();) + { + if ((*itr)==operation) itr = _operations.erase(itr); + else ++itr; + } +} + +void OperationsThread::remove(const std::string& name) +{ + osg::notify(osg::INFO)<<"Doing remove named operation"< lock(_operationsMutex); + + // find the remove all operations with specificed name + for(Operations::iterator itr = _operations.begin(); + itr!=_operations.end();) + { + if ((*itr)->getName()==name) itr = _operations.erase(itr); + else ++itr; + } + + if (_operations.empty()) + { + _operationsBlock->set(false); + } +} + +void OperationsThread::removeAllOperations() +{ + osg::notify(osg::INFO)<<"Doing remove all operations"< lock(_operationsMutex); + _operations.clear(); + + if (_operations.empty()) + { + _operationsBlock->set(false); + } +} + + +void OperationsThread::run() +{ + // make the graphics context current. + GraphicsContext* graphicsContext = dynamic_cast(_parent.get()); + if (graphicsContext) + { + graphicsContext->makeCurrent(); + } + + osg::notify(osg::INFO)<<"Doing run "<block(); + + // exit from loop if _done is set. + if (_done) break; + + itr = _operations.begin(); + } + else + { + if (itr == _operations.end()) itr = _operations.begin(); + } + + // osg::notify(osg::INFO)<<"get op "<<_done<<" "< lock(_operationsMutex); + if (!_operations.empty()) + { + // get the next item + _currentOperation = *itr; + + if (!_currentOperation->getKeep()) + { + // osg::notify(osg::INFO)<<"removing "<<_currentOperation->getName()<set(false); + } + } + else + { + // osg::notify(osg::INFO)<<"increment "<<_currentOperation->getName()<getName()<<" "< lock(_operationsMutex); + _currentOperation = 0; + } + } + + if (firstTime) + { + // do a yield to get round a peculiar thread hang when testCancel() is called + // in certain cirumstances - of which there is no particular pattern. + YieldCurrentThread(); + firstTime = false; + } + + // osg::notify(osg::NOTICE)<<"operations.size()="<<_operations.size()<<" done="<<_done<<" testCancel()"<releaseContext(); + } + + osg::notify(osg::INFO)<<"exit loop "<, getCurrentOperation, - Properties::NON_VIRTUAL, - __osg_ref_ptrT1_Operation___getCurrentOperation, - "Get the operation currently being run. ", - ""); - I_Method0(void, run, - Properties::VIRTUAL, - __void__run, - "Run does the graphics thread run loop. ", - ""); - I_Method1(void, setDone, IN, bool, done, - Properties::NON_VIRTUAL, - __void__setDone__bool, - "", - ""); - I_Method0(bool, getDone, - Properties::NON_VIRTUAL, - __bool__getDone, - "", - ""); - I_Method0(int, cancel, - Properties::VIRTUAL, - __int__cancel, - "Cancel this graphics thread. ", - ""); - I_SimpleProperty(osg::ref_ptr< osg::Operation >, CurrentOperation, - __osg_ref_ptrT1_Operation___getCurrentOperation, - 0); - I_SimpleProperty(bool, Done, - __bool__getDone, - __void__setDone__bool); - I_SimpleProperty(osg::Object *, Parent, - __Object_P1__getParent, - __void__setParent__Object_P1); -END_REFLECTOR - -BEGIN_OBJECT_REFLECTOR(osg::RefBlock) - I_DeclaringFile("osg/GraphicsThread"); - I_VirtualBaseType(osg::Referenced); - I_BaseType(OpenThreads::Block); - I_Constructor0(____RefBlock, - "", - ""); END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osg::ReleaseContext_Block_MakeCurrentOperation) diff --git a/src/osgWrappers/osgDB/DatabasePager.cpp b/src/osgWrappers/osgDB/DatabasePager.cpp index 6c30bdb05..162930643 100644 --- a/src/osgWrappers/osgDB/DatabasePager.cpp +++ b/src/osgWrappers/osgDB/DatabasePager.cpp @@ -12,9 +12,9 @@ #include #include -#include #include #include +#include #include #include #include diff --git a/src/osgWrappers/osgTerrain/TerrainNode.cpp b/src/osgWrappers/osgTerrain/TerrainNode.cpp index 8da5dc306..b60e51db1 100644 --- a/src/osgWrappers/osgTerrain/TerrainNode.cpp +++ b/src/osgWrappers/osgTerrain/TerrainNode.cpp @@ -13,9 +13,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/osgWrappers/osgViewer/CompositeViewer.cpp b/src/osgWrappers/osgViewer/CompositeViewer.cpp index 623936108..3406dce97 100644 --- a/src/osgWrappers/osgViewer/CompositeViewer.cpp +++ b/src/osgWrappers/osgViewer/CompositeViewer.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/osgWrappers/osgViewer/Viewer.cpp b/src/osgWrappers/osgViewer/Viewer.cpp index 49ec93d88..220f4e489 100644 --- a/src/osgWrappers/osgViewer/Viewer.cpp +++ b/src/osgWrappers/osgViewer/Viewer.cpp @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include #include