GLException woes

I’m running jogl within an Eclipse RCP environment with two GL canvasas which share their textures and display lists, and from time to time I get the error below and sometimes other errors about a GLContext.makeCurrent() failing. It always works on ATI and fails occassionally on nvidia. I’ve been fighting jogl multithreading issues and strange GLExceptions for months and thought for a while I had the problems conquered (mainly by delaying the first resize event for as long as possible after canvas creation). I can’t consistently reproduce these errors and a little test case is out of the question. So can anybody shed any light on what’s happening here? Would it be possible for jogl to include more sanity checking and better error reporting in this area?

Internal error: Exception while resizing the editor
net.java.games.jogl.GLException: wglShareLists(0x10001, 0x10002) failed
at net.java.games.jogl.impl.windows.WindowsGLContext.makeCurrent(WindowsGLContext.java:156)
at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.makeCurrent(WindowsOnscreenGLContext.java:110)
at net.java.games.jogl.impl.GLContext.invokeGL(GLContext.java:250)
at net.java.games.jogl.GLCanvas.reshape(GLCanvas.java:112)
at java.awt.Component.setBounds(Component.java:1847)

// In 1.1b07 the rest of the error output is produced immediately upon startup,
// in 1.1b08 these remaining errors are printed when the application exits.

Exception in thread “AWT-EventQueue-0” java.lang.AssertionError: State of ShareSet corrupted; thought context net.java.games.jogl.impl.windows.WindowsOnscreenGLContext@6ffd79 should have been in created set but wasn’t
at net.java.games.jogl.impl.GLContextShareSet$ShareSet.contextDestroyed(GLContextShareSet.java:94)
at net.java.games.jogl.impl.GLContextShareSet.contextDestroyed(GLContextShareSet.java:136)
at net.java.games.jogl.impl.GLContext.destroy(GLContext.java:641)
at net.java.games.jogl.GLCanvas.removeNotify(GLCanvas.java:96)
at java.awt.Container.removeNotify(Container.java:2527)
at java.awt.Frame.removeNotify(Frame.java:904)
at java.awt.Window$1DisposeAction.run(Window.java:621)
at java.awt.Window.doDispose(Window.java:633)
at java.awt.Window.dispose(Window.java:588)
at org.eclipse.swt.awt.SWT_AWT$6.run(SWT_AWT.java:213)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)

Unhandled event loop exception
Reason:
State of ShareSet corrupted; thought context net.java.games.jogl.impl.windows.WindowsOnscreenGLContext@6ffd79 should have been in created set but wasn’t

Regards,
Henrietta

Have you tried running with -DJOGL_SINGLE_THREADED_WORKAROUND=true on your NVidia hardware?

I think the assertion failure coming from the GLContextShareSet is probably real and is likely coming from JOGL trying to destroy the same context twice based on AWT notification events. If there is any way you could provide a test case it would be really helpful in tracking it down, but if not then if you could file a bug with the JOGL Issue Tracker and post at least the second stack trace that would help.

I’ve tried the JOGL_SINGLE_THREADED_WORKAROUND with identical results as far as my app is concerned - i.e. the second window into which a canvas should have been placed remains blank, so it follows that no valid canvas was created as the original stack trace indicates. The only difference is that no console output or error messages are produced. I’ve also upgraded to the latest nvidia beta driver; that made no difference either.

I’m sure the assertion is real - questions are - what causes it and how can I avoid it? It looks to me like the AssertionError is just down to some dodgy clean up code - the real culprit is the wglShareLists. I certainly understand your desire for a simple test case but I don’t think that’s going to be possible - I’m dependent on about 20Mb of RCP and a ton of my own scaffolding for a start, and it only screws up one time in 5 here (although once it does screw up, it keeps on screwing up until the machine is rebooted).

I have “next” and “last” buttons in my app which runs the same code that fails on start up - it checks for a valid canvas and rendering thread and creates them if they don’t exist. During startup the wglShareLists call fails, but when I hit the next or last button it succeeds and the window bursts into glorious life. So, Ken, what precondition am I not meeting on startup? I can file a report if you’d still like me too - would you be able to paste a link to your issue tracking system? For what it’s worth, the full stack trace is below.

