diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index 8149325ba..6294a681b 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -150,9 +150,6 @@ int main( int argc, char **argv ) } } - // osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(4); - osg::Referenced::setThreadSafeReferenceCounting(true); - // load the scene. osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); if (!loadedModel) @@ -172,7 +169,7 @@ int main( int argc, char **argv ) if (apm.valid()) viewer.setCameraManipulator(apm.get()); else viewer.setCameraManipulator( new osgGA::TrackballManipulator() ); -#if 1 +#if 0 // singleWindowMultipleCameras(viewer); @@ -184,13 +181,10 @@ int main( int argc, char **argv ) viewer.setUpViewAcrossAllScreens(); #endif - - loadedModel->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); - viewer.realize(); - bool limitNumberOfFrames = false; + bool limitNumberOfFrames = true; unsigned int numFrames = 0; unsigned int maxFrames = 10; diff --git a/examples/osgcatch/osgcatch.cpp b/examples/osgcatch/osgcatch.cpp index 6916ea161..a070ef949 100644 --- a/examples/osgcatch/osgcatch.cpp +++ b/examples/osgcatch/osgcatch.cpp @@ -1518,7 +1518,6 @@ int main( int argc, char **argv ) arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); // todo for osgViewer - osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(2); osg::Referenced::setThreadSafeReferenceCounting(true); // construct the viewer. diff --git a/include/osg/Drawable b/include/osg/Drawable index 88fdbceeb..9d7b0a4a5 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -278,6 +278,9 @@ class OSG_EXPORT Drawable : public Object */ virtual void compileGLObjects(RenderInfo& renderInfo) const; + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int maxSize); diff --git a/include/osg/Geode b/include/osg/Geode index 31597ac9a..fafec2a53 100644 --- a/include/osg/Geode +++ b/include/osg/Geode @@ -138,6 +138,9 @@ class OSG_EXPORT Geode : public Node virtual BoundingSphere computeBound() const; + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int maxSize); diff --git a/include/osg/Group b/include/osg/Group index 41f01d905..923b841d7 100644 --- a/include/osg/Group +++ b/include/osg/Group @@ -142,6 +142,9 @@ class OSG_EXPORT Group : public Node return _children.size(); // node not found. } + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int maxSize); diff --git a/include/osg/Node b/include/osg/Node index 1e1d5e277..2a4800630 100644 --- a/include/osg/Node +++ b/include/osg/Node @@ -299,6 +299,9 @@ class OSG_EXPORT Node : public Object /** Get the const compute bound callback.*/ const ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() const { return _computeBoundCallback.get(); } + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + /** Resize any per context GLObject buffers to specified size. */ virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/); diff --git a/include/osg/Program b/include/osg/Program index f0e8b9e02..75396a457 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -61,6 +61,10 @@ class OSG_EXPORT Program : public osg::StateAttribute * performing any rebuild operations that might be pending. */ virtual void apply(osg::State& state) const; + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + + /** Compile program and associated shaders.*/ virtual void compileGLObjects(osg::State& state) const; /** Resize any per context GLObject buffers to specified size. */ diff --git a/include/osg/Referenced b/include/osg/Referenced index b0ccb1c9b..b08b6765a 100644 --- a/include/osg/Referenced +++ b/include/osg/Referenced @@ -53,7 +53,7 @@ class OSG_EXPORT Referenced inline Referenced& operator = (const Referenced&) { return *this; } /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ - void setThreadSafeRefUnref(bool threadSafe); + virtual void setThreadSafeRefUnref(bool threadSafe); /** Get whether a mutex is used to ensure ref() and unref() are thread safe.*/ bool getThreadSafeRefUnref() const { return _refMutex!=0; } diff --git a/include/osg/StateSet b/include/osg/StateSet index cb8ffb206..3d70e6c56 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -414,6 +414,9 @@ class OSG_EXPORT StateSet : public Object * Return true if all associated modes are valid.*/ bool checkValidityOfAssociatedModes(State& state) const; + /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ + virtual void setThreadSafeRefUnref(bool threadSafe); + /** call compile on all StateAttributes contained within this StateSet.*/ void compileGLObjects(State& state) const; @@ -423,6 +426,8 @@ class OSG_EXPORT StateSet : public Object /** call release on all StateAttributes contained within this StateSet.*/ virtual void releaseGLObjects(State* state=0) const; + + protected : diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 71a9126f1..f74114325 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -479,6 +479,20 @@ void Drawable::compileGLObjects(RenderInfo& renderInfo) const } +void Drawable::setThreadSafeRefUnref(bool threadSafe) +{ + Object::setThreadSafeRefUnref(threadSafe); + + if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe); + + if (_updateCallback.valid()) _updateCallback->setThreadSafeRefUnref(threadSafe); + if (_eventCallback.valid()) _eventCallback->setThreadSafeRefUnref(threadSafe); + if (_cullCallback.valid()) _cullCallback->setThreadSafeRefUnref(threadSafe); + if (_drawCallback.valid()) _drawCallback->setThreadSafeRefUnref(threadSafe); + + if (_userData.valid()) _userData->setThreadSafeRefUnref(threadSafe); +} + void Drawable::resizeGLObjectBuffers(unsigned int maxSize) { if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize); diff --git a/src/osg/Geode.cpp b/src/osg/Geode.cpp index bad02d8aa..5808ef109 100644 --- a/src/osg/Geode.cpp +++ b/src/osg/Geode.cpp @@ -209,6 +209,18 @@ void Geode::compileDrawables(RenderInfo& renderInfo) } } +void Geode::setThreadSafeRefUnref(bool threadSafe) +{ + Node::setThreadSafeRefUnref(threadSafe); + + for(DrawableList::const_iterator itr=_drawables.begin(); + itr!=_drawables.end(); + ++itr) + { + (*itr)->setThreadSafeRefUnref(threadSafe); + } +} + void Geode::resizeGLObjectBuffers(unsigned int maxSize) { Node::resizeGLObjectBuffers(maxSize); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 35abb480e..e1207a099 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -128,6 +128,7 @@ void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID) GraphicsContext::GraphicsContext(): _threadOfLastMakeCurrent(0) { + setThreadSafeRefUnref(true); _operationsBlock = new Block; } diff --git a/src/osg/Group.cpp b/src/osg/Group.cpp index d9735ccf9..809a92d19 100644 --- a/src/osg/Group.cpp +++ b/src/osg/Group.cpp @@ -379,6 +379,18 @@ BoundingSphere Group::computeBound() const return bsphere; } +void Group::setThreadSafeRefUnref(bool threadSafe) +{ + Node::setThreadSafeRefUnref(threadSafe); + + for(NodeList::const_iterator itr=_children.begin(); + itr!=_children.end(); + ++itr) + { + (*itr)->setThreadSafeRefUnref(threadSafe); + } +} + void Group::resizeGLObjectBuffers(unsigned int maxSize) { Node::resizeGLObjectBuffers(maxSize); diff --git a/src/osg/Node.cpp b/src/osg/Node.cpp index 26d691053..672a481c6 100644 --- a/src/osg/Node.cpp +++ b/src/osg/Node.cpp @@ -491,6 +491,19 @@ void Node::dirtyBound() } } +void Node::setThreadSafeRefUnref(bool threadSafe) +{ + Object::setThreadSafeRefUnref(threadSafe); + + if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe); + + if (_updateCallback.valid()) _updateCallback->setThreadSafeRefUnref(threadSafe); + if (_eventCallback.valid()) _eventCallback->setThreadSafeRefUnref(threadSafe); + if (_cullCallback.valid()) _cullCallback->setThreadSafeRefUnref(threadSafe); + + if (_userData.valid()) _userData->setThreadSafeRefUnref(threadSafe); +} + void Node::resizeGLObjectBuffers(unsigned int maxSize) { if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize); diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 30f302404..86a3351d7 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -1983,6 +1983,15 @@ void Program::compileGLObjects( osg::State& state ) const getPCP( contextID )->linkProgram(); } +void Program::setThreadSafeRefUnref(bool threadSafe) +{ + StateAttribute::setThreadSafeRefUnref(threadSafe); + + for( unsigned int i=0; i < _shaderList.size(); ++i ) + { + if (_shaderList[i].valid()) _shaderList[i]->setThreadSafeRefUnref(threadSafe); + } +} void Program::dirtyProgram() { diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index d619eab39..5e4566813 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -1180,6 +1180,30 @@ bool StateSet::checkValidityOfAssociatedModes(osg::State& state) const return modesValid; } +void StateSet::setThreadSafeRefUnref(bool threadSafe) +{ + Object::setThreadSafeRefUnref(threadSafe); + + for(AttributeList::const_iterator itr = _attributeList.begin(); + itr!=_attributeList.end(); + ++itr) + { + itr->second.first->setThreadSafeRefUnref(threadSafe); + } + + for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin(); + taitr!=_textureAttributeList.end(); + ++taitr) + { + for(AttributeList::const_iterator itr = taitr->begin(); + itr!=taitr->end(); + ++itr) + { + itr->second.first->setThreadSafeRefUnref(threadSafe); + } + } +} + void StateSet::compileGLObjects(State& state) const { for(AttributeList::const_iterator itr = _attributeList.begin(); diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 755bc3a06..d232cc6f1 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -585,6 +585,8 @@ void GraphicsWindowX11::closeImplementation() XFlush( _display ); XSync( _display,0 ); + + XCloseDisplay( _display ); } _window = 0; @@ -626,6 +628,7 @@ void GraphicsWindowX11::checkEvents() int windowWidth = _traits->width; int windowHeight = _traits->height; + bool destroyWindowRequested = false; // osg::notify(osg::NOTICE)<<"Check events"<(ev.xclient.data.l[0]) == _deleteWindow) { osg::notify(osg::INFO)<<"DeleteWindow event recieved"<windowResize(windowX, windowY, windowWidth, windowHeight); } + + if (destroyWindowRequested) + { + close(); + } + } void GraphicsWindowX11::grabFocus() diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index a830a9c69..6ccdabe4a 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -22,7 +22,11 @@ using namespace osgViewer; View::View() { // osg::notify(osg::NOTICE)<<"Constructing osgViewer::View"<setThreadSafeRefUnref(true); + + // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it. + getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts()); + } + + osg::notify(osg::NOTICE)<<"Viewer::startThreading() - starting threading"<realize(); -// OpenThreads::Thread::YieldCurrentThread(); } bool grabFocus = true; @@ -336,8 +347,9 @@ void Viewer::realize() gw->grabFocusIfPointerInWindow(); } } - } - + } + + startThreading(); // initialize the global timer to be relative to the current time.