From a28588a84c5722d20a7ae9528007da3ad49bf3f4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Jul 2007 17:25:35 +0000 Subject: [PATCH] Introduce GraphicsOperation subclass from osg::Operation, and osgUtil::GLObjectOperation for compiling subgraphs. --- include/osg/GraphicsThread | 38 ++++++++++++----- include/osg/OperationThread | 2 +- include/osgDB/DatabasePager | 4 +- include/osgUtil/GLObjectsVisitor | 14 +++++++ src/osg/GraphicsThread.cpp | 44 +++++--------------- src/osgDB/DatabasePager.cpp | 8 ++-- src/osgUtil/GLObjectsVisitor.cpp | 16 +++++++ src/osgWrappers/osg/GraphicsThread.cpp | 20 ++++++--- src/osgWrappers/osgUtil/GLObjectsVisitor.cpp | 10 +++++ 9 files changed, 99 insertions(+), 57 deletions(-) diff --git a/include/osg/GraphicsThread b/include/osg/GraphicsThread index 139cac822..50e7f6451 100644 --- a/include/osg/GraphicsThread +++ b/include/osg/GraphicsThread @@ -18,6 +18,9 @@ namespace osg { +class GraphicsContext; + +/** GraphicsThread is a helper class for running OpenGL GraphicsOperation within a single thread assigned to a specific GraphicsContext.*/ class OSG_EXPORT GraphicsThread : public osg::OperationThread { public: @@ -28,17 +31,30 @@ class OSG_EXPORT GraphicsThread : public osg::OperationThread virtual void run(); }; +struct OSG_EXPORT GraphicsOperation : public Operation +{ + GraphicsOperation(const std::string& name, bool keep): + Operation(name,keep) {} + + /** Override the standard Operation opertator and dynamic cast object to a GraphicsContext, + * on success call operation()(GraphicsContext*).*/ + virtual void operator () (Object* object); + + virtual void operator () (GraphicsContext* context) = 0; +}; + + /** SwapBufferOperation calls swap buffers on the GraphicsContext.*/ -struct OSG_EXPORT SwapBuffersOperation : public Operation +struct OSG_EXPORT SwapBuffersOperation : public GraphicsOperation { SwapBuffersOperation(): - Operation("SwapBuffers",true) {} + GraphicsOperation("SwapBuffers",true) {} - virtual void operator () (Object* context); + virtual void operator () (GraphicsContext* context); }; /** BarrierOperation allows one to syncronize multiple GraphicsThreads with each other.*/ -struct OSG_EXPORT BarrierOperation : public Operation, public OpenThreads::Barrier +struct OSG_EXPORT BarrierOperation : public GraphicsOperation, public OpenThreads::Barrier { enum PreBlockOp { @@ -48,36 +64,36 @@ struct OSG_EXPORT BarrierOperation : public Operation, public OpenThreads::Barri }; BarrierOperation(int numThreads, PreBlockOp op=NO_OPERATION): - Operation("Barrier", true), + GraphicsOperation("Barrier", true), OpenThreads::Barrier(numThreads), _preBlockOp(op) {} virtual void release(); - virtual void operator () (Object* context); + virtual void operator () (GraphicsContext* context); PreBlockOp _preBlockOp; }; /** ReleaseContext_Block_MakeCurrentOperation releases the context for another thread to aquire, * then blocks waiting for context to be released, once the block is release the context is re-aqquired.*/ -struct OSG_EXPORT ReleaseContext_Block_MakeCurrentOperation : public Operation, public RefBlock +struct OSG_EXPORT ReleaseContext_Block_MakeCurrentOperation : public GraphicsOperation, public RefBlock { ReleaseContext_Block_MakeCurrentOperation(): - Operation("ReleaseContext_Block_MakeCurrent", false) {} + GraphicsOperation("ReleaseContext_Block_MakeCurrent", false) {} virtual void release(); - virtual void operator () (Object* context); + virtual void operator () (GraphicsContext* context); }; -struct OSG_EXPORT BlockAndFlushOperation : public Operation, public OpenThreads::Block +struct OSG_EXPORT BlockAndFlushOperation : public GraphicsOperation, public OpenThreads::Block { BlockAndFlushOperation(); virtual void release(); - virtual void operator () (Object*); + virtual void operator () (GraphicsContext*); }; } diff --git a/include/osg/OperationThread b/include/osg/OperationThread index ee64311f3..3560b8f3a 100644 --- a/include/osg/OperationThread +++ b/include/osg/OperationThread @@ -130,7 +130,7 @@ class OSG_EXPORT OperationQueue : public Referenced OperationThreads _operationThreads; }; -/** GraphicsThread is a helper class for running OpenGL GraphicsOperation within a single thread assigned to a specific GraphicsContext.*/ +/** OperationThread is a helper class for running Operation within a single thread.*/ class OSG_EXPORT OperationThread : public Referenced, public OpenThreads::Thread { public: diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index f60a89297..f8291b767 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -373,11 +373,11 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl double _minimumTimeAvailableForGLCompileAndDeletePerFrame; unsigned int _maximumNumOfObjectsToCompilePerFrame; - struct CompileOperation : public osg::Operation + struct CompileOperation : public osg::GraphicsOperation { CompileOperation(DatabasePager* databasePager); - virtual void operator () (osg::Object* object); + virtual void operator () (osg::GraphicsContext* context); osg::observer_ptr _databasePager; }; diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index 1022dcd56..e3c3cc2b0 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -113,6 +113,20 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor }; +class GLObjectsOperation : public osg::GraphicsOperation +{ + public: + + GLObjectsOperation(osg::Node* subgraph, GLObjectsVisitor::Mode mode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES|GLObjectsVisitor::CHECK_BLACK_LISTED_MODES); + + virtual void operator () (osg::GraphicsContext* context); + + protected: + + osg::ref_ptr _subgraph; + GLObjectsVisitor::Mode _mode; +}; + } #endif diff --git a/src/osg/GraphicsThread.cpp b/src/osg/GraphicsThread.cpp index 0c2e20474..a132ca83c 100644 --- a/src/osg/GraphicsThread.cpp +++ b/src/osg/GraphicsThread.cpp @@ -41,35 +41,16 @@ void GraphicsThread::run() } -struct BlockOperation : public Operation, public Block +void GraphicsOperation::operator () (Object* object) { - BlockOperation(): - Operation("Block",false) - { - reset(); - } - - virtual void release() - { - Block::release(); - } - - virtual void operator () (Object*) - { - glFlush(); - Block::release(); - } -}; - + osg::GraphicsContext* context = dynamic_cast(object); + if (context) operator() (context); +} -void SwapBuffersOperation::operator () (Object* object) +void SwapBuffersOperation::operator () (GraphicsContext* context) { - GraphicsContext* context = dynamic_cast(object); - if (context) - { - context->swapBuffersImplementation(); - context->clear(); - } + context->swapBuffersImplementation(); + context->clear(); } void BarrierOperation::release() @@ -77,7 +58,7 @@ void BarrierOperation::release() Barrier::release(); } -void BarrierOperation::operator () (Object*) +void BarrierOperation::operator () (GraphicsContext*) { if (_preBlockOp==GL_FLUSH) glFlush(); if (_preBlockOp==GL_FINISH) glFinish(); @@ -91,11 +72,8 @@ void ReleaseContext_Block_MakeCurrentOperation::release() } -void ReleaseContext_Block_MakeCurrentOperation::operator () (Object* object) +void ReleaseContext_Block_MakeCurrentOperation::operator () (GraphicsContext* context) { - GraphicsContext* context = dynamic_cast(object); - if (!context) return; - // release the graphics context. context->releaseContext(); @@ -111,7 +89,7 @@ void ReleaseContext_Block_MakeCurrentOperation::operator () (Object* object) BlockAndFlushOperation::BlockAndFlushOperation(): - Operation("Block",false) + GraphicsOperation("Block",false) { reset(); } @@ -121,7 +99,7 @@ void BlockAndFlushOperation::release() Block::release(); } -void BlockAndFlushOperation::operator () (Object*) +void BlockAndFlushOperation::operator () (GraphicsContext*) { glFlush(); Block::release(); diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 5cf508108..f5e49540e 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -903,17 +903,15 @@ bool DatabasePager::getCompileGLObjectsForContextID(unsigned int contextID) DatabasePager::CompileOperation::CompileOperation(osgDB::DatabasePager* databasePager): - osg::Operation("DatabasePager::CompileOperation",false), + osg::GraphicsOperation("DatabasePager::CompileOperation",false), _databasePager(databasePager) { } -void DatabasePager::CompileOperation::operator () (osg::Object* object) +void DatabasePager::CompileOperation::operator () (osg::GraphicsContext* context) { - osg::GraphicsContext* context = dynamic_cast(object); - if (!context) return; - // osg::notify(osg::NOTICE)<<"Background thread compiling"<compileAllGLObjects(*(context->getState())); } diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index cbc20eb3e..c8dbfc7ff 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -138,3 +138,19 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) stateset.checkValidityOfAssociatedModes(*_renderInfo.getState()); } } + +GLObjectsOperation::GLObjectsOperation(osg::Node* subgraph, GLObjectsVisitor::Mode mode): + osg::GraphicsOperation("GLObjectOperation",false), + _subgraph(subgraph), + _mode(mode) +{ +} + +void GLObjectsOperation::operator () (osg::GraphicsContext* context) +{ + GLObjectsVisitor glObjectsVisitor(_mode); + + glObjectsVisitor.setState(context->getState()); + + _subgraph->accept(glObjectsVisitor); +} diff --git a/src/osgWrappers/osg/GraphicsThread.cpp b/src/osgWrappers/osg/GraphicsThread.cpp index 6edabe1bd..933cd65fa 100644 --- a/src/osgWrappers/osg/GraphicsThread.cpp +++ b/src/osgWrappers/osg/GraphicsThread.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -30,7 +31,7 @@ END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osg::BarrierOperation) I_DeclaringFile("osg/GraphicsThread"); - I_BaseType(osg::Operation); + I_BaseType(osg::GraphicsOperation); I_BaseType(OpenThreads::Barrier); I_ConstructorWithDefaults2(IN, int, numThreads, , IN, osg::BarrierOperation::PreBlockOp, op, osg::BarrierOperation::NO_OPERATION, ____BarrierOperation__int__PreBlockOp, @@ -46,7 +47,7 @@ END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osg::BlockAndFlushOperation) I_DeclaringFile("osg/GraphicsThread"); - I_BaseType(osg::Operation); + I_BaseType(osg::GraphicsOperation); I_BaseType(OpenThreads::Block); I_Constructor0(____BlockAndFlushOperation, "", @@ -58,6 +59,15 @@ BEGIN_OBJECT_REFLECTOR(osg::BlockAndFlushOperation) ""); END_REFLECTOR +BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::GraphicsOperation) + I_DeclaringFile("osg/GraphicsThread"); + I_BaseType(osg::Operation); + I_Constructor2(IN, const std::string &, name, IN, bool, keep, + ____GraphicsOperation__C5_std_string_R1__bool, + "", + ""); +END_REFLECTOR + BEGIN_OBJECT_REFLECTOR(osg::GraphicsThread) I_DeclaringFile("osg/GraphicsThread"); I_BaseType(osg::OperationThread); @@ -73,7 +83,7 @@ END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osg::ReleaseContext_Block_MakeCurrentOperation) I_DeclaringFile("osg/GraphicsThread"); - I_BaseType(osg::Operation); + I_BaseType(osg::GraphicsOperation); I_BaseType(osg::RefBlock); I_Constructor0(____ReleaseContext_Block_MakeCurrentOperation, "", @@ -81,13 +91,13 @@ BEGIN_OBJECT_REFLECTOR(osg::ReleaseContext_Block_MakeCurrentOperation) I_Method0(void, release, Properties::VIRTUAL, __void__release, - "if this operation is a barrier then release it. ", + "", ""); END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osg::SwapBuffersOperation) I_DeclaringFile("osg/GraphicsThread"); - I_BaseType(osg::Operation); + I_BaseType(osg::GraphicsOperation); I_Constructor0(____SwapBuffersOperation, "", ""); diff --git a/src/osgWrappers/osgUtil/GLObjectsVisitor.cpp b/src/osgWrappers/osgUtil/GLObjectsVisitor.cpp index 3ea304a6a..7e529d1ce 100644 --- a/src/osgWrappers/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgWrappers/osgUtil/GLObjectsVisitor.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,15 @@ #undef OUT #endif +BEGIN_OBJECT_REFLECTOR(osgUtil::GLObjectsOperation) + I_DeclaringFile("osgUtil/GLObjectsVisitor"); + I_BaseType(osg::GraphicsOperation); + I_ConstructorWithDefaults2(IN, osg::Node *, subgraph, , IN, osgUtil::GLObjectsVisitor::Mode, mode, osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS|osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES|osgUtil::GLObjectsVisitor::CHECK_BLACK_LISTED_MODES, + ____GLObjectsOperation__osg_Node_P1__GLObjectsVisitor_Mode, + "", + ""); +END_REFLECTOR + TYPE_NAME_ALIAS(unsigned int, osgUtil::GLObjectsVisitor::Mode) BEGIN_ENUM_REFLECTOR(osgUtil::GLObjectsVisitor::ModeValues)