As an aside - I just saw the Linux thread and I’m getting hangs on exit on Windows too - thread lock problems I guess. I have to use the eclipse debugger to break out of it.

Thanks for any help at all…
Henrietta

net.java.games.jogl.GLException: wglShareLists(0x10001, 0x10002) failed
at net.java.games.jogl.impl.windows.WindowsGLContext.makeCurrent(WindowsGLContext.java:161)
at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.makeCurrent(WindowsOnscreenGLContext.java:129)
at net.java.games.jogl.impl.GLContext.invokeGL(GLContext.java:246)
at net.java.games.jogl.impl.windows.WindowsOnscreenGLContext.invokeGL(WindowsOnscreenGLContext.java:76)
at net.java.games.jogl.GLCanvas.withSingleThreadedWorkaroundDo(GLCanvas.java:228)
at net.java.games.jogl.GLCanvas.reshape(GLCanvas.java:125)
at java.awt.Component.setBounds(Component.java:1847)
at org.eclipse.ui.internal.PartPane$2.run(PartPane.java:148)
at org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1044)
at org.eclipse.core.runtime.Platform.run(Platform.java:747)
at org.eclipse.ui.internal.PartPane.doCreateChildControl(PartPane.java:144)
at org.eclipse.ui.internal.ViewPane.doCreateChildControl(ViewPane.java:135)
at org.eclipse.ui.internal.PartPane.createChildControl(PartPane.java:349)
at org.eclipse.ui.internal.ViewFactory$1.run(ViewFactory.java:398)
at org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1044)
at org.eclipse.core.runtime.Platform.run(Platform.java:747)
at org.eclipse.ui.internal.ViewFactory.busyRestoreView(ViewFactory.java:287)
at org.eclipse.ui.internal.ViewFactory$2.run(ViewFactory.java:582)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69)
at org.eclipse.ui.internal.ViewFactory.restoreView(ViewFactory.java:579)
at org.eclipse.ui.internal.ViewFactory$ViewReference.getPart(ViewFactory.java:106)
at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:329)
at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:607)
at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:126)
at org.eclipse.ui.internal.presentations.newapi.PresentablePartFolder.select(PresentablePartFolder.java:266)
at org.eclipse.ui.internal.presentations.newapi.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
at org.eclipse.ui.internal.presentations.newapi.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:381)
at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1034)
at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:535)
at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:472)
at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:477)
at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:230)
at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:779)
at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2028)
at org.eclipse.ui.internal.WorkbenchWindow$4.run(WorkbenchWindow.java:2158)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69)
at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:2144)
at org.eclipse.ui.internal.WorkbenchWindow.restoreState(WorkbenchWindow.java:1676)
at org.eclipse.ui.internal.Workbench.restoreState(Workbench.java:1414)
at org.eclipse.ui.internal.Workbench.access$10(Workbench.java:1370)
at org.eclipse.ui.internal.Workbench$15.run(Workbench.java:1273)
at org.eclipse.core.internal.runtime.InternalPlatform.run(InternalPlatform.java:1044)
at org.eclipse.core.runtime.Platform.run(Platform.java:747)
at org.eclipse.ui.internal.Workbench.restoreState(Workbench.java:1207)
at org.eclipse.ui.internal.WorkbenchConfigurer.restoreState(WorkbenchConfigurer.java:171)
at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:659)
at org.eclipse.ui.internal.Workbench.init(Workbench.java:886)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1516)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:285)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:144)
at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:220)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:273)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.basicRun(Main.java:185)
at org.eclipse.core.launcher.Main.run(Main.java:710)
at org.eclipse.core.launcher.Main.main(Main.java:694)
Exception in thread “AWT-EventQueue-0” java.lang.AssertionError: State of ShareSet corrupted; thought context net.java.games.jogl.impl.windows.WindowsOnscreenGLContext@1e940b should have been in created set but wasn’t
at net.java.games.jogl.impl.GLContextShareSet$ShareSet.contextDestroyed(GLContextShareSet.java:94)
at net.java.games.jogl.impl.GLContextShareSet.contextDestroyed(GLContextShareSet.java:136)
at net.java.games.jogl.impl.GLContext.destroy(GLContext.java:640)
at net.java.games.jogl.GLCanvas.removeNotify(GLCanvas.java:98)
at java.awt.Container.removeNotify(Container.java:2527)
at java.awt.Frame.removeNotify(Frame.java:904)
at java.awt.Window$1DisposeAction.run(Window.java:621)
at java.awt.Window.doDispose(Window.java:633)
at java.awt.Window.dispose(Window.java:588)
at org.eclipse.swt.awt.SWT_AWT$6.run(SWT_AWT.java:213)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Unhandled event loop exception
Reason:
State of ShareSet corrupted; thought context net.java.games.jogl.impl.windows.WindowsOnscreenGLContext@1e940b should have been in created set but wasn’t

