Main Menu

OpenGL Support

Started by CaseyB, September 16, 2005, 21:43:22

Previous topic - Next topic

CaseyB

I am going to write a rendering engine with two back ends.  I want to check if the computers hardware for OpenGL support and if it exists load the OpenGL version, if not then load the Java2D version.  I have found many examples of how to check for certain extension, but I can't find how to check for hardware OpenGL support!  I am sure there's a way to do it, what am I overlooking?

Casey

darkprophet

if (GLContext.getCapabilities().GL11) {
 initGL();
} else {
 init2D();


DP

CaseyB


CaseyB

GL11 cannot be resolved or is not a field, it does give me a list of extensions that I can check for, but not a wholesale yay or nay.  Any other ideas?

darkprophet

mind slip, replace GL11 with OpenGL11

DP

CaseyB

I knew I had to be something simple I was overlooking!!  I'll give it a go tomorrow!  :wink:

CaseyB

When I do that it kills the JVM.  If I replace that condition with a simple true or false, it works fine, so it has to be that line!  Any ideas?  Here is the error log:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00a8d682, pid=2776, tid=3936
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_04-b05 mixed mode)
# Problematic frame:
# j  com.sensis.gdm.CanvasFactory.newInstance()Lcom/sensis/gdm/CanvasFactory;+32
#

---------------  T H R E A D  ---------------

Current thread (0x00355ea0):  JavaThread "main" [_thread_in_Java, id=3936]

siginfo: ExceptionCode=0xc0000005, reading address 0x00001792

Registers:
EAX=0x00000000, EBX=0x00001792, ECX=0x00000000, EDX=0x00000014
ESP=0x0006fa34, EBP=0x0006fa50, ESI=0x27224518, EDI=0x0006fa64
EIP=0x00a8d682, EFLAGS=0x00010246

Top of Stack: (sp=0x0006fa34)
0x0006fa34:   0006fa34 27224518 0006fa64 27224a28
0x0006fa44:   00000000 272245d0 0006fa68 0006fa84
0x0006fa54:   00a829fa 00000000 00000000 00000000
0x0006fa64:   02a9edc0 0006fa68 26fce6d6 0006fa94
0x0006fa74:   27003ad8 00000000 26fce730 0006fa94
0x0006fa84:   0006fab8 00a82923 00000000 02b2b080
0x0006fa94:   02acc280 02acc280 0006fa9c 26fce5ec
0x0006faa4:   0006fac4 27003ad8 00000000 26fce638 

Instructions: (pc=0x00a8d682)
0x00a8d672:   44 91 1c 59 c1 e8 1c 83 e0 0f 0f 85 0a 00 00 00
0x00a8d682:   0f be 04 19 50 e9 a4 00 00 00 83 f8 03 0f 85 09 


Stack: [0x00030000,0x00070000),  sp=0x0006fa34,  free space=254k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
j  com.sensis.gdm.CanvasFactory.newInstance()Lcom/sensis/gdm/CanvasFactory;+32
j  test.FactoryTest.<init>()V+22
j  test.FactoryTest.main([Ljava/lang/String;)V+4
v  ~StubRoutines::call_stub
V  [jvm.dll+0x82696]
V  [jvm.dll+0xd6fd9]
V  [jvm.dll+0x82567]
V  [jvm.dll+0x895e6]
C  [javaw.exe+0x14c0]
C  [javaw.exe+0x313d]
C  [kernel32.dll+0x16d4f]


---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x2b289a00 JavaThread "AWT-Windows" daemon [_thread_in_native, id=3400]
  0x2b2895d0 JavaThread "AWT-Shutdown" [_thread_blocked, id=3496]
  0x2b283d30 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=3940]
  0x00a41950 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=1796]
  0x00a40528 JavaThread "CompilerThread0" daemon [_thread_blocked, id=180]
  0x00a3f8b0 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=3476]
  0x00a36b58 JavaThread "Finalizer" daemon [_thread_blocked, id=3644]
  0x009e9b30 JavaThread "Reference Handler" daemon [_thread_blocked, id=3216]
