Bug 533

Summary: A call to GLProfile.initSingleton() takes long time
Product: [JogAmp] Jogl Reporter: Ossi Herrala <oherrala>
Component: macosxAssignee: Sven Gothel <sgothel>
Status: VERIFIED FIXED    
Severity: major CC: oherrala
Priority: ---    
Version: 2   
Hardware: pc_x86_64   
OS: macosx   
Type: --- SCM Refs:
e702a9401d4564c970ddda71116d14d7661dd048
Workaround: ---
Bug Depends on:    
Bug Blocks: 548    

Description Ossi Herrala 2011-12-11 20:19:01 CET
javax.media.opengl.GLProfile.initSingleton() call on Mac OS X takes long time. 

On my MacBookPro6,2 (OSX 10.6.8, Intel HD and Nvidia geforce GT 330M) it's constantly ~23 seconds which makes program startup really slow. I'm using JogAmp 2.0RC4 and Apple's JDK 1.6.0_29.


Consider the following small program:

import javax.media.opengl.GLProfile;

public class JoglInit {
    public static void main(String[] args) {
        final long s1 = System.nanoTime();
        GLProfile.initSingleton(true);
        final long s2 = System.nanoTime();
        System.out.println("Run time: " + (s2-s1)/1e6 + " ms.");
    }
}

Which prints the following output:

Run time: 21875.81 ms.


I debugged this so far that I found out most of the time is spent in jogamp.opengl.macosx.cgl.MacOSXCGLContext.destroy() method on line:

      return CGL.deleteContext(ctx, true);

which if I understand correctly calls native code of deleteContext() found from:

  src/jogl/native/macosx/MacOSXWindowSystemInterface.m

Code has comment about hang of 10 seconds, but in my debugging the releaseOnMainThread=true when this method is called:

Bool deleteContext(NSOpenGLContext* ctx, Bool releaseOnMainThread) {
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  [ctx clearDrawable];
  if(releaseOnMainThread && NO == [NSThread isMainThread]) {
      [ctx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES];
  } else {
      // would hangs for ~10s for 1 of a shared context set or offscreen context, set releaseOnMainThread=true !
      [ctx release]; 
  }
  [pool release];
  return true;
}

Is there anything possible to do to make the call to initSingleton() be faster?
Comment 1 Sven Gothel 2011-12-13 01:39:28 CET
Thank you for your observations, great analysis.

I will validate whether the 'performSelectorOnMainThread(..)' shall only be utilized on 10.7,
maybe this solves the problem.
Comment 2 Sven Gothel 2011-12-13 03:16:37 CET
Machine 1:
  Platform: MACOS / Mac OS X 10.6.8 (os), x86_64 (arch) 2 cores
  Platform: Java Version: 1.6.0_29, VM: Java HotSpot(TM) 64-Bit Server VM
  GL_VENDOR     NVIDIA Corporation
  GL_RENDERER: NVIDIA GeForce 8600M GT OpenGL Engine
  GL_VERSION    2.1 NVIDIA-1.6.36

Machine 2:
  Platform: MACOS / Mac OS X 10.7.2 (os), x86_64 (arch) 2 cores
  Platform: Java Version: 1.6.0_29, VM: Java HotSpot(TM) 64-Bit Server VM
  GL_VENDOR: NVIDIA Corporation
  GL_RENDERER: NVIDIA GeForce 320M OpenGL Engine
  GL_VERSION: 2.1 NVIDIA-7.12.9

Machine 3:
  Platform: LINUX / Linux 2.6.39.3-x64-k10-x8 (os), amd64 (arch) 6 cores
  Platform: Java Version: 1.6.0_29, VM: Java HotSpot(TM) 64-Bit Server VM
  GL_VENDOR: NVIDIA Corporation
  GL_RENDERER: GeForce GTX 460/PCI/SSE2
  GL_VERSION: 4.1.0 NVIDIA 290.10

+++

jogl commit ed92cc34e42e334373c31a54ba601d8a9781228e

+++

com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT

1st / Machine 1:

Total:                                  2853.959ms
  GLProfile.initSingleton():   1591.159ms
  Demo Code:                      1261.864ms
  GLProfile.shutdown(COMPLETE): 0.936ms

1st / Machine 2:

