CompositeViewer support: Difference between revisions

Jump to navigation Jump to search
m
Line 266: Line 266:
of support I can provide for free.<ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg01766.html</ref>
of support I can provide for free.<ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg01766.html</ref>


=== Data Variance ===
The OSG is built for multi-threading of osgViewer View's in various ways, it's not general multi-threading support, it's designed specifically for a scene graph so overheads for that multi-threading to a minimum.
The multi-threading that osgViewer provides is managed by osgViewer itself so it can marshal all the tasks and synchronization correctly.  <ref>https://groups.google.com/g/osg-users/c/bDexX-g2Cag/m/Oj9V4hyuAQAJ</ref>
OpenGL only supports thread per context, so each context can only be driven by a single thread at any time,  The OSG's viewer threading is built around this constraint.
Principally the rendering threads (cull and draw) don't write to the scene graph, they just read from it.  There are a limited number of exceptions where nodes are view dependent and cache state within the node.  This means it should be safe to run an intersection traversal at the same time as the viewer.renderingTraversals() is running.
The OSG by default will use separate OpenGL objects and associated buffers for each graphics context.  If you enable sharing of GL objects between contexts then you'll need to run the application single theaded to avoid these shared GL objects and associated buffers being contend.
You can't use DrawThreadPerContext when sharing contexts except when your scene graph uses no OpenGL objects whatsoever.  So no display lists, no VBO's, no textures etc.  Basically if you want shared contexts you have to use it SingleThread so the different threads don't contend with the same resources.<ref>https://groups.google.com/g/osg-users/c/vtWa-YNQEAY/m/ykNHgbIOD4UJ</ref>
The DataVariance property of osg::Object is used in couple of ways.
For internal nodes of the scene it is used as a hint to operations
such as the osgUtil::Optimizer that parts of the scene graph are
static or dynamic and to use this information as guide to what can be
optimized and in what ways - generally it means leaving DYNAMIC nodes
alone. The DataVariance property on Nodes isn't used during the
update, cull and draw traversals so it's effectively ignored.
For the leaves of the scene graph - the osg::StateSet and
osg::Drawable (and it's subclasses), the DataVariance is only used
when using the DrawThreadPerContext and
CullThreadPerCameraDrawThreadPerContext threading models and is used
during the draw traversal to prevent the next frame from commensing
till all DYNAMIC StateSet and Drawables are dispatch. For
SingleThreaded and CullDrawThreadPerContext threading models the
DataVariance is not used as the next frame doesn't commence till the
whole draw dispatch is completed.
The DataVariance of the StateAttribute subclasses is not used in
update, cull or draw traversals, and like nodes is only used be
specialist traversals like some of the ones contained in the
Optimizer. So if you want to dynamic update a Uniform then the way to
make sure that draw doesn't overlap the update of it is to set the
DataVariance of the StateSet that enclose it to DYNAMIC. There isn't
an automatic scheme to check the DataVariance of StateAttributes as it
would be prohibitively expensive to do during the draw traversal.<ref>https://groups.google.com/g/osg-users/c/Lo98dBo07Pg/m/eqSsfES7hGcJ</ref>
In all the OSG 2.x series the DataVariance is used during the draw
traversal to monitor when all DYNAMIC StateSet and Drawables have been
dispatched, as once they have been the next frame can be started in a
parallel with the remaining STATIC objects are rendered (in
DrawThreadPerContex, CullThreadPerCameraDrawThreadPerContext threading
models.)
The rule of thumb is that the Data Variance should be set to DYNAMIC on instances that change once that have been added to the Scenegraph. The short reason why is that this allows the Cull and draw threads to correctly handle and stage any changes that may be made in the app threads to the instances
<ref>https://groups.google.com/g/osg-users/c/jgS0PqLcvtI/m/qlPPWXTNpzIJ</ref>
With the DrawThreadPerContext and DrawThreadPerContextCullThreadPerCamera threading models the static part of the rendering can be done in parallel with the next frame.  You guess this correct.
The one thing I'd add is that the OSG itself doesn't attempt to sort DYNAMIC objects so that are drawn first.  You can set up your StateSet::RenderBinDetails to force the dynamic objects to be drawn first, but you can only do this for objects that don't affect the rendering of other objects, or are affected by what is the fame buffer already.
StateSets and Drawables must be marked as DYNAMIC is you plan to change them. That's because they are used by the rendering stage, which can overlap the next frame's update.
Everything else (scene graph structure, etc.) is safe to change during the Update traversal/callbacks.<ref>https://groups.google.com/g/osg-users/c/j2_2vCDFdTw/m/oasQIb7HCgAJ</ref>
=== Threading ===
=== Threading ===
In single threaded mode, you can safely have a single threaded viewer and still have the DatabasePager working with multi-threading in the background.<ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg61170.html</ref>
In single threaded mode, you can safely have a single threaded viewer and still have the DatabasePager working with multi-threading in the background.<ref>https://www.mail-archive.com/osg-users@lists.openscenegraph.org/msg61170.html</ref>

Navigation menu