Separated OperationsThread out from the GraphicsThread header and introduced
new OperationQueue class.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"<<std::endl;
|
||||
|
||||
{
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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 "<<this<<std::endl;
|
||||
|
||||
cancel();
|
||||
|
||||
//osg::notify(osg::NOTICE)<<"Done Destructing graphics thread "<<this<<std::endl;
|
||||
}
|
||||
|
||||
void OperationsThread::setDone(bool done)
|
||||
{
|
||||
if (_done==done) return;
|
||||
|
||||
_done = true;
|
||||
|
||||
if (done)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"set done "<<this<<std::endl;
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"releasing "<<_currentOperation.get()<<std::endl;
|
||||
_currentOperation->release();
|
||||
}
|
||||
}
|
||||
|
||||
_operationsBlock->release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int OperationsThread::cancel()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Cancelling OperationsThred "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
int result = 0;
|
||||
if( isRunning() )
|
||||
{
|
||||
|
||||
_done = true;
|
||||
|
||||
osg::notify(osg::INFO)<<" Doing cancel "<<this<<std::endl;
|
||||
|
||||
for(Operations::iterator itr = _operations.begin();
|
||||
itr != _operations.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->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<OpenThreads::Mutex> 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 "<<this<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<" OperationsThread::cancel() thread cancelled "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void OperationsThread::add(Operation* operation, bool waitForCompletion)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing add"<<std::endl;
|
||||
|
||||
ref_ptr<BlockOperation> block = 0;
|
||||
|
||||
{
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
_operations.clear();
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OperationsThread::run()
|
||||
{
|
||||
// make the graphics context current.
|
||||
GraphicsContext* graphicsContext = dynamic_cast<GraphicsContext*>(_parent.get());
|
||||
if (graphicsContext)
|
||||
{
|
||||
graphicsContext->makeCurrent();
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"Doing run "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
bool firstTime = true;
|
||||
|
||||
Operations::iterator itr = _operations.begin();
|
||||
|
||||
do
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"In main loop "<<this<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->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<<" "<<this<<std::endl;
|
||||
|
||||
// get the front of the file request list.
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (!_operations.empty())
|
||||
{
|
||||
// get the next item
|
||||
_currentOperation = *itr;
|
||||
|
||||
if (!_currentOperation->getKeep())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"removing "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// remove it from the opeations queue
|
||||
itr = _operations.erase(itr);
|
||||
|
||||
// osg::notify(osg::INFO)<<"size "<<_operations.size()<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"setting block "<<_operations.size()<<std::endl;
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"increment "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// move on to the next operation in the list.
|
||||
++itr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"Doing op "<<_currentOperation->getName()<<" "<<this<<std::endl;
|
||||
|
||||
// call the graphics operation.
|
||||
(*_currentOperation)(_parent.get());
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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()"<<testCancel()<<std::endl;
|
||||
|
||||
} while (!testCancel() && !_done);
|
||||
|
||||
if (graphicsContext)
|
||||
{
|
||||
graphicsContext->releaseContext();
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"exit loop "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void SwapBuffersOperation::operator () (Object* object)
|
||||
{
|
||||
@@ -444,3 +86,21 @@ void ReleaseContext_Block_MakeCurrentOperation::operator () (Object* object)
|
||||
// re aquire the graphcis context.
|
||||
context->makeCurrent();
|
||||
}
|
||||
|
||||
|
||||
BlockAndFlushOperation::BlockAndFlushOperation():
|
||||
Operation("Block",false)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void BlockAndFlushOperation::release()
|
||||
{
|
||||
Block::release();
|
||||
}
|
||||
|
||||
void BlockAndFlushOperation::operator () (Object*)
|
||||
{
|
||||
glFlush();
|
||||
Block::release();
|
||||
}
|
||||
|
||||
399
src/osg/OperationsThread.cpp
Normal file
399
src/osg/OperationsThread.cpp
Normal file
@@ -0,0 +1,399 @@
|
||||
/* -*-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.
|
||||
*/
|
||||
|
||||
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/Notify>
|
||||
|
||||
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<Operation> OperationQueue::getNextOperation()
|
||||
{
|
||||
return osg::ref_ptr<Operation>();
|
||||
}
|
||||
|
||||
void OperationQueue::add(Operation* operation)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing add"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
_operations.clear();
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OperationQueue::releaseAllOperations()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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 "<<this<<std::endl;
|
||||
|
||||
cancel();
|
||||
|
||||
//osg::notify(osg::NOTICE)<<"Done Destructing graphics thread "<<this<<std::endl;
|
||||
}
|
||||
|
||||
void OperationsThread::setDone(bool done)
|
||||
{
|
||||
if (_done==done) return;
|
||||
|
||||
_done = true;
|
||||
|
||||
if (done)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"set done "<<this<<std::endl;
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"releasing "<<_currentOperation.get()<<std::endl;
|
||||
_currentOperation->release();
|
||||
}
|
||||
}
|
||||
|
||||
_operationsBlock->release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int OperationsThread::cancel()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Cancelling OperationsThred "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
int result = 0;
|
||||
if( isRunning() )
|
||||
{
|
||||
|
||||
_done = true;
|
||||
|
||||
osg::notify(osg::INFO)<<" Doing cancel "<<this<<std::endl;
|
||||
|
||||
for(Operations::iterator itr = _operations.begin();
|
||||
itr != _operations.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->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<OpenThreads::Mutex> 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 "<<this<<std::endl;
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<" OperationsThread::cancel() thread cancelled "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void OperationsThread::add(Operation* operation)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing add"<<std::endl;
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
_operations.clear();
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OperationsThread::run()
|
||||
{
|
||||
// make the graphics context current.
|
||||
GraphicsContext* graphicsContext = dynamic_cast<GraphicsContext*>(_parent.get());
|
||||
if (graphicsContext)
|
||||
{
|
||||
graphicsContext->makeCurrent();
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"Doing run "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
bool firstTime = true;
|
||||
|
||||
Operations::iterator itr = _operations.begin();
|
||||
|
||||
do
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"In main loop "<<this<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->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<<" "<<this<<std::endl;
|
||||
|
||||
// get the front of the file request list.
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (!_operations.empty())
|
||||
{
|
||||
// get the next item
|
||||
_currentOperation = *itr;
|
||||
|
||||
if (!_currentOperation->getKeep())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"removing "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// remove it from the opeations queue
|
||||
itr = _operations.erase(itr);
|
||||
|
||||
// osg::notify(osg::INFO)<<"size "<<_operations.size()<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"setting block "<<_operations.size()<<std::endl;
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"increment "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// move on to the next operation in the list.
|
||||
++itr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
// osg::notify(osg::INFO)<<"Doing op "<<_currentOperation->getName()<<" "<<this<<std::endl;
|
||||
|
||||
// call the graphics operation.
|
||||
(*_currentOperation)(_parent.get());
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> 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()"<<testCancel()<<std::endl;
|
||||
|
||||
} while (!testCancel() && !_done);
|
||||
|
||||
if (graphicsContext)
|
||||
{
|
||||
graphicsContext->releaseContext();
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"exit loop "<<this<<" isRunning()="<<isRunning()<<std::endl;
|
||||
|
||||
}
|
||||
@@ -890,9 +890,23 @@ void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
||||
|
||||
if (useThread)
|
||||
{
|
||||
#if 1
|
||||
ref_ptr<osg::BlockAndFlushOperation> block = new osg::BlockAndFlushOperation;
|
||||
|
||||
useThread->add(new DrawInnerOperation( this, renderInfo ));
|
||||
|
||||
useThread->add(block.get());
|
||||
|
||||
// wait till the DrawInnerOperations is complete.
|
||||
block->block();
|
||||
|
||||
doCopyTexture = false;
|
||||
|
||||
#else
|
||||
useThread->add(new DrawInnerOperation( this, renderInfo ), true);
|
||||
|
||||
doCopyTexture = false;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/DisplaySettings>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/Image>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Matrixd>
|
||||
#include <osg/Matrixf>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Object>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/State>
|
||||
#include <osg/Stats>
|
||||
#include <osg/Texture>
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/Object>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/State>
|
||||
#include <osg/Vec4>
|
||||
|
||||
|
||||
@@ -44,172 +44,18 @@ BEGIN_OBJECT_REFLECTOR(osg::BarrierOperation)
|
||||
I_PublicMemberProperty(osg::BarrierOperation::PreBlockOp, _preBlockOp);
|
||||
END_REFLECTOR
|
||||
|
||||
BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::Operation)
|
||||
BEGIN_OBJECT_REFLECTOR(osg::BlockAndFlushOperation)
|
||||
I_DeclaringFile("osg/GraphicsThread");
|
||||
I_VirtualBaseType(osg::Referenced);
|
||||
I_Constructor2(IN, const std::string &, name, IN, bool, keep,
|
||||
____Operation__C5_std_string_R1__bool,
|
||||
I_BaseType(osg::Operation);
|
||||
I_BaseType(OpenThreads::Block);
|
||||
I_Constructor0(____BlockAndFlushOperation,
|
||||
"",
|
||||
"");
|
||||
I_Method1(void, setName, IN, const std::string &, name,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setName__C5_std_string_R1,
|
||||
"Set the human readable name of the operation. ",
|
||||
"");
|
||||
I_Method0(const std::string &, getName,
|
||||
Properties::NON_VIRTUAL,
|
||||
__C5_std_string_R1__getName,
|
||||
"Get the human readable name of the operation. ",
|
||||
"");
|
||||
I_Method1(void, setKeep, IN, bool, keep,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setKeep__bool,
|
||||
"Set whether the operation should be kept once its been applied. ",
|
||||
"");
|
||||
I_Method0(bool, getKeep,
|
||||
Properties::NON_VIRTUAL,
|
||||
__bool__getKeep,
|
||||
"Get whether the operation should be kept once its been applied. ",
|
||||
"");
|
||||
I_Method0(void, release,
|
||||
Properties::VIRTUAL,
|
||||
__void__release,
|
||||
"if this operation is a barrier then release it. ",
|
||||
"");
|
||||
I_SimpleProperty(bool, Keep,
|
||||
__bool__getKeep,
|
||||
__void__setKeep__bool);
|
||||
I_SimpleProperty(const std::string &, Name,
|
||||
__C5_std_string_R1__getName,
|
||||
__void__setName__C5_std_string_R1);
|
||||
END_REFLECTOR
|
||||
|
||||
BEGIN_OBJECT_REFLECTOR(osg::OperationQueue)
|
||||
I_DeclaringFile("osg/GraphicsThread");
|
||||
I_BaseType(osg::Referenced);
|
||||
I_Constructor0(____OperationQueue,
|
||||
"",
|
||||
"");
|
||||
I_Method0(osg::RefBlock *, getOperationsBlock,
|
||||
Properties::NON_VIRTUAL,
|
||||
__RefBlock_P1__getOperationsBlock,
|
||||
"",
|
||||
"");
|
||||
I_Method0(const osg::RefBlock *, getOperationsBlock,
|
||||
Properties::NON_VIRTUAL,
|
||||
__C5_RefBlock_P1__getOperationsBlock,
|
||||
"",
|
||||
"");
|
||||
I_Method1(void, add, IN, osg::Operation *, operation,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__add__Operation_P1,
|
||||
"Add operation to end of OperationQueue, this will be executed by the operation thread once this operation gets to the head of the queue. ",
|
||||
"");
|
||||
I_Method1(void, remove, IN, osg::Operation *, operation,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__remove__Operation_P1,
|
||||
"Remove operation from OperationQueue. ",
|
||||
"");
|
||||
I_Method1(void, remove, IN, const std::string &, name,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__remove__C5_std_string_R1,
|
||||
"Remove named operation from OperationQueue. ",
|
||||
"");
|
||||
I_Method0(void, removeAllOperations,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__removeAllOperations,
|
||||
"Remove all operations from OperationQueue. ",
|
||||
"");
|
||||
I_SimpleProperty(osg::RefBlock *, OperationsBlock,
|
||||
__RefBlock_P1__getOperationsBlock,
|
||||
0);
|
||||
END_REFLECTOR
|
||||
|
||||
BEGIN_OBJECT_REFLECTOR(osg::OperationsThread)
|
||||
I_DeclaringFile("osg/GraphicsThread");
|
||||
I_BaseType(osg::Referenced);
|
||||
I_BaseType(OpenThreads::Thread);
|
||||
I_Constructor0(____OperationsThread,
|
||||
"",
|
||||
"");
|
||||
I_Method1(void, setParent, IN, osg::Object *, parent,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__setParent__Object_P1,
|
||||
"",
|
||||
"");
|
||||
I_Method0(osg::Object *, getParent,
|
||||
Properties::NON_VIRTUAL,
|
||||
__Object_P1__getParent,
|
||||
"",
|
||||
"");
|
||||
I_Method0(const osg::Object *, getParent,
|
||||
Properties::NON_VIRTUAL,
|
||||
__C5_Object_P1__getParent,
|
||||
"",
|
||||
"");
|
||||
I_MethodWithDefaults2(void, add, IN, osg::Operation *, operation, , IN, bool, waitForCompletion, false,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__add__Operation_P1__bool,
|
||||
"Add operation to end of OperationQueue, this will be executed by the graphics thread once this operation gets to the head of the queue. ",
|
||||
"");
|
||||
I_Method1(void, remove, IN, osg::Operation *, operation,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__remove__Operation_P1,
|
||||
"Remove operation from OperationQueue. ",
|
||||
"");
|
||||
I_Method1(void, remove, IN, const std::string &, name,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__remove__C5_std_string_R1,
|
||||
"Remove named operation from OperationQueue. ",
|
||||
"");
|
||||
I_Method0(void, removeAllOperations,
|
||||
Properties::NON_VIRTUAL,
|
||||
__void__removeAllOperations,
|
||||
"Remove all operations from OperationQueue. ",
|
||||
"");
|
||||
I_Method0(osg::ref_ptr< osg::Operation >, 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)
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/Group>
|
||||
#include <osg/Node>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/PagedLOD>
|
||||
#include <osg/State>
|
||||
#include <osgDB/DatabasePager>
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include <osg/BoundingSphere>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Object>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/TransferFunction>
|
||||
#include <osgTerrain/Layer>
|
||||
#include <osgTerrain/Locator>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/Camera>
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/Timer>
|
||||
#include <osgGA/EventQueue>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/Camera>
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/GraphicsThread>
|
||||
#include <osg/Node>
|
||||
#include <osg/OperationsThread>
|
||||
#include <osg/Timer>
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
Reference in New Issue
Block a user