I just saw this line in the stack trace:

at net.java.games.jogl.GLCanvas.withSingleThreadedWorkaroundDo(GLCanvas.jav a:22

This trace was taken with no JOGL_SINGLE_THREADED_WORKAROUND set. Odd?

I’ll stop it with the addendums soon but I do want to try and be accurate. An additional effect of setting JOGL_SINGLE_THREADED_WORKAROUND is that the textures are correctly shared between the two canvases. When it’s not set, one window cannot see textures bound in another window, so to summarize:

When JOGL_SINGLE_THREADED_WORKAROUND=true there are no errors but no canvas is created on startup. When canvas’s are later created they are correctly shared.

When JOGL_SINGLE_THREADED_WORKAROUND=false there are errors, no canvas is created on startup, and when canvas’s are later created texture sharing fails.

It’s very difficult to make a diagnosis with just this information. If you could provide some sort of test case I could run (even if I have to download and install Eclipse to run it) it would be much easier than taking guesses.

The GLException upon wglShareLists is real – the share operation is failing for some reason. It’s possible that JOGL doesn’t have enough synchronization when the single-threaded workaround is disabled. I don’t know what your threading and animation setup looks like, or how the GLCanvases are being created. Looking at some of the WindowsGLContextFactory code I can imagine that more synchronization is needed internally if creating multiple GLCanvases simultaneously. If you want to contact me offline at my email address on the JOGL web page I may be able to provide you a build or two to test with to try to fix this problem. Again, filing a bug with the JOGL Issue Tracker with a test case would help us significantly.

I don’t know what your initialization code looks like, either, so it’s impossible to guess why the initial GLCanvas doesn’t show up. If you haven’t already, I would recommend looking at the JOGL demos’ source code for some sample initialization code that seems to work on all of JOGL’s supported platforms.

For the hangs on exit, you should run your application on the command line and hit Ctrl-Break when it hangs to see what is happening. If you run with J2SE 5.0 and a deadlock is reported (and it looks like a deadlock in the JOGL internals, not in your application) please file a bug with the JOGL Issue Tracker and include the thread dump.

FYI, the withSingleThreadedWorkaroundDo() method is probably poorly named, because it doesn’t mean the single-threaded workaround is enabled. maybeDoSingleThreadedWorkaround() might be a better name.

I speculatively removed a resize command and I’ve been doing a lot more testing and the errors aren’t happening in the same way - a problem I’ve been bedeviled with. In fact, bizarrely, there’s been a reversal of fortunes with JOGL_SINGLE_THREADED_WORKAROUND; now when it’s set I get no canvas on startup, when it’s not set everything is fine. I’m getting no errors in either situation and the hang on exit has disappeared. When I move to another graphics card, or the ratio between the two canvas’s startup times changes slightly, it’ll all sod up in a slightly different way. So I have zero confidence in the stability of my system and I was looking at this:

and was wondering whether jogl was able to pass through that extended error information?

[quote]So I have zero confidence in the stability of my system and I was looking at this:

and was wondering whether jogl was able to pass through that extended error information?
[/quote]
Yes. I just checked in printing of the GetLastError return value; if you can build the source tree from CVS you can pick up that fix right away.

Thanks Ken, that might give me a few more clues.