Re: [Plib-users] How to run loader and render in separate threads?
Brought to you by:
sjbaker
From: Curtis L. O. <cu...@fl...> - 2003-02-20 19:02:54
|
Brian R Hill writes: > Does anyone have an example of how to run a loader process (read files, > create ssg objects, merge into scene graph) and rendering process (glut and > ssgcullandraw) in separate threads? FlightGear does this, but I wouldn't call the code straight forward. There are a couple things you need to watch out for. You mustn't *ever* interleave opengl commands between two threads. This is a recipe for disaster. OpenGL is not thread safe, you can think of it as a single resource. Even worse, it's a state machine so the order of opengl calls is very important. Imagine if you are rendering in one thread, and loading a model (and therefore probably textures) in another; and the opengl commands from those two threads get interleaved. Most likely you'll just get a crash, but if your code somehow survived, you'd still likely get some bizarre rendering effects. FlightGear goes to great lengths (and thus complexity) to avoid doing any opengl commands outside of the main render loop. We also are careful not to alter the main scene graph while it is being rendered. So, we: - load all self contained models from the main render loop. (Terrain is a specialized case that we have complete control over so we can load that in the thread.) - In the second thread we don't actually modify the main scene graph. Instead we build up sub trees, push those onto a queue, and then have the main thread connect this tree into the main scene graph. - Likewise, we can lop off a sub tree we want to delete in the main thread, and then work on deleting it in a 2nd thread ... however if you have multiple instances of objects in your graph you need to be really careful. We ended up not doing this in our 2nd thread. Instead we wrote a routine that deletes "n" elements of a subtree and then bails out. This way we can spread the work of deleting a sub tree over several frames, call the routine from the main render thread, and not worry about scene graph consistency issues. As you can imagine this all adds a big measure of complexity. We have load queues, model load queues, attache queues, free queues, etc. We have also found that introducing threading is a great way to add really subtle and very hard to find bugs to your program. My advice is to only do threading as a last resort. It's one thing to code a simple producer / consumer example for a class, it can be an entirely different thing to add threading to a large, complex, real world app. Beware! :-) Regards, Curt. -- Curtis Olson IVLab / HumanFIRST Program FlightGear Project Twin Cities cu...@me... cu...@fl... Minnesota http://www.menet.umn.edu/~curt http://www.flightgear.org |