From 93a2c3d0119909a75adfc4c912dc4ddeefc0d67f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Jan 2006 17:05:17 +0000 Subject: [PATCH] Improved handling of clean up of osg::Program/osg::Shader on closing of a graphis context. --- include/osg/Program | 2 +- include/osg/Shader | 5 +++++ src/osg/Program.cpp | 20 ++++++++++++++++---- src/osg/Shader.cpp | 10 ++++++++++ src/osgUtil/SceneView.cpp | 3 +++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/include/osg/Program b/include/osg/Program index c608f388f..8a32ce060 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -132,7 +132,7 @@ class OSG_EXPORT Program : public osg::StateAttribute void requestLink(); void linkProgram(); - void validateProgram(); + bool validateProgram(); bool needsLink() const {return _needsLink;} bool isLinked() const {return _isLinked;} bool getInfoLog( std::string& infoLog ) const; diff --git a/include/osg/Shader b/include/osg/Shader index ea066b8d9..9d5f42a8b 100644 --- a/include/osg/Shader +++ b/include/osg/Shader @@ -81,6 +81,11 @@ class OSG_EXPORT Shader : public osg::Object /** Get the Shader type as a descriptive string. */ const char* getTypename() const; + /** release OpenGL objects in specified graphics context if State + object is passed, otherwise release OpenGL objects for all graphics context if + State object pointer NULL.*/ + void releaseGLObjects(osg::State* state=0) const; + /** Mark our PCSs as needing recompilation. * Also mark Programs that depend on us as needing relink */ void dirtyShader(); diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 08f9af318..8ab42ad73 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -1999,9 +1999,19 @@ void Program::dirtyProgram() } -void Program::releaseGLObjects(osg::State* /*state*/) const +void Program::releaseGLObjects(osg::State* state) const { - // TODO + for( unsigned int i=0; i < _shaderList.size(); ++i ) + { + if (_shaderList[i].valid()) _shaderList[i]->releaseGLObjects(state); + } + + if (!state) _pcpList.setAllElementsTo(0); + else + { + unsigned int contextID = state->getContextID(); + _pcpList[contextID] = 0; + } } @@ -2274,13 +2284,13 @@ void Program::PerContextProgram::linkProgram() osg::notify(osg::INFO) << std::endl; } -void Program::PerContextProgram::validateProgram() +bool Program::PerContextProgram::validateProgram() { GLint validated = GL_FALSE; _extensions->glValidateProgram( _glProgramHandle ); _extensions->glGetProgramiv( _glProgramHandle, GL_VALIDATE_STATUS, &validated ); if( validated == GL_TRUE) - return; + return true; osg::notify(osg::INFO) << "glValidateProgram FAILED \"" << _program->getName() << "\"" @@ -2293,6 +2303,8 @@ void Program::PerContextProgram::validateProgram() osg::notify(osg::INFO) << "infolog:\n" << infoLog << std::endl; osg::notify(osg::INFO) << std::endl; + + return false; } bool Program::PerContextProgram::getInfoLog( std::string& infoLog ) const diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 99cf21296..4a7ed4207 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -201,6 +201,16 @@ const char* Shader::getTypename() const } +void Shader::releaseGLObjects(osg::State* state) const +{ + if (!state) _pcsList.setAllElementsTo(0); + else + { + unsigned int contextID = state->getContextID(); + _pcsList[contextID] = 0; + } +} + void Shader::compileShader( unsigned int contextID ) const { PerContextShader* pcs = getPCS( contextID ); diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index cbd75dc76..e863c1922 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -736,6 +736,9 @@ void SceneView::releaseAllGLObjects() if (!_camera) return; _camera->releaseGLObjects(_state.get()); + + // we need to reset State as it keeps handles to Program objects. + if (_state.valid()) _state->reset(); }