ffmpeg/Threading issues in 1.8.0?

Since you have tasks that are different task chains (threads) operating on the same counter, it is entirely up to you to ensure that they don’t try to operate on the counter simultaneously. So, no, this is not overkill, this is correct.

David

Hmm… I think I have a slower but less dirty implementation for the BulletDebugNode still around somewhere on my disks. I go searching and check it in this weekend.

I checked in an alternate way of rendering the debug geometry for Bullet. It slower, but I hope it won’t freeze this way.

So far I have created geom/vdata/primitive once, and kept the pointer around. This is bound to cause trouble if Panda3D starts to optimize. Now I get geom/primitive pointer each frame using the “get modify” functions.

Please let me know sometime if the freezes are gone now. I still have a third way of rendering up m y sleeve, if there are still problems.

Hi enn0x, I’ll give a try and let you know how it goes.

FYI. Since I removed the use of BulletDebugNode, I didn’t experience a freeze.

My two $ feeling:
Overall the issue with Bullet modifying geometries in a thread that is separated from the main thread, is that the change may happen any time (as seen by the main thread) and screw up things.
Having a critical section could be one way, but I tend to think that what should be done is to insure that the change occurs in the main_thread. This can be done maybe by generating an “event” that will take care of the change (at the beginning of next frame).

Concurrent activities and proper synchronizations using threads are really interesting!

The safe way to modify geometry in a sub-thread that might be attached to the scene graph (and thus discoverable by the render thread) is to create new geometry and assign it in place with GeomNode::set_geom(). set_geom() is atomic, but GeomVertexRewriter and other related methods are not.

If you only need to modify vertices, you can use Geom::set_vertex_data(), which is also atomic. If you only need to animate vertex indices, you can use GeomPrimitive::set_indices(), and so on. But if you need to change both of these at once, then you have no choice but to use GeomNode::set_geom().

David

I have two Geoms within the GeomNode, one for lines and one for triangles. Currently I use node->modify_geom() each frame to get the geom, then I clear the vertices/indices, and use GeomVertexWriter to write new ones. The number of vertices is not constant, so just rewriting vertex positions is not enough.

If I understand you right you suggest creating two new PT(Geom) each frame, and replace the old geoms with node->set_geom(idx, geom)? Ok, will change the code this evening.

Right, the problem is that if the render thread comes across the GeomNode while you are modifying its vertices, it will read incomplete data. So you have to either guarantee that your thread doesn’t run in parallel with the render thread, or you have to do all of your modifications on geometry that’s not attached to the scene graph, and only attach it once you’re finished.

Of course, with graphics-threading-model set to anything other than empty, the render thread will run on its own copy of the data anyway, so you’d be safe in that case. And if the debug geometry were being computed in the main thread, you’d also be safe.

It’s only a potential problem when the debug geometry is being computed in its own child thread which is running in parallel with the main thread, and the graphics-threading-model is empty, causing the rendering to occur in the main thread.

David

Ok, applied to CVS.