Total:                                   2289.804ms
  GLProfile.initSingleton():    1083.359ms
  Demo Code:                      1205.492ms
  GLProfile.shutdown(COMPLETE): 0.953ms

1st / Machine 3:

Total:                                  2151.486812ms
  GLProfile.initSingleton():    795.055182ms
  Demo Code:                     1335.82104ms
  GLProfile.shutdown(COMPLETE): 20.61059ms

..
Last / Machine 1:

Total:                                 2158.116ms
  GLProfile.initSingleton():    979.452ms
  Demo Code:                     1178.617ms
  GLProfile.shutdown(COMPLETE): 0.047ms

Last / Machine 2:

Total:                                 1617.736ms
  GLProfile.initSingleton():    552.0ms
  Demo Code:                    1064.383ms
  GLProfile.shutdown(COMPLETE): 1.353ms

Last / Machine 3:

Total:                                 1486.401819ms
  GLProfile.initSingleton():    161.630229ms
  Demo Code:                    1299.578403ms
  GLProfile.shutdown(COMPLETE): 25.193187ms

+++

The extreme high numbers for the 1st run 
and much lower values for the subsequent ones must be explained
with the actual class loading (JOGL classes) and some static init blocks.
The latter has been reduced lately so the delta should be class loading time only.
~ 500ms class loading is reasonable here, I guess.

So my values are 1.5s - 1.0s compared to your 21.9s (w/ class loading)

For sure we might need to cont. evaluating the net initialization costs of 
0.5s - 1.0s (machine2 - machine1).

I also tests the NEWT Applets w/ Machine1 and the freeze/lag at startup is gone,
so the latest initialization changes fixed that one as well.
Looks like the old buggy initialization sequence caused such lag indeed.

Pls try again w/ latest gluegen/jogl code (or wait until next aggregated build).

Thank you.
Comment 3 Sven Gothel 2011-12-13 07:07:23 CET
On the 10.6.8 machine, I get the following 'Console' logs (this OSX tool which allows you to
see the error logs) .. while experience the 'freezes':

11-12-13 6:44:36 AM kernel  NVDA(OpenGL): Channel exception! exception type = 0xd = GR: SW Notify Error
11-12-13 6:44:36 AM kernel  0000006e
11-12-13 6:44:36 AM kernel  00200000 0000502d 00000472 00000040
11-12-13 6:44:36 AM kernel  0000047a 000002ac 00000003 0000000d
11-12-13 6:44:36 AM kernel  00000000 00000000 00000002
11-12-13 6:44:36 AM kernel  00000040 00000000
11-12-13 6:44:37 AM kernel  NVDA(OpenGL): Channel exception! exception type = 0xd = GR: SW Notify Error
11-12-13 6:44:57 AM kernel  NVDA(OpenGL): Channel timeout!
11-12-13 6:44:57 AM kernel  0000006e
11-12-13 6:44:57 AM kernel  00200000 0000502d 00000472 00000040
11-12-13 6:44:57 AM kernel  0000047a 000002ac 00000003 0000000d
11-12-13 6:44:57 AM kernel  00000000 00000000 00000002
11-12-13 6:44:57 AM kernel  00000040 00000000

Looks like the same here:
  http://www.insanelymac.com/forum/index.php?showtopic=244227

And if you google 'NVDA(OpenGL): Channel exception! exception type = 0xd = GR: SW Notify Error'
you see a lot messages :(

Dunno if there is a solution (I didn't find any) .. plus whether it's JOGL or 'just' a broken NV driver.
Comment 4 Sven Gothel 2011-12-13 07:09:56 CET
I forgot to mention - yes, when the freeze happens, the init sequence takes about 20s
regardless how we destroy the context (main thread or not).
The freeze happens a few time .. depending on the state of the machine.
Comment 5 Ossi Herrala 2011-12-13 19:58:50 CET
Hi and thanks for the quick response.

I'm sorry, but your latest commits to JOGL didn't help. I built and tried latest from your github: 1122f20a73e1dd912839f860efc6fcbed8c89808.

I also tried my Google-Fu against the NVidia Channel Exception and found out this: http://support.apple.com/kb/TS4088. However, in my laptop it didn't help but look promising. Maybe it's time to move to Lion and find out if that helps..

As it seems that this is not a JOGL problem, I'll close the issue. Thank you for your time. :)
Comment 6 Sven Gothel 2012-01-09 13:51:14 CET
see bug 548