diff --git a/include/osg/FrameBufferObject b/include/osg/FrameBufferObject index bd31859ea..c84226ec0 100644 --- a/include/osg/FrameBufferObject +++ b/include/osg/FrameBufferObject @@ -242,6 +242,14 @@ namespace osg static int getMaxSamples(unsigned int contextID, const FBOExtensions *ext); + /** Resize any per context GLObject buffers to specified size. */ + virtual void resizeGLObjectBuffers(unsigned int maxSize); + + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const; + protected: virtual ~RenderBuffer(); RenderBuffer &operator=(const RenderBuffer &) { return *this; } @@ -451,6 +459,14 @@ namespace osg * in the OpenGL context related to contextID.*/ static void discardDeletedFrameBufferObjects(unsigned int contextID); + /** Resize any per context GLObject buffers to specified size. */ + virtual void resizeGLObjectBuffers(unsigned int maxSize); + + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const; + protected: virtual ~FrameBufferObject(); FrameBufferObject& operator = (const FrameBufferObject&) { return *this; } diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index 5364afbd6..5d6181d6d 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -148,6 +148,11 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object void copyLeavesFromStateGraphListToRenderLeafList(); + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* state= 0) const; + protected: virtual ~RenderBin(); diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index f356c4814..2fd86c61a 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -253,7 +253,12 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin /** clear the references to any dependent cameras.*/ void clearReferencesToDependentCameras(); - protected: + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* state= 0) const; + +protected: virtual ~RenderStage(); diff --git a/src/osg/FrameBufferObject.cpp b/src/osg/FrameBufferObject.cpp index e50c158b1..5604e5327 100644 --- a/src/osg/FrameBufferObject.cpp +++ b/src/osg/FrameBufferObject.cpp @@ -284,6 +284,36 @@ GLuint RenderBuffer::getObjectID(unsigned int contextID, const FBOExtensions *ex return objectID; } +void RenderBuffer::resizeGLObjectBuffers(unsigned int maxSize) +{ + _objectID.resize(maxSize); + _dirty.resize(maxSize); +} + +void RenderBuffer::releaseGLObjects(osg::State* state) const +{ + if (state) + { + unsigned int contextID = state->getContextID(); + if (_objectID[contextID]) + { + deleteRenderBuffer(contextID, _objectID[contextID]); + _objectID[contextID] = 0; + } + } + else + { + for(unsigned i=0; i<_objectID.size(); ++i) + { + if (_objectID[i]) + { + deleteRenderBuffer(i, _objectID[i]); + _objectID[i] = 0; + } + } + } +} + /************************************************************************** * FrameBufferAttachment **************************************************************************/ @@ -748,6 +778,37 @@ FrameBufferObject::~FrameBufferObject() } } +void FrameBufferObject::resizeGLObjectBuffers(unsigned int maxSize) +{ + _fboID.resize(maxSize); + _unsupported.resize(maxSize); + _fboID.resize(maxSize); +} + +void FrameBufferObject::releaseGLObjects(osg::State* state) const +{ + if (state) + { + unsigned int contextID = state->getContextID(); + if (_fboID[contextID]) + { + deleteFrameBufferObject(contextID, _fboID[contextID]); + _fboID[contextID] = 0; + } + } + else + { + for(unsigned int i=0; i<_fboID.size(); ++i) + { + if (_fboID[i]) + { + deleteFrameBufferObject(i, _fboID[i]); + _fboID[i] = 0; + } + } + } +} + void FrameBufferObject::setAttachment(BufferComponent attachment_point, const FrameBufferAttachment &attachment) { _attachments[attachment_point] = attachment; diff --git a/src/osg/GLObjects.cpp b/src/osg/GLObjects.cpp index c230970ee..2090e8a23 100644 --- a/src/osg/GLObjects.cpp +++ b/src/osg/GLObjects.cpp @@ -34,8 +34,8 @@ void osg::flushDeletedGLObjects(unsigned int contextID, double currentTime, doub osg::GLBufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime); osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime); - osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime); osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime); + osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime); osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime); osg::Texture::flushDeletedTextureObjects(contextID,currentTime,availableTime); osg::OcclusionQueryNode::flushDeletedQueryObjects(contextID,currentTime,availableTime); diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 28ccedce2..b972aeed7 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1285,6 +1285,30 @@ class RenderStageCache : public osg::Object typedef std::map > RenderStageMap; + /** Resize any per context GLObject buffers to specified size. */ + virtual void resizeGLObjectBuffers(unsigned int maxSize) + { + for(RenderStageMap::const_iterator itr = _renderStageMap.begin(); + itr != _renderStageMap.end(); + ++itr) + { + itr->second->resizeGLObjectBuffers(maxSize); + } + } + + /** If State is non-zero, this function releases any associated OpenGL objects for + * the specified graphics context. Otherwise, releases OpenGL objexts + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* state= 0) const + { + for(RenderStageMap::const_iterator itr = _renderStageMap.begin(); + itr != _renderStageMap.end(); + ++itr) + { + itr->second->releaseGLObjects(state); + } + } + OpenThreads::Mutex _mutex; RenderStageMap _renderStageMap; }; diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index 24380b2c9..bdd3d2047 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -648,3 +648,16 @@ unsigned int RenderBin::computeNumberOfDynamicRenderLeaves() const return count; } + + +void RenderBin::releaseGLObjects(osg::State* state) const +{ + if (_stateset) _stateset->releaseGLObjects(state); + + for(RenderBinList::const_iterator itr = _bins.begin(); + itr != _bins.end(); + ++itr) + { + itr->second->releaseGLObjects(state); + } +} diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 642b77deb..dffd83aa5 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -1494,3 +1494,35 @@ void RenderStage::clearReferencesToDependentCameras() _dependentCameras.clear(); } + +void RenderStage::releaseGLObjects(osg::State* state) const +{ + RenderBin::releaseGLObjects(state); + + for(RenderStageList::const_iterator itr = _preRenderList.begin(); + itr != _preRenderList.end(); + ++itr) + { + itr->second->releaseGLObjects(state); + } + + for(RenderStageList::const_iterator itr = _postRenderList.begin(); + itr != _postRenderList.end(); + ++itr) + { + itr->second->releaseGLObjects(state); + } + + for(Cameras::const_iterator itr = _dependentCameras.begin(); + itr != _dependentCameras.end(); + ++itr) + { + (*itr)->releaseGLObjects(state); + } + + if (_texture.valid()) _texture->releaseGLObjects(state); + + if (_fbo.valid()) _fbo->releaseGLObjects(state); + if (_resolveFbo.valid()) _resolveFbo->releaseGLObjects(state); + if (_graphicsContext.valid()) _graphicsContext->releaseGLObjects(state); +}