Is there a write-up for what JOGL is doing under the covers? Some of the things are obvious (using Buffers rather than pointers), but some are not (vsync, calling glFlush, etc.) It would help in locating bottlenecks and relating the OpenGL Profiler output to what calls I am making in the application.
JOGL does very little under the covers – no mysterious calls to glFlush() or other OpenGL commands. It calls the window system’s swapBuffers function by default after calling all GLEventListeners during a display() cycle. It exposes wglSwapIntervalEXT though it doesn’t supply a platform-independent function for that yet. Aside from a glViewport call before calling the GLEventListeners’ reshape() methods it really doesn’t do much behind the scenes aside from OpenGL context management and implementation of the GLEventListener callback mechanism.
That is what I would want from a GL binding. But I am seeing other indications. Possibly you can point me in the right direction. The OpenGL profiler shows a large amount of time in CGLFlushDrawable (about 1/2 my GL time). This appears to be called once per frame, as the call count mathes the calls to glClear. I also see the viewport being reset for each frame to the canvas size when the window was first opened, rather than matching the size resulting from setSize, that is being used for drawing. Having the viewport wrong messes up attempts to prune on visible areas. I am currently having to do my own pruning against the canvas bounds and transforming that to world space, rather than getting the matrices from OGL.
JOGL shouldn’t be calling glViewport() once per frame, only when the GLCanvas is being resized. If you’re calling setSize() on any of your widgets by hand and your widget hierarchy has already been realized then you should be doing that on the AWT event queue thread with EventQueue.invokeLater(). If you can get me a stack trace for the glViewport calls I can take a look. You could probably get this by hacking the DebugGL’s generated source code and putting in a Thread.dumpStack() in the appropriate place.
I call setSize from the code that creates the frame (the main method) and before setVisible(true). It does not appear to be calling it every frame, just 2 times, the second time after my init methods were trying to set viewport to match the canvas. I do not mind it managing the viewport, if it set it to 1:1 to the canvas size.
Here is the stack trace:
at net.java.games.jogl.GLCanvas$1.run(GLCanvas.java:116)
at net.java.games.jogl.impl.macosx.MacOSXOnscreenGLContext$1.run(MacOSXOnscreenGLContext.java:76)
at net.java.games.jogl.impl.GLContext.invokeGL(GLContext.java:292)
at net.java.games.jogl.impl.macosx.MacOSXOnscreenGLContext.invokeGL(MacOSXOnscreenGLContext.java:81)
at net.java.games.jogl.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:228)
at net.java.games.jogl.GLCanvas.display(GLCanvas.java:75)
at net.java.games.jogl.GLCanvas.paint(GLCanvas.java:84)
at sun.awt.RepaintArea.paint(RepaintArea.java:194)
at apple.awt.ComponentModel.handleEvent(ComponentModel.java:281)
at java.awt.Component.dispatchEventImpl(Component.java:3744)
at java.awt.Component.dispatchEvent(Component.java:3543)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:178)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:170)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Do the JOGL demos work properly, or do they have the problem you’re seeing where the OpenGL viewport doesn’t match the size of the GLCanvas? If the demos work properly then please check your app for problems in packing or setting of the size of components.
I can reproduce the resize problem on a G4 Powerbook with the Gears demo.
Here’s part of an email from Dmitry about a year ago when I was trying to track it down. It crashed then, and things have improved since then, but the size mismatch is still there.
[quote]BTW: I can see that hanging almost for every jogl-demo example (except Gera and jGear)
here is a code from GL4Java implementation related to resizing:
JNIEXPORT void JNICALL Java_gl4java_GLContext_gljResizeNative
(JNIEnv *env, jobject object, jboolean isOwnWindow, jlong disp, jlong pData, jint width, jint height)
{
NSLock *lock = [[NSLock alloc] init];
if ([lock tryLock]) {
gl4javaResize(env,object,(NSWindow *)pData,width,height);//
[lock unlock];
}
[lock release];
}
before I use locking
gl4java exhibited very similar behavior: it crashed
(not heavily as jogl though)
hope it will help
just FYI
void gl4javaResize(JNIEnv *env, jobject object, NSWindow *window, int width, int height)
{
jclass cls = 0;
NSView *view = NULL;
jfieldID fglContext=0;
jfieldID foffScreenRenderer=0;
jboolean joffScreenRenderer=JNI_FALSE;
NSOpenGLContext *gc = NULL;
NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
NSRect viewFrame;
jboolean needResetContext = JNI_FALSE;
cls = (*env)->GetObjectClass(env, object);
if (cls==0) return;
foffScreenRenderer = (*env)->GetFieldID(env, cls, “offScreenRenderer”, “Z”);
if (foffScreenRenderer==0) return;
joffScreenRenderer =(*env)->GetBooleanField(env, object, foffScreenRenderer);
if(joffScreenRenderer == JNI_TRUE) return;
fglContext=(env)->GetFieldID(env, cls, “glContext”, “J”);
if (fglContext==0) return;
gc =(NSOpenGLContext)((int)(*env)->GetLongField(env, object, fglContext));
if (gc==0) return;
view = [gc view];
if(view == NULL) return;
viewFrame = [view frame];
if(gc == currentContext) needResetContext = JNI_TRUE;
else needResetContext = JNI_FALSE;
if(needResetContext){
[NSOpenGLContext clearCurrentContext];
}
[gc clearDrawable];
[gc setView : view];
if(needResetContext){
[gc makeCurrentContext];
}
[gc flushBuffer];
if(window != NULL) [window setViewsNeedDisplay:YES];
}
[/quote]
I looked into this more and was able to reproduce at least one of the problems reported, namely garbage visible in the window during and after resizing of a GLCanvas. This appears to have been caused by not properly calling NSOpenGLContext’s update method after the resize operation. The only workaround I was able to find so far was to call the update method during every makeCurrent operation. Fortunately this doesn’t seem to impact performance too much. If any of you on Mac OS X have the ability to take a CVS update and do a JOGL build I’d appreciate knowing whether the current sources have solved any issues. If not then I’ll try to get another beta build out within the next week or two.