Show
Ignore:
Timestamp:
09/04/15 17:35:24 (8 hours ago)
Author:
robert
Message:

From Jannik Heller, "I've hit what I believe to be a bug (or at the very least, an unintuitive behaviour) in the osg::Geometry copy constructor. I noticed it when using osg::clone on a Geometry with vertex buffer objects, and the copy flags DEEP_COPY_ARRAYS. To be precise, I add a Geometry to an osgUtil::IncrementalCompileOperation?, then osg::clone the Geometry. I was getting reports from users of random crashes happening.

I believe the offending lines are in the osg::Geometry copy constructor:

if ((copyop.getCopyFlags() & osg::CopyOp::DEEP_COPY_ARRAYS))
{

if (_useVertexBufferObjects)
{

// copying of arrays doesn't set up buffer objects so we'll need to force
// Geometry to assign these, we'll do this by switching off VBO's then renabling them.
setUseVertexBufferObjects(false);
setUseVertexBufferObjects(true);

}

}

Toggling the vertex buffer objects off then on again actually touches not only the arrays controlled by DEEP_COPY_ARRAYS, but also the PrimitiveSets? which are controlled by DEEP_COPY_PRIMITIVES. This means if the user has copyflags of only DEEP_COPY_ARRAYS, we are modifying arrays that belong to the original const Geometry& we are copying from. I believe this shouldn't be allowed to happen because we are using a const& specifier for the original Geometry.

In my case the osgUtil::IncrementalCompileOperation? was trying to compile the geometry, while in the main thread a clone operation toggled the VBO's off and on, a crash ensues.

In the attached patch, you will find a more efficient handling of VBO's in the osg::Geometry copy constructor, so that only the Arrays that were actually deep copied have their VBO assigned, and no changes are made to Arrays that already had a valid VBO assigned. In addition, the DEEP_COPY_PRIMITIVES flag is now honored so that VBO's are set up correctly should a user copy a Geometry with only that flag.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osgViewer/View

    r13172 r13376  
    228228        bool containsCamera(const osg::Camera* camera) const; 
    229229 
    230         /** Get the camera which contains the pointer position x,y specified in the master camera's window/eye coordinates. 
    231           * Also passes back the local window coordinatess for the graphics context associated with the camera. */ 
     230         
     231        /** deprecated. */ 
    232232        const osg::Camera* getCameraContainingPosition(float x, float y, float& local_x, float& local_y) const; 
    233233 
    234         /** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified node. 
    235           * Note, when a master camera has slaves and no viewport itself, its coordinate frame will be in clip space i.e. -1,-1 to 1,1, 
    236           * while if it has a viewport the coordintates will be relative to its viewport dimensions. 
    237           * Mouse events handled by the view will automatically be attached to the master camera window/clip coordinates so that they can be passed 
    238           * directly to the computeIntersections method. */ 
     234        /** deprecated. */ 
    239235        bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
    240236 
    241         /** Compute intersections between a ray through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */ 
     237        /** deprecated. */ 
    242238        bool computeIntersections(float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
    243239 
     240         
     241        /** Compute intersections of a ray, starting the current mouse position, through the specified camera. */ 
     242        bool computeIntersections(const osgGA::GUIEventAdapter& ea, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
     243 
     244        /** Compute intersections of a ray, starting the current mouse position, through the specified master camera's window/eye coordinates and a specified nodePath's subgraph. */ 
     245        bool computeIntersections(const osgGA::GUIEventAdapter& ea, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
     246 
     247         
     248        /** Compute intersections of a ray through the specified camera. */ 
     249        bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
     250 
     251        /** Compute intersections of a ray through the specified camera and a specified nodePath's subgraph. */ 
     252        bool computeIntersections(const osg::Camera* camera, osgUtil::Intersector::CoordinateFrame cf, float x,float y, const osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); 
    244253 
    245254        virtual void requestRedraw();