<div dir="ltr"><div><div><div><div><div>Hi Jannik,<br><br></div>General purpose double buffering of data is something I've considered in the past but not attempted to implement into the core OSG as it introduces a range of complexities in implementation and API.  There are places in the OSG where buffering is done locally but in general these are areas where the implementation is lightweight and there is a clear benefit.<br><br></div>In your case it's cool that you've found a way of implementing and got a performance benefit.  It's a complexity that most users haven't tried to tackle before, but I suspect this is probably partly down to not having the same bottlenecks that you are probably seeing.<br><br></div>I don't know the bottlenecks in your app, but for DrawThreadPerContext to make such big difference in performance it would suggest that your are CPU bound.  Are you update, cull, draw dispatch or draw GPU bound?  Use the osgViewer::StatsHandler to show the relatively load on screen.  Most scene graphs app will have a pretty light update, a modest cull and draw dispatch.  If any of these phases are the bottleneck then look to resolving these might be the key to getting best performance rather than adding double buffering.<br><br></div>Also, make sure that you are using a release build when performance profiling, the results you get in debug make a huge difference and can totally distort the relative cost of different phases.<br><br></div><div>Cheers,<br></div>Robert.<br><div><div><div><div><br><br></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 14 April 2015 at 18:28, Jannik Heller <span dir="ltr"><<a href="mailto:scrawl@baseoftrash.de" target="_blank">scrawl@baseoftrash.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi OSG friends,<br>
<br>
A common challenge for OSG users are the implications of the viewer threading model - by default the viewer.frame() will return before the draw dispatch is complete, meaning users (and the OSG) can start preparing the next frame before the current frame has completed. However, if you attempt to change a StateSet or Drawable in the frame update, you run the risk of modifying data that the OSG is still working with in a background thread, resulting in crashes.<br>
Often times you will see code dealing with this by setting the DataVariance of the object to DYNAMIC. Unfortunately as result the draw dispatch has to complete before the frame() returns, for me this dropped the frame rate in half.<br>
Recently I developed a more efficient solution for dealing with this and would like to hear your thoughts.<br>
The idea is similar to "double buffering" with the framebuffer - you create two copies of the data on start, one copy is write only, another copy is read only, and when the frame completes the roles are swapped. You can implement this idea for both Drawables and StateSets:<br>
- Dynamic Drawables (RigGeometry, MorphGeometry, etc): create a deep copy of the Drawable, decorate both Drawables with a FrameSwitch node. A FrameSwitch node is a variant of Group that only traverses even or non-even children based on the current FrameStamp. Code (<a href="https://github.com/OpenMW/openmw/blob/f7da9796692e14c79632cb85fa75a90b082cd863/components/nifosg/nifloader.cpp#L179" target="_blank">https://github.com/OpenMW/openmw/blob/f7da9796692e14c79632cb85fa75a90b082cd863/components/nifosg/nifloader.cpp#L179</a>)<br>
- Dynamic StateSets: Create two copies of the StateSet on start, then every frame in a NodeCallback swap the roles of these StateSets, apply changes to the first StateSet, then set the currently active StateSet on the Node. Code (<a href="https://github.com/scrawl/openmw/blob/osg/components/sceneutil/statesetupdater.cpp#L8" target="_blank">https://github.com/scrawl/openmw/blob/osg/components/sceneutil/statesetupdater.cpp#L8</a>)<br>
<br>
There are some downsides to this approach (mostly that for data that is just rarely changing, you have to apply every change twice), but other than that it works beautifully and now I've got 2x the framerate again.<br>
<br>
I'm curious how the OSG veterans are dealing with this. Anything I've missed?<br>
<br>
Cheers<br>
Jannik<br>
<br>
------------------<br>
Read this topic online here:<br>
<a href="http://forum.openscenegraph.org/viewtopic.php?p=63390#63390" target="_blank">http://forum.openscenegraph.org/viewtopic.php?p=63390#63390</a><br>
<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
osg-users mailing list<br>
<a href="mailto:osg-users@lists.openscenegraph.org">osg-users@lists.openscenegraph.org</a><br>
<a href="http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org" target="_blank">http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org</a><br>
</blockquote></div><br></div>