Multi-thread and osg::MatrixTransform #1207
-
Hi, First I'd like to thank the OSG team for this great framework. In this project, the poses of the objects are refreshed in a separate thread at around 20 Hz. First I have used a This question is to make sure we can multi-thread the transforms update with the rendering. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Strictly speaking you should only update the main scene graph during the update phase of the rendering loop, so between the viewer,advance() and the call to viewer.renderingTraversals() as this is when the internal nodes of the scene graph are being run single threaded. If you use DrawThreqdPerContext then the dynamic StateSet and Drawables that are being handled in the draw thread could overlap with the next frame's update unless you se the hint on them about being them dynamic. I'm afraid it's so long since I did work on this I can't remember the API off the top of my head. In the case of transform nodes, they are internal elements so aren't affected by this and won't have any issues as the next frame will next start will all the internal nodes have been traversed. I started this reply with "Strictly speaking" as while it's true that the OSG is designed to only update the scene graph during the update phase from the main thread for items like a osg::Matrix on an object that lives the full lifetime of each of the threads, something you can guarantee by each thread maintaining it's own ref_ptr<> to the node that own the matrix. then if you modified the matrix values multi-threaded then the worst thing that could happen would be the matrix could be read by the cull traversal in an inconsistent state - this could lead to an object being in the wrong place but it's likely to be a very occurrence, and when it happens you'll have a visual glitch but no risk of crash. Potentially you could also end up with different transforms being update at different times, but again that might not look ideal it probably isn't going to cause a race condition. If you wish to do things in the most robust way then I'd create a way of caching all the updates you want to make to the scene graph in a thread safe buffer, then pull all the changes from this buffer in the update phase and apply all the changes together. This would only require a brief mutex lock of the buffer so shouldn't cause any noticeable performance overhead. This buffered approach could also manage the frame coherence so all the updates that are relevant to particular frame are all applied together, avoiding the issue of transforms being in inconsistent states. |
Beta Was this translation helpful? Give feedback.
-
I would avoid locking the whole frame, far better to have a thread safe queue with the updates you want to make as I outlined, |
Beta Was this translation helpful? Give feedback.
Strictly speaking you should only update the main scene graph during the update phase of the rendering loop, so between the viewer,advance() and the call to viewer.renderingTraversals() as this is when the internal nodes of the scene graph are being run single threaded.
If you use DrawThreqdPerContext then the dynamic StateSet and Drawables that are being handled in the draw thread could overlap with the next frame's update unless you se the hint on them about being them dynamic. I'm afraid it's so long since I did work on this I can't remember the API off the top of my head. In the case of transform nodes, they are internal elements so aren't affected by this and won't have any issues as…