From f6b64afdfcff216e33fe85f5a8694d42ec80856b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 8 Jan 2019 19:32:50 +0000 Subject: [PATCH] Fixed for crashes on exit associaciated with VAO usage and vairous niche usage cases --- include/osg/Object | 1 - include/osg/Referenced | 11 ++++++- include/osg/View | 3 ++ include/osgUtil/RenderLeaf | 10 ++++++ include/osgUtil/SceneView | 3 ++ include/osgUtil/StateGraph | 40 ++++++++++++++++++++++-- include/osgViewer/Renderer | 3 ++ src/osg/Camera.cpp | 7 ++++- src/osg/GraphicsContext.cpp | 2 +- src/osg/View.cpp | 23 ++++++++++++++ src/osgSim/LightPointDrawable.cpp | 1 - src/osgUtil/SceneView.cpp | 52 +++++++++++++++++++++++++++++++ src/osgViewer/Renderer.cpp | 12 +++++++ 13 files changed, 161 insertions(+), 7 deletions(-) diff --git a/include/osg/Object b/include/osg/Object index f15257e2b..fe0031388 100644 --- a/include/osg/Object +++ b/include/osg/Object @@ -25,7 +25,6 @@ namespace osg { // forward declare -class State; class UserDataContainer; class Node; class NodeVisitor; diff --git a/include/osg/Referenced b/include/osg/Referenced index 924b06390..2c83276c0 100644 --- a/include/osg/Referenced +++ b/include/osg/Referenced @@ -30,6 +30,7 @@ namespace osg { class DeleteHandler; class Observer; class ObserverSet; +class State; /** template class to help enforce static initialization order. */ template @@ -115,7 +116,15 @@ class OSG_EXPORT Referenced /** Remove Observer that is observing this object.*/ void removeObserver(Observer* observer) const; - public: + /** 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 objects + * for all graphics contexts. */ + virtual void releaseGLObjects(osg::State* = 0) const {} + +public: friend class DeleteHandler; diff --git a/include/osg/View b/include/osg/View index 6143be11b..e45c326a3 100644 --- a/include/osg/View +++ b/include/osg/View @@ -161,6 +161,9 @@ class OSG_EXPORT View : public virtual osg::Object void updateSlaves(); + virtual void resizeGLObjectBuffers(unsigned int maxSize); + virtual void releaseGLObjects(osg::State* = 0) const; + protected : virtual ~View(); diff --git a/include/osgUtil/RenderLeaf b/include/osgUtil/RenderLeaf index f219a8634..ec621bd12 100644 --- a/include/osgUtil/RenderLeaf +++ b/include/osgUtil/RenderLeaf @@ -72,6 +72,16 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced virtual void render(osg::RenderInfo& renderInfo,RenderLeaf* previous); + virtual void resizeGLObjectBuffers(unsigned int maxSize) + { + if (_drawable) _drawable->resizeGLObjectBuffers(maxSize); + } + + virtual void releaseGLObjects(osg::State* state=0) const + { + if (_drawable) _drawable->releaseGLObjects(state); + } + /// Allow StateGraph to change the RenderLeaf's _parent. friend class osgUtil::StateGraph; diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 22f5f42a5..2870d0b49 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -484,6 +484,9 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings * then need to be deleted in OpenGL by SceneView::flushAllDeleteGLObjects(). */ virtual void releaseAllGLObjects(); + virtual void resizeGLObjectBuffers(unsigned int maxSize); + virtual void releaseGLObjects(osg::State* = 0) const; + /** Flush all deleted OpenGL objects, such as texture objects, display lists, etc.*/ virtual void flushAllDeletedGLObjects(); diff --git a/include/osgUtil/StateGraph b/include/osgUtil/StateGraph index cc78face4..e170342b1 100644 --- a/include/osgUtil/StateGraph +++ b/include/osgUtil/StateGraph @@ -43,8 +43,8 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced public: - typedef std::map< const osg::StateSet*, osg::ref_ptr > ChildList; - typedef std::vector< osg::ref_ptr > LeafList; + typedef std::map< const osg::StateSet*, osg::ref_ptr > ChildList; + typedef std::vector< osg::ref_ptr > LeafList; StateGraph* _parent; @@ -172,6 +172,42 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced void prune(); + void resizeGLObjectBuffers(unsigned int maxSize) + { + for(ChildList::iterator itr = _children.begin(); + itr != _children.end(); + ++itr) + { + (itr->second)->resizeGLObjectBuffers(maxSize); + } + + for(LeafList::iterator itr = _leaves.begin(); + itr != _leaves.end(); + ++itr) + { + (*itr)->resizeGLObjectBuffers(maxSize); + } + } + + void releaseGLObjects(osg::State* state=0) const + { + if (_stateset) _stateset->releaseGLObjects(state); + + for(ChildList::const_iterator itr = _children.begin(); + itr != _children.end(); + ++itr) + { + (itr->second)->releaseGLObjects(state); + } + + for(LeafList::const_iterator itr = _leaves.begin(); + itr != _leaves.end(); + ++itr) + { + (*itr)->releaseGLObjects(state); + } + } + inline StateGraph* find_or_insert(const osg::StateSet* stateset) { // search for the appropriate state group, return it if found. diff --git a/include/osgViewer/Renderer b/include/osgViewer/Renderer index f570fbe4a..a8dbb7ea9 100644 --- a/include/osgViewer/Renderer +++ b/include/osgViewer/Renderer @@ -60,6 +60,9 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation virtual void compile(); + virtual void resizeGLObjectBuffers(unsigned int maxSize); + virtual void releaseGLObjects(osg::State* = 0) const; + void setCompileOnNextDraw(bool flag) { _compileOnNextDraw = flag; } bool getCompileOnNextDraw() const { return _compileOnNextDraw; } diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index 81bc80672..1fec7aadc 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -340,9 +340,14 @@ void Camera::resizeGLObjectBuffers(unsigned int maxSize) void Camera::releaseGLObjects(osg::State* state) const { + if (_renderer.valid()) + { + _renderer->releaseGLObjects(state); + } + if (_renderingCache.valid()) { - const_cast(this)->_renderingCache->releaseGLObjects(state); + _renderingCache->releaseGLObjects(state); } Transform::releaseGLObjects(state); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 9d172ec88..1a35497d0 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -438,7 +438,7 @@ bool GraphicsContext::realize() void GraphicsContext::close(bool callCloseImplementation) { - OSG_INFO<<"close("<resizeGLObjectBuffers(maxSize); + + for(Slaves::iterator itr = _slaves.begin(); + itr != _slaves.end(); + ++itr) + { + if (itr->_camera.valid()) itr->_camera->resizeGLObjectBuffers(maxSize); + } +} + +void View::releaseGLObjects(osg::State* state) const +{ + if (_camera) _camera->releaseGLObjects(state); + + for(Slaves::const_iterator itr = _slaves.begin(); + itr != _slaves.end(); + ++itr) + { + if (itr->_camera.valid()) itr->_camera->releaseGLObjects(state); + } +} diff --git a/src/osgSim/LightPointDrawable.cpp b/src/osgSim/LightPointDrawable.cpp index b97e5461a..5af537d6b 100644 --- a/src/osgSim/LightPointDrawable.cpp +++ b/src/osgSim/LightPointDrawable.cpp @@ -56,7 +56,6 @@ LightPointDrawable::LightPointDrawable(const LightPointDrawable& lpd,const osg:: LightPointDrawable::~LightPointDrawable() { - OSG_NOTICE<<"LightPointDrawable::~LightPointDrawable()"<releaseGLObjects(_renderInfo.getState()); } +void SceneView::resizeGLObjectBuffers(unsigned int maxSize) +{ + struct Resize + { + unsigned int maxSize = 1; + + Resize(unsigned int ms) : maxSize(ms) {} + + void operator() (osg::Referenced* object) + { + if (object) object->resizeGLObjectBuffers(maxSize); + } + } operation(maxSize); + + operation(_localStateSet.get()); + operation(_updateVisitor.get()); + operation(_cullVisitor.get()); + operation(_stateGraph.get()); + operation(_renderStage.get()); + operation(_cullVisitorRight.get()); + operation(_stateGraphRight.get()); + operation(_renderStageRight.get()); + operation(_globalStateSet.get()); + operation(_secondaryStateSet.get()); + operation(_cameraWithOwnership.get()); +} + +void SceneView::releaseGLObjects(osg::State* state) const +{ + if (state && state!=_renderInfo.getState()) return; + + struct Release + { + void operator() (const osg::Referenced* object) + { + if (object) object->releaseGLObjects(); + } + } operation; + + operation(_localStateSet.get()); + operation(_updateVisitor.get()); + operation(_cullVisitor.get()); + operation(_stateGraph.get()); + operation(_renderStage.get()); + operation(_cullVisitorRight.get()); + operation(_stateGraphRight.get()); + operation(_renderStageRight.get()); + operation(_globalStateSet.get()); + operation(_secondaryStateSet.get()); + operation(_cameraWithOwnership.get()); +} + void SceneView::flushAllDeletedGLObjects() { _requiresFlush = false; diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 706277801..59775885e 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -930,6 +930,18 @@ void Renderer::operator () (osg::GraphicsContext* /*context*/) } } +void Renderer::resizeGLObjectBuffers(unsigned int maxSize) +{ + if (_sceneView[0].valid()) _sceneView[0]->resizeGLObjectBuffers(maxSize); + if (_sceneView[1].valid()) _sceneView[1]->resizeGLObjectBuffers(maxSize); +} + +void Renderer::releaseGLObjects(osg::State* state) const +{ + if (_sceneView[0].valid()) _sceneView[0]->releaseGLObjects(state); + if (_sceneView[1].valid()) _sceneView[1]->releaseGLObjects(state); +} + void Renderer::release() { OSG_INFO<<"Renderer::release()"<