=>0x00355ea0 JavaThread "main" [_thread_in_Java, id=3936]

Other Threads:
  0x00a32bb0 VMThread [id=3032]
  0x00a42b28 WatcherThread [id=3888]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
 def new generation   total 41088K, used 2200K [0x02a80000, 0x05710000, 0x05710000)
  eden space 36544K,   6% used [0x02a80000, 0x02ca6310, 0x04e30000)
  from space 4544K,   0% used [0x04e30000, 0x04e30000, 0x052a0000)
  to   space 4544K,   0% used [0x052a0000, 0x052a0000, 0x05710000)
 tenured generation   total 548288K, used 0K [0x05710000, 0x26e80000, 0x26e80000)
   the space 548288K,   0% used [0x05710000, 0x05710000, 0x05710200, 0x26e80000)
 compacting perm gen  total 8192K, used 4177K [0x26e80000, 0x27680000, 0x2ae80000)
   the space 8192K,  50% used [0x26e80000, 0x27294558, 0x27294600, 0x27680000)
No shared spaces configured.

Dynamic libraries:
0x00400000 - 0x0040c000 	C:\Program Files\Java\jre1.5.0_04\bin\javaw.exe
0x7c900000 - 0x7c9b0000 	C:\WINDOWS\system32\ntdll.dll
0x7c800000 - 0x7c8f4000 	C:\WINDOWS\system32\kernel32.dll
0x77dd0000 - 0x77e6b000 	C:\WINDOWS\system32\ADVAPI32.dll
0x77e70000 - 0x77f01000 	C:\WINDOWS\system32\RPCRT4.dll
0x77d40000 - 0x77dd0000 	C:\WINDOWS\system32\USER32.dll
0x77f10000 - 0x77f56000 	C:\WINDOWS\system32\GDI32.dll
0x77c10000 - 0x77c68000 	C:\WINDOWS\system32\MSVCRT.dll
0x6d640000 - 0x6d7c9000 	C:\Program Files\Java\jre1.5.0_04\bin\client\jvm.dll
0x76b40000 - 0x76b6d000 	C:\WINDOWS\system32\WINMM.dll
0x6d280000 - 0x6d288000 	C:\Program Files\Java\jre1.5.0_04\bin\hpi.dll
0x76bf0000 - 0x76bfb000 	C:\WINDOWS\system32\PSAPI.DLL
0x6d610000 - 0x6d61c000 	C:\Program Files\Java\jre1.5.0_04\bin\verify.dll
0x6d300000 - 0x6d31d000 	C:\Program Files\Java\jre1.5.0_04\bin\java.dll
0x6d630000 - 0x6d63f000 	C:\Program Files\Java\jre1.5.0_04\bin\zip.dll
0x6d000000 - 0x6d167000 	C:\Program Files\Java\jre1.5.0_04\bin\awt.dll
0x73000000 - 0x73026000 	C:\WINDOWS\system32\WINSPOOL.DRV
0x76390000 - 0x763ad000 	C:\WINDOWS\system32\IMM32.dll
0x774e0000 - 0x7761d000 	C:\WINDOWS\system32\ole32.dll
0x73760000 - 0x737a9000 	C:\WINDOWS\system32\ddraw.dll
0x73bc0000 - 0x73bc6000 	C:\WINDOWS\system32\DCIMAN32.dll
0x73940000 - 0x73a10000 	C:\WINDOWS\system32\D3DIM700.DLL
0x6d240000 - 0x6d27d000 	C:\Program Files\Java\jre1.5.0_04\bin\fontmanager.dll
0x74720000 - 0x7476b000 	C:\WINDOWS\system32\MSCTF.dll
0x7c9c0000 - 0x7d1d4000 	C:\WINDOWS\system32\shell32.dll
0x77f60000 - 0x77fd6000 	C:\WINDOWS\system32\SHLWAPI.dll
0x773d0000 - 0x774d2000 	C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll
0x5d090000 - 0x5d127000 	C:\WINDOWS\system32\comctl32.dll
0x2b570000 - 0x2b5b1000 	C:\WINDOWS\SYSTEM32\lwjgl.dll
0x72280000 - 0x722aa000 	C:\WINDOWS\system32\DINPUT.dll
0x5ed00000 - 0x5edcc000 	C:\WINDOWS\system32\OPENGL32.dll
0x68b20000 - 0x68b40000 	C:\WINDOWS\system32\GLU32.dll
0x77c00000 - 0x77c08000 	C:\WINDOWS\system32\VERSION.dll

