From 4493d11ca3d7e0746941b500660d08161981585b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 21 Oct 2013 16:35:12 +0000 Subject: [PATCH] Added State::releaseGLObjects() and ShaderComposer::releaseGLObjects() to avoid problems with cleanup of graphics context --- include/osg/ShaderComposer | 3 ++- include/osg/State | 3 +++ src/osg/GraphicsContext.cpp | 6 +++-- src/osg/ShaderComposer.cpp | 6 +++++ src/osg/State.cpp | 53 ++++++++++++++++++++++++++++++++++++- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/include/osg/ShaderComposer b/include/osg/ShaderComposer index 97ea26cd7..a784eaed4 100644 --- a/include/osg/ShaderComposer +++ b/include/osg/ShaderComposer @@ -35,11 +35,12 @@ class OSG_EXPORT ShaderComposer : public osg::Object virtual osg::Program* getOrCreateProgram(const ShaderComponents& shaderComponents); - typedef std::vector< const osg::Shader* > Shaders; virtual osg::Shader* composeMain(const Shaders& shaders); virtual void addShaderToProgram(Program* program, const Shaders& shaders); + void releaseGLObjects(osg::State* state); + protected: virtual ~ShaderComposer(); diff --git a/include/osg/State b/include/osg/State index efa79bb9f..1df058436 100644 --- a/include/osg/State +++ b/include/osg/State @@ -218,6 +218,9 @@ class OSG_EXPORT State : public Referenced, public Observer /** Copy the modes and attributes which capture the current state.*/ void captureCurrentState(StateSet& stateset) const; + /** Release all OpenGL objects associated cached by this osg::State object.*/ + void releaseGLObjects(); + /** reset the state object to an empty stack.*/ void reset(); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index c7c3e3944..037b459cc 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -546,6 +546,10 @@ void GraphicsContext::close(bool callCloseImplementation) } } + if (_state.valid()) + { + _state->releaseGLObjects(); + } if (callCloseImplementation && _state.valid() && isRealized()) { @@ -569,8 +573,6 @@ void GraphicsContext::close(bool callCloseImplementation) osg::flushAllDeletedGLObjects(_state->getContextID()); } - _state->reset(); - releaseContext(); } else diff --git a/src/osg/ShaderComposer.cpp b/src/osg/ShaderComposer.cpp index 5035da105..a35ea52c4 100644 --- a/src/osg/ShaderComposer.cpp +++ b/src/osg/ShaderComposer.cpp @@ -37,6 +37,12 @@ ShaderComposer::~ShaderComposer() OSG_INFO<<"ShaderComposer::~ShaderComposer() "<releaseGLObjects(this); + + // release any StateSet's on the stack + for(StateSetStack::iterator itr = _stateStateStack.begin(); + itr != _stateStateStack.end(); + ++itr) + { + (*itr)->releaseGLObjects(this); + } + + _modeMap.clear(); + _textureModeMapList.clear(); + + // release any cached attributes + for(AttributeMap::iterator aitr = _attributeMap.begin(); + aitr != _attributeMap.end(); + ++aitr) + { + AttributeStack& as = aitr->second; + if (as.global_default_attribute.valid()) + { + as.global_default_attribute->releaseGLObjects(this); + } + } + _attributeMap.clear(); + + // release any cached texture attributes + for(TextureAttributeMapList::iterator itr = _textureAttributeMapList.begin(); + itr != _textureAttributeMapList.end(); + ++itr) + { + AttributeMap& attributeMap = *itr; + for(AttributeMap::iterator aitr = attributeMap.begin(); + aitr != attributeMap.end(); + ++aitr) + { + AttributeStack& as = aitr->second; + if (as.global_default_attribute.valid()) + { + as.global_default_attribute->releaseGLObjects(this); + } + } + } + + _textureAttributeMapList.clear(); +} + void State::reset() { @@ -911,7 +962,7 @@ void State::initializeExtensionProcs() if ( osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(_contextID,"GL_ARB_vertex_shader") || OSG_GLES2_FEATURES) { glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&_glMaxTextureUnits); - if(OSG_GLES2_FEATURES) + if(OSG_GLES2_FEATURES) _glMaxTextureCoords = _glMaxTextureUnits; else glGetIntegerv(GL_MAX_TEXTURE_COORDS,&_glMaxTextureCoords);