Bug 429

Summary: Error: Failed to create an external OpenGL Context from an SWT GLCanvas
Product: [JogAmp] Jogl Reporter: Wade Walker <wwalker3>
Component: windowsAssignee: Sven Gothel <sgothel>
Status: VERIFIED FIXED    
Severity: normal CC: carlo.salinari, martin.pernollet
Priority: P3    
Version: 2   
Hardware: pc_x86_32   
OS: windows   
Type: --- SCM Refs:
7262641429b542929efc699e392f410f1dee2187 b6c02b25a28a430506e6e9ab2e19b7a967220427
Workaround: ---
Attachments: Console output with debug switches turned on
Simple test case to duplicate problem.
win7-64, SWT 3.7M3, jogl-a77abd78367fd8e172b6bae0fa742ac3c89bb243
Debug output with JOGL 1.1.1a
Test case code for JOGL 1.1.1a
Debug output for JOGL 2 b242
Debug log with JOGL 2 b248
New debug log for b329; shows unsupported color depth

Description Wade Walker 2010-11-16 15:35:45 CET
On some 32-bit Windows XP systems, I see this error:

Exception in thread "main" javax.media.opengl.GLException: Error: attempted to make an external GLContext without a valid pixelformat
	at com.jogamp.opengl.impl.windows.wgl.WindowsExternalWGLContext.create(WindowsExternalWGLContext.java:75)
	at com.jogamp.opengl.impl.windows.wgl.WindowsWGLDrawableFactory.createExternalGLContextImpl(WindowsWGLDrawableFactory.java:268)
	at com.jogamp.opengl.impl.GLDrawableFactoryImpl.createExternalGLContext(GLDrawableFactoryImpl.java:206)
	at name.wadewalker.onetriangle.OneTriangle.main(OneTriangle.java:42)

