Threading options for JOGL

I know this is not a new question and I did look through information I could find but this is still confusing. I would like to understand my options when it comes to thread management for JOGL.
Here are my options as I understand them so far:

  1. AWT mode. Basically, standard AWT event-based rendering model, where when some parameters of the model change I call .repaint and AWT thread calls .display. In this model I can still call .display as blocking, which detects that we are in a wrong thread and basically does an alternative or .repaint();.wait() and when display called from AWT (see above) finishes it sends a notify() to current thread. Or maybe this is not how it works but this is the basic effect.
    Easy enough…
  2. I can call Threading.disableSingleThreading() which… I am not really sure what it will do. Does it allow me to call GL instructions from my thread AND from AWT thread? In that case, if I do not add any listeners to the GLCanvas, am I safe putting my main loop in the current thread? Are there details on this mode anywhere?
  3. I can call Threading.invokeOnOpenGLThread(Runnable r). I am not sure what this does though. Will it call r only once (sort of like invokeLater())? It seems that by default (or in the current implementation) it is dropped into AWT thread so if I put my main loop there I will effectively lock rest of AWT. Would this be a correct assessment?

These are the options I see so far. Are these correct? What I want to do is the main loop as described in the User’s Guide. The problem with having main loop in one thread and invoking GLCanvas.display in it is that this is not the only way to initiate repaint and I am not sure what other conditions I need to cover (window gets focus, window is resized, another window moves so that this window is now visible, etc.). I want to make sure my rending does not start while I am updating the scene. Is N2 my only/best option?

You’re right about what #1 does. For #2, calling Threading.disableSingleThreading() will cause the GLCanvas.display() method to always execute on the current thread which called it. I would strongly recommend against doing this as it will cause problems with many kinds of graphics cards on all platforms due to many OpenGL drivers’ lack of robust support for multithreaded applications. #3 is really only needed if you’re calling GLContext.makeCurrent()/release() yourself and want to interoperate correctly with the implementation of GLCanvas.display().

For your application’s purposes you can still write your main loop as you want. Depending on how your scene is updated you may need to be careful. If your goal is to write the main loop which performs the updates and then calls display(), you’re right, it’s possible that a render may be initiated without your calling display(). Rather than try to work around this fact I would suggest you protect your scene with one global lock which is held during updates and also during the rendering process. This is the easiest solution. I’ve personally done this in another project recently and it works fine; no scalability problems. There used to be APIs in JOGL which tried to restrict the redrawing done outside display() but they were removed as being too complicated to explain. Nonetheless you may be able to use Component.setIgnoreRepaint(true) (which is in the core AWT API) to achieve this as well.

Ken,
Thank you for the reply. This is probably my personal witchhunt and may be not worth-while but I would really like to stay out of AWT thread for several reasons.

  1. Additional synchronization requirements. These are probably not hard to do but I have had some issues with Java synchronization, especially with fast paced environments (mostly when lock was not available long enough for different thread to grab it). These are all resolvable (and pretty easily) but I still would like to review my options…
  2. Scene rendering is a heavy procedure. I am a lausy programmer. I want to make sure that when I mess something up AWT still works and I can at least close the window.
  3. Not sure 3 is needed since it’s very close to 1 and 2 but when you lock AWT on something that happens in another thread it can create a pretty sluggish and unresponsive environment if AWT components (buttons, labels, etc.) are used.

Said all that, I agree that option 2 is probably not the best one (or rather I realize that now, thanks for explanation). However your metioning GLContext.makeCurrent() made me currious. Is this any different from good old setRenderingThread? Is there documentation on this API beyond Javadoc? It looks like this would be the best bet but I would really like to get more information.
Again, thank you for the reply, I will look into your suggestions.

I understand your concerns but if you attempt to do OpenGL rendering from any other thread than the AWT event queue thread you are opening yourself up to lots of problems. For best stability and portability I recommend using the GLEventListener mechanism, calling GLCanvas.display() in your main loop, and basically forgetting about which thread is doing the actual OpenGL rendering.

The GLContext API new in JSR-231 provides direct control over the OpenGL context. The old GLCanvas.setRenderingThread() attempted to do some context optimization behind the scenes but it was never very robust and was discarded. It is possible to do the same thing now using just the GLContext APIs. I personally think though that using the callback mechanism is generally going to be more portable and reliable.

Ken,
Thank you as always. I understand your recommendation and will follow it, at least until I have better undrstanding of OpenGL in general and JOGL in particular.
However I would still like to continue researching threading with respect to OpenGL in general and JOGL in particular. What do you think would be the best approach for me to get more details on GLContext and the stability problems you are talking about (and maybe some articles about implementation on different platforms and threading)?

Probably the best way to see what was fixed is to browse the old mail archives for the cvs@jogl.dev.java.net mailing list from the time period where the JOGL 1.1 and 1.1.1 releases were being worked on. There is some amount of discussion of multithreading issues in the JOGL User’s Guide as well. You can probably find other articles by Googling for terms like “opengl multithreading”.

I am too a bit unhappy with the AWT event thread being blocked by GL calls. Multithreaded swing is already hard enough without GL :wink:

Is there a specific reason to lock the rendering to the AWT event thread? Wouldn’t any other thread be equally good as long the rendering remains constantly on the same single thread? So why isn’t there a dedicated “GLRenderManagerThread” or something in jogl for synchronizing the GLEventListener calls?

Don’t take this as criticism, I am just curious =)

If I had to guess I would assume that the idea is to keep all rendering in one thread since multiple widgets (and some of them even overlaping) can be using GL and thus you are no longer locking GL processing in one thread and this wa problematic. But that’s if I had to guess, and I don’t since there are people here who can just answer your quest :wink:

Could you be a little more concrete about the problems you’re having? It seems to me that most OpenGL rendering should be very fast and therefore in the current setup should not block the EDT for long periods of time.

The original motivation was (1) that the EDT was already present and (2) a hypothesis that making all of the window system-related operations occur on one thread would have better stability than doing the work on a different thread. However you raise a good point and in fact Issue 191 was filed a few weeks ago covering this. The main problem is that it isn’t guaranteed that there’s always exactly 1 EDT. The single-threaded rendering project in Java2D in Mustang indicates that as long as the OpenGL work is done by one thread (even if it isn’t the EDT) stability is still good on most drivers, so we may switch JOGL over to a different thread than the EDT.

[quote]Could you be a little more concrete about the problems you’re having? It seems to me that most OpenGL rendering should be very fast and therefore in the current setup should not block the EDT for long periods of time.
[/quote]
I must admit, that my current problems result from lazyness like not doing texture loading etc. outside the gl callback. However, I am currently starting a GLSL editor plugin for netbeans and am afraid, the whole IDE could freeze, if for example the preview renderer goes to software-emulation for some reasons. I noticed this behaviour in the OpenGL Shader Designer and want to avoid that.