Shared context initialization problems

I am developing a 3D terrain visualization program http://www.virtual-globe.info. I am using JOGL/JSR-231 for rendering. When handling 3D objects (buildings etc…) I use Aviatrix3D / Xj3D for loading and drawing 3D models, which means I have to use the Aviatrix3D render loop. Aviatrix3D uses makeCurrent/release in its own render loop instead of the Animator/listener interface. In addition to a large perspective 3D window I want a smaller orthographic overview map window using simple OGL calls and the default JOGL animator interface. The two windows should share textures.

With the previous versions (Aviatrix3D / Xj3D v:1.0, JOGL v:1.1.1) this worked well (Java Web Start example: http://globe.sintef.no/webstart/hemne-simple.jnlp), but now it bombs when creating shared contexts:

However, if there is a delay between the creation of the two windows everything works well. Try: http://www.virtual-globe.info/VirtualGlobeStarter.php?name=Kyrksæterøra&dataset=http%3A%2F%2Fwww.virtual-globe.info%2Fhemne%2Fhemne-features.vgml&libs=Xj3D&viewpoint=9.095805309133254,63.29461450913526,107.50134078584125,227.38738411964144,-7.322190162622405. Open menu Tools/Overview map to open the Map view.

According to the Aviatrix3D/Xj3D guys running different render loop models is supposed to work. It seems like there are some delayed initialization that is not quite completed before the second viewer starts, and it is not adequately synchronized when using the two different render loop models or what? Or have I run into one of the famous ATI bugs? I’m developing on a HP laptop with an X1600.

Rune Aasgaard

Not sure exactly what is going wrong here. I think you should try to get in touch with the Aviatrix3D developers. Due to the asynchronous nature of the AWT implementing OpenGL context sharing is a little tricky and there certainly might be bugs in JOGL’s implementation, but I think the problems are more likely due to Aviatrix3D’s internal use of multithreading and potentially race conditions this introduces. I haven’t seen too many problems with the JOGL demos or other applications which use the JOGL callback mechanism and which share textures and display lists between contexts.

I started asking the Aviatrix3D developers, and was sent here… This starts to look like I am going to be sent from one of you to the other, both blaming each other…

I use the single threaded version of aviatrix, the SingleThreadedRenderManager, so ther should be nothing special there. I believed the shared context should lock properly and serialize accesses in makeCurrent/release pairs?

Rune

Does the demos.testContextSharing.TestContextSharing demo from the jogl-demos workspace work on your machine? That should provide a baseline indication that sharing between contexts is working. What about the other demos such as the Water (ProceduralTexturePhysics) demo? This one and several of the others rely on sharing textures and display lists between on-screen and off-screen contexts.

Texture sharing by itself works splendidly, even the procedural water demo.

  • when I use two JSR-231 windows controlled by event listeners and animators it works
  • with aviatrix v 1.0 and jogl v 1.1.1 it works
  • when using Aviatrix and JSR-231 and introducing a delay between the creation of the two windows (the AV window first, the JSR window some 5sec later) it works

But when creating the two windows in succession in the same main frame creator and opening both of them in the same main frame it bombs…

By the way, when I create a GLCanvas and add it to an existing open main window the standard way of starting the Animator in window listeners doesnt work, because the window is already opened and no event is generated. What is the fool proof way of detecting that a window is open and it is safe to start the animator manually?

Rune

Given the nature of the error I’m guessing there is some race condition at the driver level where it doesn’t like a request to share textures involving two threads simultaneously. Can you find out from the Aviatrix3D developers whether it’s possible for them to provide a switch to use the JOGL Threading class to do their rendering? My guess is that their current system is doing manual OpenGL context manipulation on a different thread than the EDT and that’s what’s causing the problems.

What graphics card do you have? Are you running your vendor’s latest drivers?

I’m not sure there’s a “standard” way of starting the Animator. I think you should be able to start it basically on addition of the GLCanvas to the surrounding window. There’s enough infrastructure in the JOGL implementation that until the window is realized the Animator shouldn’t have any detrimental side effects.

I’ll send them a reference to this thread (or they may be listening already)… From what I have seen of the Aviatrix internals it would be difficolt to change the model to use the JOGL Threding class:

The render loop model is:


  // prepare all the graphical objects
 .....
  GLContext glContext = glcanvas.getContext();
  glContext.makeCurrent();
  // do all of the drawing
  ....
  glContext.release();
  glcanvas.swapBuffers();

in its basic form simple enough, but packed into lots of abstractions.

Radeon X1600 mobile. Yes I have the latest drivers (even if mobile drivers are a few months behind the main releases).

After thinking a little more I found a way of packing the relevant parts of the AV render loop into Threading callbacks. Now it works!

I’ll send the AV3D/Xj3D guys an outline of a fix.

Rune

Good to hear it’s working. I can believe there still might be missing synchronization in the JOGL implementation related to context sharing which is the underlying cause of the breakage; do you think you might be able to distill a self-contained test case out of all of this which provokes the failure?

It is not possible for us to use the JOGL threading classes because it introduces more problems than it solves. At a simple level, we no longer can control the framerates that require - an extremely important requirement when you have to guarantee a framerate in an application (eg real flight simulator). In addition, introduction of the RI Threading class, or anything even remotely associated with it causes the entire system to lock solid when using SWT on a Mac.

I see there (as usual) are other issues than what I have tought about. But again, for applications that are not so framerate dependent, don’t use SWT on Macs and may run into ATI mulitthreading bugs it would be nice (read: necessary) to use something like the Threading class.

If it could be possible to set the singleThreading variable in the Threading class to “false” by default for Aviatrix applications, it would work as today unless the “opengl.1thread” property where actively set (instead of being “true” unless actively set to false in the “opengl.1thread” property as today). In my own code I have this to detect Aviatrix3D at static initialization time:


  static boolean has_aviatrix = true;

  static {
    if (has_aviatrix) {
      try {
        Class.forName("org.j3d.aviatrix3d.Node");
      }
      catch (Throwable ex) {
        has_aviatrix = false;
      }
    }
  }

This could be used in the Threading initialization to determine the default value of “singleThreaded”.

Rune

The majority of our users, and more importantly, those that are paying us to do work on AV3D, are all using SWT. As such its an absolute no-go on using the Threading class(es) on either platform - we did the same thing for the SWT OpenGL bindings with an OS-dependent Threading class for those that need it.

I did some tests over the weekend and our SWT code handles this situation perfectly on all platforms, so the problem is a bug in the AWT bindings that should be resolved. I recommend you enter it into the bug tracker so that it can be looked at.