Fixed for crashes on exit associaciated with VAO usage and vairous niche usage cases

This commit is contained in:
Robert Osfield 2019-01-08 19:32:50 +00:00
parent 1c65815f4e
commit f6b64afdfc
13 changed files with 161 additions and 7 deletions

View File

@ -25,7 +25,6 @@
namespace osg {
// forward declare
class State;
class UserDataContainer;
class Node;
class NodeVisitor;

View File

@ -30,6 +30,7 @@ namespace osg {
class DeleteHandler;
class Observer;
class ObserverSet;
class State;
/** template class to help enforce static initialization order. */
template <typename T, T M()>
@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -43,8 +43,8 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
public:
typedef std::map< const osg::StateSet*, osg::ref_ptr<StateGraph> > ChildList;
typedef std::vector< osg::ref_ptr<RenderLeaf> > LeafList;
typedef std::map< const osg::StateSet*, osg::ref_ptr<StateGraph> > ChildList;
typedef std::vector< osg::ref_ptr<RenderLeaf> > 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.

View File

@ -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; }

View File

@ -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<Camera*>(this)->_renderingCache->releaseGLObjects(state);
_renderingCache->releaseGLObjects(state);
}
Transform::releaseGLObjects(state);

View File

@ -438,7 +438,7 @@ bool GraphicsContext::realize()
void GraphicsContext::close(bool callCloseImplementation)
{
OSG_INFO<<"close("<<callCloseImplementation<<")"<<this<<std::endl;
OSG_INFO<<"GraphicsContext::close("<<callCloseImplementation<<")"<<this<<std::endl;
// switch off the graphics thread...
setGraphicsThread(0);

View File

@ -222,3 +222,26 @@ unsigned int View::findSlaveIndexForCamera(osg::Camera* camera) const
return _slaves.size();
}
void View::resizeGLObjectBuffers(unsigned int maxSize)
{
if (_camera) _camera->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);
}
}

View File

@ -56,7 +56,6 @@ LightPointDrawable::LightPointDrawable(const LightPointDrawable& lpd,const osg::
LightPointDrawable::~LightPointDrawable()
{
OSG_NOTICE<<"LightPointDrawable::~LightPointDrawable()"<<std::endl;
}
void LightPointDrawable::reset()

View File

@ -927,6 +927,58 @@ void SceneView::releaseAllGLObjects()
_camera->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;

View File

@ -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()"<<std::endl;