JOGLAppletLauncher and slow repaint on Firefox/Mozilla

So from the early feedback from my game, it appears that the JOGLAppletLauncher runs at full speed on IE, and slooooow on firefox and mozilla.

I’ve done the following tests to identify the origin of the problem :

  • a simple awt canvas with buffer strategy swap ina loop runs in FF and > 3000 fps, so it’s not a FF/Applet repaint problem
  • my ultra simple JOGLApplet (draws a single triangle) runs at 55 fps on my high end PC (independant of screen refresh rate : tried 60 to 75)

So there seems to be a problem with the JOGL repaint system (may be a contention/lock of the event dispatch thread ?)

I’m now going to try the direct approach (without the glenventlistener ) and see if it performs any better…

Lilian

Updated : tried direct approach (context.makeCurrent() / paint / context.release() and canvas.swapBuffers() in a loop) : 350 fps in a frame, 35 fps in FF, 350 fps in IE

any suggestions ?

Lilian

Strange,

Like I replied to your JackFlowers thread, I got ~350fps in FireFox, which was about the same for me in IE. (I used FireFox 1.5 and the 1.5.0_06 JVM)… So maybe the problem is FireFox 1.4 related?

No, I’ve switched from FF 1.0.7 to 1.5 and the problem remains on my desktop PC (on the laptop, it’s still a good 200 fps)

Lilian

Actually I can reproduce this problem. I see 150 FPS in IE and only 20 FPS in Mozilla 1.7.6. This is with J2SE 1.5.0_06 on Windows XP SP1 with NVidia graphics hardware.

My best guess at this point would be architectural differences between the Java Plug-Ins for IE and Mozilla. I don’t know a lot about how the Plug-In works but know that there are effectively two different code bases due to how the different browsers work. I thought that at one time the Mozilla plug-in actually ran out-of-process or something similar. Maybe that’s changed. I do think it is strange that a pure Java2D applet could get extremely high frame rates while JOGL applets would be slow. I don’t think JOGL’s locking or repainting code would be the problem especially if the same code runs fine in IE but anything’s possible.

I’ll ask some people more familiar with the Plug-In to take a look at this next week. In the meantime if you have a chance to do any instrumentation of the JOGLAppletLauncher to see where all of the time is going (makeCurrent()? swapBuffers()? release()?) that would be helpful.

here’s a basic applet loop (don’t know if the code is correct, but it works fine (except fps) on both IE & FF (>1000 fps IE, 30 fps FF)

(The loop is started as a thread with default priority)


  double start = System.nanoTime() * 1E-6;
  void profile(String text){
    double now = System.nanoTime() * 1E-6;
    System.out.println(text + " : " + (now - start) + " ms");
    start = now;
  }
  
  public void run(){
    System.out.println("making current");
    GLContext context = canvas.getContext();
    context.setSynchronized(false);
    System.out.println("autoswap off");
    canvas.setAutoSwapBufferMode(false);
      
    GLU glu = new GLU();
    
    profile("before loop");
    while ( ! destroyed){      
      profile("before makeCurrent");
      context.makeCurrent();
      profile("after makeCurrent");
      //System.out.println("get gl");
      GL gl = context.getGL();
      gl.setSwapInterval(0);
      int height = getHeight();
      int width = getWidth();
      if (height <= 0){ // avoid a divide by zero error!
        height = 1;
      }
      
      final float h = (float) width / (float) height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL.GL_PROJECTION);
      gl.glLoadIdentity();
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glLoadIdentity();
      
      
      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
      gl.glLoadIdentity(); // Reset The View
      gl.glTranslatef(0.0f, 0.0f, -5.0f);
      gl.glColor3f(1,1,0);
      gl.glBegin(GL.GL_TRIANGLES);
      gl.glVertex3f(1,0,0);
      gl.glVertex3f(1,1,0);
      gl.glVertex3f(0,1,0);
      gl.glEnd();
      
      profile("before flush");

      
      //System.out.println("flush !");
      gl.glFlush();
      //System.out.println("swapping");
      profile("before release");
      context.release();
      profile("before swap buffers");

      canvas.swapBuffers();
      profile("after swap");

    }
    
  }



This code shows problems with

  • makeCurrent ( > 15millis on FF, never above 1ms in IE)
  • swapBuffers ( > 15 millis on FF, < 3 mills in IE)

flush, release and internal gl calls are all sub-millis

Lilian

Try moving the swapBuffers() call before release(). That should eliminate the time for swapBuffers since it avoids making the context current again. This is how the JOGL internals are structured.

There are only two operations that could be taking the time here: locking the surface wtih the JAWT and actually doing the wglMakeCurrent call. My guess would be that somehow locking the surface is taking more time in the plug-in, though I can’t guess why.

Could you also print out whenever GLContext.makeCurrent() returns CONTEXT_CURRENT_NEW? That should happen exactly once but I’d like to ensure it isn’t happening every frame.

Ok i’ll try it tomorrow (but the problem will remain as the game applet, which is based on GLEventListener also shows poor performance… )

From what you say I guess the makeCurrent() call is the problematic one, and the release/swapBuffers is just a bug for this specific applet.

Lilian

Tried moving swapBuffers before release()… this caused either a hang or an exception depending on context.setSynchronized(true/false)

The stack trace shows that the swapBuffer invokes maybedosinglethreadworkaround which sends the request swap to another thread.

I’ve also tried with -Dopengl.1thread=false, it solved the exception, but the delay was worse for swapBuffers (around 30 ms).