VM Arguments:
jvm_args: -Xms580m -Xmx580m
java_command: test.FactoryTest

Environment Variables:
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\matlab6p5p1\bin\win32;C:\Program Files\Common Files\Autodesk Shared\
USERNAME=cborders
OS=Windows_NT
PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 1, GenuineIntel



---------------  S Y S T E M  ---------------

OS: Windows XP Build 2600 Service Pack 2

CPU:total 1 family 15, cmov, cx8, fxsr, mmx, sse, sse2, ht

Memory: 4k page, physical 1038408k(508088k free), swap 1712236k(664764k free)

vm_info: Java HotSpot(TM) Client VM (1.5.0_04-b05) for windows-x86, built on Jun  3 2005 02:10:41 by "java_re" with MS VC++ 6.0
[/code]

elias

Heh. The problem here is that GLContext.getCapabilities() is null, since it is only initialized when a context is active. The right way to check for OpenGL is to create the Display or a Pbuffer.

However, even a null ContextCapabilities reference should not result in a native crash, so I investigated further and it seems that CaseyB has run into a JVM bug! To verify that it really is a JVM bug, I've created a somewhat minimal test case that can be found here:

http://odense.kollegienet.dk/~naur/JVMCrash.zip

it contains a stand alone cut down version of ContextCapabilities and a JVMCrash.java that looks like this:

public class JVMCrash {
    public static void main(String[] args) {
        ContextCapabilities f = null;
System.out.println("f = " + f + " | f.OpenGL11 = " + f.OpenGL11);
    }
}


The test contains no native code, so it is proof that this is a JVM bug. The bug seems to be caused by large classes, since deleting fields from the ContextCapabilities class will make the native crash disappear and result in the expected NullPointerException.

I'll post a bug to sun.

- elias

princec

This bug is probably caused by us exceeding the 64kb limit on class file size. ContextCapabilities is 90-odd kb. I should think that it's not checked properly on local class loads (ie. the verifier is not turned on) and this might lead to some unexpected behaviour.

Cas :)

CaseyB

I downloaded the newest snapshot of 6.0 and it's broken there too!  If it is a class size restriction issue is there a way around it??

-=EDIT=-
I googled "LWJGL Pbuffer" and found some very useful code by gregorypierce that lets me check for the support I need!!  Thank you guys!

elias

Don't use the getCapabilities check. The correct way to check for OpenGL support is to try to create a Display or a Pbuffer.

- elias

CaseyB

so it would be:
Pbuffer pbuffer = new Pbuffer(1, 1, new PixelFormat(), null, null);
if(pbuffer != null)
{
     // OpenGL
}
else
{
    // Java2D
}


You see the trouble that I'm having is that I don't have an OpenGL-less computer to test this on, so I don't know if it will simply not create the pbuffer or if it will crash most egregiously!

princec

Further investigation reveals that the class size itself is not the issue but the size of some part of the class file; in this case I think we're using more than 64kb for the constant pool because of all those variables.

Cas :)

elias

If it crashes, it's a lwjgl bug and you should report it :). But why not simply create the Display right away, and if it fails, fall back to Java2D? It seems wasteful to create a Pbuffer just the check if the Display can be created (assuming you want to display something, not just do offline rendering).

Besides, Pbuffer creation can fail where Display creation succeeds. For example when the OpenGL drivers doesn't support Pbuffers. However, if you keep the Pbuffer check, remember to destroy it again.

- elias

CaseyB

I am using an AWTGLCanvas as part of a larger app, so I am writing classes that extend java.awt.Canvas and AWTGLCanvas and loading the correct one depending on the results of the test!