20,741
edits
m (→Canvas.Path (OpenVG): https://forum.flightgear.org/viewtopic.php?f=71&t=39535&hilit=path+osg+canvas&start=45#p390533) |
m (→Canvas.Path (OpenVG): https://forum.flightgear.org/viewtopic.php?f=71&t=39535&hilit=path+osg+canvas&start=45#p390536) |
||
Line 274: | Line 274: | ||
{{Main article|Canvas Path}} | {{Main article|Canvas Path}} | ||
<!-- | |||
{{WIP}} | {{WIP}} | ||
--> | |||
Will likely need to replace shiva vg with an OpenGL 2.0 based implementation like nanovg <ref>https://github.com/memononen/nanovg</ref>. | Will likely need to replace shiva vg with an OpenGL 2.0 based implementation like nanovg <ref>https://github.com/memononen/nanovg</ref>. | ||
Line 308: | Line 310: | ||
As far as I can tell right now, it's due to ShivaVG - which some core devs have been wanting to replace/update for years anyway, see for example James' comments on "Skia": [[Canvas_news#Skia_talks]]. | As far as I can tell right now, it's due to ShivaVG - which some core devs have been wanting to replace/update for years anyway, see for example James' comments on "Skia": [[Canvas_news#Skia_talks]]. | ||
{{Note|It's important to highlight that the issue is apprently not specific to Qt5 and neither to the CompositeViewer or the Compositor - it's a bug that people can probably also trigger when using aggressive OSG threading and a single window, since the shiva back-end may get called from multiple OSG threads.}} | |||
it does make sense that the OP can trigger this issue reliably, because he happens to be creating 3 different windows (=threads) - whereas I have been testing with a single additional window, which is why the issue probably takes time to show up. With multiple concurrent threads, the shiva code may get called from different threads, so that it will probably segfault rather "reliably". | it does make sense that the OP can trigger this issue reliably, because he happens to be creating 3 different windows (=threads) - whereas I have been testing with a single additional window, which is why the issue probably takes time to show up. With multiple concurrent threads, the shiva code may get called from different threads, so that it will probably segfault rather "reliably". | ||
Line 314: | Line 319: | ||
Alternatively, we could look at reworking the CanvasPath drawable implementation so that it's using explicit synchronization, to ensure it never gets called from multiple OSG threads.<ref>https://forum.flightgear.org/viewtopic.php?f=71&t=39535&hilit=path+osg+canvas&start=45#p390533</ref> | Alternatively, we could look at reworking the CanvasPath drawable implementation so that it's using explicit synchronization, to ensure it never gets called from multiple OSG threads.<ref>https://forum.flightgear.org/viewtopic.php?f=71&t=39535&hilit=path+osg+canvas&start=45#p390533</ref> | ||
It seems, the current analysis is spot-on, and seems to be in line with comments found in the osg-users archives: | |||
<pre> | |||
https://groups.google.com/g/osg-users/c/nH-73NNFw4A | |||
when using DrawThreadPerContext or CullThreadPerCameraDrawThreadPerContext threading models the StateSet and Drawable DataVariance is used to prevent dynamic leaves of the scene graph being updated and rendered at the same time - the draw traversal holds back the main thread till all the dynamic objects have been dispatched. | |||
https://groups.google.com/g/osg-users/c ... CkzY9geHEJ | |||
The thread safety provided by the OSG isn't quite what you are | |||
assuming, just setting the DataVariance to DYNAMIC only affects | |||
whether the update, event and cull traversals of the current frame can | |||
be run multi-thread the draw traversal of the previous frame, and this | |||
hint is only applicable to StateSet and Drawable and is used to | |||
prevent multi-threading where objects are that are being modified by | |||
the update or event traversals running concurrently with the draw | |||
thread that is reading from them. This threading model is | |||
light-weight in that it avoids the need to large numbers of mutex | |||
locks or multi-buffering, but it doesn't provide an means for general | |||
multi-threading. The OSG's multi-threading also can handle running | |||
cull or draw threads on multiple contexts in parallel, and with | |||
database paging, again this is done a light-weight manner than scales | |||
well and has a small overhead. The design is very much geared towards | |||
the needs of high performance graphics applications rather than | |||
general purpose multi-threading. | |||
So... you'll need to take a step back and work on how to work best | |||
with the design of the OSG. The OSG is designed to allow single | |||
threaded updates of the scene graph during the update and event | |||
traversals. If you do wish to do some work multi-thread preparing new | |||
scene graph elements these can be done as a separate subgraph in a | |||
separate thread then merged with the main scene graph during the | |||
update phase - this is how the osgDB::DatabasePager works. | |||
https://groups.google.com/g/osg-users/c ... YJEx_jcAYJ | |||
Modifying the scene graph outside of the frame call is safe in | |||
SingleThreader, and CullDrawThreadPerCamera threading models as they | |||
don't leave any threads active after the end of the | |||
renderingTraversals() method (called from frame()). | |||
With DrawThreadPerContext and CullThreadPerCamewraDrawThreadPerContext | |||
the draw threads will still be active on completion of the | |||
renderingTraversals(), so if you modifying drawables and state that | |||
the thread is still reading from in the draw traversal you will end up | |||
with problems - and potential crashes. There is a standard mechanism | |||
to deal with this issue - and that is the renderingTraversals() method | |||
to block till all dynamic objects in the draw traversals have been | |||
dispatched. The way you tell the draw traversal that an drawable or | |||
stateset will be modified dynamically is to set its data variance to | |||
DYNAMIC. | |||
drawable->setDataVariance(osg::Object::DYNAMIC); | |||
stateset->setDataVariance(osg::Object::DYNAMIC); | |||
This is mentioned in the "Quick Start Guide" book, as well as many | |||
times on the osg-users mailing list so have a look through the | |||
archives if you want more background reading. | |||
</pre> | |||
OBJECT::DYNAMIC is already being set on the drawable itself (via the interface of sc::Element), but probably not yet on the StateSet (?) - so that might be worth trying next, but other than that, there's probably no "real fix", other than telling OSG not to execute shiva code from multiple threads - short of fixing Shiva, which seems unlikely since a number of core devs have been wanting to get rid of it anyway | |||
So far however everything points at canvas, and looking at canvas code, it seems that there's a lot of stuff going on in update and | So far however everything points at canvas, and looking at canvas code, it seems that there's a lot of stuff going on in update and |