And last test : the makeCurrent() returns CONTEXT_CURRENT_NEW only once at the beginning.

Oh, and I’ve also checked the EventQueue.invokeAndWait(Runnable) with a dummy runnable (not GL related), and I can perform 100 calls in 6 ms, so this is not the origin of the problem.

Lilian

Sorry about that. I should have realized that would happen. That might be considered a bug. However I’m leery of adding too much mechanism in this area.

[quote]I’ve also tried with -Dopengl.1thread=false, it solved the exception, but the delay was worse for swapBuffers (around 30 ms).
[/quote]
That -D or calling Threading.disableSingleThreading() would be the only way to work around the issue. I’m very surprised that swapBuffers would be taking this long.

Thanks for verifying that.

[quote]Oh, and I’ve also checked the EventQueue.invokeAndWait(Runnable) with a dummy runnable (not GL related), and I can perform 100 calls in 6 ms, so this is not the origin of the problem.
[/quote]
Thanks for checking this as well.

I think more instrumentation is needed in the WindowsGLContext and WindowsOnscreenGLContext implementations to see exactly where all of the time is going. I’ll try to get to this within the next couple of days and get some people more familiar with the internals of the Java Plug-In to look at a test case. BTW, do you have a particular small applet which exhibits the problem? Is it reproducible with the standard Gears applet if the call to GL.setSwapInterval(1) is removed?

Here’s a full small problematic applet

Lilian

Thanks for the test case. I wrote another one based on it (attached) using just the normal GLEventListener mechanism and put some profiling stuff deeper into JOGL. It looks like all of the time is going in to the low-level call to the WINGDI routine SwapBuffers(). I have no idea why this would have different behavior from one Java Plug-In environment to another. It’s very obvious that when run inside the appletviewer or IE’s plug-in SwapBuffers takes basically zero time, but when in the Mozilla/Firefox plug-in it’s taking on the order of 9 ms/frame. WGL_EXT_swap_control is reported as available in all situations, the chosen pixel format is exactly the same, etc. The thing that’s most confusing to me is that SwapBuffers is a very low-level call which doesn’t even generate a Windows event, and since the plug-in is essentially just a wrapper around a normal JVM, how could any differences in the Windows event dispatching between the two plug-ins make any difference? Anyway, now that I have an instrumented test case I’ll contact the plug-in team next week and try to figure out what’s going on.

Hi, is there an issue # to track this problem ? should I file one ?

Lilian

Yes, please feel free to file one.

We have done some further investigation of this problem internally and it’s pretty mystifying. My co-worker’s two machines with NVidia cards (one with older drivers, one with current drivers) do not exhibit the problem. My old office machine with a GeForce FX 5800 Ultra did, so it’s not something like running low on VRAM (which might be the case on the notebook where the problem also occurs). We eliminated things like the Firefox version as variables. I’ve been in discussions with co-workers who work on the Java Plug-In and we can’t think of a way that the event dispatch structure of the plug-in can affect the speed in this way. I’m thinking it might be something about how Mozilla sets up the window it hands to Java; I checked though and one thing is that Mozilla doesn’t load DDRAW.DLL, which is the only thing I know of that could cause a driver-level incompatibility with OpenGL resulting in a symptom like this. We’re continuing to look into it and I may post on NVidia’s web site for some help once we’ve characterized it a little better.

Could you please tell us exactly what CPU types and speeds, OS versions, graphics cards and driver versions the slowdown happens with? Maybe we can identify a pattern.

Actually I just went back and reread the Jack Flowers thread so see that it’s happening with both ATI and NVidia hardware.

Looks like we might need to support a way to specify -Dsun.java2d.noddraw=true for applets as well as Java Web Start applications. Unfortunately due to the applet lifecycle model (in the browser) I’m not sure that’s possible.

Just to add something : the -Dsun.java2d.noddraw=true resolves ATI freeze issues (long pauses every n seconds), not the slow frame rate.

I’ve just checked this on my desktop pc (nvidia) : still around 30 fps with noddraw on FF (300 fps with IE)

Lilian

Hi guys,

I’m not sure if this is related, but I’m having problems getting any higher than 60fps in any JOGL applet, FF, IE, Applet Launcher or otherwise. I also do not think it is related to JOGLAppletLauncher either, as I used my own applet launcher, and also tried just using JOGL directly in a Frame.

I used the JGears applet as another test, to make sure it wasn’t my code. Even using the FPSAnimator, I couldn’t get higher than 60fps, another strange symptom is if I try and tell it to run at, for example, 40fps, my FPS come out at around 33.

I’m using jdk1.5.0_06, the poor performance is not related to my PC either: 3.2ghz, 1.5gb ram, 256mb GeForce 6800…

Drop me a line at me@sambro.info if you want me to run any tests/debug.

-Sam

EDIT:
Vendor: NVIDIA Corporation
Renderer: GeForce 6800 GT/AGP/SSE2/3DNOW!

Well I guess your rendering is in sync with your monitor’s frame rate. Did you try to unlock vsync from your graphics card control panel ?

Also does this game shows the same behaviour (http://www.javapause.com/games/jack) ? it uses an opengl call to disable vsync.

Lilian

Ahhh I feel stupid >:( Thanks Lilian :slight_smile:

After more investigation it currently looks to me like the slower performance in Mozilla/Firefox looks a lot like wglSwapIntervalEXT(0) silently failing. I’ve posted on opengl.org describing some of the tests that have been done and asking for any input. Let’s see if there are any responses.