/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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 #include #include using namespace osg; using namespace OpenThreads; struct BlockOperation : public GraphicsThread::Operation, public Block { BlockOperation() { reset(); } virtual void operator () (GraphicsContext*) { //osg::notify(osg::NOTICE)<<"BlockOperation doing release"<<(unsigned int)this<release(); // then wait for the the thread to stop running. while(isRunning()) { // 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::NOTICE)<<"Waiting for GraphicsThread to cancel"< lock(_operationsMutex); // add the operation to the end of the list _operations.push_back(operation); if (waitForCompletion) { block = new BlockOperation; _operations.push_back(block); } _operationsBlock->set(true); } if (block) { // now we wait till the barrier is joined by the graphics thread. block->block(); } } void GraphicsThread::run() { // make the graphics context current. if (_graphicsContext) { osg::notify(osg::NOTICE)<<"Doing make current"<makeCurrent(); } osg::notify(osg::NOTICE)<<"Doing run"<block(); } // osg::notify(osg::NOTICE)<<"get op"< operation; // get the front of the file request list. { OpenThreads::ScopedLock lock(_operationsMutex); if (!_operations.empty()) { // get the front the queue operation = _operations.front(); // remove it from the opeations queue _operations.erase(_operations.begin()); if (_operations.empty()) { _operationsBlock->set(false); } } } if (operation.valid()) { // osg::notify(osg::NOTICE)<<"Doing op"<releaseContext(); } void SwapBuffersOperation::operator () (GraphicsContext* context) { if (context) { context->swapBuffersImplementation(); } } void BarrierOperation::operator () (GraphicsContext*) { if (_preBlockOp==GL_FLUSH) glFlush(); if (_preBlockOp==GL_FINISH) glFinish(); block(); } void ReleaseContext_Block_MakeCurrentOperation::operator () (GraphicsContext* context) { if (!context) return; // release the graphics context. context->releaseContext(); // reset the block so that it the next call to block() reset(); // block this thread, untill the block is released externally. block(); // re aquire the graphcis context. context->makeCurrent(); }