[osg-users] [About VertexArrayObject Branch] FeedBack and Insight

Robert Osfield robert.osfield at gmail.com
Sun Sep 4 04:35:46 PDT 2016

Hi Julien,

Updating VAO's isn't particularly costly in itself, the cost that
Jannik was seeing was entirely down to the fact that the when you use
DrawThreadPerContext the next frame is held back until all StateSet
and Drawable's that have been dispatched.  The solution for Jannik was
nothing more than call drawable->dirtyGLObjects() to force the VAO to
compile the VBO's without setting the DataVariance to DYNAMIC.

I may introduce a STREAM entry to the DataVariance enum to capture
data the idea that data is not being reallocated/sizes being changed,
just updated in place on each frame and hence not a thread critical
data change.  I haven't made any decision on this yet,

The question whether we need to share VAO's between Drawable is really
down to whether there is any tangible performance benefit.  For you
own tests I believe the cost of matching up VAO's at runtime was too
high so distorted the results to have fewer VAO's.

The implementation in the vertex_array_branch minimises the cost of
switching between VAO's avoiding any dynamic matching costs.  Adding
sharing of VertexArrayState is possible but if we do it it's something
that should be done in scene graph creation not dynamically during the
draw traversal.  If we did add sharing of VAS then I'd do it by adding
a data structure above VAS that contains a the buffer_object<VAS> that
is presently in Drawable.  This contain object would be the bit that
would be shared between Drawable and it would only make sense to share
it when the associated Drawable all share the same osg::Array's.

An osgUtil::Optimizer pass could easily do this match up after loading
of scene graph.  You potentially could have an optimization pass that
merges osg::Arraty's and reassigns to the osg::Geometry to make
sharing of VAO's possible.

However, all this work has no established benefit, we don't whether
we'll see any tangible performance benefit to make this extra
complexity worthwhile.  Personally I haven't felt this extra work
justified, we are only like to be seeing small marginal gains at this
point as the bulk of the gains achievable with VAO have already been

At this stage my priority is getting the getting the wider community
to start testing the vertex_array_branch and get ready to merge with
master as soon as possible, then it's time to move on to getting
OSG-3.6 ourt the door.  Effort on this front is where I really need


On 3 September 2016 at 15:09, Julien Valentin
<julienvalentin51 at gmail.com> wrote:
> Hi Robert,
> I think I understand what Jannik wanna means:
> Dynamic meshes doesn't require the vao to be "recompiled" on arrays changes. The only case when vao have to be redefined/"recompiled" is when vas change (in case of arrays adding/removing)
> So the datavariance of arrays is DYNAMIC but in order not to force the vao to be redifined at each frame (and the loossing all advantages of using vao) ones should set datavariance of the geometry to STATIC.
> So it leads to datavariance semantic violation...
> What I think of is making VAS a component of Drawable with that kind of code:
> class VAS : Object {
> void setVertexArray(Array);
> void setNormalArray(Array);
> protected:
> mutable bufferred_object<PCVAS> percontextVAS;
> }
> With this kind of stuff ones could control the data variance of the VAS itself and not the drawable:
> For the case of dynamic meshes:
> -geometry and arrays dattavariance would be DYNAMIC
> -but geometry vas datavariance would be STATIC
> (Further it would allow to share VAO  between Drawables at compile time)
> ...and everyone would be happy...No?
> I'm currently trying to implement it but I would rather have your opinion first (to avoid coding for nothing)
> Cheers
> robertosfield wrote:
>> Hi Jannik,
>> On 17 August 2016 at 14:52, Jannik Heller <> wrote:
>> > I have tested out the VAO branch on my Nvidia graphics card. As you said, VAO+VBO is slightly faster than VBO but not as fast as display lists. Would be curious on the performance results with AMD cards.
>> >
>> > Unfortunately, I am unable to use VAO for animated meshes because you've introduced a new meaning of the dataVariance flag. https://github.com/openscenegraph/OpenSceneGraph/blob/vertex_array_object/include/osg/Drawable#L523
>> >
>> I haven't introduced a new meaning to DataVariance, all I have done it
>> utilize it for knowing whether the VAO needs updating or not.  I have
>> done this to avoid the extra checks required against the individual
>> arrays to see if they are dirty or not - I have done it for
>> performance reasons as I want to keep the CPU overhead for draw
>> dispatch as low as possible.
>> > I do *not* set the dataVariance to DYNAMIC for all my animated meshes because the performance overhead of DYNAMIC is not acceptable for me. If Drawables are set to DYNAMIC, OSG would not break frame until all the draws are submitted. I manage the updates using a double buffering scheme that prevents the buffer from being modified while the draw thread is using it. So essentially I don't need the DYNAMIC flag, but now I'm forced to use it (and incur the performance overhead associated with it) because OSG won't update the arrays if I don't. :( Previously it was sufficient to dirty() the vertex arrays to get OSG to update things. Hopefully that can be fixed.
>> >
>> This is a sticky one.  Your mesh *is* dynamic, the correct way to
>> label the geometry is DYNAMIC.  In your usage case you are taking
>> advantage of the fact that in certain circumstances you ignore the
>> threading issues associated with dynamically updating whilst it's
>> being dispatched by the drawing thread, however, this is a dangerous
>> game to play that you have to be really careful to do without
>> introducing a race condition.  Whether you are just getting lucky in
>> your code or it's genuinely safe I can't say as I don't have the code.
>> In your case you are wanting a DataVariance of
>> I guess the special case where modifying the data is safe would be
>> STATIC_ALLOCATION_DYNAMIC_UPDATE or something along those line.
>> Perhaps STREAM might be terminology that might fit this.
>> However, even with the STREAM case if you are updating in the update
>> or cull traversal while the draw thread is reading that same data you
>> could get corrupted data sent to OpenGL driver, here you really should
>> be double buffering.
>> I'll ponder on this issue, but for now strictly speaking the VAO
>> implementation is perfectly correct, requiring that the DataVariance
>> be DYNAMIC is a correct interpretation of what the DataVariance is.
>> Robert.
>> _______________________________________________
>> osg-users mailing list
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>  ------------------
>> Post generated by Mail2Forum
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=68509#68509
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

More information about the osg-users mailing list