This has also been seen "in the wild" here (http://www.javagaming.org/index.php?action=printpage;topic=21387.0) and again here (http://jogamp.762907.n3.nabble.com/GLException-with-SWT-Demo-td1886152.html).

I duplicated it on two systems:

System 1:
Windows XP SP2 32-bit running inside VMWare on Centos 5.4
Java 1.6.0_20
GL_VENDOR: VMware, Inc.
GL_RENDERER: Gallium 0.3 on SVGA3D; build: RELEASE; 
GL_VERSION: 2.1 Mesa 7.5.1

System 2:
Windows XP SP2 32-bit
Java 1.6.0_17
!MESSAGE 
GL_VENDOR: NVIDIA Corporation
GL_RENDERER: GeForce FX 5200/AGP/SSE2
GL_VERSION: 2.1.2

I'll attach the log files and also the simple test program I wrote to demonstrate the bug. The test program just needs swt.jar and the JOGL *.jar and *.dll files to run.
Comment 1 Wade Walker 2010-11-16 15:36:36 CET
Created attachment 163 [details]
Console output with debug switches turned on
Comment 2 Wade Walker 2010-11-16 15:38:44 CET
Created attachment 164 [details]
Simple test case to duplicate problem.

Put this file plus swt.jar (from http://www.eclipse.org/swt/) and the JOGL *.jar and *.dll files into a project, then run as a Java application to duplicate the error.
Comment 3 Sven Gothel 2010-11-19 04:10:21 CET
Thank you, fetched your attachments and will fix it with #397, since the cause is the same.

*** This bug has been marked as a duplicate of bug 397 ***
Comment 4 Sven Gothel 2010-11-26 05:22:18 CET
Created attachment 179 [details]
win7-64, SWT 3.7M3, jogl-a77abd78367fd8e172b6bae0fa742ac3c89bb243
Comment 5 Sven Gothel 2010-11-26 05:31:39 CET
the actual bug description would be: 'Can't create external context with SWT'

see attachment 178 [details], works here on:

- JOGL a77abd78367fd8e172b6bae0fa742ac3c89bb243
- SWT 3.7M3
- 64bit
- windows 7
- linux/x11

JOGL's external drawable/context requires a valid native current context/drawable.

Wade's comment bug 397, comment 16 
and my tests show that Wade's setup the native drawable
is not set yet (GDI's DC -> native surface) when you call SWT's GLCanvas setCurrent().

So the JOGL exception is right.

IMHO this is a behavioral difference of our setup, 
where at mine, the native construction is finished at SWT GLCanvas setCurrent(),
in yours not.

I am not so familiar with SWT (yet), for sure this proves that we should implement our own 
SWT GLCanvas as I mentioned earlier, maybe even a NEWT wrapper.

Please verify.
Comment 6 Sven Gothel 2010-11-26 05:33:08 CET
sorry, my SWT tests are logs are stored in attachment 179 [details].
Comment 7 Sven Gothel 2010-11-26 08:50:51 CET
As I have described in comment 5 and attachment 179 [details]
it works for me.

Maybe a specific SWT / platform issue.
Hence, reduced prio and severity.

Wade, please tripple check 
I like to close this one - thank you!
Comment 8 Wade Walker 2010-11-26 16:09:06 CET
I'll take a look on Monday -- I'm off on holiday now for Thanksgiving :)

I'm pretty sure this test case works with JOGL 1.1.1a, but I'll double-check that to be sure.

It works with JOGL 2 on Windows Vista, so I'm not surprised your Windows 7 test worked too. This problem seems to be Windows XP-specific.
Comment 9 Wade Walker 2010-11-29 15:49:51 CET
Created attachment 186 [details]
Debug output with JOGL 1.1.1a

This output comes from JOGL 1.1.1a. The test case works fine this way.
Comment 10 Wade Walker 2010-11-29 15:51:14 CET
Created attachment 187 [details]
Test case code for JOGL 1.1.1a

This is the test case, but slightly modified to be JOGL 1.1.1a-compliant (GL2 -> GL, removed profile). This test case runs on the platforms that fail for JOGL 2.
Comment 11 Wade Walker 2010-11-29 15:52:09 CET
Created attachment 188 [details]
Debug output for JOGL 2 b242

Shows the same bug as previous versions of JOGL 2. Just included in case it's helpful.
Comment 12 Wade Walker 2010-11-29 16:10:35 CET
Hi Sven,

I modified the source code for test case very slightly to use JOGL 1.1.1a instead of JOGL 2.0, and it works fine that way, no errors at all. All non-code factors (platform, Java version, SWT version, etc.) are exactly the same.

This seems to show that there's some slight difference between JOGL 1.1.1a and JOGL 2.0 that causes this failure on these Windows XP platforms.

The order of operations in my code is the same in the 1.1.1a and 2.0 versions, so I'm certain that I'm not accidentally initializing the GDI DC somehow and making it work.

The only JOGL code that's removed in the 1.1.1a version is these two lines:

GLProfile.initSingleton( true );
GLProfile glprofile = GLProfile.get( GLProfile.GL2 );

Could one of these be affecting the GDI DC somehow? Or perhaps the difference between this in JOGL 2:

GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();

and this in JOGL 1.1.1a:

GLContext glcontext = GLDrawableFactory.getFactory().createExternalGLContext();

has some effect?

Please let me know if there's something else I can do to help you track this down. Perhaps if the JOGL build system creates a source code JAR, I could attach that to my project and step through to see what's different between the 1.1.1a and 2.0 versions?
Comment 13 Sven Gothel 2010-12-12 02:13:47 CET
pls check with build #248, if it's okay (still building), thanks.
Comment 14 Wade Walker 2010-12-12 10:07:55 CET
Created attachment 195 [details]
Debug log with JOGL 2 b248
Comment 15 Wade Walker 2010-12-12 10:10:19 CET
Retested with b248, it seems to be getting better :) The etc\test.bat doesn't crash, but I get "org.eclipse.swt.SWTException: Unsupported color depth" when I try to use b248 in the simple test case above. Log file is attached.
Comment 16 Sven Gothel 2010-12-12 11:00:56 CET
Exception in thread "main" org.eclipse.swt.SWTException: Unsupported color depth
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.opengl.GLCanvas.<init>(Unknown Source)
	at name.wadewalker.onetriangle.OneTriangle.main(OneTriangle.java:40)

Thats pretty 'funny', since I can't see how JOGL interferes here with SWT's GLCanvas
context creation ?
Comment 17 Wade Walker 2010-12-12 11:58:44 CET
I traced through in the debugger to get more info. Inside GLCanvas(), the failure is in these lines:

	int /*long*/ hDC = OS.GetDC (handle);
	pixelFormat = WGL.ChoosePixelFormat (hDC, pfd);
	if (pixelFormat == 0 || !WGL.SetPixelFormat (hDC, pixelFormat, pfd)) {
		OS.ReleaseDC (handle, hDC);
		dispose ();
		SWT.error (SWT.ERROR_UNSUPPORTED_DEPTH);
	}

The WGL.SetPixelFormat() call returns false, which causes the SWT exception. The pfd is all zeroes, except for dwFlags=37, nSize=40, and nVersion=1. The pixelFormat=3 after WGL.ChoosePixelFormat() is called.

I traced through both the JOGL 1.1.1a and JOGL 2 b248 versions, and the variable values are the same in both cases. The only difference is the behavior of WGL.SetPixelFormat() (a native method inside SWT).

So perhaps there's a difference in the way the hDC is set up in JOGL 1.1.1a and JOGL 2 that causes this failure?
Comment 18 Sven Gothel 2011-02-05 04:13:00 CET
Any news with this bug ?
Comment 19 Wade Walker 2011-02-05 04:48:33 CET
I ran this test on a friend's computer... I'll get him to loan it to me again on Monday so I can redo this test. In the meantime I'll retest on a similar machine tomorrow.
Comment 20 Wade Walker 2011-02-15 03:01:03 CET
It seems like this bug is the same as the one we discussed on the forum at http://forum.jogamp.org/New-tutorial-on-AWT-SWT-Swing-GLJPanel-GLCanvas-tp2363921p2478777.html. I show a hack on the forum that people could use temporarily to work around this problem until the fix is in place.
Comment 21 Sven Gothel 2011-02-25 05:35:02 CET
http://jogamp.org/git/?p=jogl.git;a=commit;h=b6c02b25a28a430506e6e9ab2e19b7a967220427

.. even though, my winxp 32bit was not refreshing the window properly. pls verify.
Comment 22 Wade Walker 2011-02-27 00:46:00 CET
This one still fails on Win XP 32-bit, ATI Mobility Radeon x300. I checkout out the code and built it just now, so it's at b329. Here's the stack trace for TestSWT01GLn:

org.eclipse.swt.SWTException: Unsupported color depth
	at org.eclipse.swt.SWT.error(SWT.java:4083)
	at org.eclipse.swt.SWT.error(SWT.java:3998)
	at org.eclipse.swt.SWT.error(SWT.java:3969)
	at org.eclipse.swt.opengl.GLCanvas.<init>(GLCanvas.java:84)
	at com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn.runTestAGL(TestSWT01GLn.java:123)
	at com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn.testA01GLDefault(TestSWT01GLn.java:247)
	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:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

The new debug log is attached.
Comment 23 Wade Walker 2011-02-27 00:49:56 CET
Created attachment 233 [details]
New debug log for b329; shows unsupported color depth
Comment 24 Sven Gothel 2011-02-27 18:10:03 CET
line 123 > final GLCanvas glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );

so it's an SWT/GPU-driver issue here, or you have to tweak the 'gldata' which defines the 
non ARB pixelformat.

as you see, all SWT limitations, ie no ARB PFD etc ..

will submit a native SWT test for win/linux later today/tomorrow,
enabling you to use our PFD/GLCaps selection and profile.
Comment 25 Wade Walker 2011-02-27 19:29:28 CET
I don't understand how it can be an SWT issue, since this exact test runs perfectly with JOGL 1 :) SWT has not changed since then, so it seems like JOGL 2 must be treating external GL contexts in a different way. I'll wait for your example, maybe then I'll understand better what you mean.
Comment 26 Wade Walker 2011-03-17 15:27:48 CET
I've verified that this fix works on Win 32 with Nvidia graphics cards. The ATI problem with color depth that I mentioned here earlier seems to be a different problem related to ATI video cards (see bug 480).