From c02e91c1b4db84852af7658611fb42865c9534b8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 30 Aug 2005 22:28:30 +0000 Subject: [PATCH] Added support for GrapicsOpeations that are reused each frame, cleaned up osgcamera example. --- examples/osgcamera/osgcamera.cpp | 119 +++++++++++++++++++---------- examples/osgcluster/osgcluster.cpp | 10 +++ include/osg/GraphicsThread | 8 +- src/osg/Geometry.cpp | 3 + src/osg/GraphicsThread.cpp | 50 ++++++++---- 5 files changed, 133 insertions(+), 57 deletions(-) diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index c47fdec06..3a32b2e40 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -29,6 +30,28 @@ /////////////////////////////////////////////////////////////////////////////// +struct CompileOperation : public osg::GraphicsThread::Operation +{ + CompileOperation(osg::Node* scene): + osg::GraphicsThread::Operation("Compile",false), + _scene(scene) + { + } + + virtual void operator () (osg::GraphicsContext* context) + { + std::cout<<"Compile"<getState()); + + // do the compile traversal + _scene->accept(compileVisitor); + } + + osg::ref_ptr _scene; +}; + struct FrameOperation : public osg::GraphicsThread::Operation { FrameOperation(osg::CameraNode* camera, osg::FrameStamp* frameStamp): @@ -100,6 +123,9 @@ int main( int argc, char **argv ) CameraMap cameraMap; GraphicsContextSet graphicsContextSet; + + bool shareContexts = false; + osg::GraphicsContext* previousContext = 0; for(unsigned int i=0; i< numberCameras; ++i) { osg::ref_ptr camera = new osg::CameraNode; @@ -113,7 +139,8 @@ int main( int argc, char **argv ) traits->_height = height; traits->_windowDecoration = true; traits->_doubleBuffer = true; - + traits->_sharedContext = shareContexts ? previousContext : 0; + xpos += width; osg::ref_ptr gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); @@ -139,6 +166,8 @@ int main( int argc, char **argv ) gfxc->createGraphicsThread(); cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get()); + + previousContext = gfxc.get(); } @@ -150,9 +179,12 @@ int main( int argc, char **argv ) graphicsContextSet.insert(const_cast(citr->first->getGraphicsContext())); } - osg::ref_ptr swapOp = new osg::SwapBuffersOperation(); + osg::ref_ptr compileOp = new CompileOperation(loadedModel.get()); + + osg::ref_ptr frameBeginBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); osg::ref_ptr frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); osg::ref_ptr preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH); + osg::ref_ptr swapOp = new osg::SwapBuffersOperation(); std::cout<<"nubmer of gfx."<getGraphicsThread()->add(compileOp.get(), true); + } + + + // second the begin frame barrier to all graphics threads + for(gitr = graphicsContextSet.begin(); + gitr != graphicsContextSet.end(); + ++gitr) + { + osg::GraphicsContext* context = *gitr; + context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false); + } + + // third add the frame for each camera. + for(citr = cameraMap.begin(); + citr != cameraMap.end(); + ++citr) + { + osg::CameraNode* camera = const_cast(citr->first.get()); + camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false); + } + + // fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread + for(gitr = graphicsContextSet.begin(); + gitr != graphicsContextSet.end(); + ++gitr) + { + osg::GraphicsContext* context = *gitr; + context->getGraphicsThread()->add(frameEndBarrierOp.get(), false); + context->getGraphicsThread()->add(preSwapBarrierOp.get(), false); + context->getGraphicsThread()->add(swapOp.get(), false); + } + + // main loop - update scene graph, dispatch frame, wait for frame done. while( !done ) { @@ -178,43 +250,11 @@ int main( int argc, char **argv ) // do the update traversal. loadedModel->accept(updateVisitor); - // issue the frame for each camera. - for(citr = cameraMap.begin(); - citr != cameraMap.end(); - ++citr) - { - osg::CameraNode* camera = const_cast(citr->first.get()); - camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false); - } - - GraphicsContextSet::iterator gitr; - for(gitr = graphicsContextSet.begin(); - gitr != graphicsContextSet.end(); - ++gitr) - { - osg::GraphicsContext* context = *gitr; - context->getGraphicsThread()->add(frameEndBarrierOp.get(), false); - context->getGraphicsThread()->add(preSwapBarrierOp.get(), false); - } - - osg::notify(osg::INFO)<<"Join frameEndBarrierOp block "<tick(); + // dispatch the frame. + frameBeginBarrierOp->block(); + + // wait till the frame is done. frameEndBarrierOp->block(); - osg::Timer_t after_tick = osg::Timer::instance()->tick(); - osg::notify(osg::INFO)<<"Leave frameEndBarrierOp block "<delta_s(before_tick,after_tick)<tick(); - after_tick = osg::Timer::instance()->tick(); - osg::notify(osg::INFO)<<"Leave preSwapBarrierOp block "<delta_s(before_tick,after_tick)<getGraphicsThread()->add(swapOp.get(), true); - } // check if any of the windows are closed for(gitr = graphicsContextSet.begin(); @@ -226,6 +266,5 @@ int main( int argc, char **argv ) } } - return 0; } diff --git a/examples/osgcluster/osgcluster.cpp b/examples/osgcluster/osgcluster.cpp index 0e4e616d8..f80331547 100644 --- a/examples/osgcluster/osgcluster.cpp +++ b/examples/osgcluster/osgcluster.cpp @@ -229,6 +229,8 @@ class DataConverter void write(const osg::FrameStamp& fs) { + osg::notify(osg::NOTICE)<<"writeFramestamp = "<drawImplementation(state); diff --git a/src/osg/GraphicsThread.cpp b/src/osg/GraphicsThread.cpp index 6de3e889f..16075d499 100644 --- a/src/osg/GraphicsThread.cpp +++ b/src/osg/GraphicsThread.cpp @@ -83,7 +83,7 @@ void GraphicsThread::add(Operation* operation, bool waitForCompletion) { osg::notify(osg::INFO)<<"Doing add"< block = 0; { // aquire the lock on the operations queue to prevent anyone else for modifying it at the same time @@ -95,13 +95,13 @@ void GraphicsThread::add(Operation* operation, bool waitForCompletion) if (waitForCompletion) { block = new BlockOperation; - _operations.push_back(block); + _operations.push_back(block.get()); } _operationsBlock->set(true); } - if (block) + if (block.valid()) { // now we wait till the barrier is joined by the graphics thread. block->block(); @@ -126,16 +126,24 @@ void GraphicsThread::run() bool firstTime = true; + OperationQueue::iterator itr = _operations.begin(); + do { - // osg::notify(osg::NOTICE)<<"In main loop"<block(); + + itr = _operations.begin(); + } + else + { + if (itr == _operations.end()) itr = _operations.begin(); } - // osg::notify(osg::NOTICE)<<"get op"< operation; @@ -144,16 +152,32 @@ void GraphicsThread::run() OpenThreads::ScopedLock lock(_operationsMutex); if (!_operations.empty()) { - // get the front the queue - operation = _operations.front(); + // get the next item + operation = *itr; - // remove it from the opeations queue - _operations.erase(_operations.begin()); - - if (_operations.empty()) + if (!operation->getKeep()) { - _operationsBlock->set(false); + osg::notify(osg::INFO)<<"removing "<getName()<set(false); + } } + else + { + osg::notify(osg::INFO)<<"increment "<getName()<getName()<