diff options
246 files changed, 7388 insertions, 3389 deletions
diff --git a/doc/NEWT.txt b/doc/NEWT.txt new file mode 100644 index 000000000..c97d90e30 --- /dev/null +++ b/doc/NEWT.txt @@ -0,0 +1,30 @@ +NEWT / Swing/AWT mixed usage: +================================== + +1) Shut down menus when NEWT window gains focus: ++++ + glWindow.addWindowListener(new WindowAdapter() { + public void windowGainedFocus(WindowEvent arg0) { + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + }); ++++ + +2) Mixing hw/lw components + +http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6776743 +http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788954 +http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6797587 + +Bug 6788954: + If an existing application embedds a heavyweight component in a frame, + and at the same time installs a custom glass pane, + the heavyweight component will disappear. + This regression is not very serious since we never supported mixing of hw and lw components + in general. The developer will have two options to resolve the problem: + 1. By modifying the software to tag the glass pane properly, or + 2. To suggest users to use the sun.awt.disableMixing system property + to disable the hw/lw mixing code at all. + + + diff --git a/doc/TODO.txt b/doc/TODO.txt index 294f16cd1..4c5f61f88 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -1,17 +1,12 @@ -This list is probably completely out of date... -anyone the guts to remove it? :) --mbien +WIP: + +- Protected access for Impl classes Random, somewhat old to-do list: - Non-const array types must be properly released with JNI_COMMIT in order to see side effects if the array was copied. -- Think about e.g. protected access for Impl classes - -- Fix glProgramStringARB and glGetProgramString{NV,ARB} so that they - use Strings and/or StringBuffers insteead of GLUbyte* and void* - - figure out how to deal with WGL entry points: WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC, int); WINGDIAPI BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD); @@ -33,9 +28,3 @@ Random, somewhat old to-do list: - Throw an exception if native calls to GetPrimitiveArrayCritical return null. -- Before emitting functions and constants, sort them first by - extension suffix (i.e., ARB, ATI, NV, etc) and then by name. This - will organize them in the file more logically. When writing the - code, the sort function can check the last substring that's all caps, - and treat this as the extension owner. Be careful though, some end - in "3D" and that's not an extension. diff --git a/jnlp-files/applet-version-jnlp.html b/jnlp-files/applet-version-jnlp.html new file mode 100644 index 000000000..6f91908ea --- /dev/null +++ b/jnlp-files/applet-version-jnlp.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head> +<title>JOGL JNLP Applet Version (JNLP/Launcher)</title> +</head> +<body> + +<P> +The applet below shall show you the version of the Jogl components +and your platform. +</P> +<p> +JNLP Applet with AppletLauncher fallback version. +</p> + +<P> + +<applet code="org.jdesktop.applet.util.JNLPAppletLauncher" + width=800 + height=600 + archive="JOGL_CODEBASE_TAG/../util/applet-launcher.jar, + JOGL_CODEBASE_TAG/newt.all.jar, + JOGL_CODEBASE_TAG/jogl.all.jar, + JOGL_CODEBASE_TAG/nativewindow.all.jar, + JOGL_CODEBASE_TAG/gluegen-rt.jar"> + <param name="codebase_lookup" value="false"> + <param name="subapplet.classname" value="com.jogamp.newt.impl.awt.opengl.VersionApplet"> + <param name="subapplet.displayname" value="JOGL Applet Version"> + <!-- param name="noddraw.check" value="true" --> + <param name="progressbar" value="true"> + <param name="jnlpNumExtensions" value="1"> + <param name="jnlpExtension1" value="JOGL_CODEBASE_TAG/jogl-core.jnlp"> + <!-- param name="java_arguments" value="-Dsun.java2d.noddraw=true" --> + <param name="jnlp_href" value="JOGL_CODEBASE_TAG/applet-version.jnlp"> +</applet> + + +</P> + +</body> +</html> diff --git a/jnlp-files/applet-version-lancheronly.html b/jnlp-files/applet-version-lancheronly.html new file mode 100644 index 000000000..804aeebbb --- /dev/null +++ b/jnlp-files/applet-version-lancheronly.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head> +<title>JOGL JNLP Applet Version (Launcher)</title> +</head> +<body> + +<P> +The applet below shall show you the version of the Jogl components +and your platform. +</P> +<p> +AppletLauncher only version. +</p> + +<P> + +<applet code="org.jdesktop.applet.util.JNLPAppletLauncher" + width=800 + height=600 + archive="JOGL_CODEBASE_TAG/../util/applet-launcher.jar, + JOGL_CODEBASE_TAG/newt.all.jar, + JOGL_CODEBASE_TAG/jogl.all.jar, + JOGL_CODEBASE_TAG/nativewindow.all.jar, + JOGL_CODEBASE_TAG/gluegen-rt.jar"> + <param name="codebase_lookup" value="false"> + <param name="subapplet.classname" value="com.jogamp.newt.impl.awt.opengl.VersionApplet"> + <param name="subapplet.displayname" value="JOGL Applet Version"> + <!-- param name="noddraw.check" value="true" --> + <param name="progressbar" value="true"> + <param name="jnlpNumExtensions" value="1"> + <param name="jnlpExtension1" value="JOGL_CODEBASE_TAG/jogl-core.jnlp"> +</applet> + + +</P> + +</body> +</html> diff --git a/jnlp-files/applet-version.jnlp b/jnlp-files/applet-version.jnlp new file mode 100644 index 000000000..821cef0c7 --- /dev/null +++ b/jnlp-files/applet-version.jnlp @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<jnlp codebase="JOGL_CODEBASE_TAG" href="applet-version.jnlp" version="JOGAMP_VERSION"> + <information> + <title>JOGL JNLP Applet Version</title> + <vendor>JogAmp Community</vendor> + <homepage href="http://jogamp.org/"/> + <description>JOGL Version</description> + <offline-allowed/> + </information> + <update check="background" policy="always"/> + + <resources> + <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/> + <!-- property name="sun.java2d.noddraw" value="true"/--> + <extension name="newt-all-awt" href="JOGL_CODEBASE_TAG/newt-all-awt.jnlp" /> + </resources> + + <applet-desc + name="Version-Applet" + main-class="com.jogamp.newt.impl.awt.opengl.VersionApplet" + width="800" + height="600"> + </applet-desc> +</jnlp> diff --git a/jnlp-files/javaws-version.jnlp b/jnlp-files/javaws-version.jnlp new file mode 100755 index 000000000..6bf59e915 --- /dev/null +++ b/jnlp-files/javaws-version.jnlp @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<jnlp codebase="JOGL_CODEBASE_TAG" href="javaws-version.jnlp" version="JOGAMP_VERSION"> + <information> + <title>JOGL JNLP Javaws Version</title> + <vendor>JogAmp Community</vendor> + <homepage href="http://jogamp.org/"/> + <description>JOGL Version</description> + <offline-allowed/> + </information> + <update check="background" policy="always"/> + + <resources> + <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/> + <!-- property name="sun.java2d.noddraw" value="true"/--> + <extension name="newt-all-awt" href="JOGL_CODEBASE_TAG/newt-all-awt.jnlp" /> + </resources> + + <application-desc main-class="com.jogamp.newt.impl.awt.opengl.VersionApplet"/> +</jnlp> diff --git a/jnlp-files/jogl-all-awt.jnlp b/jnlp-files/jogl-all-awt.jnlp index df0c56076..822c26abf 100644 --- a/jnlp-files/jogl-all-awt.jnlp +++ b/jnlp-files/jogl-all-awt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="jogl-all-awt.jnlp"> + href="jogl-all-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) Binding to the OpenGL(r) API (ALL.AWT)</title> <vendor>JogAmp Community</vendor> diff --git a/jnlp-files/jogl-all-noawt.jnlp b/jnlp-files/jogl-all-noawt.jnlp index 14fb181a7..55b548f50 100644 --- a/jnlp-files/jogl-all-noawt.jnlp +++ b/jnlp-files/jogl-all-noawt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="jogl-all-noawt.jnlp"> + href="jogl-all-noawt.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) Binding to the OpenGL(r) API (ALL.NO_AWT)</title> <vendor>JogAmp Community</vendor> diff --git a/jnlp-files/jogl-awt.jnlp b/jnlp-files/jogl-awt.jnlp index 684c2d5da..ffdaee0cc 100644 --- a/jnlp-files/jogl-awt.jnlp +++ b/jnlp-files/jogl-awt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="jogl-awt.jnlp"> + href="jogl-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) Binding to the OpenGL(r) API (AWT)</title> <vendor>JogAmp Community</vendor> diff --git a/jnlp-files/jogl-core.jnlp b/jnlp-files/jogl-core.jnlp index dca293720..464c65c94 100644 --- a/jnlp-files/jogl-core.jnlp +++ b/jnlp-files/jogl-core.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="jogl-core.jnlp"> + href="jogl-core.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) Binding to the OpenGL(r) API (CORE)</title> <vendor>JogAmp Community</vendor> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="jogl.core.jar" main="true"/> + <jar href="jogl.core.jar"/> <jar href="jogl.util.jar" download="lazy"/> <extension name="gluegen-rt" href="GLUEGEN_CODEBASE_TAG/gluegen-rt.jnlp" /> diff --git a/jnlp-files/jogl-gl2es12.jnlp b/jnlp-files/jogl-gl2es12.jnlp deleted file mode 100644 index 92fa621cf..000000000 --- a/jnlp-files/jogl-gl2es12.jnlp +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<jnlp codebase="JOGL_CODEBASE_TAG/" - href="jogl-gl2es12.jnlp"> - <information> - <title>Java(tm) Binding to the OpenGL(r) API (GL2ES12)</title> - <vendor>JogAmp Community</vendor> - <homepage href="http://jogamp.org/"/> - <description>Java Binding to the OpenGL API - JSR-231 2.0.0 - GL2ES12</description> - <description kind="short">Java programming language binding for the OpenGL 3D graphics API - GL2ES12.</description> - <offline-allowed/> - </information> - <update check="background" policy="always"/> - <security> - <all-permissions/> - </security> - <resources> - <jar href="jogl.glu.mipmap.jar" download="lazy"/> - <jar href="jogl.glu.tess.jar" download="lazy"/> - - <jar href="jogl.util.fixedfuncemu.jar" download="lazy"/> - - <!-- jar href="jogl.sdk.jar" /--> - - <extension name="jogl-core" href="JOGL_CODEBASE_TAG/jogl-core.jnlp" /> - </resources> - - <resources os="Mobile-Embedded"> - <jar href="jogl.egl.jar" /> - <jar href="jogl.gles1.jar" /> - <jar href="jogl.gles1.dbg.jar" download="lazy"/> - <jar href="jogl.gles2.jar" /> - <jar href="jogl.gles2.dbg.jar" download="lazy"/> - </resources> - <resources os="Windows"> - <jar href="jogl.gl2es12.win.jar" /> - <jar href="jogl.gl2es12.dbg.jar" download="lazy"/> - </resources> - <resources os="SunOS Linux"> - <jar href="jogl.gl2es12.x11.jar" /> - <jar href="jogl.gl2es12.dbg.jar" download="lazy"/> - </resources> - <resources os="Mac OS X"> - <jar href="jogl.gl2es12.osx.jar" /> - <jar href="jogl.gl2es12.dbg.jar" download="lazy"/> - </resources> - - <component-desc /> -</jnlp> diff --git a/jnlp-files/nativewindow-all-awt.jnlp b/jnlp-files/nativewindow-all-awt.jnlp index 5273c2c88..57a189530 100644 --- a/jnlp-files/nativewindow-all-awt.jnlp +++ b/jnlp-files/nativewindow-all-awt.jnlp @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="nativewindow-all-awt.jnlp"> + href="nativewindow-all-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) NativeWindow Interface API (ALL.AWT)</title> <vendor>JogAmp Community</vendor> - <homepage href="http://nativewindow.dev.java.net/"/> + <homepage href="http://jogamp.org/"/> <description>Java API for a binding to a native windowing system - 2.0 - ALL.AWT</description> <description kind="short">Java API for a binding to a native windowing system - 2.0 - ALL.AWT</description> <offline-allowed/> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="nativewindow.all.jar" main="true" /> + <jar href="nativewindow.all.jar"/> <extension name="gluegen-rt" href="GLUEGEN_CODEBASE_TAG/gluegen-rt.jnlp" /> </resources> diff --git a/jnlp-files/nativewindow-awt.jnlp b/jnlp-files/nativewindow-awt.jnlp index b7a5c0f88..d37446c5a 100644 --- a/jnlp-files/nativewindow-awt.jnlp +++ b/jnlp-files/nativewindow-awt.jnlp @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="nativewindow-awt.jnlp"> + href="nativewindow-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) NativeWindow Interface API (AWT)</title> <vendor>JogAmp Community</vendor> - <homepage href="http://nativewindow.dev.java.net/"/> + <homepage href="http://jogamp.org/"/> <description>Java API for a binding to a native windowing system - 2.0 - AWT</description> <description kind="short">Java API for a binding to a native windowing system - 2.0 - AWT</description> <offline-allowed/> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="nativewindow.awt.jar" main="true" /> + <jar href="nativewindow.awt.jar"/> <extension name="nativewindow" href="JOGL_CODEBASE_TAG/nativewindow.jnlp" /> </resources> diff --git a/jnlp-files/nativewindow.jnlp b/jnlp-files/nativewindow.jnlp index 8af99a57c..a2b0c79de 100644 --- a/jnlp-files/nativewindow.jnlp +++ b/jnlp-files/nativewindow.jnlp @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="nativewindow.jnlp"> + href="nativewindow.jnlp" version="JOGAMP_VERSION"> <information> <title>Java(tm) NativeWindow Interface API (CORE)</title> <vendor>JogAmp Community</vendor> - <homepage href="http://nativewindow.dev.java.net/"/> + <homepage href="http://jogamp.org/"/> <description>Java API for a binding to a native windowing system - 2.0 - CORE</description> <description kind="short">Java API for a binding to a native windowing system - 2.0 - CORE</description> <offline-allowed/> @@ -14,56 +14,56 @@ <all-permissions/> </security> <resources> - <jar href="nativewindow.core.jar" main="true" /> + <jar href="nativewindow.core.jar" /> <extension name="gluegen-rt" href="GLUEGEN_CODEBASE_TAG/gluegen-rt.jnlp" /> </resources> <resources os="Windows" arch="x86"> - <jar href="nativewindow.os.windows.jar" main="true" /> + <jar href="nativewindow.os.win.jar" /> <nativelib href = "nativewindow-natives-windows-i586.jar" /> </resources> <resources os="Windows" arch="amd64"> - <jar href="nativewindow.os.windows.jar" main="true" /> + <jar href="nativewindow.os.win.jar" /> <nativelib href = "nativewindow-natives-windows-amd64.jar" /> </resources> <resources os="Windows" arch="x86_64"> - <jar href="nativewindow.os.windows.jar" main="true" /> + <jar href="nativewindow.os.win.jar" /> <nativelib href = "nativewindow-natives-windows-amd64.jar" /> </resources> <resources os="SunOS" arch="sparc"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-solaris-sparc.jar" /> </resources> <resources os="SunOS" arch="sparcv9"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-solaris-sparcv9.jar" /> </resources> <resources os="SunOS" arch="x86"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-solaris-i586.jar" /> </resources> <resources os="SunOS" arch="amd64"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-solaris-amd64.jar" /> </resources> <resources os="SunOS" arch="x86_64"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-solaris-amd64.jar" /> </resources> <resources os="Linux" arch="i386"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-linux-i586.jar" /> </resources> <resources os="Linux" arch="x86"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-linux-i586.jar" /> </resources> <resources os="Linux" arch="amd64"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-linux-amd64.jar" /> </resources> <resources os="Linux" arch="x86_64"> - <jar href="nativewindow.os.x11.jar" main="true" /> + <jar href="nativewindow.os.x11.jar" /> <nativelib href = "nativewindow-natives-linux-amd64.jar" /> </resources> <resources os="Mac OS X" arch="i386"> diff --git a/jnlp-files/newt-all-awt.jnlp b/jnlp-files/newt-all-awt.jnlp index f063ae1b9..c4444ff63 100644 --- a/jnlp-files/newt-all-awt.jnlp +++ b/jnlp-files/newt-all-awt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="newt-all-awt.jnlp"> + href="newt-all-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>NEWT - New Windowing Toolkit (ALL.AWT)</title> <vendor>JogAmp Community</vendor> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="newt.all.jar" main="true"/> + <jar href="newt.all.jar" /> <extension name="jogl-all-awt" href="JOGL_CODEBASE_TAG/jogl-all-awt.jnlp" /> </resources> diff --git a/jnlp-files/newt-all-noawt.jnlp b/jnlp-files/newt-all-noawt.jnlp index 63ff48e3b..c67c7ac08 100644 --- a/jnlp-files/newt-all-noawt.jnlp +++ b/jnlp-files/newt-all-noawt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="newt-all-noawt.jnlp"> + href="newt-all-noawt.jnlp" version="JOGAMP_VERSION"> <information> <title>NEWT - New Windowing Toolkit (ALL.NO_AWT)</title> <vendor>JogAmp Community</vendor> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="newt.all-noawt.jar" main="true"/> + <jar href="newt.all-noawt.jar" /> <extension name="jogl-all-noawt" href="JOGL_CODEBASE_TAG/jogl-all-noawt.jnlp" /> </resources> diff --git a/jnlp-files/newt-awt.jnlp b/jnlp-files/newt-awt.jnlp index 02f25786a..fc5b7f178 100644 --- a/jnlp-files/newt-awt.jnlp +++ b/jnlp-files/newt-awt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="newt-awt.jnlp"> + href="newt-awt.jnlp" version="JOGAMP_VERSION"> <information> <title>NEWT - New Windowing Toolkit (AWT)</title> <vendor>JogAmp Community</vendor> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="newt.awt.jar" main="true"/> + <jar href="newt.awt.jar" /> <extension name="nativewindow-awt" href="JOGL_CODEBASE_TAG/nativewindow-awt.jnlp" /> <extension name="newt" href="JOGL_CODEBASE_TAG/newt.jnlp" /> </resources> diff --git a/jnlp-files/newt-jogl.jnlp b/jnlp-files/newt-jogl.jnlp index ee95a1faa..cd0f5d633 100644 --- a/jnlp-files/newt-jogl.jnlp +++ b/jnlp-files/newt-jogl.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="newt-jogl.jnlp"> + href="newt-jogl.jnlp" version="JOGAMP_VERSION"> <information> <title>NEWT - New Windowing Toolkit (JOGL)</title> <vendor>JogAmp Community</vendor> @@ -14,7 +14,7 @@ <all-permissions/> </security> <resources> - <jar href="newt.ogl.jar" main="true"/> + <jar href="newt.ogl.jar" /> <extension name="newt" href="JOGL_CODEBASE_TAG/newt.jnlp" /> <extension name="jogl-core" href="JOGL_CODEBASE_TAG/jogl-core.jnlp" /> </resources> diff --git a/jnlp-files/newt.jnlp b/jnlp-files/newt.jnlp index ce4ed6f28..9decf249d 100644 --- a/jnlp-files/newt.jnlp +++ b/jnlp-files/newt.jnlp @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="JOGL_CODEBASE_TAG/" - href="newt.jnlp"> + href="newt.jnlp" version="JOGAMP_VERSION"> <information> <title>NEWT - New Windowing Toolkit (CORE)</title> <vendor>JogAmp Community</vendor> @@ -14,64 +14,64 @@ <all-permissions/> </security> <resources> - <jar href="newt.core.jar" main="true" /> + <jar href="newt.core.jar" /> <extension name="nativewindow" href="JOGL_CODEBASE_TAG/nativewindow.jnlp" /> </resources> <resources os="Windows" arch="x86"> - <jar href="newt.win.jar" main="true" /> + <jar href="newt.os.win.jar" /> <nativelib href = "newt-natives-windows-i586.jar" /> </resources> <resources os="Windows" arch="amd64"> - <jar href="newt.win.jar" main="true" /> + <jar href="newt.os.win.jar" /> <nativelib href = "newt-natives-windows-amd64.jar" /> </resources> <resources os="Windows" arch="x86_64"> - <jar href="newt.win.jar" main="true" /> + <jar href="newt.os.win.jar" /> <nativelib href = "newt-natives-windows-amd64.jar" /> </resources> <resources os="SunOS" arch="sparc"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-solaris-sparc.jar" /> </resources> <resources os="SunOS" arch="sparcv9"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-solaris-sparcv9.jar" /> </resources> <resources os="SunOS" arch="x86"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-solaris-i586.jar" /> </resources> <resources os="SunOS" arch="amd64"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-solaris-amd64.jar" /> </resources> <resources os="SunOS" arch="x86_64"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-solaris-amd64.jar" /> </resources> <resources os="Linux" arch="i386"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-linux-i586.jar" /> </resources> <resources os="Linux" arch="x86"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-linux-i586.jar" /> </resources> <resources os="Linux" arch="amd64"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-linux-amd64.jar" /> </resources> <resources os="Linux" arch="x86_64"> - <jar href="newt.x11.jar" main="true" /> + <jar href="newt.os.x11.jar" /> <nativelib href = "newt-natives-linux-amd64.jar" /> </resources> <resources os="Mac OS X" arch="i386"> - <jar href="newt.osx.jar" main="true" /> + <jar href="newt.os.osx.jar" /> <nativelib href = "newt-natives-macosx-universal.jar" /> </resources> <resources os="Mac OS X" arch="x86_64"> - <jar href="newt.osx.jar" main="true" /> + <jar href="newt.os.osx.jar" /> <nativelib href = "newt-natives-macosx-universal.jar" /> </resources> diff --git a/make/build-common.xml b/make/build-common.xml index a13ccefe5..876aa27ce 100644 --- a/make/build-common.xml +++ b/make/build-common.xml @@ -168,17 +168,15 @@ <property name="build.newt" value="${build}/newt" /> <property name="obj.newt" value="${build.newt}/obj"/> - <property name="junit.make" value="." /> - <property name="junit.build.xml" value="${junit.make}/build-junit.xml" /> - <property name="results.junit" value="${build}/test/results" /> - <property name="build.junit" value="${build}/test/build" /> - <property name="obj.junit" value="${build.junit}/obj"/> + <property name="results.test" value="${build}/test/results" /> + <property name="build.test" value="${build}/test/build" /> + <property name="obj.test" value="${build.test}/obj"/> <condition property="obj.custom" value="${custom.libdir}${path.separator}" else=""> <isset property="custom.libdir"/> </condition> - <property name="obj.all.paths" value="${obj.custom}${obj.gluegen}${path.separator}${obj.nativewindow}${path.separator}${obj.jogl}${path.separator}${obj.newt}${path.separator}${obj.junit}" /> + <property name="obj.all.paths" value="${obj.custom}${obj.gluegen}${path.separator}${obj.nativewindow}${path.separator}${obj.jogl}${path.separator}${obj.newt}${path.separator}${obj.test}" /> <path id="gluegen.classpath"> <pathelement location="${gluegen.jar}" /> @@ -283,6 +281,9 @@ <pathelement location="${newt.all.jar}" /> <pathelement location="${jogl.test.jar}" /> </path> + <property name="junit_jogl_newt_awt.run.jars" + value="${junit.jar}${path.separator}${ant.jar}${path.separator}${ant-junit.jar}${path.separator}${gluegen-rt.jar}${path.separator}${nativewindow.all.jar}${path.separator}${jogl.all.jar}${path.separator}${newt.all.jar}${path.separator}${jogl.test.jar}"/> + <path id="jogl_newt_all-noawt.classpath"> <pathelement location="${gluegen-rt.jar}" /> @@ -322,7 +323,7 @@ <property name="nativewindow.core.jar" value="${build.nativewindow}/nativewindow.core.jar" /> <property name="nativewindow.awt.jar" value="${build.nativewindow}/nativewindow.awt.jar" /> <property name="nativewindow.os.x11.jar" value="${build.nativewindow}/nativewindow.os.x11.jar" /> - <property name="nativewindow.os.windows.jar" value="${build.nativewindow}/nativewindow.os.windows.jar" /> + <property name="nativewindow.os.win.jar" value="${build.nativewindow}/nativewindow.os.win.jar" /> <property name="jogl.core.jar" value="${build.jogl}/jogl.core.jar" /> <property name="jogl.cg.jar" value="${build.jogl}/jogl.cg.jar" /> @@ -357,13 +358,13 @@ <property name="newt.os.win.jar" value="${build.newt}/newt.os.win.jar" /> <property name="newt.os.osx.jar" value="${build.newt}/newt.os.osx.jar" /> <property name="newt.ogl.jar" value="${build.newt}/newt.ogl.jar" /> - <property name="newt.broadcomegl.jar" value="${build.newt}/newt.broadcomegl.jar" /> - <property name="newt.intelgdl.jar" value="${build.newt}/newt.intelgdl.jar" /> + <property name="newt.hw.broadcomegl.jar" value="${build.newt}/newt.hw.broadcomegl.jar" /> + <property name="newt.hw.intelgdl.jar" value="${build.newt}/newt.hw.intelgdl.jar" /> <!-- Atomic CDC JARS --> <property name="nativewindow.core.cdc.jar" value="${build.nativewindow}/nativewindow.core.cdc.jar" /> <property name="nativewindow.os.x11.cdc.jar" value="${build.nativewindow}/nativewindow.os.x11.cdc.jar" /> - <property name="nativewindow.os.windows.cdc.jar" value="${build.nativewindow}/nativewindow.os.windows.cdc.jar" /> + <property name="nativewindow.os.win.cdc.jar" value="${build.nativewindow}/nativewindow.os.win.cdc.jar" /> <property name="jogl.core.cdc.jar" value="${build.jogl}/jogl.core.cdc.jar" /> <property name="jogl.gles1.cdc.jar" value="${build.jogl}/jogl.gles1.cdc.jar" /> @@ -384,8 +385,8 @@ <property name="newt.os.win.cdc.jar" value="${build.newt}/newt.os.win.cdc.jar" /> <property name="newt.os.osx.cdc.jar" value="${build.newt}/newt.os.osx.cdc.jar" /> <property name="newt.ogl.cdc.jar" value="${build.newt}/newt.ogl.cdc.jar" /> - <property name="newt.broadcomegl.cdc.jar" value="${build.newt}/newt.broadcomegl.cdc.jar" /> - <property name="newt.intelgdl.cdc.jar" value="${build.newt}/newt.intelgdl.cdc.jar" /> + <property name="newt.hw.broadcomegl.cdc.jar" value="${build.newt}/newt.hw.broadcomegl.cdc.jar" /> + <property name="newt.hw.intelgdl.cdc.jar" value="${build.newt}/newt.hw.intelgdl.cdc.jar" /> <!-- The location and name of the configuration ANT file that will - validate to ensure that all user-define variables are set. --> @@ -402,14 +403,7 @@ <!-- Run the GlueGen build to ensure that the GlueGen ANT task - has been built. --> - <!-- FIXME: remove passing down of antlr.jar when gluegen.properties is on all - nightly build machines --> - <ant antfile="${gluegen.build.xml}" dir="${gluegen.make}" target="all" inheritAll="false"> - <propertyset> - <propertyref name="antlr.jar" /> - <!--propertyref name="gluegen.nsig" /--> - </propertyset> - </ant> + <ant antfile="${gluegen.build.xml}" dir="${gluegen.make}" target="base.compile" inheritAll="false"/> </target> diff --git a/make/build-nativewindow.xml b/make/build-nativewindow.xml index 432646841..be8f6a7a2 100644 --- a/make/build-nativewindow.xml +++ b/make/build-nativewindow.xml @@ -560,14 +560,16 @@ </patternset> <patternset id="c.src.files.x11"> - <include name="${rootrel.generated.c}/X11/X11*.c" if="isX11"/> - <include name="${rootrel.src.c}/x11/Xmisc.c" if="isX11"/> - <include name="${rootrel.src.c}/x11/XineramaHelper.c" if="isX11"/> + <include name="${rootrel.generated.c}/X11/X11*.c"/> + <include name="${rootrel.src.c}/x11/Xmisc.c"/> + <include name="${rootrel.src.c}/x11/XineramaHelper.c"/> + <include name="${rootrel.src.c}/NativewindowCommon.c"/> </patternset> <patternset id="c.src.files.windows"> - <include name="${rootrel.generated.c}/Windows/GDI*.c" if="isWindows"/> - <include name="${rootrel.src.c}/windows/GDImisc.c" if="isWindows"/> + <include name="${rootrel.generated.c}/Windows/GDI*.c"/> + <include name="${rootrel.src.c}/windows/GDImisc.c"/> + <include name="${rootrel.src.c}/NativewindowCommon.c"/> </patternset> <echo message="Compiling @{output.lib.name}" /> @@ -591,6 +593,7 @@ <includepath path="${src.generated.c}/X11" if="isX11"/> <includepath path="${src.generated.c}/MacOSX" if="isOSX"/> <includepath path="${src.generated.c}/Windows" if="isWindows"/> + <includepath path="${src.c}"/> <!-- This must come last to not override real include paths --> <!-- includepath path="stub_includes/macosx" if="isOSX" / --> @@ -731,13 +734,13 @@ </target> <target name="build-jars-windows" depends="setup-manifestfile"> - <jar manifest="tempversion" destfile="${nativewindow.os.windows.jar}" filesonly="true"> + <jar manifest="tempversion" destfile="${nativewindow.os.win.jar}" filesonly="true"> <fileset dir="${classes}" includes="${java.part.windows}" /> </jar> </target> <target name="build-jars-windows-cdc" depends="setup-manifestfile-cdc"> - <jar manifest="tempversion-cdc" destfile="${nativewindow.os.windows.cdc.jar}" filesonly="true"> + <jar manifest="tempversion-cdc" destfile="${nativewindow.os.win.cdc.jar}" filesonly="true"> <fileset dir="${classes-cdc}" includes="${java.part.windows}" /> </jar> diff --git a/make/build-newt.xml b/make/build-newt.xml index 7f33f9c2a..3487da217 100644 --- a/make/build-newt.xml +++ b/make/build-newt.xml @@ -90,7 +90,7 @@ value="com/jogamp/newt/*, com/jogamp/newt/event/*, com/jogamp/newt/util/*, com/jogamp/newt/impl/*, com/jogamp/newt/impl/event/*"/> <property name="java.part.awt" - value="com/jogamp/newt/impl/awt/*, com/jogamp/newt/awt/*, com/jogamp/newt/event/awt/*"/> + value="com/jogamp/newt/awt/*, com/jogamp/newt/event/awt/*, com/jogamp/newt/impl/awt/**"/> <property name="java.part.x11" value="com/jogamp/newt/impl/x11/*"/> @@ -609,14 +609,14 @@ <fileset dir="${classes}" includes="${java.part.opengl}"/> </jar> - <jar manifest="tempversion" destfile="${newt.broadcomegl.jar}" filesonly="true"> + <jar manifest="tempversion" destfile="${newt.hw.broadcomegl.jar}" filesonly="true"> <fileset dir="${classes}" includes="${java.part.broadcomegl}"/> </jar> </target> <target name="build-jars-driver" depends="setup-manifestfile"> - <jar manifest="tempversion" destfile="${newt.intelgdl.jar}" filesonly="true"> + <jar manifest="tempversion" destfile="${newt.hw.intelgdl.jar}" filesonly="true"> <fileset dir="${classes}" includes="${java.part.intelgdl}"/> </jar> @@ -627,14 +627,14 @@ <fileset dir="${classes-cdc}" includes="${java.part.opengl}"/> </jar> - <jar manifest="tempversion-cdc" destfile="${newt.broadcomegl.cdc.jar}" filesonly="true"> + <jar manifest="tempversion-cdc" destfile="${newt.hw.broadcomegl.cdc.jar}" filesonly="true"> <fileset dir="${classes-cdc}" includes="${java.part.broadcomegl}"/> </jar> </target> <target name="build-jars-driver-cdc" depends="setup-manifestfile-cdc"> - <jar manifest="tempversion-cdc" destfile="${newt.intelgdl.cdc.jar}" filesonly="true"> + <jar manifest="tempversion-cdc" destfile="${newt.hw.intelgdl.cdc.jar}" filesonly="true"> <fileset dir="${classes}" includes="${java.part.intelgdl}"/> </jar> diff --git a/make/build-junit.xml b/make/build-test.xml index a271ac09e..b51e2e6c3 100644 --- a/make/build-junit.xml +++ b/make/build-test.xml @@ -15,50 +15,55 @@ - Declare all paths and user defined variables. --> <target name="declare.common" description="Declare properties" depends="common.init"> - <property name="rootrel.src.junit" value="src/junit" /> - <property name="src.junit" value="${project.root}/${rootrel.src.junit}" /> + <property name="rootrel.src.test" value="src/test" /> + <property name="src.test" value="${project.root}/${rootrel.src.test}" /> - <property name="classes" value="${build.junit}/classes" /> + <property name="classes" value="${build.test}/classes" /> <property name="classes.path" location="${classes}"/> <!-- absolute path --> - <property name="java.dir.test" value="com/jogamp/test"/> - <property name="java.part.test" value="${java.dir.test}/**"/> + <property name="java.part.test" value="com/jogamp/**"/> + <property name="java.dir.test" value="com/jogamp/opengl/test"/> + <property name="java.dir.junit" value="${java.dir.test}/junit"/> + <property name="java.dir.bugs" value="${java.dir.test}/bugs"/> - <property name="batchtest.timeout" value="1800000"/> <!-- 30 min --> + <property name="test.archive.name" value="${archive.name}-test-results"/> + <condition property="jvmarg.newt.headless" value="-XstartOnFirstThread -Djava.awt.headless=true"><isset property="isOSX"/></condition> + <condition property="jvmarg.newt.headless" value="-Djava.awt.headless=true"><not><isset property="isOSX"/></not></condition> + <property name="batchtest.timeout" value="1800000"/> <!-- 30 min --> </target> <!-- ================================================================== --> - <!-- - - Initialize all parameters required for the build and create any - - required directories. - --> - <target name="init" depends="declare.common"> - <!-- Create the required output directories. --> - <mkdir dir="${obj.junit}" /> - <mkdir dir="${classes}" /> - </target> - - <!-- ================================================================== --> <!-- - Clean up all that is built. --> <target name="clean" description="Remove all build products" depends="declare.common"> <delete includeEmptyDirs="true" quiet="true"> - <fileset dir="${build.junit}" /> + <fileset dir="${build.test}" /> </delete> </target> <!-- ================================================================== --> <!-- - - Build/run junit. + - Build/run tests/junit. --> - <target name="junit.compile.check" depends="init"> + <target name="test.compile.check" depends="declare.common"> + <!-- Create the required output directories. --> + <mkdir dir="${obj.test}" /> + <mkdir dir="${classes}" /> + + <!-- Clean the results --> + <delete quiet="true"> + <fileset dir="${results.test}" includes="**"/> + <fileset file="${build}/${test.archive.name}.zip"/> + </delete> + <mkdir dir="${results.test}" /> + <property name="jogl.test.jar.path" location="${jogl.test.jar}"/> <!-- absolute path --> <echo message="jogl.test.jar ${jogl.test.jar.path}"/> - <uptodate property="junit.compile.skip"> + <uptodate property="test.compile.skip"> <srcfiles dir= "." includes="*.xml"/> - <srcfiles dir= "${src.junit}" includes="**"/> + <srcfiles dir= "${src.test}" includes="**"/> <srcfiles file="${nativewindow.all.jar}" /> <srcfiles file="${jogl.all.jar}" /> <srcfiles file="${newt.all.jar}" /> @@ -67,7 +72,7 @@ </uptodate> </target> - <target name="junit.compile" depends="junit.compile.check" unless="junit.compile.skip"> + <target name="test.compile" depends="test.compile.check" unless="test.compile.skip"> <!-- Perform the junit pass Java compile --> <javac destdir="${classes}" source="${host.sourcelevel}" @@ -76,7 +81,7 @@ includeAntRuntime="false" debug="${javacdebug}" debuglevel="${javacdebuglevel}"> <classpath refid="junit_jogl_newt.compile.classpath"/> - <src path="${src.junit}" /> + <src path="${src.test}" /> </javac> <delete includeEmptyDirs="true" quiet="true"> <fileset file="${jogl.test.jar}" /> @@ -88,18 +93,84 @@ </jar> </target> - <target name="junit.run.setup" depends="junit.compile"> - <mkdir dir="${results.junit}" /> - <delete quiet="true"> - <fileset dir="${results.junit}" includes="**"/> - </delete> + <target name="test.manual.run" depends="test.compile"> + <for param="test.class.path.m" keepgoing="true"> + <!-- results in absolute path --> + <fileset dir="${classes}"> + <include name="${java.dir.bugs}/**/*Test*"/> + <exclude name="**/*$$*"/> + </fileset> + <sequential> + <var name="test.class.path" unset="true"/> + <property name="test.class.path" basedir="${classes}" relative="true" location="@{test.class.path.m}"/> + <var name="test.class.fqn" unset="true"/> + <pathconvert property="test.class.fqn"> + <fileset file="${classes}${file.separator}${test.class.path}"/> + <chainedmapper> + <globmapper from="${classes.path}${file.separator}*" to="*"/> <!-- rel. --> + <packagemapper from="*.class" to="*"/> <!-- FQCN --> + </chainedmapper> + </pathconvert> + <var name="test.class.result.file" value="${results.test}/TEST-${test.class.fqn}.log"/> + <echo message="Testing ${test.class.fqn} -- ${test.class.result.file}"/> + <apply dir="." executable="${java.home}/bin/java" + parallel="false" + timeout="${batchtest.timeout}" + vmlauncher="false" + relative="true" + failonerror="false" + output="${test.class.result.file}"> + <env key="${system.env.library.path}" path="${obj.all.paths}"/> + <env key="CLASSPATH" value="${junit_jogl_newt_awt.run.jars}"/> + <arg value="-Djava.library.path=${obj.all.paths}"/> + <!-- + <arg line="-Dnewt.debug.EDT"/> + --> + <srcfile/> + <mappedresources> + <fileset dir="${classes}" includes="${test.class.path}"/> + <packagemapper from="*.class" to="*"/> + </mappedresources> + </apply> + </sequential> + </for> + <antcall target="test-zip-archive" inheritRefs="true" inheritAll="true"/> + </target> - <condition property="jvmarg.newt.headless" value="-XstartOnFirstThread -Djava.awt.headless=true"><isset property="isOSX"/></condition> - <condition property="jvmarg.newt.headless" value="-Djava.awt.headless=true"><not><isset property="isOSX"/></not></condition> + <target name="junit.run.noui" depends="test.compile"> + <!-- Test*NOUI* --> + <junit forkmode="perTest" showoutput="true" fork="true" haltonerror="off" timeout="${batchtest.timeout}"> + <env key="${system.env.library.path}" path="${obj.all.paths}"/> + <jvmarg value="-Djava.library.path=${obj.all.paths}"/> + + <!-- + <jvmarg value="-Djogl.debug=all"/> + <jvmarg value="-Dgluegen.debug.NativeLibrary=true"/> + <jvmarg value="-Dgluegen.debug.ProcAddressHelper=true"/> + <jvmarg value="-Djogl.debug.GLSLState"/> + <jvmarg value="-Dnativewindow.debug=all"/> + <jvmarg value="-verbose:jni"/> + <jvmarg value="-client"/> + <jvmarg value="-d32"/> + --> + + <formatter usefile="false" type="plain"/> + <formatter usefile="true" type="xml"/> + <classpath refid="junit_jogl_awt.run.classpath"/> + + <batchtest todir="${results.test}"> + <fileset dir="${classes}"> + <include name="${java.dir.junit}/**/Test*NOUI*"/> + <exclude name="**/*$$*"/> + </fileset> + <formatter usefile="false" type="brief"/> + <formatter usefile="true" type="xml"/> + </batchtest> + </junit> </target> <!-- NEWT is currently not supported on OSX --> - <target name="junit.run.newt.headless" depends="junit.run.setup" unless="isOSX"> + <target name="junit.run.newt.headless" depends="test.compile" unless="isOSX"> <!-- Test*NEWT* Emulation of junit task, @@ -110,7 +181,7 @@ <for param="test.class.path.m" keepgoing="true"> <!-- results in absolute path --> <fileset dir="${classes}"> - <include name="${java.dir.test}/**/Test*NEWT*"/> + <include name="${java.dir.junit}/**/Test*NEWT*"/> <exclude name="**/*$$*"/> </fileset> <sequential> @@ -124,7 +195,7 @@ <packagemapper from="*.class" to="*"/> <!-- FQCN --> </chainedmapper> </pathconvert> - <var name="test.class.result.file" value="${results.junit}/TEST-${test.class.fqn}.xml"/> + <var name="test.class.result.file" value="${results.test}/TEST-${test.class.fqn}.xml"/> <echo message="Testing ${test.class.fqn} -- ${test.class.result.file}"/> <apply dir="." executable="${java.home}/bin/java" parallel="false" @@ -165,7 +236,7 @@ if run in parallel. NEWT is currently not supported on OSX --> - <target name="junit.run.newt" depends="junit.run.setup" unless="isOSX"> + <target name="junit.run.newt" depends="test.compile" unless="isOSX"> <!-- Test*NEWT* --> <junit forkmode="perTest" showoutput="true" fork="true" haltonerror="off" timeout="${batchtest.timeout}"> <env key="${system.env.library.path}" path="${obj.all.paths}"/> @@ -188,9 +259,9 @@ <formatter usefile="true" type="xml"/> <classpath refid="junit_jogl_newt.run.classpath"/> - <batchtest todir="${results.junit}"> + <batchtest todir="${results.test}"> <fileset dir="${classes}"> - <include name="${java.dir.test}/**/Test*NEWT*"/> + <include name="${java.dir.junit}/**/Test*NEWT*"/> <exclude name="**/*$$*"/> </fileset> <formatter usefile="false" type="brief"/> @@ -199,7 +270,7 @@ </junit> </target> - <target name="junit.run.awt" depends="junit.run.setup"> + <target name="junit.run.awt" depends="test.compile"> <!-- Test*AWT* --> <junit forkmode="perTest" showoutput="true" fork="true" haltonerror="off" timeout="${batchtest.timeout}"> <env key="${system.env.library.path}" path="${obj.all.paths}"/> @@ -222,9 +293,9 @@ <formatter usefile="true" type="xml"/> <classpath refid="junit_jogl_awt.run.classpath"/> - <batchtest todir="${results.junit}"> + <batchtest todir="${results.test}"> <fileset dir="${classes}"> - <include name="${java.dir.test}/**/Test*AWT*"/> + <include name="${java.dir.junit}/**/Test*AWT*"/> <exclude name="**/*$$*"/> <exclude name="**/*SWT*"/> <exclude name="**/newt/**"/> @@ -271,7 +342,7 @@ </target> <!-- NEWT is currently not supported on OSX --> - <target name="junit.run.newt.awt" depends="junit.run.setup" unless="isOSX"> + <target name="junit.run.newt.awt" depends="test.compile" unless="isOSX"> <!-- Test*AWT* --> <junit forkmode="perTest" showoutput="true" fork="true" haltonerror="off" timeout="${batchtest.timeout}"> <env key="${system.env.library.path}" path="${obj.all.paths}"/> @@ -294,9 +365,9 @@ <formatter usefile="true" type="xml"/> <classpath refid="junit_jogl_newt_awt.run.classpath"/> - <batchtest todir="${results.junit}"> + <batchtest todir="${results.test}"> <fileset dir="${classes}"> - <include name="${java.dir.test}/**/newt/**/Test*AWT*"/> + <include name="${java.dir.junit}/**/newt/**/Test*AWT*"/> <exclude name="**/*$$*"/> </fileset> <formatter usefile="false" type="brief"/> @@ -305,12 +376,22 @@ </junit> </target> - <target name="junit.run" depends="junit.run.newt.headless,junit.run.awt,junit.run.newt.awt"/> + <target name="test.auto.run" depends="junit.run"/> + <target name="junit.run" depends="junit.run.noui,junit.run.newt.headless,junit.run.awt,junit.run.newt.awt"> + <antcall target="test-zip-archive" inheritRefs="true" inheritAll="true"/> + </target> + + <!-- updates / create the test results zip file --> + <target name="test-zip-archive" depends="declare.common"> + <zip destfile="${build}/${test.archive.name}.zip" update="true"> + <zipfileset dir="${results.test}" prefix="${archive.name}/test-results"/> + </zip> + </target> <!-- ================================================================== --> <!-- - Build everything. --> - <target name="all" description="Build JOGL JUNIT tests and run them." depends="junit.compile, junit.run" /> + <target name="all" description="Build JOGL JUNIT tests" depends="test.compile" /> </project> diff --git a/make/build.xml b/make/build.xml index 62ebcde21..69be99472 100644 --- a/make/build.xml +++ b/make/build.xml @@ -8,16 +8,24 @@ - Main build target. --> - <target name="all" description="Build nativewindow, jogl and newt projects, incl. all junit tests " depends="init,build.nativewindow,build.jogl,build.newt,junit.compile,one.dir,tag.build,developer-zip-archive" /> + <target name="all" description="Build nativewindow, jogl and newt projects, incl. all junit tests " depends="init,build.nativewindow,build.jogl,build.newt,test.compile,one.dir,tag.build,developer-zip-archive" /> - <target name="all.but-archives" description="Build nativewindow, jogl and newt projects, incl. all junit tests " depends="init,build.nativewindow,build.jogl,build.newt,junit.compile,one.dir,tag.build" /> + <target name="all.but-archives" description="Build nativewindow, jogl and newt projects, incl. all junit tests " depends="init,build.nativewindow,build.jogl,build.newt,test.compile,one.dir,tag.build" /> - <target name="junit.compile"> - <ant antfile="build-junit.xml" target="junit.compile" inheritRefs="true" inheritAll="true"/> + <target name="test.compile"> + <ant antfile="build-test.xml" target="test.compile" inheritRefs="true" inheritAll="true"/> </target> - <target name="junit.run" description="Run JUNIT tests in nativewindow, jogl and newt projects"> - <ant antfile="build-junit.xml" target="junit.run" inheritRefs="true" inheritAll="true"/> + <target name="test.auto.run" description="Run automated tests (junit and others) in nativewindow, jogl and newt projects"> + <ant antfile="build-test.xml" target="test.auto.run" inheritRefs="true" inheritAll="true"/> + </target> + + <target name="junit.run" description="Run automated junit tests in nativewindow, jogl and newt projects"> + <ant antfile="build-test.xml" target="junit.run" inheritRefs="true" inheritAll="true"/> + </target> + + <target name="test.manual.run" description="Run manual operated tests in nativewindow, jogl and newt projects"> + <ant antfile="build-test.xml" target="test.manual.run" inheritRefs="true" inheritAll="true"/> </target> <target name="javadoc.all.zip" depends="javadoc.init, javadoc.all, javadoc.zip"/> @@ -226,7 +234,7 @@ <property name="javadoc.spec.packagenames" value="javax.media.opengl.*" /> <property name="javadoc.windowtitle" value="JOGL, NativeWindow and NEWT APIs" /> - <property name="javadoc.packagenames" value="${javadoc.nw.spec.packagenames}, ${javadoc.spec.packagenames}, com.jogamp.opengl, com.jogamp.opengl.util.*, com.jogamp.nativewindow, com.jogamp.newt, com.jogamp.newt.event.*, com.jogamp.newt.opengl" /> + <property name="javadoc.packagenames" value="${javadoc.nw.spec.packagenames}, ${javadoc.spec.packagenames}, com.jogamp.opengl, com.jogamp.opengl.util.*, com.jogamp.nativewindow, com.jogamp.newt, com.jogamp.newt.util.*, com.jogamp.newt.event.*, com.jogamp.newt.opengl" /> <property name="javadoc.dev.packagenames" value="${javadoc.packagenames}, com.jogamp.opengl.*, com.jogamp.nativewindow.*, com.jogamp.newt.*, com.jogamp.gluegen.opengl.*, com.jogamp.gluegen.runtime.opengl.*" /> diff --git a/make/config/jogl/cg-common-CustomJavaCode.java b/make/config/jogl/cg-common-CustomJavaCode.java index cdaa6f2b2..31d1961fc 100644 --- a/make/config/jogl/cg-common-CustomJavaCode.java +++ b/make/config/jogl/cg-common-CustomJavaCode.java @@ -1,12 +1,12 @@ -private static DynamicLookupHelper cgDynamicLookupHelper; -private static CgProcAddressTable cgProcAddressTable; +private static final DynamicLibraryBundle cgDynamicLookupHelper; +private static final CgProcAddressTable cgProcAddressTable; static { cgProcAddressTable = new CgProcAddressTable(); if(null==cgProcAddressTable) { throw new RuntimeException("Couldn't instantiate CgProcAddressTable"); } - DynamicLibraryBundle cgDynamicLookupHelper = new DynamicLibraryBundle(new CgDynamicLibraryBundleInfo()); + cgDynamicLookupHelper = new DynamicLibraryBundle(new CgDynamicLibraryBundleInfo()); if(null==cgDynamicLookupHelper) { throw new RuntimeException("Null CgDynamicLookupHelper"); } diff --git a/make/config/jogl/glx-CustomJavaCode.java b/make/config/jogl/glx-CustomJavaCode.java index 0c3693b8b..36ad10031 100644 --- a/make/config/jogl/glx-CustomJavaCode.java +++ b/make/config/jogl/glx-CustomJavaCode.java @@ -21,7 +21,7 @@ { final long __addr_ = glxProcAddressTable._addressof_glXChooseFBConfig; if (__addr_ == 0) { - throw new GLException("Method \"glXGetVisualFromFBConfig\" not available"); + throw new GLException("Method \"glXChooseFBConfig\" not available"); } if(attribList != null && attribList.length <= attribList_offset) throw new GLException("array offset argument \"attribList_offset\" (" + attribList_offset + ") equals or exceeds array length (" + attribList.length + ")"); diff --git a/make/config/nativewindow/win32-CustomJavaCode.java b/make/config/nativewindow/win32-CustomJavaCode.java index 54a7fa53a..5d0c82998 100644 --- a/make/config/nativewindow/win32-CustomJavaCode.java +++ b/make/config/nativewindow/win32-CustomJavaCode.java @@ -1,28 +1,58 @@ - private static final long hInstance; + private static final boolean DEBUG = Debug.debug("GDI"); - static { - NWJNILibLoader.loadNativeWindow("win32"); - hInstance = initIDs0(); - if( 0 == hInstance ) { - throw new NativeWindowException("GDI: Could not initialized native stub"); + private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ; + private static RegisteredClassFactory dummyWindowClassFactory; + private static boolean isInit = false; + + private static native boolean initIDs0(); + private static native long getDummyWndProc0(); + + public static synchronized void initSingleton(boolean firstX11ActionOnProcess) { + if(!isInit) { + NWJNILibLoader.loadNativeWindow("win32"); + + if( !initIDs0() ) { + throw new NativeWindowException("GDI: Could not initialized native stub"); + } + + if(DEBUG) { + System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess); + } + + dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0()); + isInit = true; } } - public static synchronized void initSingleton() { - } - private static native long initIDs0(); + private static RegisteredClass dummyWindowClass = null; + private static Object dummyWindowSync = new Object(); - public static long getModuleHandle() { - return hInstance; + public static long CreateDummyWindow(int x, int y, int width, int height) { + synchronized(dummyWindowSync) { + dummyWindowClass = dummyWindowClassFactory.getSharedClass(); + return CreateDummyWindow0(dummyWindowClass.getHandle(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height); + } } - public static long CreateDummyWindow(int x, int y, int width, int height) { - return CreateDummyWindow0(getModuleHandle(), x, y, width, height); + public static boolean DestroyDummyWindow(long hwnd) { + boolean res; + synchronized(dummyWindowSync) { + if( null == dummyWindowClass ) { + throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null"); + } + res = DestroyWindow(hwnd); + dummyWindowClassFactory.releaseSharedClass(); + } + return res; } public static Point GetRelativeLocation(long src_win, long dest_win, int src_x, int src_y) { - return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y); + return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y); } private static native Object GetRelativeLocation0(long src_win, long dest_win, int src_x, int src_y); + public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc); + public static native boolean DestroyWindowClass(long hInstance, String className); + static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height); + diff --git a/make/config/nativewindow/win32-lib.cfg b/make/config/nativewindow/win32-lib.cfg index 46c4f2f92..d4ca642bf 100644 --- a/make/config/nativewindow/win32-lib.cfg +++ b/make/config/nativewindow/win32-lib.cfg @@ -23,6 +23,7 @@ Opaque long void ** Import javax.media.nativewindow.util.Point Import javax.media.nativewindow.NativeWindowException Import com.jogamp.nativewindow.impl.NWJNILibLoader +import com.jogamp.nativewindow.impl.Debug CustomCCode #define WIN32_LEAN_AND_MEAN CustomCCode #include <windows.h> @@ -33,7 +34,7 @@ CustomCCode #include <stddef.h> Include ../intptr.cfg -CustomCCode extern HWND CreateDummyWindow0( HINSTANCE hInstance, int x, int y, int width, int height ) ; +CustomCCode extern HINSTANCE GetApplicationHandle(); IncludeAs CustomJavaCode GDI win32-CustomJavaCode.java diff --git a/make/scripts/java-win32-dbg.bat b/make/scripts/java-win32-dbg.bat index 92bc62d81..34e0be70a 100755 --- a/make/scripts/java-win32-dbg.bat +++ b/make/scripts/java-win32-dbg.bat @@ -1,8 +1,8 @@ set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_22_x32
-set JAVA_HOME=c:\jdk1.6.0_22_x32
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x32
+set JAVA_HOME=c:\jdk1.6.0_23_x32
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
@@ -17,7 +17,8 @@ REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary= REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnativewindow.debug.TraceLock"
-set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
+REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
+set D_ARGS="-Djogl.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"
set X_ARGS="-Dsun.java2d.noddraw=true" "-Dsun.awt.noerasebackground=true"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat index 63d69b8b2..3bfab721f 100755 --- a/make/scripts/java-win32.bat +++ b/make/scripts/java-win32.bat @@ -1,8 +1,8 @@ set BLD_SUB=build-win32
-set J2RE_HOME=c:\jre1.6.0_22_x32
-set JAVA_HOME=c:\jdk1.6.0_22_x32
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x32
+set JAVA_HOME=c:\jdk1.6.0_23_x32
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat index 1abce8f02..fc51b9caf 100755 --- a/make/scripts/java-win64-dbg.bat +++ b/make/scripts/java-win64-dbg.bat @@ -1,8 +1,8 @@ set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_22_x64
-set JAVA_HOME=c:\jdk1.6.0_22_x64
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x64
+set JAVA_HOME=c:\jdk1.6.0_23_x64
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
@@ -18,7 +18,9 @@ REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.ExtensionAvailabilityCache REM set D_ARGS="-Djogl.debug.GraphicsConfiguration"
REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.Lock" "-Djogamp.debug.Lock.TraceLock"
+REM set D_ARGS="-Djogl.debug=all" "-Dnativewindow.debug=all"
set D_ARGS="-Djogl.debug=all"
+REM set D_ARGS="-Djogl.debug.GLContext" "-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat index f1275f46c..b4cc3d120 100755 --- a/make/scripts/java-win64.bat +++ b/make/scripts/java-win64.bat @@ -1,8 +1,8 @@ set BLD_SUB=build-win64
-set J2RE_HOME=c:\jre1.6.0_22_x64
-set JAVA_HOME=c:\jdk1.6.0_22_x64
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x64
+set JAVA_HOME=c:\jdk1.6.0_23_x64
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/make.jogl.all.win32.bat b/make/scripts/make.jogl.all.win32.bat index 39db2a402..6b66ff1c8 100755 --- a/make/scripts/make.jogl.all.win32.bat +++ b/make/scripts/make.jogl.all.win32.bat @@ -1,8 +1,8 @@ set THISDIR="C:\JOGL"
-set J2RE_HOME=c:\jre1.6.0_22_x32
-set JAVA_HOME=c:\jdk1.6.0_22_x32
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x32
+set JAVA_HOME=c:\jdk1.6.0_23_x32
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/make.jogl.all.win64.bat b/make/scripts/make.jogl.all.win64.bat index 4241d4d5d..8dbcd01e7 100755 --- a/make/scripts/make.jogl.all.win64.bat +++ b/make/scripts/make.jogl.all.win64.bat @@ -1,8 +1,8 @@ set THISDIR="C:\JOGL"
-set J2RE_HOME=c:\jre1.6.0_22_x64
-set JAVA_HOME=c:\jdk1.6.0_22_x64
-set ANT_PATH=C:\apache-ant-1.8.0
+set J2RE_HOME=c:\jre1.6.0_23_x64
+set JAVA_HOME=c:\jdk1.6.0_23_x64
+set ANT_PATH=C:\apache-ant-1.8.2
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;c:\mingw\bin;%PATH%
diff --git a/make/scripts/setvc9-jogl.bat b/make/scripts/setvc9-jogl.bat index 2e8338374..6ff16053e 100755 --- a/make/scripts/setvc9-jogl.bat +++ b/make/scripts/setvc9-jogl.bat @@ -1,7 +1,7 @@ -set PATH=C:\cygwin\devtools\share\apache-ant-1.8.0\bin;%PATH%
-set ANT_PATH=C:\cygwin\devtools\share\apache-ant-1.8.0
+set PATH=C:\cygwin\devtools\share\apache-ant-1.8.2\bin;%PATH%
+set ANT_PATH=C:\cygwin\devtools\share\apache-ant-1.8.2
c:
cd C:\SUN\JOGL2\jogl\make
diff --git a/make/scripts/tests-javaws-x64.bat b/make/scripts/tests-javaws-x64.bat new file mode 100644 index 000000000..0bc8272fe --- /dev/null +++ b/make/scripts/tests-javaws-x64.bat @@ -0,0 +1,18 @@ +set JRE_PATH=C:\jre1.6.0_23_x64\bin +set LOG_PATH=%USERPROFILE%\AppData\LocalLow\Sun\Java\Deployment\log + +%JRE_PATH%\javaws -uninstall +del /F /Q %LOG_PATH%\*.* + +set JNLP=Gears.jnlp +REM set JNLP=TextCube.jnlp +REM set JNLP=JRefractNoOGL.jnlp + +set D_FLAGS="-J-Djnlp.nativewindow.debug=all" "-J-Djnlp.jogl.debug=all" "-J-Djnlp.newt.debug=all" + +REM set X_FLAGS="-J-Dsun.java2d.noddraw=true" "-J-Dsun.awt.noerasebackground=true" "-J-Dsun.java2d.opengl=false" +REM set X_FLAGS="-J-verbose:jni" +set X_FLAGS= + +%JRE_PATH%\javaws %X_FLAGS% %D_FLAGS% http://risa/deployment/test/jau01s/jogl-demos/%JNLP% > tests-javaws.log 2>&1 + diff --git a/make/scripts/tests-javaws.sh b/make/scripts/tests-javaws.sh new file mode 100644 index 000000000..a1b1b1e2e --- /dev/null +++ b/make/scripts/tests-javaws.sh @@ -0,0 +1,16 @@ +javaws -uninstall + +rm -f ~/.java/deployment/log/* + +JNLP=Gears.jnlp +# JNLP=TextCube.jnlp +# JNLP=JRefractNoOGL.jnlp + +D_FLAGS="-J-Djnlp.nativewindow.debug=all -J-Djnlp.jogl.debug=all -J-Djnlp.newt.debug=all" + +#X_FLAGS="-J-Dsun.java2d.noddraw=true -J-Dsun.awt.noerasebackground=true -J-Dsun.java2d.opengl=false" +#X_FLAGS="-J-verbose:jni" +X_FLAGS= + +javaws $X_FLAGS $D_FLAGS http://risa/deployment/test/jau01s/jogl-demos/$JNLP 2>&1 | tee tests-javaws.log + diff --git a/make/scripts/tests-x32.bat b/make/scripts/tests-x32.bat index e8734a053..50d875a98 100644 --- a/make/scripts/tests-x32.bat +++ b/make/scripts/tests-x32.bat @@ -1,31 +1,34 @@ REM scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.acore.TestGLProfile01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT -time 30000 -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT -scripts\java-win32.bat com.jogamp.test.junit.jogl.glsl.TestGLSLSimple01NEWT -time 2000 +REM scripts\java-win32-dbg.bat com.jogamp.newt.opengl.GLWindow +REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000 +scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT -time 30000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT +REM scripts\java-win32.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT -time 2000 -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestParenting01AWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01cAWT -time 50000 -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestListenerCom01AWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestParenting01AWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cAWT -time 50000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestGLWindows01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestGLWindows02NEWTAnimated -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestFocus02SwingAWTRobot -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestFocus01SwingAWTRobot -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.nativewindow.TestRecursiveToolkitLockCORE -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting03AWT -time 100000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT -time 100000 -REM scripts\java-win32.bat com.jogamp.test.junit.newt.TestFocus02SwingAWTRobot -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestScreenMode00NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestScreenMode01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestScreenMode02NEWT +REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.TestDisplayLifecycle01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting02NEWT -REM scripts\java-win32.bat com.jogamp.test.junit.newt.TestCloseNewtAWT -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.caps.TestMultisampleAWT -time 10000 -REM scripts\java-win32-dbg.bat com.jogamp.test.junit.jogl.caps.TestMultisampleNEWT -time 10000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT +REM scripts\java-win32.bat com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleAWT -time 10000 +REM scripts\java-win32-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleNEWT -time 10000 diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat index a801feffb..994d2a107 100644 --- a/make/scripts/tests-x64.bat +++ b/make/scripts/tests-x64.bat @@ -1,35 +1,47 @@ -scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow -REM scripts\java-win64.bat com.jogamp.test.junit.jogl.awt.TestAWT01GLn -REM scripts\java-win64.bat com.jogamp.test.junit.jogl.awt.TestSwingAWT01GLn -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.acore.TestGLProfile01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT -time 30000 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.demos.gl2.gears.TestGearsGLJPanelAWT -time 5000 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.glsl.TestGLSLSimple01NEWT -time 2000 +scripts\java-win64-dbg.bat com.jogamp.newt.impl.awt.opengl.VersionApplet +REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow +REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000 +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT -time 5000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT -time 5000 +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT -time 5000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestParenting01AWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01cAWT -time 50000 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestListenerCom01AWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT -time 30000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.TestGearsGLJPanelAWT -time 5000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT -time 2000 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestGLWindows01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestGLWindows02NEWTAnimated -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestFocus02SwingAWTRobot -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestFocus01SwingAWTRobot -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.nativewindow.TestRecursiveToolkitLockCORE -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting03AWT -time 100000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestParenting01AWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cAWT -time 50000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win64.bat com.jogamp.test.junit.newt.TestFocus02SwingAWTRobot -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestScreenMode00NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestScreenMode01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestScreenMode02NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT -time 100000 + +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT + +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleAWT -time 10000 +REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleNEWT -time 10000 + +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $* +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $* +REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT $* -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.TestDisplayLifecycle01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting01NEWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.newt.parenting.TestParenting02NEWT -REM scripts\java-win64.bat com.jogamp.test.junit.newt.TestCloseNewtAWT -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.caps.TestMultisampleAWT -time 10000 -REM scripts\java-win64-dbg.bat com.jogamp.test.junit.jogl.caps.TestMultisampleNEWT -time 10000 diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 3bfaf7247..8b6350542 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -32,14 +32,19 @@ function jrun() { # D_ARGS="-Dnewt.debug.Window -Dnewt.debug.EDT -Dnewt.debug.Display " #D_ARGS="-Dnewt.debug.EDT -Djogamp.common.utils.locks.Lock.timeout=600000 -Djogl.debug.Animator -Dnewt.debug.Display -Dnewt.debug.Screen" #D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas" - #D_ARGS="-Dnewt.debug.EDT -Djogl.debug.GLContext" + #D_ARGS="-Djogl.debug.GLContext -Dnewt.debug=all" #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock" #D_ARGS="-Dnewt.debug.EDT" #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all" - D_ARGS="-Djogl.debug=all" + #D_ARGS="-Djogl.debug=all -Dnewt.debug=all" + #D_ARGS="-Dnewt.debug=all" + #D_ARGS="-Dnativewindow.debug=all" #D_ARGS="-Djogl.debug.GraphicsConfiguration" + #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GraphicsConfiguration" #D_ARGS="-Djogl.debug.GLCanvas" + #D_ARGS="-Dnativewindow.debug.ToolkitLock.TraceLock" #X_ARGS="-Dsun.java2d.noddraw=true -Dsun.java2d.opengl=true" + #X_ARGS="-verbose:jni" echo echo "Test Start: $*" echo @@ -63,64 +68,75 @@ function testawt() { #testnoawt com.jogamp.nativewindow.NativeWindowVersion $* #testnoawt com.jogamp.opengl.JoglVersion $* #testnoawt com.jogamp.newt.NewtVersion $* -testnoawt com.jogamp.newt.opengl.GLWindow $* -#testnoawt com.jogamp.test.junit.jogl.acore.TestGLProfile01NEWT $* -#testawt com.jogamp.test.junit.jogl.acore.TestGLProfile01NEWT $* -#testnoawt com.jogamp.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT $* -#testnoawt com.jogamp.test.junit.jogl.glsl.TestGLSLSimple01NEWT $* -#testnoawt com.jogamp.test.junit.newt.TestRemoteWindow01NEWT -time 1000000 -#testnoawt com.jogamp.test.junit.newt.TestRemoteGLWindows01NEWT -time 1000000 -#testawt com.jogamp.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT -#testawt com.jogamp.test.junit.newt.TestDisplayLifecycle01NEWT -#testawt com.jogamp.test.junit.newt.TestDisplayLifecycle02NEWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01NEWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting02NEWT -#testawt com.jogamp.test.junit.newt.TestScreenMode00NEWT -#testnoawt com.jogamp.test.junit.newt.TestScreenMode01NEWT -#testnoawt com.jogamp.test.junit.newt.TestScreenMode02NEWT -#testawt com.jogamp.test.junit.newt.TestGLWindows01NEWT -time 1000000 -#testawt -Djava.awt.headless=true com.jogamp.test.junit.newt.TestGLWindows01NEWT -#testawt com.jogamp.test.junit.newt.TestGLWindows02NEWTAnimated +#testnoawt com.jogamp.newt.opengl.GLWindow $* +#testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* +#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $* +#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.TestRemoteWindow01NEWT $* +#testnoawt com.jogamp.opengl.test.junit.newt.TestRemoteGLWindows01NEWT $* +#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt.TestGearsNEWT $* +#testawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +#testawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT +#testawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT +#testawt com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT -time 1000000 +#testawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT +#testawt com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated # # awt (testawt) # +#testawt com.jogamp.newt.impl.awt.opengl.VersionApplet $* #testawt javax.media.opengl.awt.GLCanvas $* -#testawt com.jogamp.test.junit.jogl.awt.TestAWT01GLn $* -#testawt com.jogamp.test.junit.jogl.awt.TestSwingAWT01GLn -#testawt com.jogamp.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $* -#testawt com.jogamp.test.junit.jogl.awt.TestAWT02WindowClosing -#testawt com.jogamp.test.junit.jogl.demos.gl2.gears.TestGearsAWT -#testawt com.jogamp.test.junit.jogl.demos.gl2.gears.TestGearsGLJPanelAWT -#testawt com.jogamp.test.junit.jogl.texture.TestTexture01AWT +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $* +#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $* +#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT02WindowClosing +#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.TestGearsAWT +#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.TestGearsGLJPanelAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.texture.TestTexture01AWT +testawt com.jogamp.opengl.test.junit.jogl.awt.text.TestAWTTextRendererUseVertexArrayBug464 # # newt.awt (testawt) # -#testawt com.jogamp.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 -#testawt com.jogamp.test.junit.jogl.demos.gl2.gears.newt.TestGearsNewtAWTWrapper -#testawt com.jogamp.test.junit.newt.TestEventSourceNotAWTBug -#testawt com.jogamp.test.junit.newt.TestFocus01SwingAWTRobot -#testawt com.jogamp.test.junit.newt.TestFocus02SwingAWTRobot -#testawt com.jogamp.test.junit.newt.TestListenerCom01AWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01aAWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01bAWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01cAWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01cSwingAWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting02AWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting03AWT -#testawt com.jogamp.test.junit.newt.parenting.TestParenting03AWT -time 100000 -#testawt com.jogamp.test.junit.newt.parenting.TestParenting03bAWT -time 100000 -#testawt com.jogamp.test.junit.newt.TestCloseNewtAWT -#testawt com.jogamp.test.junit.jogl.caps.TestMultisampleAWT $* -#testawt com.jogamp.test.junit.jogl.caps.TestMultisampleNEWT $* - -#testawt com.jogamp.test.junit.newt.TestGLWindows02NEWTAnimated $* -#testawt com.jogamp.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 $* -#testawt com.jogamp.test.junit.newt.parenting.TestParenting01NEWT $* +#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 +#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt.TestGearsNewtAWTWrapper +#testawt com.jogamp.opengl.test.junit.newt.TestEventSourceNotAWTBug +#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot +#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot +#testawt com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aAWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01bAWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cAWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cSwingAWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02AWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT -time 100000 +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03bAWT -time 100000 +#testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT +#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleAWT $* +#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleNEWT $* + +#testawt com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated $* +#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 $* +#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $* + +#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $* +#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $* +#testawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT $* #testawt $* + $spath/count-edt-start.sh java-run.log diff --git a/make/stub_includes/win32/windows.h b/make/stub_includes/win32/windows.h index d9f9e692a..ddee94c06 100644 --- a/make/stub_includes/win32/windows.h +++ b/make/stub_includes/win32/windows.h @@ -12,9 +12,9 @@ typedef int BOOL; typedef unsigned char BYTE; typedef char CHAR; -typedef unsigned int DWORD; +typedef unsigned __int32 DWORD; typedef int INT; -typedef int INT32; +typedef __int32 INT32; typedef __int64 INT64; typedef float FLOAT; typedef struct _handle* HANDLE; @@ -26,14 +26,18 @@ typedef HANDLE HMODULE; typedef HANDLE HINSTANCE; typedef HANDLE HPALETTE; typedef HANDLE HWND; -typedef long LONG; +typedef __int32 LONG; typedef const char* LPCSTR; typedef void* LPVOID; +typedef unsigned __int64 ULONG_PTR; typedef struct _proc* PROC; typedef unsigned int* PUINT; typedef unsigned int UINT; typedef unsigned short USHORT; typedef unsigned short WORD; +typedef unsigned short ATOM; +typedef intptr_t DWORD_PTR; +typedef intptr_t* PDWORD_PTR; /* Necessary handle typedefs for parsing wglext.h */ diff --git a/make/stub_includes/win32/wingdi.h b/make/stub_includes/win32/wingdi.h index fd4bc16a2..b169621f5 100644 --- a/make/stub_includes/win32/wingdi.h +++ b/make/stub_includes/win32/wingdi.h @@ -133,6 +133,24 @@ typedef struct tagPIXELFORMATDESCRIPTOR { #define SW_FORCEMINIMIZE 11 #define SW_MAX 11 +/** + * GetObjectType() Command + */ +#define OBJ_PEN 1 +#define OBJ_BRUSH 2 +#define OBJ_DC 3 +#define OBJ_METADC 4 +#define OBJ_PAL 5 +#define OBJ_FONT 6 +#define OBJ_BITMAP 7 +#define OBJ_REGION 8 +#define OBJ_METAFILE 9 +#define OBJ_MEMDC 10 +#define OBJ_EXTPEN 11 +#define OBJ_ENHMETADC 12 +#define OBJ_ENHMETAFILE 13 +#define OBJ_COLORSPACE 14 + #endif /* WGL_GDI_VERSION_1_X */ #ifndef WGL_GDI_VERSION_1_X @@ -169,11 +187,17 @@ WINGDIAPI HGDIOBJ WINAPI SelectObject(HDC, HGDIOBJ); // Routines for creation of a dummy window, device context and OpenGL // context for the purposes of getting wglChoosePixelFormatARB and // associated routines - HWND CreateDummyWindow0( HINSTANCE hInstance, int x, int y, int width, int height ) ; + HINSTANCE GetApplicationHandle(); WINUSERAPI BOOL WINAPI ShowWindow(HWND hWnd, int nCmdShow); WINUSERAPI HDC WINAPI GetDC(HWND); WINUSERAPI int WINAPI ReleaseDC(HWND hWnd, HDC hDC); WINUSERAPI BOOL WINAPI DestroyWindow(HWND hWnd); +WINUSERAPI DWORD WINAPI GetObjectType(HGDIOBJ h); + +WINUSERAPI HANDLE WINAPI GetCurrentProcess(void); +WINUSERAPI BOOL WINAPI GetProcessAffinityMask(HANDLE hProcess,PDWORD_PTR lpProcessAffinityMask,PDWORD_PTR lpSystemAffinityMask); +WINUSERAPI BOOL WINAPI SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR dwProcessAffinityMask); + // Routines for changing gamma ramp of display device WINGDIAPI BOOL WINAPI GetDeviceGammaRamp(HDC,LPVOID); diff --git a/nbproject/ide-file-targets.xml b/nbproject/ide-file-targets.xml index dd98d30f1..666cf0106 100644 --- a/nbproject/ide-file-targets.xml +++ b/nbproject/ide-file-targets.xml @@ -18,14 +18,14 @@ </target> <target name="compile-test" depends="init"> <mkdir dir="build/test/build/classes"/> - <javac debug="true" debuglevel="lines,vars,source" destdir="build/test/build/classes" failonerror="false" source="1.5" srcdir="src/junit" includeantruntime="false"> + <javac debug="true" debuglevel="lines,vars,source" destdir="build/test/build/classes" failonerror="false" source="1.5" srcdir="src/test" includeantruntime="false"> <classpath refid="cp"/> </javac> </target> <target name="compile-selected-files-in-junit" depends="init"> <fail unless="files">Must set property 'files'</fail> <mkdir dir="build/test/build/classes"/> - <javac debug="true" debuglevel="lines,vars,source" destdir="build/test/build/classes" includes="${files}" source="1.5" srcdir="src/junit" includeantruntime="false"> + <javac debug="true" debuglevel="lines,vars,source" destdir="build/test/build/classes" includes="${files}" source="1.5" srcdir="src/test" includeantruntime="false"> <classpath refid="cp"/> </javac> </target> diff --git a/nbproject/project.xml b/nbproject/project.xml index ce6509193..be7660190 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -43,9 +43,9 @@ <encoding>UTF-8</encoding> </source-folder> <source-folder> - <label>src/junit</label> + <label>src/test</label> <type>java</type> - <location>src/junit</location> + <location>src/test</location> <encoding>UTF-8</encoding> </source-folder> <source-folder> @@ -94,7 +94,7 @@ <target>run-selected-file-in-junit</target> <context> <property>run.class</property> - <folder>src/junit</folder> + <folder>src/test</folder> <pattern>\.java$</pattern> <format>java-name</format> <arity> @@ -107,7 +107,7 @@ <target>debug-selected-file-in-junit</target> <context> <property>debug.class</property> - <folder>src/junit</folder> + <folder>src/test</folder> <pattern>\.java$</pattern> <format>java-name</format> <arity> @@ -120,7 +120,7 @@ <target>debug-selected-file-in-junit</target> <context> <property>debug.class</property> - <folder>src/junit</folder> + <folder>src/test</folder> <pattern>\.java$</pattern> <format>java-name</format> <arity> @@ -133,7 +133,7 @@ <target>compile-selected-files-in-junit</target> <context> <property>files</property> - <folder>src/junit</folder> + <folder>src/test</folder> <pattern>\.java$</pattern> <format>relative-path</format> <arity> @@ -177,8 +177,8 @@ <location>src/newt/classes</location> </source-folder> <source-folder style="packages"> - <label>src/junit</label> - <location>src/junit</location> + <label>src/test</label> + <location>src/test</location> </source-folder> <source-file> <location>${ant.script}</location> @@ -206,7 +206,7 @@ <source-level>1.4</source-level> </compilation-unit> <compilation-unit> - <package-root>src/junit</package-root> + <package-root>src/test</package-root> <unit-tests/> <classpath mode="compile">build/jogl/classes:build/jogl/gensrc/classes:build/newt/classes:build/nativewindow/classes:build/nativewindow/gensrc/classes:build/test/build/classes:${jdk.home}/lib/tools.jar:${ant.core.lib}:${ant.home}/lib/ant-junit.jar:../gluegen/make/lib/antlr.jar:../gluegen/make/lib/junit.jar:../gluegen/build/gluegen-rt.jar</classpath> <built-to>bin</built-to> diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java index b096f84ae..b1db2974a 100644 --- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java +++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java @@ -33,8 +33,10 @@ import javax.media.opengl.*; import com.jogamp.common.os.Platform; import com.jogamp.common.util.VersionUtil; import com.jogamp.common.util.JogampVersion; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.NativeWindowVersion; import java.util.jar.Manifest; +import javax.media.nativewindow.AbstractGraphicsDevice; public class JoglVersion extends JogampVersion { @@ -68,15 +70,17 @@ public class JoglVersion extends JogampVersion { } public static StringBuffer getGLInfo(GL gl, StringBuffer sb) { + AbstractGraphicsDevice device = gl.getContext().getGLDrawable().getNativeSurface() + .getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); if(null==sb) { sb = new StringBuffer(); } GLContext ctx = gl.getContext(); sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline()); - sb.append("Default Desktop ").append(GLProfile.getDefaultDesktopDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultDesktopDevice())); - sb.append(Platform.getNewline()); - sb.append("Default EGL ").append(GLProfile.getDefaultEGLDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultEGLDevice())); + sb.append(ReflectionUtil.getBaseName(device.getClass())).append("[type ") + .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ") + .append(GLProfile.glAvailabilityToString(device)); sb.append(Platform.getNewline()); sb.append("Swap Interval ").append(gl.getSwapInterval()); sb.append(Platform.getNewline()); diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java index c414e6684..5655d1a7a 100644 --- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java @@ -28,13 +28,8 @@ package com.jogamp.opengl.cg; -import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.os.DynamicLibraryBundleInfo; -import com.jogamp.common.os.NativeLibrary; -import com.jogamp.common.os.Platform; import java.util.*; -import java.security.*; -import javax.media.opengl.GLException; public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { private static List/*<String>*/ glueLibNames; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java index 08821910f..77b6ba981 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java @@ -28,13 +28,8 @@ package com.jogamp.opengl.impl; -import com.jogamp.common.os.DynamicLibraryBundle; -import com.jogamp.common.os.DynamicLibraryBundleInfo; -import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.os.NativeLibrary; import java.util.*; -import java.security.*; -import javax.media.opengl.GLException; public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index cd121979a..c597e5d88 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -40,16 +40,17 @@ package com.jogamp.opengl.impl; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + import com.jogamp.common.os.DynamicLookupHelper; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.gluegen.runtime.FunctionAddressResolver; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLExtensionNames; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; + import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -67,9 +68,9 @@ public abstract class GLContextImpl extends GLContext { /** * Context full qualified name: display_type + display_connection + major + minor + ctp. - * This is the key for all cached ProcAddressTables, etc, to support multi display/device setups. + * This is the key for all cached GL ProcAddressTables, etc, to support multi display/device setups. */ - protected String contextFQN; + private String contextFQN; // Cache of the functions that are available to be called at the current // moment in time @@ -171,9 +172,9 @@ public abstract class GLContextImpl extends GLContext { public GL setGL(GL gl) { if(DEBUG) { - String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():"<null>"; - String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():"<null>"; - Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2); + String sgl1 = (null!=this.gl)?ReflectionUtil.getBaseName(this.gl.getClass())+", "+this.gl.toString():"<null>"; + String sgl2 = (null!=gl)?ReflectionUtil.getBaseName(gl.getClass())+", "+gl.toString():"<null>"; + Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread().getName()+", "+sgl1+" -> "+sgl2); e.printStackTrace(); } this.gl = gl; @@ -505,7 +506,9 @@ public abstract class GLContextImpl extends GLContext { GLContext.getAvailableGLVersionsSet(device)); } - mapGLVersions(device); + if ( !GLContext.getAvailableGLVersionsSet(device) ) { + mapGLVersions(device); + } int reqMajor; if(glp.isGL4()) { @@ -532,20 +535,14 @@ public abstract class GLContextImpl extends GLContext { return _ctx; } - private final void mapGLVersions(AbstractGraphicsDevice device) { - if ( !GLContext.getAvailableGLVersionsSet(device) ) { - synchronized (GLContext.deviceVersionAvailable) { - createContextARBMapVersionsAvailable(4, false /* core */); // GL4 - createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc - createContextARBMapVersionsAvailable(3, false /* core */); // GL3 - createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc - createContextARBMapVersionsAvailable(2, true /* compat */); // GL2 - GLContext.setAvailableGLVersionsSet(device); - } - } else { - if(DEBUG) { - System.err.println(getThreadName() + ": no mapping, all versions set "+device.getConnection()); - } + private final void mapGLVersions(AbstractGraphicsDevice device) { + synchronized (GLContext.deviceVersionAvailable) { + createContextARBMapVersionsAvailable(4, false /* core */); // GL4 + createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc + createContextARBMapVersionsAvailable(3, false /* core */); // GL3 + createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc + createContextARBMapVersionsAvailable(2, true /* compat */); // GL2 + GLContext.setAvailableGLVersionsSet(device); } } @@ -561,15 +558,9 @@ public abstract class GLContextImpl extends GLContext { ctp |= CTX_PROFILE_COMPAT ; } - // FIXME GL3GL4: - // To avoid OpenGL implementation bugs and raise compatibility - // within JOGL, we map to the proper GL version. - // This may change later when GL3 and GL4 drivers become more mature! - // Bug: To ensure GL profile compatibility within the JOGL application - // Bug: we always try to map against the highest GL version, - // Bug: so the use can always cast to a higher one - // Bug: int majorMax=GLContext.getMaxMajor(); - // Bug: int minorMax=GLContext.getMaxMinor(majorMax); + // To ensure GL profile compatibility within the JOGL application + // we always try to map against the highest GL version, + // so the user can always cast to the highest available one. int majorMax, minorMax; int majorMin, minorMin; int major[] = new int[1]; @@ -810,7 +801,6 @@ public abstract class GLContextImpl extends GLContext { * * @see #setContextVersion */ - protected final void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) { if(null!=this.gl && null!=glProcAddressTable && !force) { return; // already done and not forced @@ -819,6 +809,8 @@ public abstract class GLContextImpl extends GLContext { setGL(createGL(getGLDrawable().getGLProfile())); } + updateGLXProcAddressTable(); + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); contextFQN = getContextFQN(adevice, major, minor, ctp); @@ -826,8 +818,6 @@ public abstract class GLContextImpl extends GLContext { System.err.println(getThreadName() + ": !!! Context FQN: "+contextFQN); } - updateGLXProcAddressTable(major, minor, ctp); - // // UpdateGLProcAddressTable functionality // @@ -899,7 +889,7 @@ public abstract class GLContextImpl extends GLContext { /** * Updates the platform's 'GLX' function cache */ - protected abstract void updateGLXProcAddressTable(int major, int minor, int ctp); + protected abstract void updateGLXProcAddressTable(); protected boolean hasNativeES2Methods = false; @@ -992,6 +982,14 @@ public abstract class GLContextImpl extends GLContext { return false; } + protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) { + return device.getUniqueID() + "-" + toHexString(compose8bit(major, minor, ctp, 0)); + } + + protected String getContextFQN() { + return contextFQN; + } + /** Indicates which floating-point pbuffer implementation is in use. Returns one of GLPbuffer.APPLE_FLOAT, GLPbuffer.ATI_FLOAT, or GLPbuffer.NV_FLOAT. */ @@ -1008,6 +1006,7 @@ public abstract class GLContextImpl extends GLContext { /** Only called for offscreen contexts; needed by glReadPixels */ public abstract int getOffscreenContextPixelDataType(); + //---------------------------------------------------------------------- // Helpers for buffer object optimizations diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java index 01e0b8298..6e30f4aa0 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java @@ -165,7 +165,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { // fix caps .. GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); caps2.setPBuffer(true); capsChosen = caps2; } else { @@ -207,20 +206,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } - GLCapabilitiesImmutable capsChosen; + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) ); @@ -233,25 +220,12 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { - GLCapabilitiesImmutable capsChosen; - AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq); if(null == device) { throw new GLException("No shared device for requested: "+deviceReq); } + GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq)); - if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) { - // fix caps .. - GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); - caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - caps2.setOnscreen(false); - if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) { - caps2.setPBuffer(false); - } - capsChosen = caps2; - } else { - capsChosen = capsRequested; - } device.lock(); try { return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java index 45b04fac1..4aae89bcf 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java @@ -103,6 +103,8 @@ public class GLDrawableHelper { if(0>index) { index = listeners.size(); } + // GLEventListener may be added after context is created, + // hence we earmark initialization for the next display call. listenersToBeInit.add(listener); if(!listenersIter) { // fast path @@ -142,7 +144,6 @@ public class GLDrawableHelper { for (int i=0; i < listeners.size(); i++) { GLEventListener listener = (GLEventListener) listeners.get(i) ; listener.dispose(drawable); - listenersToBeInit.add(listener); } listenersIter = false; } @@ -164,6 +165,12 @@ public class GLDrawableHelper { listenersIter = true; for (int i=0; i < listeners.size(); i++) { GLEventListener listener = (GLEventListener) listeners.get(i) ; + + // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called. + // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window), + // hence the must always be initialized unconditional. + listenersToBeInit.add(listener); + if ( ! init( listener, drawable, false ) ) { throw new GLException("GLEventListener "+listener+" already initialized: "+drawable); } @@ -314,7 +321,7 @@ public class GLDrawableHelper { Runnable initAction) { if(null==context) { if (DEBUG) { - Exception e = new GLException(Thread.currentThread().getName()+"Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); + Exception e = new GLException(Thread.currentThread().getName()+" Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext"); e.printStackTrace(); } return; @@ -323,7 +330,7 @@ public class GLDrawableHelper { if(null==initAction) { // disposal case if(!context.isCreated()) { - throw new GLException("Dispose case (no init action given): Native context must be created: "+context); + throw new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context is not created: "+context); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java index d7d2836aa..5459d886c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java @@ -146,7 +146,7 @@ public abstract class GLDrawableImpl implements GLDrawable { AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice(); if(realizedArg) { if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { - throw new GLException("X11GLXDrawable.setRealized(true): already realized, but surface not ready (lockSurface)"); + throw new GLException("GLDrawableImpl.setRealized(true): already realized, but surface not ready (lockSurface)"); } } else { aDevice.lock(); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java index e94a9c6e0..c88e96c5e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java @@ -29,12 +29,6 @@ package com.jogamp.opengl.impl; import com.jogamp.common.os.DynamicLibraryBundle; -import com.jogamp.common.os.DynamicLibraryBundleInfo; -import com.jogamp.common.os.DynamicLookupHelper; -import com.jogamp.common.os.NativeLibrary; -import java.util.*; -import java.security.*; -import javax.media.opengl.GLException; public class GLDynamicLookupHelper extends DynamicLibraryBundle { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java new file mode 100644 index 000000000..62770daf8 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java @@ -0,0 +1,97 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl; + +import java.util.List; +import javax.media.nativewindow.CapabilitiesChooser; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; +import javax.media.opengl.DefaultGLCapabilitiesChooser; + +public abstract class GLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + + protected static int chooseCapabilities(CapabilitiesChooser chooser, CapabilitiesImmutable capsRequested, + List /*<CapabilitiesImmutable>*/ availableCaps, int recommendedIndex) { + if (null == capsRequested) { + throw new NativeWindowException("Null requested capabilities"); + } + if ( 0 == availableCaps.size() ) { + if (DEBUG) { + System.err.println("Empty available capabilities"); + } + return -1; // none available + } + + if(null == chooser && 0 <= recommendedIndex) { + if (DEBUG) { + System.err.println("chooseCapabilities: Using recommendedIndex: idx " + recommendedIndex); + } + return recommendedIndex; + } + int chosenIndex = recommendedIndex; + + if (null == chooser) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + try { + chosenIndex = chooser.chooseCapabilities(capsRequested, availableCaps, recommendedIndex); + if(0 <= chosenIndex) { + if (DEBUG) { + System.err.println("chooseCapabilities: Chosen idx " + chosenIndex); + } + return chosenIndex; + } + } catch (NativeWindowException e) { + if (DEBUG) { + e.printStackTrace(); + } + } + + // keep on going .. + // seek first available one .. + for (chosenIndex = 0; chosenIndex < availableCaps.size() && availableCaps.get(chosenIndex) == null; chosenIndex++) { + // nop + } + if (chosenIndex == availableCaps.size()) { + // give up .. + if (DEBUG) { + System.err.println("chooseCapabilities: Failed .. nothing available, bail out"); + } + return -1; + } + if (DEBUG) { + System.err.println("chooseCapabilities: Fall back to 1st available idx " + chosenIndex); + } + + return chosenIndex; + } + +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java new file mode 100644 index 000000000..53d42259a --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java @@ -0,0 +1,133 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl; + +import java.util.ArrayList; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; + +public class GLGraphicsConfigurationUtil { + public static final int WINDOW_BIT = 1 << 0; + public static final int BITMAP_BIT = 1 << 1; + public static final int PBUFFER_BIT = 1 << 2; + public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ; + + public static final StringBuffer winAttributeBits2String(StringBuffer sb, int winattrbits) { + if(null==sb) { + sb = new StringBuffer(); + } + boolean seperator = false; + if( 0 != ( WINDOW_BIT & winattrbits ) ) { + sb.append("WINDOW"); + seperator=true; + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("BITMAP"); + seperator=true; + } + if( 0 != ( PBUFFER_BIT & winattrbits ) ) { + if(seperator) { + sb.append(", "); + } + sb.append("PBUFFER"); + } + return sb; + } + + /** + * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set + */ + public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) { + int winattrbits = 0; + if(isOnscreen) { + winattrbits |= WINDOW_BIT; + } else if (!isPBuffer) { + winattrbits |= BITMAP_BIT; + } else { + winattrbits |= PBUFFER_BIT; + } + return winattrbits; + } + + /** + * @see #getWinAttributeBits(boolean, boolean) + */ + public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) { + return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer()); + } + + public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) { + int preSize = capsBucket.size(); + if( 0 != ( WINDOW_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setOnscreen(true); + capsBucket.add(cpy); + } + if( 0 != ( PBUFFER_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setPBuffer(true); + capsBucket.add(cpy); + } + if( 0 != ( BITMAP_BIT & winattrbits ) ) { + GLCapabilities cpy = (GLCapabilities) temp.cloneMutable(); + cpy.setOnscreen(false); + cpy.setPBuffer(false); + capsBucket.add(cpy); + } + return capsBucket.size() > preSize; + } + + public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( !capsRequested.isOnscreen() ) { + return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable); + } + return capsRequested; + } + public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable) + { + if( capsRequested.getDoubleBuffered() || + capsRequested.isOnscreen() || + ( !pbufferAvailable && capsRequested.isPBuffer() ) ) + { + // fix caps .. + GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable(); + caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN + caps2.setOnscreen(false); + if(caps2.isPBuffer() && !pbufferAvailable) { + caps2.setPBuffer(false); + } + return caps2; + } + return capsRequested; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java deleted file mode 100644 index 1daf3358b..000000000 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.jogamp.opengl.impl; - -// FIXME: refactor Java SE dependencies -//import java.awt.Toolkit; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.HashSet; -import com.jogamp.common.jvm.JNILibLoaderBase; - -public class GLJNILibLoader extends JNILibLoaderBase { - public static void loadNEWT() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - loadLibrary("newt", nativeOSPreload, true); - return null; - } - }); - } - - private static final String[] nativeOSPreload = { "nativewindow_x11" }; -} - diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java index 558cda106..5119f5360 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java @@ -104,16 +104,18 @@ public class GLPbufferImpl implements GLPbuffer { DisposeAction disposeAction = new DisposeAction(); public void destroy() { - if (null != context) { - try { - drawableHelper.invokeGL(pbufferDrawable, context, disposeAction, null); - } catch (GLException gle) { - gle.printStackTrace(); + if(pbufferDrawable.isRealized()) { + if (null != context && context.isCreated()) { + try { + drawableHelper.invokeGL(pbufferDrawable, context, disposeAction, null); + } catch (GLException gle) { + gle.printStackTrace(); + } + context.destroy(); + // drawableHelper.reset(); } - drawableHelper.reset(); - context.destroy(); + pbufferDrawable.destroy(); } - pbufferDrawable.destroy(); } public void setSize(int width, int height) { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java new file mode 100644 index 000000000..765c6620d --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java @@ -0,0 +1,249 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.impl; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; + +public class SharedResourceRunner implements Runnable { + protected static final boolean DEBUG = GLDrawableImpl.DEBUG; + + public static interface Resource { + AbstractGraphicsDevice getDevice(); + AbstractGraphicsScreen getScreen(); + GLDrawableImpl getDrawable(); + GLContextImpl getContext(); + } + + public static interface Implementation { + Resource createSharedResource(String connection); + void releaseSharedResource(Resource shared); + void clear(); + + Resource mapPut(String connection, Resource resource); + Resource mapGet(String connection); + Collection/*<Resource>*/ mapValues(); + } + + Implementation impl = null; + + boolean ready = false; + boolean released = false; + boolean shouldRelease = false; + String initConnection = null; + String releaseConnection = null; + + HashSet devicesTried = new HashSet(); + + private boolean getDeviceTried(String connection) { + synchronized (devicesTried) { + return devicesTried.contains(connection); + } + } + private void addDeviceTried(String connection) { + synchronized (devicesTried) { + devicesTried.add(connection); + } + } + private void removeDeviceTried(String connection) { + synchronized (devicesTried) { + devicesTried.remove(connection); + } + } + + public SharedResourceRunner(Implementation impl) { + this.impl = impl; + } + + public SharedResourceRunner.Resource getShared(AbstractGraphicsDevice device) { + String connection = device.getConnection(); + return impl.mapGet(connection); + } + + public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) { + String connection = device.getConnection(); + SharedResourceRunner.Resource sr = impl.mapGet(connection); + + if (null == sr && !getDeviceTried(connection)) { + addDeviceTried(connection); + if (DEBUG) { + System.err.println("getOrCreateShared() " + connection + ": trying"); + } + doAndWait(connection, null); + sr = impl.mapGet(connection); + if (DEBUG) { + Throwable t = new Throwable("getOrCreateSharedl() " + connection + ": done"); + t.printStackTrace(); + } + } + return sr; + } + + public SharedResourceRunner.Resource releaseShared(AbstractGraphicsDevice device) { + String connection = device.getConnection(); + SharedResourceRunner.Resource sr = impl.mapGet(connection); + + if (null != sr) { + removeDeviceTried(connection); + if (DEBUG) { + System.err.println("releaseShared() " + connection + ": trying"); + } + doAndWait(null, connection); + if (DEBUG) { + Throwable t = new Throwable("releaseSharedl() " + connection + ": done"); + t.printStackTrace(); + } + } + return sr; + } + + private final void doAndWait(String initConnection, String releaseConnection) { + // wait until thread becomes ready to init new device, + // pass the device and release the sync + String threadName = Thread.currentThread().getName(); + if (DEBUG) { + System.err.println(threadName + " doAndWait START init: " + initConnection + ", release: "+releaseConnection); + } + synchronized (this) { + while (!ready) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + if (DEBUG) { + System.err.println(threadName + " initializeAndWait set command init: " + initConnection + ", release: "+releaseConnection); + } + this.initConnection = initConnection; + this.releaseConnection = releaseConnection; + this.notifyAll(); + + // wait until thread has init/released the device + while (!ready || null != this.initConnection || null != this.releaseConnection) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + if (DEBUG) { + System.err.println(threadName + " initializeAndWait END init: " + initConnection + ", release: "+releaseConnection); + } + } + // done + } + + public final void releaseAndWait() { + synchronized (this) { + shouldRelease = true; + this.notifyAll(); + + while (!released) { + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + } + } + + public final void run() { + String threadName = Thread.currentThread().getName(); + + if (DEBUG) { + System.err.println(threadName + " STARTED"); + } + + synchronized (this) { + while (!shouldRelease) { + try { + // wait for stop or init + ready = true; + if (DEBUG) { + System.err.println(threadName + " -> ready"); + } + notifyAll(); + this.wait(); + } catch (InterruptedException ex) { } + ready = false; + + if (!shouldRelease) { + if (DEBUG) { + System.err.println(threadName + " woke up for device connection init: " + initConnection + + ", release: " + releaseConnection); + } + if(null != initConnection) { + if (DEBUG) { + System.err.println(threadName + " create Shared for: " + initConnection); + } + Resource sr = impl.createSharedResource(initConnection); + if (null != sr) { + impl.mapPut(initConnection, sr); + } + } + if(null != releaseConnection) { + if (DEBUG) { + System.err.println(threadName + " release Shared for: " + releaseConnection); + } + Resource sr = impl.mapPut(releaseConnection, null); + if (null != sr) { + impl.releaseSharedResource(sr); + } + } + } + initConnection = null; + releaseConnection = null; + } + + if (DEBUG) { + System.err.println(threadName + " release START"); + } + + releaseSharedResources(); + + if (DEBUG) { + System.err.println(threadName + " release END"); + } + + released = true; + ready = false; + notifyAll(); + } + } + + private void releaseSharedResources() { + Collection/*<Resource>*/ sharedResources = impl.mapValues(); + for (Iterator iter = sharedResources.iterator(); iter.hasNext();) { + Resource sr = (Resource) iter.next(); + impl.releaseSharedResource(sr); + } + impl.clear(); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java index 36c0a3250..081d1f9b3 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -38,8 +39,6 @@ package com.jogamp.opengl.impl.awt; import com.jogamp.nativewindow.impl.jawt.*; -import com.jogamp.opengl.impl.*; - import javax.media.opengl.*; import java.lang.reflect.*; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java index 246814537..107d7fbbb 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java @@ -41,6 +41,8 @@ import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; import java.nio.*; import java.util.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; public abstract class EGLContext extends GLContextImpl { private boolean eglQueryStringInitialized; @@ -191,21 +193,24 @@ public abstract class EGLContext extends GLContextImpl { return true; } - protected final void updateGLXProcAddressTable(int major, int minor, int ctp) { + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); if (DEBUG) { - System.err.println(getThreadName() + ": !!! Initializing EGL extension address table"); + System.err.println(getThreadName() + ": !!! Initializing EGLextension address table: "+key); } eglQueryStringInitialized = false; eglQueryStringAvailable = false; EGLExtProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN ); + table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( key ); } if(null != table) { eglExtProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode()); + System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } } else { if (eglExtProcAddressTable == null) { @@ -215,9 +220,9 @@ public abstract class EGLContext extends GLContextImpl { } resetProcAddressTable(getEGLExtProcAddressTable()); synchronized(mappedContextTypeObjectLock) { - mappedGLXProcAddress.put(contextFQN, getEGLExtProcAddressTable()); + mappedGLXProcAddress.put(key, getEGLExtProcAddressTable()); if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+contextFQN+") -> "+getEGLExtProcAddressTable().hashCode()); + System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+key+") -> "+getEGLExtProcAddressTable().hashCode()); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java index f451cb9bc..c32f2f22c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java @@ -37,13 +37,16 @@ package com.jogamp.opengl.impl.egl; import javax.media.nativewindow.*; +import javax.media.nativewindow.egl.EGLGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; + import java.util.HashMap; -import javax.media.nativewindow.egl.EGLGraphicsDevice; +import java.util.List; public class EGLDrawableFactory extends GLDrawableFactoryImpl { @@ -166,6 +169,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { return null; } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) getOrCreateShared(device); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) { if (2==esProfile) { if(null==eglES2DynamicLookupHelper) { @@ -184,6 +191,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java new file mode 100644 index 000000000..db6d485e3 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.egl; + +import java.util.Comparator; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class EGLGLCapabilities extends GLCapabilities { + long eglcfg; + int eglcfgid; + + /** Comparing EGLConfig ID only */ + public static class EglCfgIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof EGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a EGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof EGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a EGLGLCapabilities object: " + c); + } + + final EGLGLCapabilities caps1 = (EGLGLCapabilities) o1; + final long id1 = caps1.getEGLConfigID(); + + final EGLGLCapabilities caps2 = (EGLGLCapabilities) o2; + final long id2 = caps2.getEGLConfigID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public EGLGLCapabilities(long eglcfg, int eglcfgid, GLProfile glp) { + super(glp); + this.eglcfg = eglcfg; + this.eglcfgid = eglcfgid; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public long getEGLConfig() { return eglcfg; } + final public int getEGLConfigID() { return eglcfgid; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(eglcfgid)).append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java index fd37c1f6d..eca324046 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java @@ -36,30 +36,29 @@ package com.jogamp.opengl.impl.egl; -import com.jogamp.common.nio.PointerBuffer; +import java.util.ArrayList; import javax.media.nativewindow.*; import javax.media.nativewindow.egl.*; import javax.media.opengl.*; +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.opengl.impl.*; public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); - public long getNativeConfig() { - return config; + public final long getNativeConfig() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig(); } - public int getNativeConfigID() { - return configID; + public final int getNativeConfigID() { + return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID(); } EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - long cfg, int cfgID) { + EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { super(absScreen, capsChosen, capsRequested); this.chooser = chooser; - config = cfg; - configID = cfgID; } public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) { @@ -73,8 +72,8 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } GLProfile glp = capsRequested.getGLProfile(); long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID); - GLCapabilitiesImmutable caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); - return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), cfg, cfgID); + EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer()); + return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser()); } public Object clone() { @@ -88,8 +87,6 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple if(null!=newConfig) { // FIXME: setScreen( ... ); setChosenCapabilities(newConfig.getChosenCapabilities()); - config = newConfig.getNativeConfig(); - configID = newConfig.getNativeConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -115,27 +112,61 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple return configs.get(0); } - static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int EGLConfigDrawableTypeBits(final long display, final long config) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ; - } + int[] stype = new int[1]; + if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) { + throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); + } + + if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; } - return res; + return val; } - public static GLCapabilitiesImmutable EGLConfig2Capabilities(GLProfile glp, long display, long config, + public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config, boolean relaxed, boolean onscreen, boolean usePBuffer) { - GLCapabilities caps = new GLCapabilities(glp); + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask) ) { + return (EGLGLCapabilities) bucket.get(0); + } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS) ) { + return (EGLGLCapabilities) bucket.get(0); + } + return null; + } + + public static boolean EGLConfig2Capabilities(ArrayList capsBucket, + GLProfile glp, long display, long config, + int winattrmask) { + final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] val = new int[1]; + // get the configID + if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val, 0)) { + if(DEBUG) { + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError())); + } + return false; + } + GLCapabilities caps = new EGLGLCapabilities(config, val[0], glp); + // Read the actual configuration into the choosen caps if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) { caps.setRedBits(val[0]); @@ -177,26 +208,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]); } */ } - if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, val, 0)) { - if(EGLConfigDrawableTypeVerify(val[0], onscreen, usePBuffer)) { - caps.setDoubleBuffered(onscreen); - caps.setOnscreen(onscreen); - caps.setPBuffer(usePBuffer); - } else if(relaxed) { - caps.setDoubleBuffered( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) ); - caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) ); - } else { - if(DEBUG) { - System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")"); - } - return null; - } - } else { - throw new GLException("Could not determine EGL_SURFACE_TYPE !!!"); - } - - return caps; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits ); } public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { @@ -288,7 +300,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } public String toString() { - return getClass().toString()+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+ + return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID "+toHexString(getNativeConfigID())+ ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; @@ -296,7 +308,5 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple } private GLCapabilitiesChooser chooser; - private long config; - private int configID; } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java index fc2416cb9..3e3d4f964 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java @@ -33,7 +33,6 @@ package com.jogamp.opengl.impl.egl; -import java.io.PrintStream; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; @@ -41,17 +40,22 @@ import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.egl.EGLGraphicsDevice; -import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; +import javax.media.opengl.GLDrawableFactory; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.io.PrintStream; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits @@ -59,8 +63,9 @@ import com.jogamp.common.nio.PointerBuffer; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL"); + static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator(); EGLGraphicsConfigurationFactory() { // become the selector for KD/EGL .. @@ -93,6 +98,41 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor absScreen); } + protected static List/*<EGLGLCapabilities>*/ getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) { + EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + EGLGraphicsDevice eglDevice = sharedResource.getDevice(); + long eglDisplay = eglDevice.getHandle(); + + List/*<EGLGLCapabilities>*/ availableCaps = null; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); + int[] numConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if (numConfigs[0] > 0) { + GLProfile glp = GLProfile.getDefault(device); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], GLGraphicsConfigurationUtil.ALL_BITS); + if( null != availableCaps ) { + Collections.sort(availableCaps, EglCfgIDComparator); + } + } + + return availableCaps; + } + private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -100,7 +140,6 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor if (capsChosen == null) { capsChosen = new GLCapabilities(null); } - GLProfile glp = capsChosen.getGLProfile(); if(null==absScreen) { throw new GLException("Null AbstractGraphicsScreen"); @@ -116,12 +155,10 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor throw new GLException("Invalid EGL display: "+absDevice); } - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } + EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory(); + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) ); + + GLProfile glp = capsChosen.getGLProfile(); EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen); if(null!=res) { @@ -131,43 +168,6 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor System.err.println("eglChooseConfig failed with given capabilities "+capsChosen); } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - PointerBuffer configs = PointerBuffer.allocateDirect(10); - int[] numConfigs = new int[1]; - - if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) failed"); - } - if (numConfigs[0] == 0) { - throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found"); - } - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen.isOnscreen(), capsChosen.isPBuffer()); - if(DEBUG) { - System.err.println("EGL Get Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglGetConfigs", caps, System.err); - } - int chosen = -1; - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, -1); - } catch (NativeWindowException e) { throw new GLException(e); } - if(chosen<0) { - throw new GLException("Graphics configuration chooser failed"); - } - if(DEBUG) { - System.err.println("Chosen "+caps[chosen]); - } - res = eglChooseConfig(eglDisplay, caps[chosen], capsReq, chooser, absScreen); - if(null!=res) { - return res; - } - if(DEBUG) { - System.err.println("eglChooseConfig failed with eglGetConfig/choosen capabilities "+caps[chosen]); - } - // Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..] // // rgb888 - d16, s4 @@ -221,73 +221,100 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor } static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay, - GLCapabilitiesImmutable capsChosen0, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - GLProfile glp = capsChosen0.getGLProfile(); - int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0); - PointerBuffer configs = PointerBuffer.allocateDirect(1); + GLProfile glp = capsChosen.getGLProfile(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + List/*<EGLGLCapabilities>*/ availableCaps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + int recommendedIndex = -1; + long recommendedEGLConfig = -1; + int[] maxConfigs = new int[1]; + + if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); + } + if(0 == maxConfigs[0]) { + throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs"); + } + if (DEBUG) { + System.err.println("!!! eglChooseConfig maxConfigs: "+maxConfigs[0]); + } + + int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen); + PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]); int[] numConfigs = new int[1]; + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice if (!EGL.eglChooseConfig(eglDisplay, attrs, 0, configs, configs.capacity(), numConfigs, 0)) { - throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0); + throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen+", error "+toHexString(EGL.eglGetError())); } if (numConfigs[0] > 0) { - if(DEBUG) { - GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], - capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - System.err.println("EGL Choose Configs: "+numConfigs[0]+", Caps "+caps.length); - printCaps("eglChooseConfig", caps, System.err); - } - int[] val = new int[1]; - // get the configID - if(!EGL.eglGetConfigAttrib(eglDisplay, configs.get(0), EGL.EGL_CONFIG_ID, val, 0)) { - if(DEBUG) { - // FIXME: this happens on a ATI PC Emulation .. - System.err.println("EGL couldn't retrieve ConfigID for already chosen eglConfig "+capsChosen0+", error 0x"+Integer.toHexString(EGL.eglGetError())); + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); + if(availableCaps.size() > 0) { + recommendedEGLConfig = configs.get(0); + recommendedIndex = 0; + if (DEBUG) { + System.err.println("!!! eglChooseConfig recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } - return null; + } else if (DEBUG) { + System.err.println("!!! eglChooseConfig no caps for recommended fbcfg " + toHexString(configs.get(0))); + System.err.println("!!! user caps " + capsChosen); } - GLCapabilitiesImmutable capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities( - glp, eglDisplay, configs.get(0), - true, capsChosen0.isOnscreen(), capsChosen0.isPBuffer()); - if(null!=capsChosen1) { - if(DEBUG) { - System.err.println("eglChooseConfig found: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", "+capsChosen0+" -> "+capsChosen1); - } - return new EGLGraphicsConfiguration(absScreen, capsChosen1, capsRequested, chooser, configs.get(0), val[0]); + } + + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if( null == availableCaps || 0 == availableCaps.size() ) { + // reset .. + recommendedEGLConfig = -1; + recommendedIndex = -1; + + if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) { + throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError())); } - if(DEBUG) { - System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", eglConfig ID 0x"+Integer.toHexString(val[0])+ - ", for "+capsChosen0); + if (numConfigs[0] > 0) { + availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask); } - } else { + } + + if( null == availableCaps || 0 == availableCaps.size() ) { if(DEBUG) { - System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+ - ", "+capsChosen0); + // FIXME: this happens on a ATI PC Emulation .. + System.err.println("Graphics configuration 1st choice and 2nd choice failed - no configs"); } + return null; } - return null; + + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex); + + return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser); } - static GLCapabilitiesImmutable[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, - boolean onscreen, boolean usePBuffer) { - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[num]; + static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask) { + ArrayList caps = new ArrayList(num); for(int i=0; i<num; i++) { - caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(i), - true, onscreen, usePBuffer); + EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask); } return caps; } - static void printCaps(String prefix, GLCapabilitiesImmutable[] caps, PrintStream out) { - for(int i=0; i<caps.length; i++) { - out.println(prefix+"["+i+"] "+caps[i]); + static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) { + for(int i=0; i<caps.size(); i++) { + out.println(prefix+"["+i+"] "+caps.get(i)); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java index 6a916765a..3450c456e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -223,18 +223,21 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } - protected final void updateGLXProcAddressTable(int major, int minor, int ctp) { + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); if (DEBUG) { - System.err.println(getThreadName() + ": !!! Initializing CGL extension address table"); + System.err.println(getThreadName() + ": !!! Initializing CGL extension address table: "+key); } CGLExtProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN ); + table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( key ); } if(null != table) { cglExtProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode()); + System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } } else { if (cglExtProcAddressTable == null) { @@ -244,9 +247,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl } resetProcAddressTable(getCGLExtProcAddressTable()); synchronized(mappedContextTypeObjectLock) { - mappedGLXProcAddress.put(contextFQN, getCGLExtProcAddressTable()); + mappedGLXProcAddress.put(key, getCGLExtProcAddressTable()); if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+contextFQN+") -> "+getCGLExtProcAddressTable().hashCode()); + System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+key+") -> "+getCGLExtProcAddressTable().hashCode()); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index 1895c8e67..421bae715 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -41,14 +41,17 @@ package com.jogamp.opengl.impl.macosx.cgl; import java.nio.*; +import java.util.HashMap; +import java.util.List; + import javax.media.nativewindow.*; +import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; import javax.media.opengl.*; + import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.ProxySurface; -import java.util.HashMap; -import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; @@ -123,6 +126,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { protected final void shutdownInstance() {} + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + throw new UnsupportedOperationException("not yet implemented"); + } + protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index 5d7a0375b..cc06a6775 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -33,6 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; @@ -47,7 +48,7 @@ import javax.media.opengl.GLCapabilitiesImmutable; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); MacOSXCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java index 702d66fce..95b6f473f 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java @@ -33,6 +33,7 @@ package com.jogamp.opengl.impl.macosx.cgl.awt; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -54,7 +55,7 @@ import javax.media.opengl.GLException; import com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration; -public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public MacOSXAWTCGLGraphicsConfigurationFactory() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java new file mode 100644 index 000000000..b5be4bf8d --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java @@ -0,0 +1,243 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.windows.wgl; + +import java.util.Comparator; + +import com.jogamp.nativewindow.impl.windows.GDI; +import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; +import javax.media.opengl.GL; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +public class WGLGLCapabilities extends GLCapabilities { + PIXELFORMATDESCRIPTOR pfd; + int pfdID; + int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB + + /** Comparing pfd id only */ + public static class PfdIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof WGLGLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a WGLGLCapabilities object: " + c); + } + if ( ! ( o2 instanceof WGLGLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a WGLGLCapabilities object: " + c); + } + + final WGLGLCapabilities caps1 = (WGLGLCapabilities) o1; + final long id1 = caps1.getPFDID(); + + final WGLGLCapabilities caps2 = (WGLGLCapabilities) o2; + final long id2 = caps2.getPFDID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) { + super(glp); + this.pfd = pfd; + this.pfdID = pfdID; + this.arb_pixelformat = 0; + } + + public boolean setValuesByGDI() { + arb_pixelformat = -1; + + setRedBits(pfd.getCRedBits()); + setGreenBits(pfd.getCGreenBits()); + setBlueBits(pfd.getCBlueBits()); + setAlphaBits(pfd.getCAlphaBits()); + setAccumRedBits(pfd.getCAccumRedBits()); + setAccumGreenBits(pfd.getCAccumGreenBits()); + setAccumBlueBits(pfd.getCAccumBlueBits()); + setAccumAlphaBits(pfd.getCAccumAlphaBits()); + setDepthBits(pfd.getCDepthBits()); + setStencilBits(pfd.getCStencilBits()); + setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); + setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); + setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 + || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0); + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer + + return true; + } + + public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) { + arb_pixelformat = 1; + + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case WGLExt.WGL_DRAW_TO_WINDOW_ARB: + case WGLExt.WGL_DRAW_TO_BITMAP_ARB: + case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: + break; + + case WGLExt.WGL_ACCELERATION_ARB: + setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); + break; + + case WGLExt.WGL_SUPPORT_OPENGL_ARB: + if (iresults[i] != GL.GL_TRUE) { + return false; + } + break; + + case WGLExt.WGL_DEPTH_BITS_ARB: + setDepthBits(iresults[i]); + break; + + case WGLExt.WGL_STENCIL_BITS_ARB: + setStencilBits(iresults[i]); + break; + + case WGLExt.WGL_DOUBLE_BUFFER_ARB: + setDoubleBuffered(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_STEREO_ARB: + setStereo(iresults[i] == GL.GL_TRUE); + break; + + case WGLExt.WGL_PIXEL_TYPE_ARB: + // Fail softly with unknown results here + if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB || + iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_FLOAT_COMPONENTS_NV: + if (iresults[i] != 0) { + setPbufferFloatingPointBuffers(true); + } + break; + + case WGLExt.WGL_RED_BITS_ARB: + setRedBits(iresults[i]); + break; + + case WGLExt.WGL_GREEN_BITS_ARB: + setGreenBits(iresults[i]); + break; + + case WGLExt.WGL_BLUE_BITS_ARB: + setBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ALPHA_BITS_ARB: + setAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_RED_BITS_ARB: + setAccumRedBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: + setAccumGreenBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: + setAccumBlueBits(iresults[i]); + break; + + case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: + setAccumAlphaBits(iresults[i]); + break; + + case WGLExt.WGL_SAMPLE_BUFFERS_ARB: + setSampleBuffers(iresults[i] != 0); + break; + + case WGLExt.WGL_SAMPLES_ARB: + setNumSamples(iresults[i]); + break; + + default: + throw new GLException("Unknown pixel format attribute " + iattribs[i]); + } + } + return true; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; } + final public int getPFDID() { return pfdID; } + + final public boolean isSetByARB() { return 0 < arb_pixelformat; } + final public boolean isSetByGDI() { return 0 > arb_pixelformat; } + final public boolean isSet() { return 0 != arb_pixelformat; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append(pfdID).append(" "); + switch (arb_pixelformat) { + case -1: + sink.append("gdi"); + break; + case 0: + sink.append("nop"); + break; + case 1: + sink.append("arb"); + break; + default: + throw new InternalError("invalid arb_pixelformat: " + arb_pixelformat); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java index 0d360b339..c61a8d0e4 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java @@ -40,6 +40,7 @@ package com.jogamp.opengl.impl.windows.wgl; +import com.jogamp.common.nio.PointerBuffer; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.SurfaceChangeable; import javax.media.opengl.GLContext; @@ -73,11 +74,19 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { } private void create() { + int werr; NativeSurface ns = getNativeSurface(); + if(DEBUG) { + System.err.println("WindowsBitmapWGLDrawable (1): "+ns); + } WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities(); int width = getWidth(); int height = getHeight(); + + // + // 1. Create DIB Section + // BITMAPINFO info = BITMAPINFO.create(); BITMAPINFOHEADER header = info.getBmiHeader(); int bitsPerPixel = (capabilities.getRedBits() + @@ -97,22 +106,42 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { header.setBiClrUsed(0); header.setBiClrImportant(0); header.setBiCompression(GDI.BI_RGB); - header.setBiSizeImage(width * height * bitsPerPixel / 8); + int byteNum = width * height * ( bitsPerPixel >> 3 ) ; + header.setBiSizeImage(byteNum); + + PointerBuffer pb = PointerBuffer.allocateDirect(1); + hbitmap = GDI.CreateDIBSection(0, info, GDI.DIB_RGB_COLORS, pb, 0, 0); + werr = GDI.GetLastError(); + if(DEBUG) { + long p = ( pb.capacity() > 0 ) ? pb.get(0) : 0; + System.err.println("WindowsBitmapWGLDrawable: pb sz/ptr "+pb.capacity() + ", "+toHexString(p)); + System.err.println("WindowsBitmapWGLDrawable: " + width+"x"+height + + ", bpp " + bitsPerPixel + + ", bytes " + byteNum + + ", header sz " + header.size() + + ", DIB ptr num " + pb.capacity()+ + ", "+capabilities+ + ", werr "+werr); + } + if (hbitmap == 0) { + throw new GLException("Error creating offscreen bitmap of " + ns + ", werr " + werr); + } + // + // 2. Create memory DC (device context) , and associate it with the DIB. + // long hdc = GDI.CreateCompatibleDC(0); + werr = GDI.GetLastError(); if (hdc == 0) { - System.out.println("LastError: " + GDI.GetLastError()); - throw new GLException("Error creating device context for offscreen OpenGL context"); + GDI.DeleteObject(hbitmap); + hbitmap = 0; + throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr); } ((SurfaceChangeable)ns).setSurfaceHandle(hdc); - - hbitmap = GDI.CreateDIBSection(hdc, info, GDI.DIB_RGB_COLORS, null, 0, 0); - if (hbitmap == 0) { - GDI.DeleteDC(hdc); - hdc = 0; - throw new GLException("Error creating offscreen bitmap of width " + width + - ", height " + height); + if(DEBUG) { + System.err.println("WindowsBitmapWGLDrawable (2): "+ns); } + if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) { GDI.DeleteObject(hbitmap); hbitmap = 0; @@ -120,7 +149,8 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable { hdc = 0; throw new GLException("Error selecting bitmap into new device context"); } - config.updateGraphicsConfiguration(getFactory(), ns); + + config.updateGraphicsConfiguration(getFactory(), ns, null); } protected void destroyImpl() { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index 015ef61a4..a307e295d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -47,31 +47,40 @@ import javax.media.opengl.GLProfile; import javax.media.nativewindow.AbstractGraphicsScreen; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.windows.GDI; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeSurface; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { - private static final int f_dim = 128; + private static final int f_dim = 64; private long hwnd, hdc; protected WindowsDummyWGLDrawable(GLDrawableFactory factory, GLCapabilitiesImmutable caps, AbstractGraphicsScreen absScreen) { super(factory, new ProxySurface(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen)), true); hwnd = GDI.CreateDummyWindow(0, 0, f_dim, f_dim); - hdc = GDI.GetDC(hwnd); + if(0 == hwnd) { + throw new GLException("Error hwnd 0, werr: "+GDI.GetLastError()); + } + // manual debug only - GDI.ShowWindow(hwnd, GDI.SW_SHOW); ProxySurface ns = (ProxySurface) getNativeSurface(); - ns.setSurfaceHandle(hdc); ns.setSize(f_dim, f_dim); - WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - + + if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) { + throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)"); + } try { - config.updateGraphicsConfiguration(factory, ns); + WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + config.updateGraphicsConfiguration(factory, ns, null); if (DEBUG) { System.err.println("!!! WindowsDummyWGLDrawable: "+config); } } catch (Throwable t) { destroyImpl(); throw new GLException(t); + } finally { + unlockSurface(); } } @@ -80,10 +89,56 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { caps.setDepthBits(16); caps.setDoubleBuffered(true); caps.setOnscreen (true); - caps.setPBuffer (true); return new WindowsDummyWGLDrawable(factory, caps, absScreen); } + public int lockSurface() throws GLException { + int res = NativeSurface.LOCK_SURFACE_NOT_READY; + ProxySurface ns = (ProxySurface) getNativeSurface(); + AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); + adevice.lock(); + try { + res = ns.lockSurface(); + if(NativeSurface.LOCK_SUCCESS == res) { + if(0 == hdc) { + hdc = GDI.GetDC(hwnd); + ns.setSurfaceHandle(hdc); + if(0 == hdc) { + res = NativeSurface.LOCK_SURFACE_NOT_READY; + ns.unlockSurface(); + throw new GLException("Error hdc 0, werr: "+GDI.GetLastError()); + // finally will unlock adevice + } + } + } else { + Throwable t = new Throwable("Error lock failed - res "+res+", hwnd "+toHexString(hwnd)+", hdc "+toHexString(hdc)); + t.printStackTrace(); + } + } finally { + if( NativeSurface.LOCK_SURFACE_NOT_READY == res ) { + adevice.unlock(); + } + } + return res; + } + + public void unlockSurface() { + ProxySurface ns = (ProxySurface) getNativeSurface(); + ns.validateSurfaceLocked(); + AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); + + try { + if ( 0 != hdc && 0 != hwnd && ns.getSurfaceRecursionCount() == 0) { + GDI.ReleaseDC(hwnd, hdc); + hdc=0; + ns.setSurfaceHandle(hdc); + } + surface.unlockSurface(); + } finally { + adevice.unlock(); + } + } + public void setSize(int width, int height) { } @@ -96,10 +151,6 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { } public GLContext createContext(GLContext shareWith) { - if (hdc == 0) { - // Construction failed - return null; - } // FIXME: figure out how to hook back in the Java 2D / JOGL bridge return new WindowsWGLContext(this, shareWith); } @@ -108,10 +159,12 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { if (hdc != 0) { GDI.ReleaseDC(hwnd, hdc); hdc = 0; + ProxySurface ns = (ProxySurface) getNativeSurface(); + ns.setSurfaceHandle(hdc); } if (hwnd != 0) { GDI.ShowWindow(hwnd, GDI.SW_HIDE); - GDI.DestroyWindow(hwnd); + GDI.DestroyDummyWindow(hwnd); hwnd = 0; } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index fd70842ac..d8d410d39 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -66,9 +66,6 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - WindowsWGLGraphicsConfiguration config = - (WindowsWGLGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateGraphicsConfiguration(drawable.getFactory(), drawable.getNativeSurface()); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } @@ -87,12 +84,8 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true); - - ProxySurface ns = new ProxySurface(cfg); - ns.setSurfaceHandle(hdc); - - return new WindowsExternalWGLContext(new Drawable(factory, ns), ctx, cfg); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true); + return new WindowsExternalWGLContext(new Drawable(factory, new ProxySurface(cfg, hdc)), ctx, cfg); } public int makeCurrent() throws GLException { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java index 66a5c80a4..f3329b73b 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java @@ -69,14 +69,8 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { } AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true); - - ProxySurface ns = new ProxySurface(cfg); - ns.setSurfaceHandle(hdc); - - cfg.updateGraphicsConfiguration(factory, ns); - - return new WindowsExternalWGLDrawable(factory, ns); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true); + return new WindowsExternalWGLDrawable(factory, new ProxySurface(cfg, hdc)); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 47b33dd6b..720ac84ca 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -50,7 +50,6 @@ import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; -import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import javax.media.opengl.GLCapabilitiesImmutable; public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { @@ -144,7 +143,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, sharedCtx, -1, true, floatModeTmp)){ + iattributes, sharedCtx, -1, floatModeTmp)){ throw new GLException("Pbuffer-related extensions not supported"); } @@ -174,96 +173,57 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); } - boolean haveMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - if (DEBUG) { System.err.println("" + nformats + " suitable pixel formats found"); - // query pixel format - iattributes[0] = WGLExt.WGL_RED_BITS_ARB; - iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[9]; for (int i = 0; i < nformats; i++) { - if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) { - throw new GLException("Error while querying pixel format " + pformats[i] + - "'s (index " + i + "'s) capabilities for debugging"); - } - System.err.print("pixel format " + pformats[i] + " (index " + i + "): "); - System.err.print( "r: " + ivalues[0]); - System.err.print(" g: " + ivalues[1]); - System.err.print(" b: " + ivalues[2]); - System.err.print(" a: " + ivalues[3]); - System.err.print(" depth: " + ivalues[4]); - if (haveMultisample) { - System.err.print(" multisample: " + ivalues[6]); - } - System.err.print(" samples: " + ivalues[7]); - if (useFloat) { - if (ati) { - if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - System.err.print(" [ati float]"); - } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) { - System.err.print(" [unknown pixel type " + ivalues[5] + "]"); - } - } else { - if (ivalues[5] != 0) { - System.err.print(" [float]"); - } - } - } - - if (ivalues[8] != 0) { - System.err.print(" [pbuffer]"); - } - System.err.println(); + WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pformats[i], glProfile, false, true); + System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps); } } + int pfdid = 0; long tmpBuffer = 0; - int whichFormat = -1; - // Loop is a workaround for bugs in NVidia's recent drivers - for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; - - // Create the p-buffer. - niattribs = 0; - - if (rtt) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; - if (useFloat) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; - } else { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; - } + { + int whichFormat; + // Loop is a workaround for bugs in NVidia's recent drivers + for (whichFormat = 0; whichFormat < nformats; whichFormat++) { + int format = pformats[whichFormat]; + + // Create the p-buffer. + niattribs = 0; + + if (rtt) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB; + if (useFloat) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; + } else { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB; + } - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; - iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB; + iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB; - iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; - iattributes[niattribs++] = GL.GL_FALSE; + iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB; + iattributes[niattribs++] = GL.GL_FALSE; - iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; - iattributes[niattribs++] = GL.GL_FALSE; - } + iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; + iattributes[niattribs++] = GL.GL_FALSE; + } - iattributes[niattribs++] = 0; + iattributes[niattribs++] = 0; - tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); - if (tmpBuffer != 0) { - // Done - break; - } - } + tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0); + if (tmpBuffer != 0) { + // Done + break; + } + } - if (tmpBuffer == 0) { - throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + - " pixel formats, last error was: " + wglGetLastError()); + if (0 == tmpBuffer) { + throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + + " pixel formats, last error was: " + wglGetLastError()); + } + pfdid = pformats[whichFormat]; } // Get the device context. @@ -280,48 +240,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { // Re-query chosen pixel format { - niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB); - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; - int[] ivalues = new int[niattribs]; - if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false, true); - if(null == newCaps|| newCaps.isOnscreen() || !newCaps.isPBuffer()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); - } - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - if (DEBUG) { - System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps); - } - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true); - } else { - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); - } - GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true); - if(newCaps.isOnscreen()) { - throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps); - } - config.setCapsPFD(newCaps, pfd, pformats[whichFormat], false); + WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pfdid, glProfile, false, true); + if(null == newCaps) { + throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + this.toHexString(tmpHdc)); + } + if(newCaps.isOnscreen() || !newCaps.isPBuffer()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); } + config.setCapsPFD(newCaps); } // Determine the actual width and height we were able to create. diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java index e85308371..7d38f8ee8 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GLContext; import javax.media.opengl.GLException; +import javax.media.opengl.GLCapabilitiesImmutable; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -55,16 +56,14 @@ import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLContextShareSet; import com.jogamp.opengl.impl.GLDrawableImpl; -import javax.media.opengl.GLCapabilitiesImmutable; - public class WindowsWGLContext extends GLContextImpl { static final Map/*<String, String>*/ functionNameMap; static final Map/*<String, String>*/ extensionNameMap; private boolean wglGetExtensionsStringEXTInitialized; private boolean wglGetExtensionsStringEXTAvailable; - private boolean wglMakeContextCurrentInitialized; - private boolean wglMakeContextCurrentAvailable; + private boolean wglGLReadDrawableAvailableSet; + private boolean wglGLReadDrawableAvailable; private WGLExt wglExt; // Table that holds the addresses of the native C-language entry points for // WGL extension functions. @@ -89,8 +88,8 @@ public class WindowsWGLContext extends GLContextImpl { protected void resetState() { wglGetExtensionsStringEXTInitialized=false; wglGetExtensionsStringEXTAvailable=false; - wglMakeContextCurrentInitialized=false; - wglMakeContextCurrentAvailable=false; + wglGLReadDrawableAvailableSet=false; + wglGLReadDrawableAvailable=false; // no inner state _wglExt=null; wglExtProcAddressTable=null; } @@ -100,6 +99,9 @@ public class WindowsWGLContext extends GLContextImpl { } /* package private */ final WGLExt getWGLExt() { + if( null == getWGLExtProcAddressTable()) { + throw new InternalError("Null WGLExtProcAddressTable"); + } if (wglExt == null) { wglExt = new WGLExtImpl(this); } @@ -107,27 +109,27 @@ public class WindowsWGLContext extends GLContextImpl { } public final boolean isGLReadDrawableAvailable() { - if(!wglMakeContextCurrentInitialized && null != getWGLExtProcAddressTable()) { + if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) { WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); AbstractGraphicsDevice device = config.getScreen().getDevice(); switch( factory.isReadDrawableAvailable(device) ) { case 1: - wglMakeContextCurrentAvailable = true; - wglMakeContextCurrentInitialized=true; + wglGLReadDrawableAvailable = true; + wglGLReadDrawableAvailableSet=true; break; case 0: - wglMakeContextCurrentAvailable = false; - wglMakeContextCurrentInitialized=true; + wglGLReadDrawableAvailable = false; + wglGLReadDrawableAvailableSet=true; break; } } - return wglMakeContextCurrentAvailable; + return wglGLReadDrawableAvailable; } private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) { boolean ok = false; - if(wglMakeContextCurrentAvailable) { + if(wglGLReadDrawableAvailable) { // needs initilized WGL ProcAddress table ok = getWGLExt().wglMakeContextCurrent(hDrawDC, hReadDC, ctx); } else if ( hDrawDC == hReadDC ) { @@ -136,10 +138,17 @@ public class WindowsWGLContext extends GLContextImpl { // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl throw new InternalError("Given readDrawable but no driver support"); } + int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS; + if(DEBUG && !ok) { + Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+ + this.toHexString(hDrawDC) + ", read " + this.toHexString(hReadDC) + + ", ctx " + this.toHexString(ctx) + ", werr " + werr); + t.printStackTrace(); + } if(!ok && 0==hDrawDC && 0==hReadDC) { // Some GPU's falsely fails with a zero error code (success), // in case this is a release context request we tolerate this - return GDI.GetLastError() == GDI.ERROR_SUCCESS ; + return werr == GDI.ERROR_SUCCESS ; } return ok; } @@ -162,15 +171,15 @@ public class WindowsWGLContext extends GLContextImpl { } protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { - WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl(); - AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); - WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); - WGLExt _wglExt; - if(null==sharedContext) { - _wglExt = getWGLExt(); - } else { - _wglExt = sharedContext.getWGLExt(); + if( null == getWGLExtProcAddressTable()) { + updateGLXProcAddressTable(); + } + WGLExt _wglExt = getWGLExt(); + if(DEBUG) { + System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") + + ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+ + ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB)); + Thread.dumpStack(); } boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; @@ -221,8 +230,7 @@ public class WindowsWGLContext extends GLContextImpl { } if(0!=ctx) { - // cannot use wglMakeContextCurrent since WGLExt ProcAddressTable is not ready yet. - if( !WGL.wglMakeCurrent(drawable.getHandle(), ctx) ) { + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) { if(DEBUG) { System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); } @@ -231,7 +239,7 @@ public class WindowsWGLContext extends GLContextImpl { ctx = 0; } else { if (DEBUG) { - System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext)); + System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct); } // the following is issued by the caller 'GLContextImpl.createContextARB()' // setGLFunctionAvailability(true, major, minor, ctp); @@ -253,7 +261,7 @@ public class WindowsWGLContext extends GLContextImpl { WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities(); - isGLReadDrawableAvailable(); // trigger setup wglMakeContextCurrentAvailable + isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable // Windows can set up sharing of display lists after creation time WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this); @@ -315,12 +323,12 @@ public class WindowsWGLContext extends GLContextImpl { if(0!=contextHandle) { share = 0; // mark as shared thx to the ARB create method - WGL.wglMakeCurrent(0, 0); // the ARB create method used WGL.wglMakeCurrent(0, 0) - if(0!=temp_ctx) { + if(0!=temp_ctx) { + WGL.wglMakeCurrent(0, 0); WGL.wglDeleteContext(temp_ctx); - } - if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { - throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); + if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError()); + } } } else { if(glCaps.getGLProfile().isGL3()) { @@ -385,23 +393,26 @@ public class WindowsWGLContext extends GLContextImpl { } } - protected final void updateGLXProcAddressTable(int major, int minor, int ctp) { + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); if (DEBUG) { - System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this); + System.err.println(getThreadName() + ": !!! Initializing WGL extension address table: "+key); } wglGetExtensionsStringEXTInitialized=false; wglGetExtensionsStringEXTAvailable=false; - wglMakeContextCurrentInitialized=false; - wglMakeContextCurrentAvailable=false; + wglGLReadDrawableAvailableSet=false; + wglGLReadDrawableAvailable=false; WGLExtProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN ); + table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key ); } if(null != table) { wglExtProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode()); + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } } else { if (wglExtProcAddressTable == null) { @@ -409,11 +420,11 @@ public class WindowsWGLContext extends GLContextImpl { // share them among contexts classes (GL4, GL4bc, GL3, GL3bc, ..) wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver()); } - resetProcAddressTable(getWGLExtProcAddressTable()); + resetProcAddressTable(wglExtProcAddressTable); synchronized(mappedContextTypeObjectLock) { - mappedGLXProcAddress.put(contextFQN, getWGLExtProcAddressTable()); + mappedGLXProcAddress.put(key, getWGLExtProcAddressTable()); if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+contextFQN+") -> "+getWGLExtProcAddressTable().hashCode()); + System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+key+") -> "+getWGLExtProcAddressTable().hashCode()); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java index a98366f58..83b52fbcb 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java @@ -68,7 +68,7 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { NativeSurface ns = getNativeSurface(); WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateGraphicsConfiguration(getFactory(), ns); + config.updateGraphicsConfiguration(getFactory(), ns, null); if (DEBUG) { System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 903e1af81..674690e50 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -45,8 +45,6 @@ import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -55,6 +53,8 @@ import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.windows.WindowsGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; @@ -62,15 +62,17 @@ import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.windows.GDI; +import com.jogamp.nativewindow.impl.windows.RegisteredClassFactory; import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper; +import com.jogamp.opengl.impl.GLContextImpl; import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDrawableImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.impl.SharedResourceRunner; public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper; @@ -108,31 +110,182 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); + + // Init shared resources off thread + // Will be released via ShutdownHook + sharedResourceImpl = new SharedResourceImplementation(); + sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl); + sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner"); + sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running + sharedResourceThread.start(); } - static class SharedResource { + WindowsGraphicsDevice defaultDevice; + SharedResourceImplementation sharedResourceImpl; + SharedResourceRunner sharedResourceRunner; + Thread sharedResourceThread; + HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); + + long processAffinityChanges = 0; + PointerBuffer procMask = PointerBuffer.allocateDirect(1); + PointerBuffer sysMask = PointerBuffer.allocateDirect(1); + + protected void enterThreadCriticalZone() { + synchronized (sysMask) { + if( 0 == processAffinityChanges) { + long pid = GDI.GetCurrentProcess(); + if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) { + if(DEBUG) { + System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + Thread.dumpStack(); + } + processAffinityChanges = pid; + GDI.SetProcessAffinityMask(pid, 1); + } + } + } + } + + protected void leaveThreadCriticalZone() { + synchronized (sysMask) { + if( 0 != processAffinityChanges) { + long pid = GDI.GetCurrentProcess(); + if( pid != processAffinityChanges) { + throw new GLException("PID doesn't match: set PID 0x" + Long.toHexString(processAffinityChanges) + + " this PID 0x" + Long.toHexString(pid) ); + } + if(DEBUG) { + System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName()); + } + GDI.SetProcessAffinityMask(pid, sysMask.get(0)); + } + } + } + + static class SharedResource implements SharedResourceRunner.Resource { private WindowsGraphicsDevice device; + private AbstractGraphicsScreen screen; private WindowsDummyWGLDrawable drawable; private WindowsWGLContext context; private boolean canCreateGLPbuffer; private boolean readDrawableAvailable; - SharedResource(WindowsGraphicsDevice dev, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, + SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx, boolean readBufferAvail, boolean canPbuffer) { device = dev; + screen = scrn; drawable = draw; context = ctx; canCreateGLPbuffer = canPbuffer; readDrawableAvailable = readBufferAvail; } - WindowsGraphicsDevice getDevice() { return device; } - WindowsWGLContext getContext() { return context; } - boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } - boolean isReadDrawableAvailable() { return readDrawableAvailable; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } + final boolean canCreateGLPbuffer() { return canCreateGLPbuffer; } + final boolean isReadDrawableAvailable() { return readDrawableAvailable; } + } + + class SharedResourceImplementation implements SharedResourceRunner.Implementation { + public void clear() { + synchronized(sharedMap) { + sharedMap.clear(); + } + } + public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.put(connection, resource); + } + } + public SharedResourceRunner.Resource mapGet(String connection) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.get(connection); + } + } + public Collection/*<Resource>*/ mapValues() { + synchronized(sharedMap) { + return sharedMap.values(); + } + } + + public SharedResourceRunner.Resource createSharedResource(String connection) { + WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT); + sharedDevice.lock(); + try { + AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0); + if (null == absScreen) { + throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); + } + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); + if (null == glp) { + throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); + } + WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen); + if (null == sharedDrawable) { + throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp); + } + WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null); + if (null == sharedContext) { + throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); + } + sharedContext.setSynchronized(true); + boolean canCreateGLPbuffer; + boolean readDrawableAvailable; + sharedContext.makeCurrent(); + try { + canCreateGLPbuffer = sharedContext.getGL().isExtensionAvailable(GL_ARB_pbuffer); + readDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) && + sharedContext.isFunctionAvailable(wglMakeContextCurrent); + } finally { + sharedContext.release(); + } + if (DEBUG) { + System.err.println("!!! SharedDevice: " + sharedDevice); + System.err.println("!!! SharedScreen: " + absScreen); + System.err.println("!!! SharedContext: " + sharedContext); + System.err.println("!!! pbuffer avail: " + canCreateGLPbuffer); + System.err.println("!!! readDrawable: " + readDrawableAvailable); + } + return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, readDrawableAvailable, canCreateGLPbuffer); + } catch (Throwable t) { + throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); + } finally { + sharedDevice.unlock(); + } + } + + public void releaseSharedResource(SharedResourceRunner.Resource shared) { + SharedResource sr = (SharedResource) shared; + if (DEBUG) { + System.err.println("!!! Shutdown Shared:"); + System.err.println("!!! Device : " + sr.device); + System.err.println("!!! Screen : " + sr.screen); + System.err.println("!!! Drawable: " + sr.drawable); + System.err.println("!!! CTX : " + sr.context); + } + + if (null != sr.context) { + // may cause JVM SIGSEGV: sharedContext.destroy(); + sr.context = null; + } + + if (null != sr.drawable) { + sr.drawable.destroy(); + sr.drawable = null; + } + + if (null != sr.screen) { + sr.screen = null; + } + + if (null != sr.device) { + sr.device.close(); + sr.device = null; + } + } } - HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); - WindowsGraphicsDevice defaultDevice; public final AbstractGraphicsDevice getDefaultDevice() { return defaultDevice; @@ -145,62 +298,24 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { return false; } - HashSet devicesTried = new HashSet(); - private final boolean getDeviceTried(String connection) { - synchronized(devicesTried) { - return devicesTried.contains(connection); - } - } - private final void addDeviceTried(String connection) { - synchronized(devicesTried) { - devicesTried.add(connection); - } - } - final static String GL_ARB_pbuffer = "GL_ARB_pbuffer"; final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read"; final static String wglMakeContextCurrent = "wglMakeContextCurrent"; - private SharedResource getOrCreateShared(AbstractGraphicsDevice device) { - String connection = device.getConnection(); - SharedResource sr; - synchronized(sharedMap) { - sr = (SharedResource) sharedMap.get(connection); + protected final GLContext getSharedContextImpl(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getShared(device); + if(null!=sr) { + return sr.getContext(); } - if(null==sr && !getDeviceTried(connection)) { - addDeviceTried(connection); - NativeWindowFactory.getDefaultToolkitLock().lock(); // OK - try { - WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT); - GLProfile glp = GLProfile.getDefault(/*sharedDevice*/); // can't fetch device profile, which shared resource we create here - AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0); - WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(this, glp, absScreen); - WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null); - ctx.makeCurrent(); - boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable(GL_ARB_pbuffer); - boolean readDrawableAvailable = ctx.isExtensionAvailable(WGL_ARB_make_current_read) && - ctx.isFunctionAvailable(wglMakeContextCurrent); - ctx.release(); - sr = new SharedResource(sharedDevice, sharedDrawable, ctx, readDrawableAvailable, canCreateGLPbuffer); - synchronized(sharedMap) { - sharedMap.put(connection, sr); - } - if (DEBUG) { - System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+ - ", readDrawable supported "+readDrawableAvailable); - } + return null; + } - } catch (Throwable t) { - throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t); - } finally { - NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK - } - } - return sr; + protected final boolean hasSharedContextImpl(AbstractGraphicsDevice device) { + return null != getSharedContextImpl(device); } protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return sr.getContext(); } @@ -208,43 +323,32 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return sr.getDevice(); } return null; } - protected final void shutdownInstance() { - if (DEBUG) { - Exception e = new Exception("Debug"); - e.printStackTrace(); + protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return (WindowsWGLDrawable) sr.getDrawable(); } - Collection/*<SharedResource>*/ sharedResources = sharedMap.values(); - for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) { - SharedResource sr = (SharedResource) iter.next(); - - if (DEBUG) { - System.err.println("!!! Shutdown Shared:"); - System.err.println("!!! Drawable: "+sr.drawable); - System.err.println("!!! CTX : "+sr.context); - } + return null; + } - if (null != sr.context) { - // may cause JVM SIGSEGV: sharedContext.destroy(); - sr.context = null; - } + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); + } - if (null != sr.drawable) { - // may cause JVM SIGSEGV: sharedDrawable.destroy(); - sr.drawable = null; - } + protected final void shutdownInstance() { + sharedResourceRunner.releaseAndWait(); + RegisteredClassFactory.shutdownSharedClasses(); + } - } - sharedMap.clear(); - if (DEBUG) { - System.err.println("!!! Shutdown Shared Finished"); - } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device); } protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { @@ -267,7 +371,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { // PBuffer GLDrawable Creation final AbstractGraphicsDevice device = config.getScreen().getDevice(); - final SharedResource sr = getOrCreateShared(device); + final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); if(null==sr) { throw new IllegalArgumentException("No shared resource for "+device); } @@ -278,19 +382,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { if (lastContext != null) { lastContext.release(); } - synchronized(sr.context) { - sr.context.makeCurrent(); - try { - GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target, - sr.drawable, - sr.context); - returnList.add(pbufferDrawable); - } finally { - sr.context.release(); - if (lastContext != null) { - lastContext.makeCurrent(); - } - } + sr.context.makeCurrent(); + try { + GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target, + sr.drawable, + sr.context); + returnList.add(pbufferDrawable); + } finally { + sr.context.release(); + if (lastContext != null) { + lastContext.makeCurrent(); + } } } }; @@ -303,7 +405,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { * and -1 if undefined yet, ie no shared device exist at this point. */ public final int isReadDrawableAvailable(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice); + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice); if(null!=sr) { return sr.isReadDrawableAvailable() ? 1 : 0 ; } @@ -311,7 +413,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { } public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice); + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice); if(null!=sr) { return sr.canCreateGLPbuffer(); } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index aa1b1b70d..36d78b38d 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -33,12 +33,15 @@ package com.jogamp.opengl.impl.windows.wgl; +import java.util.ArrayList; +import java.util.List; + import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.DefaultGraphicsConfiguration; import javax.media.nativewindow.NativeSurface; -import javax.media.opengl.DefaultGLCapabilitiesChooser; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -48,84 +51,128 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; import com.jogamp.opengl.impl.GLContextImpl; -import javax.media.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { // Keep this under the same debug flag as the drawable factory for convenience protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); + final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format"; + final static String WGL_ARB_multisample = "WGL_ARB_multisample"; + protected static final int MAX_PFORMATS = 256; protected static final int MAX_ATTRIBS = 256; - private PIXELFORMATDESCRIPTOR pixelfmt; - private int pixelfmtID; - private boolean isChosen = false; private GLCapabilitiesChooser chooser; - private boolean choosenByWGLPixelFormat=false; + private boolean isChosen = false; WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, - PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, GLCapabilitiesChooser chooser) { + GLCapabilitiesChooser chooser) { super(screen, capsChosen, capsRequested); this.chooser=chooser; - this.pixelfmt = pixelfmt; - this.pixelfmtID = pixelfmtID; + this.isChosen = false; } - static WindowsWGLGraphicsConfiguration create(long hdc, int pfdID, + WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, + WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) { + super(screen, capsChosen, capsRequested); + setCapsPFD(capsChosen); + this.chooser=null; + } + + + static WindowsWGLGraphicsConfiguration create(GLDrawableFactory _factory, long hdc, int pfdID, GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer) { + if(_factory==null) { + throw new GLException("Null factory"); + } + if(hdc==0) { + throw new GLException("Null HDC"); + } if(pfdID<=0) { throw new GLException("Invalid pixelformat id "+pfdID); } if(null==glp) { glp = GLProfile.getDefault(screen.getDevice()); } - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Unable to describe pixel format " + pfdID); + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + AbstractGraphicsDevice device = screen.getDevice(); + WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); + boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ; + + WGLGLCapabilities caps = null; + + if(hasARB) { + sharedContext.makeCurrent(); + try { + caps = wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glp, onscreen, usePBuffer); + } finally { + sharedContext.release(); + } + } else if(!usePBuffer) { + caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen); } - - GLCapabilitiesImmutable caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); if(null==caps) { - throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID); + throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB); } - WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser()); - cfg.setCapsPFD(caps, pfd, pfdID, false); - return cfg; + return new WindowsWGLGraphicsConfiguration(screen, caps, caps); } public Object clone() { return super.clone(); } - final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns) { - WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns); + /** + * Updates the graphics configuration in case it has been determined yet.<br> + * Uses the NativeSurface's HDC.<br> + * Ensures that a PIXELFORMAT is set. + * + * @param factory + * @param ns + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + * + * @see #isDetermined() + */ + public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) { + WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs); } - void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) { - this.pixelfmt = pfd; - this.pixelfmtID = pfdID; + /** + * Preselect the graphics configuration in case it has been determined yet.<br> + * Uses a shared device's HDC and the given pfdIDs to preselect the pfd. + * No PIXELFORMAT is set. + * + * @param factory + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + * + * @see #isDetermined() + */ + public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) { + AbstractGraphicsDevice device = getNativeGraphicsConfiguration().getScreen().getDevice(); + WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs); + } + + final void setCapsPFD(WGLGLCapabilities caps) { setChosenCapabilities(caps); this.isChosen=true; - this.choosenByWGLPixelFormat=choosenByWGLPixelFormat; if (DEBUG) { - System.err.println("*** setCapsPFD: WGL-Choosen "+choosenByWGLPixelFormat+", pfdID "+pfdID+", "+caps); + System.err.println("*** setCapsPFD: "+caps); } } - public boolean getCapabilitiesChosen() { - return isChosen; - } - - public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; } - public int getPixelFormatID() { return pixelfmtID; } - public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; } + public final boolean isDetermined() { return isChosen; } + public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; } + public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; } + public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; } static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) { int niattribs = 0; iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB; iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; @@ -145,6 +192,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; } + // pbo float buffer + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; // ati + iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia + return niattribs; } @@ -159,177 +210,147 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } - static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, - GLProfile glp, boolean onscreen, boolean usePBuffer) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) { + int[] iattributes = new int[1]; + int[] iresults = new int[1]; + + WGLExt wglExt = sharedCtx.getWGLExt(); + iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + if(DEBUG) { + System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; + } + int numFormats = iresults[0]; + if(0 == numFormats) { + if(DEBUG) { + System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + Thread.dumpStack(); + } + return null; + } + int[] pfdIDs = new int[numFormats]; + for (int i = 0; i < numFormats; i++) { + pfdIDs[i] = 1 + i; + } + return pfdIDs; + } + + static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID, + GLProfile glp, boolean onscreen, boolean usePBuffer) { + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); int[] iattributes = new int [2*MAX_ATTRIBS]; int[] iresults = new int [2*MAX_ATTRIBS]; - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - if(iresults[0] > 0 ) { - int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); - } - return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, - onscreen, usePBuffer); - } + int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + + if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) { + throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context"); } - long lastErr = GDI.GetLastError(); - // Intel Extreme graphics fails with a zero error code - if (lastErr != 0) { - throw new GLException("wglARBPFID2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError()); + ArrayList bucket = new ArrayList(1); + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) { + return (WGLGLCapabilities) bucket.get(0); } return null; } - static int wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, - GLCapabilitiesImmutable capabilities, - int[] iattributes, int accelerationMode, float[] fattributes, - int[] pformats) + static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext, + GLCapabilitiesImmutable capabilities, + int[] iattributes, int accelerationMode, float[] fattributes) { - int numFormats = -1; - - if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, - sharedContext, - accelerationMode, - false, - null)) { - int[] numFormatsTmp = new int[1]; - if (sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, - iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformats, 0, - numFormatsTmp, 0)) { - numFormats = numFormatsTmp[0]; - if (DEBUG) { - System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + - Integer.toHexString(accelerationMode) + ": " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS); - } - } else { - if (DEBUG) { - System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError() ); - Thread.dumpStack(); - } - } - } else { - if (DEBUG) { - System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError() ); - Thread.dumpStack(); - } - } - return numFormats; - } - static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, int numFormats, - GLProfile glp, boolean onscreen, boolean usePBuffer) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); - if (!haveWGLChoosePixelFormatARB) { + if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, + iattributes, sharedContext, accelerationMode, null)) + { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError()); + Thread.dumpStack(); + } return null; } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - - GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats]; - int[] iattributes = new int [2*MAX_ATTRIBS]; - int[] iresults = new int [2*MAX_ATTRIBS]; - int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - - for(int i = 0; i<numFormats; i++) { - if ( pfdIDs[i] >= 1 && - sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { - caps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } else { - if (DEBUG) { - System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + - i + "/" + numFormats + ": " + pfdIDs[i]); - } - caps[i] = null; + int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; + int[] numFormatsTmp = new int[1]; + if ( !sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformatsTmp, 0, numFormatsTmp, 0)) + { + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError()); + Thread.dumpStack(); } + return null; } - return caps; + int numFormats = numFormatsTmp[0]; + int[] pformats = null; + if( 0 < numFormats ) { + pformats = new int[numFormats]; + System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats); + } + if (DEBUG) { + System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" + + Integer.toHexString(accelerationMode) + ": " + numFormats); + } + return pformats; } - /** - * - * @param sharedCtx - * @param hdc - * @param glp - * @param onscreen - * @param usePBuffer - * @param pfIDs stores the PIXELFORMAT ID for the GLCapabilitiesImmutable[] - * @return the resulting GLCapabilitiesImmutable[] - */ - static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, - GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, boolean onscreen, boolean usePBuffer) { + final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, winattrbits); + } + + static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp) { + return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS); + } + + private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, + GLProfile glp, int winattrbits) { + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); if (!haveWGLChoosePixelFormatARB) { return null; } - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); - - // Produce a list of GLCapabilities to give to the - // GLCapabilitiesChooser. - // Use wglGetPixelFormatAttribivARB instead of - // DescribePixelFormat to get higher-precision information - // about the pixel format (should make the GLCapabilities - // more precise as well...i.e., remove the - // "HardwareAccelerated" bit, which is basically - // meaningless, and put in whether it can render to a - // window, to a pbuffer, or to a pixmap) - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = 0; - int niattribs = 0; - int[] iattributes = new int[2 * MAX_ATTRIBS]; - int[] iresults = new int[2 * MAX_ATTRIBS]; + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); + final int numFormats = pfdIDs.length; - WGLExt wglExt = sharedCtx.getWGLExt(); - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; - if (DEBUG) { - System.err.println("wglARBAllPFIDs2GLCapabilities: wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats + ", pfIDs sz "+pfIDs.length); - } - if (numFormats > pfIDs.length) { - numFormats = pfIDs.length; - } + int[] iattributes = new int [2*MAX_ATTRIBS]; + int[] iresults = new int [2*MAX_ATTRIBS]; + int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); - niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes); + ArrayList bucket = new ArrayList(); - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - pfIDs[i] = i + 1; - if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfIDs[i], 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Error getting pixel format attributes for pixel format " + pfIDs[i]); - } - availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer); - } - } else { - long lastErr = GDI.GetLastError(); - // Some GPU's falsely fails with a zero error code (success) - if (lastErr != GDI.ERROR_SUCCESS) { - throw new GLException("wglARBAllPFIDs2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + lastErr); + for(int i = 0; i<numFormats; i++) { + if ( pfdIDs[i] >= 1 && + sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) { + AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits); + } else if (DEBUG) { + System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " + + i + "/" + numFormats + ": " + pfdIDs[i] + ", " + + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString()); } } - return availableCaps; + return bucket; } static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps, int[] iattributes, GLContextImpl sharedCtx, - int accellerationValue, - boolean pbuffer, + int accellerationValue, int[] floatMode) throws GLException { - boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format"); - boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample"); + boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format); + boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample); if(DEBUG) { System.err.println("HDC2GLCapabilities: ARB_pixel_format: "+haveWGLChoosePixelFormatARB); System.err.println("HDC2GLCapabilities: ARB_multisample : "+haveWGLARBMultisample); @@ -339,6 +360,9 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return false; } + boolean onscreen = caps.isOnscreen(); + boolean pbuffer = caps.isPBuffer(); + int niattribs = 0; iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; @@ -347,11 +371,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; iattributes[niattribs++] = accellerationValue; } - if (pbuffer) { + if (onscreen) { + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = GL.GL_TRUE; + } else if (pbuffer) { iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; iattributes[niattribs++] = GL.GL_TRUE; } else { - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB; iattributes[niattribs++] = GL.GL_TRUE; } @@ -488,204 +515,120 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } - public static final int WINDOW_BIT = 1 << 0 ; - public static final int BITMAP_BIT = 1 << 1 ; - public static final int PBUFFER_BIT = 1 << 2 ; - - static int WGLConfig2DrawableTypeBits(int[] iattribs, - int niattribs, - int[] iresults) { + static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) { int val = 0; for (int i = 0; i < niattribs; i++) { int attr = iattribs[i]; switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT; break; case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT; break; case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT; + if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; break; } } return val; } - static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static boolean AttribList2GLCapabilities( ArrayList capsBucket, + final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs, + final int niattribs, + final int[] iresults, final int winattrmask) { + final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults); + int drawableTypeBits = winattrmask & allDrawableTypeBits; - if ( onscreen ) { - res = ( 0 != (val & WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & BITMAP_BIT) ) ; - } + if( 0 == drawableTypeBits ) { + return false; } + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); - return res; - } - - static GLCapabilitiesImmutable AttribList2GLCapabilities( - GLProfile glp, int[] iattribs, - int niattribs, - int[] iresults, - boolean onscreen, boolean usePBuffer) { - GLCapabilities res = new GLCapabilities(glp); - int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults); - if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else { - if(DEBUG) { - System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")"); + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // remove displayable bits, since pfdID is non displayable + drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT); + if( 0 == drawableTypeBits ) { + return false; } - return null; + // non displayable requested (pbuffer) } + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByARB(iattribs, niattribs, iresults); - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - case WGLExt.WGL_DRAW_TO_BITMAP_ARB: - case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: - break; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); + } - case WGLExt.WGL_ACCELERATION_ARB: - res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB); - break; + // + // GDI PIXELFORMAT + // - case WGLExt.WGL_SUPPORT_OPENGL_ARB: - if (iresults[i] != GL.GL_TRUE) { - return null; - } - break; + static int[] wglAllGDIPFIDs(long hdc) { + int numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); + if (numFormats == 0) { + throw new GLException("DescribePixelFormat: No formats - HDC 0x" + Long.toHexString(hdc) + + ", LastError: " + GDI.GetLastError()); + } + int[] pfdIDs = new int[numFormats]; + for (int i = 0; i < numFormats; i++) { + pfdIDs[i] = 1 + i; + } + return pfdIDs; + } - case WGLExt.WGL_DEPTH_BITS_ARB: - res.setDepthBits(iresults[i]); - break; + static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) { + int val = 0; - case WGLExt.WGL_STENCIL_BITS_ARB: - res.setStencilBits(iresults[i]); - break; + int dwFlags = pfd.getDwFlags(); - case WGLExt.WGL_DOUBLE_BUFFER_ARB: - res.setDoubleBuffered(iresults[i] == GL.GL_TRUE); - break; + if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + return val; + } - case WGLExt.WGL_STEREO_ARB: - res.setStereo(iresults[i] == GL.GL_TRUE); - break; + static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) { + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); + ArrayList capsBucket = new ArrayList(1); + if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) { + return (WGLGLCapabilities) capsBucket.get(0); + } + return null; + } - case WGLExt.WGL_PIXEL_TYPE_ARB: - // Fail softly with unknown results here - if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB|| - iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) { - res.setPbufferFloatingPointBuffers(true); - } - break; + static boolean PFD2GLCapabilities(ArrayList capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) { + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID); + if(null == pfd) { + return false; + } + if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { + return false; + } + final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd); + final int drawableTypeBits = winattrmask & allDrawableTypeBits; - case WGLExt.WGL_FLOAT_COMPONENTS_NV: - if (iresults[i] != 0) { - res.setPbufferFloatingPointBuffers(true); - } - break; - - case WGLExt.WGL_RED_BITS_ARB: - res.setRedBits(iresults[i]); - break; - - case WGLExt.WGL_GREEN_BITS_ARB: - res.setGreenBits(iresults[i]); - break; - - case WGLExt.WGL_BLUE_BITS_ARB: - res.setBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ALPHA_BITS_ARB: - res.setAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_RED_BITS_ARB: - res.setAccumRedBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_GREEN_BITS_ARB: - res.setAccumGreenBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_BLUE_BITS_ARB: - res.setAccumBlueBits(iresults[i]); - break; - - case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB: - res.setAccumAlphaBits(iresults[i]); - break; - - case WGLExt.WGL_SAMPLE_BUFFERS_ARB: - res.setSampleBuffers(iresults[i] != 0); - break; - - case WGLExt.WGL_SAMPLES_ARB: - res.setNumSamples(iresults[i]); - break; - - default: - throw new GLException("Unknown pixel format attribute " + iattribs[i]); - } + if( 0 == drawableTypeBits ) { + return false; } - return res; - } - // PIXELFORMAT + WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp); + res.setValuesByGDI(); - static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { - if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) { - return null; - } - GLCapabilities res = new GLCapabilities(glp); - res.setRedBits (pfd.getCRedBits()); - res.setGreenBits (pfd.getCGreenBits()); - res.setBlueBits (pfd.getCBlueBits()); - res.setAlphaBits (pfd.getCAlphaBits()); - res.setAccumRedBits (pfd.getCAccumRedBits()); - res.setAccumGreenBits(pfd.getCAccumGreenBits()); - res.setAccumBlueBits (pfd.getCAccumBlueBits()); - res.setAccumAlphaBits(pfd.getCAccumAlphaBits()); - res.setDepthBits (pfd.getCDepthBits()); - res.setStencilBits (pfd.getCStencilBits()); - res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0); - res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0); - res.setHardwareAccelerated( (pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 || - (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 ); - res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) ); - res.setPBuffer ( usePBuffer ); - /* FIXME: Missing ?? - if (GLXUtil.isMultisampleAvailable()) { - res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); - res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0)); - } - res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) != GLX.GLX_NONE); - try { - res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); - } catch (Exception e) {} - */ - return res; + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } - static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps) { + static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) { int colorDepth = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); if (colorDepth < 15) { throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); } - PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); int pfdFlags = (GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED); if (caps.getDoubleBuffered()) { @@ -718,27 +661,35 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio pfd.setCStencilBits((byte) caps.getStencilBits()); pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE); - /* FIXME: Missing: - caps.getSampleBuffers() - caps.getNumSamples () - } - caps.getBackgroundOpaque() - try { - caps.getPbufferFloatingPointBuffers() - } catch (Exception e) {} - */ + // n/a with non ARB/GDI method: + // multisample + // opaque + // pbuffer return pfd; } - static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) { PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create(); pfd.setNSize((short) pfd.size()); pfd.setNVersion((short) 1); + if(0 != hdc && 1 <= pfdID) { + if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + // Accelerated pixel formats that are non displayable + if(DEBUG) { + System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError()); + } + return null; + } + } return pfd; } + static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() { + return createPixelFormatDescriptor(0, 0); + } + public String toString() { - return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", wglChoosen "+choosenByWGLPixelFormat+ + return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() + ",\n\trequested " + getRequestedCapabilities() + ",\n\tchosen " + getChosenCapabilities() + "]"; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index 87bbec018..812829168 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -39,10 +39,10 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.DefaultGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; -import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; @@ -50,17 +50,22 @@ import javax.media.opengl.GLProfile; import com.jogamp.nativewindow.impl.windows.GDI; import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR; -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.opengl.DefaultGLCapabilitiesChooser; -import javax.media.opengl.GLCapabilitiesImmutable; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; +import com.jogamp.opengl.impl.SharedResourceRunner; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT tookits are used on Windows platforms. Toolkits will likely need to delegate to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); + static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator(); WindowsWGLGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this); @@ -82,10 +87,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps, AbstractGraphicsScreen absScreen) { - if(null==absScreen) { - absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); - } - return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, null); + return chooseGraphicsConfigurationStatic(caps, caps, null, absScreen); } static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, @@ -95,21 +97,82 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio if(null==absScreen) { absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS); } + AbstractGraphicsDevice absDevice = absScreen.getDevice(); + + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( + capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) ); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; + return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser ); + } + + protected static List/*<WGLGLCapabilities>*/ getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + WindowsWGLDrawable sharedDrawable = (WindowsWGLDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + WindowsWGLContext sharedContext = (WindowsWGLContext) sharedResource.getContext(); + List availableCaps = null; + + sharedDrawable.lockSurface(); + try { + long hdc = sharedDrawable.getHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + if (sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedContext, capsChosen.getGLProfile()); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen); + } + } finally { + sharedDrawable.unlockSurface(); } - return new WindowsWGLGraphicsConfiguration(absScreen, capsChosen, capsReq, - WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen), -1, - (GLCapabilitiesChooser)chooser); + if( null != availableCaps ) { + Collections.sort(availableCaps, PfdIDComparator); + } + return availableCaps; } + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLContext sharedContext, GLProfile glProfile) { + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); + return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedContext, hdc, pformats, glProfile); + } + + static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesGDI(long hdc, GLCapabilitiesImmutable capsChosen) { + boolean onscreen = capsChosen.isOnscreen(); + if(capsChosen.isPBuffer()) { + return null; + } + GLProfile glProfile = capsChosen.getGLProfile(); + + int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + int numFormats = pformats.length; + ArrayList bucket = new ArrayList(numFormats); + for (int i = 0; i < numFormats; i++) { + bucket.add( WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen) ); + } + return bucket; + } + + /** + * + * @param chooser + * @param _factory + * @param ns + * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection + */ static void updateGraphicsConfiguration(CapabilitiesChooser chooser, - GLDrawableFactory _factory, NativeSurface ns) { + GLDrawableFactory factory, NativeSurface ns, int[] pfdIDs) { + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + if (factory == null) { + throw new IllegalArgumentException("GLDrawableFactory is null"); + } if (ns == null) { throw new IllegalArgumentException("NativeSurface is null"); } @@ -118,22 +181,75 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio throw new GLException("Error: HDC is null"); } WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + + if(!config.isDetermined()) { + updateGraphicsConfiguration(config, chooser, factory, hdc, false, pfdIDs); + } else { + // set PFD if not set yet + int pfdID = -1; + boolean set = false; + if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) { + if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) { + throw new GLException("Unable to set pixel format " + config.getPixelFormatID() + + " for device context " + toHexString(hdc) + + ": error code " + GDI.GetLastError()); + } + set = true; + pfdID = config.getPixelFormatID(); + } + if (DEBUG) { + System.err.println("!!! setPixelFormat (post): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID+", set: "+set); + Thread.dumpStack(); + } + } + } + + static void preselectGraphicsConfiguration(CapabilitiesChooser chooser, + GLDrawableFactory _factory, AbstractGraphicsDevice device, + WindowsWGLGraphicsConfiguration config, int[] pfdIDs) { if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); } + if (_factory == null) { + throw new IllegalArgumentException("GLDrawableFactory is null"); + } + if (config == null) { + throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null"); + } + WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory; + WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device); + if(null == sharedDrawable) { + throw new IllegalArgumentException("Shared Drawable is null"); + } + sharedDrawable.lockSurface(); + try { + long hdc = sharedDrawable.getHandle(); + if (0 == hdc) { + throw new GLException("Error: HDC is null"); + } + updateGraphicsConfiguration(config, chooser, factory, hdc, true, pfdIDs); + } finally { + sharedDrawable.unlockSurface(); + } + } + private static void updateGraphicsConfiguration(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, + GLDrawableFactory factory, long hdc, boolean extHDC, int[] pfdIDs) { if (DEBUG) { - System.err.println("updateGraphicsConfiguration: hdc "+toHexString(hdc)); + if(extHDC) { + System.err.println("updateGraphicsConfiguration(using shared): hdc "+toHexString(hdc)); + } else { + System.err.println("updateGraphicsConfiguration(using target): hdc "+toHexString(hdc)); + } System.err.println("!!! user chosen caps " + config.getChosenCapabilities()); } - - if( !updateGraphicsConfigurationARB(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory) ) { - updateGraphicsConfigurationGDI(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory); + if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) { + updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs); } } - private static boolean updateGraphicsConfigurationARB(long hdc, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) { AbstractGraphicsDevice device = config.getScreen().getDevice(); WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device); if (null == sharedContext) { @@ -142,282 +258,204 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio } return false; } + if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available"); + } + return false; + } + GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - int pixelFormatSet = -1; // 1-based pixel format - GLCapabilitiesImmutable pixelFormatCaps = null; - - GLCapabilitiesImmutable[] availableCaps = null; - int[] pformats = null; // if != null, then index matches availableCaps - int numFormats = -1; - int recommendedIndex = -1; - - synchronized (sharedContext) { - sharedContext.makeCurrent(); - try { - if (!sharedContext.isExtensionAvailable("WGL_ARB_pixel_format")) { - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB not available"); - } - return false; + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps + boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] + + sharedContext.makeCurrent(); + try { + final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ; + if ( 1 <= presetPFDID ) { + // Pixelformat already set by either + // - a previous preselectGraphicsConfiguration() call on the same HDC, + // - the graphics driver, copying the HDC's pixelformat to the new one, + // - or the Java2D/OpenGL pipeline's configuration + if (DEBUG) { + System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) + + ", pixelformat " + presetPFDID); } - if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) >= 1) { - // Pixelformat already set by either - // - a previous updateGraphicsConfiguration() call on the same HDC, - // - the graphics driver, copying the HDC's pixelformat to the new one, - // - or the Java2D/OpenGL pipeline's configuration - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pixelFormatSet); - } - - // only fetch the specific one .. - pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pixelFormatSet, glProfile, onscreen, usePBuffer); - } else { + pixelFormatSet = true; + pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, presetPFDID, glProfile, onscreen, usePBuffer); + } else { + int recommendedIndex = -1; // recommended index + + if(null == pformats) { + // No given PFD IDs + // + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; float[] fattributes = new float[1]; - pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - - // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice - numFormats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, - iattributes, -1, fattributes, pformats); - if (0 < numFormats) { - availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, numFormats, - glProfile, onscreen, usePBuffer); - if (null != availableCaps) { - recommendedIndex = 0; - pixelFormatCaps = availableCaps[0]; - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS); - System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex); - System.err.println("!!! recommended caps " + pixelFormatCaps); - } + pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen, + iattributes, -1, fattributes); + + if (null != pformats) { + recommendedIndex = 0; + } else { + if(DEBUG) { + System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen); } - } - - // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - if (null == availableCaps) { + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc); if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed (Query all formats without recommendation): " + GDI.GetLastError()); + System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + pformats.length); } - availableCaps = WindowsWGLGraphicsConfiguration.wglARBAllPFIDs2GLCapabilities(sharedContext, hdc, - glProfile, onscreen, usePBuffer, pformats); - if (null != availableCaps) { - numFormats = availableCaps.length; + } + if (null == pformats) { + if (DEBUG) { + Thread.dumpStack(); } + return false; } } - } finally { - sharedContext.release(); - } - } // synchronized(factory.sharedContext) - - if (pixelFormatSet <= 0 && null == availableCaps) { - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: No PixelFormat chosen via ARB ... (LastError: " + GDI.GetLastError() + ")"); - } - return false; - } - - int pfdID; - if (pixelFormatSet <= 0) { - if (null == pixelFormatCaps && null == chooser) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - int chosenIndex = recommendedIndex; - try { - if (null != chooser) { - chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); - pixelFormatCaps = availableCaps[chosenIndex]; + List /*<WGLGLCapabilities>*/ availableCaps = + WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, + glProfile, onscreen, usePBuffer); + if( null == availableCaps || 0 == availableCaps.size() ) { if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: chooser: idx " + chosenIndex); - System.err.println("!!! chosen caps " + pixelFormatCaps); + System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer); + Thread.dumpStack(); } + return false; } - } catch (NativeWindowException e) { + if (DEBUG) { - e.printStackTrace(); + System.err.println("updateGraphicsConfigurationARB: " + pformats.length + + " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps"); + if(0 <= recommendedIndex) { + System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + + pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex)); + } } - } - if (chosenIndex < 0) { - // keep on going .. - // seek first available one .. - for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { - // nop - } - if (chosenIndex == availableCaps.length) { - // give up .. + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: Failed .. nothing available, bail out"); + Thread.dumpStack(); } return false; } - pixelFormatCaps = availableCaps[chosenIndex]; + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); + if( null == pixelFormatCaps) { + throw new GLException("Null Capabilities with "+ + " chosen pfdID: native recommended "+ (recommendedIndex+1) + + " chosen "+pixelFormatCaps.getPFDID()); + } if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: Failed .. unable to choose config, using first available idx: " + chosenIndex); - System.err.println("!!! fallback caps " + pixelFormatCaps); + System.err.println("!!! chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) + + " chosen "+pixelFormatCaps); } } - pfdID = pformats[chosenIndex]; - } else { - pfdID = pixelFormatSet; - } - if (DEBUG) { - System.err.println("updateGraphicsConfigurationARB: using pfdID "+pfdID); - } - - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); + } finally { + sharedContext.release(); } - if (pixelFormatSet <= 0) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if ( !extHDC && !pixelFormatSet ) { + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } + if (DEBUG) { + System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID()); + } } - - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + config.setCapsPFD(pixelFormatCaps); return true; } - private static boolean updateGraphicsConfigurationGDI(long hdc, WindowsWGLGraphicsConfiguration config, - CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) { + private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config, + CapabilitiesChooser chooser, int[] pformats) { GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(capsChosen.isPBuffer()) { + if (DEBUG) { + System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen); + } + return false; + } boolean onscreen = capsChosen.isOnscreen(); - boolean usePBuffer = capsChosen.isPBuffer(); GLProfile glProfile = capsChosen.getGLProfile(); - int pixelFormatSet = -1; // 1-based pixel format - GLCapabilitiesImmutable pixelFormatCaps = null; + ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList(); + int pfdID; // chosen or preset PFD ID + WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps + boolean pixelFormatSet = false; // indicates a preset PFD ID [caps] - GLCapabilitiesImmutable[] availableCaps = null; - int numFormats = -1; - int recommendedIndex = -1; - - if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) != 0) { + if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) { // Pixelformat already set by either - // - a previous updateGraphicsConfiguration() call on the same HDC, + // - a previous preselectGraphicsConfiguration() call on the same HDC, // - the graphics driver, copying the HDC's pixelformat to the new one, // - or the Java2D/OpenGL pipeline's configuration if (DEBUG) { System.err.println("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc) - + ", pixelformat " + pixelFormatSet); + + ", pixelformat " + pfdID); } - } + pixelFormatSet = true; + pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen); + } else { + if(null == pformats) { + pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc); + } + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false); - int recommendedPixelFormat = pixelFormatSet; + for (int i = 0; i < pformats.length; i++) { + WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask); + } - numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null); - if (numFormats == 0) { - throw new GLException("Unable to enumerate pixel formats of window " - + toHexString(hdc) + " for GLCapabilitiesChooser (LastError: " + GDI.GetLastError() + ")"); - } - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: NumFormats (DescribePixelFormat) " + numFormats); - } - - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - availableCaps = new GLCapabilitiesImmutable[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (GDI.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { - throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd); + pfdID = GDI.ChoosePixelFormat(hdc, pfd); + int recommendedIndex = -1 ; + if( 1 <= pfdID ) { + // seek index .. + for (recommendedIndex = availableCaps.size() - 1 ; + 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID(); + recommendedIndex--) + { /* nop */ } } - availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); - } - - int pfdID; - - if (pixelFormatSet <= 0) { - pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen); - recommendedPixelFormat = GDI.ChoosePixelFormat(hdc, pfd); - recommendedIndex = recommendedPixelFormat - 1; - pixelFormatCaps = availableCaps[recommendedIndex]; + // 2nd choice: if no preferred recommendedIndex available if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + recommendedPixelFormat + " (LastError: " + GDI.GetLastError() + ")"); - System.err.println("!!! recommended caps " + pixelFormatCaps); + System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")"); } - - int chosenIndex = recommendedIndex; - try { - if (null != chooser) { - chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); - pixelFormatCaps = availableCaps[chosenIndex]; - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: chooser: idx " + chosenIndex); - System.err.println("!!! chosen caps " + pixelFormatCaps); - } - } - } catch (NativeWindowException e) { + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { if (DEBUG) { - e.printStackTrace(); + Thread.dumpStack(); } + return false; } - - if (chosenIndex < 0) { - // keep on going .. - // seek first available one .. - for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) { - // nop - } - if (chosenIndex == availableCaps.length) { - // give up .. - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: Failed .. nothing available, bail out"); - } - return false; - } - pixelFormatCaps = availableCaps[chosenIndex]; - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: Failed .. unable to choose config, using first available idx: " + chosenIndex); - System.err.println("!!! fallback caps " + pixelFormatCaps); - } - } - pfdID = chosenIndex + 1; - } else { - pfdID = pixelFormatSet; - pixelFormatCaps = availableCaps[pixelFormatSet-1]; + pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex); if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: Using preset PFID: " + pixelFormatSet); - System.err.println("!!! preset caps " + pixelFormatCaps); + System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) + + ", caps " + pixelFormatCaps); } } - if (DEBUG) { - System.err.println("updateGraphicsConfigurationGDI: using pfdID "+pfdID); - } - - if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { - throw new GLException("Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError()); - } - if (pixelFormatSet <= 0) { - if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) { - throw new GLException("Unable to set pixel format " + pfdID + + if ( !extHDC && !pixelFormatSet ) { + if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) { + throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() + " for device context " + toHexString(hdc) + ": error code " + GDI.GetLastError()); } + if (DEBUG) { + System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID()); + } } - - config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true); + config.setCapsPFD(pixelFormatCaps); return true; - - } - - static String getThreadName() { - return Thread.currentThread().getName(); - } - - static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java index da4f2113d..f753c08c5 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,6 +34,9 @@ package com.jogamp.opengl.impl.windows.wgl.awt; +import com.jogamp.common.util.ArrayHashSet; +import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -53,8 +57,9 @@ import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLException; import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration; +import javax.media.opengl.GLDrawableFactory; -public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration"); public WindowsAWTWGLGraphicsConfigurationFactory() { @@ -72,6 +77,9 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura if(null==absScreen) { absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT); + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen); + } } AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); @@ -92,28 +100,74 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura if(DEBUG) { System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen); } - GraphicsConfiguration gc = device.getDefaultConfiguration(); + WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex()); - if(DEBUG) { - System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: made "+winScreen); - } + GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice); + GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory( ((GLCapabilitiesImmutable)capsChosen).getGLProfile() ); WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(winDevice).chooseGraphicsConfiguration(capsChosen, - capsRequested, - chooser, winScreen); - + configFactory.chooseGraphicsConfiguration(capsChosen, + capsRequested, + chooser, winScreen); if (winConfig == null) { throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen); } - if(DEBUG) { - System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig); + GraphicsConfiguration chosenGC = null; + + // 1st Choice: Create an AWT GraphicsConfiguration with the desired PFD + // This gc will probably not be able to support GDI (WGL_SUPPORT_GDI_ARB, PFD_SUPPORT_GDI) + // however on most GPUs this is the current situation for Windows, + // otherwise no hardware accelerated PFD could be achieved. + // - preselect with no constrains + // - try to create dedicated GC + winConfig.preselectGraphicsConfiguration(drawableFactory, null); + if ( 1 <= winConfig.getPixelFormatID() ) { + chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID()); + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); + } + } + + if( null == chosenGC ) { + // 2nd Choice: Choose and match the GL Visual with AWT: + // - collect all AWT PFDs + // - choose a GL config from the pool of AWT PFDs + // + // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer, + // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify(). + // + + // collect all available PFD IDs + GraphicsConfiguration[] configs = device.getConfigurations(); + int[] pfdIDs = new int[configs.length]; + ArrayHashSet pfdIDOSet = new ArrayHashSet(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration gc = configs[i]; + pfdIDs[i] = Win32SunJDKReflection.graphicsConfigurationGetPixelFormatID(gc); + pfdIDOSet.add(new Integer(pfdIDs[i])); + if(DEBUG) { + System.err.println("AWT pfd["+i+"] "+pfdIDs[i]); + } + } + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: PFD IDs: "+pfdIDs.length+", unique: "+pfdIDOSet.size()); + } + winConfig.preselectGraphicsConfiguration(drawableFactory, pfdIDs); + int gcIdx = pfdIDOSet.indexOf(new Integer(winConfig.getPixelFormatID())); + if( 0 > gcIdx ) { + chosenGC = configs[gcIdx]; + if(DEBUG) { + System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found matching AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig); + } + } } - // We have nothing to match .. so choose the default + if ( null == chosenGC ) { + throw new GLException("Unable to determine GraphicsConfiguration: "+winConfig); + } return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(), - gc, winConfig); + chosenGC, winConfig); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java index 72698d759..1f2bf9344 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java @@ -35,7 +35,7 @@ import com.jogamp.nativewindow.impl.*; import com.jogamp.nativewindow.impl.x11.*; public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { - private static final int f_dim = 128; + private static final int f_dim = 64; private long dummyWindow = 0; /** diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java new file mode 100644 index 000000000..e3a1e7d72 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java @@ -0,0 +1,116 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import com.jogamp.nativewindow.impl.x11.XVisualInfo; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import java.util.Comparator; + +public class X11GLCapabilities extends GLCapabilities { + XVisualInfo xVisualInfo; + long fbcfg; + int fbcfgid; + + /** Comparing xvisual id only */ + public static class XVisualIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof X11GLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a X11GLCapabilities object: " + c); + } + if ( ! ( o2 instanceof X11GLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a X11GLCapabilities object: " + c); + } + + final X11GLCapabilities caps1 = (X11GLCapabilities) o1; + final long id1 = caps1.getXVisualID(); + + final X11GLCapabilities caps2 = (X11GLCapabilities) o2; + final long id2 = caps2.getXVisualID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, long fbcfg, int fbcfgid, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = fbcfg; + this.fbcfgid = fbcfgid; + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = 0; + this.fbcfgid = -1; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public XVisualInfo getXVisualInfo() { return xVisualInfo; } + final public long getXVisualID() { return xVisualInfo.getVisualid(); } + + final public long getFBConfig() { return fbcfg; } + final public int getFBConfigID() { return fbcfgid; } + final public boolean isFBConfig() { return 0!=fbcfg && fbcfgid>0; } + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + sink.append("0x").append(Long.toHexString(xVisualInfo.getVisualid())).append(" "); + if(isFBConfig()) { + sink.append("0x").append(Integer.toHexString(fbcfgid)); + } else { + sink.append("----"); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java index fddfb4cd1..dd25f241e 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -40,11 +40,14 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.util.VersionNumber; import java.nio.*; import java.util.*; + import javax.media.opengl.*; import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.X11GraphicsDevice; + +import com.jogamp.common.util.VersionNumber; import com.jogamp.opengl.impl.*; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -119,21 +122,23 @@ public abstract class X11GLXContext extends GLContextImpl { protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } - public final boolean isGLReadDrawableAvailable() { + public final boolean isGLXVersionGreaterEqualOneThree() { if(null == glXVersion) { X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); + X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice(); glXVersion = factory.getGLXVersion(device); - if( null != glXVersion ) { - glXVersionOneThreeCapable = glXVersion.compareTo(factory.versionOneThree)>=0; - } + glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false ; } return glXVersionOneThreeCapable; } + public final boolean isGLReadDrawableAvailable() { + return isGLXVersionGreaterEqualOneThree(); + } + private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { boolean res = false; @@ -173,18 +178,13 @@ public abstract class X11GLXContext extends GLContextImpl { } protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { - X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); - - X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); - X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device); - long display = device.getHandle(); - - GLXExt glXExt; - if(null==sharedContext) { - glXExt = getGLXExt(); - } else { - glXExt = sharedContext.getGLXExt(); + updateGLXProcAddressTable(); + GLXExt _glXExt = getGLXExt(); + if(DEBUG) { + System.err.println("X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") + + ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+ + ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB)); + Thread.dumpStack(); } boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; @@ -224,11 +224,15 @@ public abstract class X11GLXContext extends GLContextImpl { } } + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + long display = device.getHandle(); + try { // critical path, a remote display might not support this command, // hence we need to catch the X11 Error within this block. X11Util.XSync(display, false); - ctx = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); + ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); X11Util.XSync(display, false); } catch (RuntimeException re) { if(DEBUG) { @@ -247,7 +251,7 @@ public abstract class X11GLXContext extends GLContextImpl { ctx = 0; } else { if (DEBUG) { - System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext)); + System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct); } // the following is issued by the caller 'GLContextImpl.createContextARB()' // setGLFunctionAvailability(true, major, minor, ctp); @@ -458,21 +462,24 @@ public abstract class X11GLXContext extends GLContextImpl { // Should check for X errors and raise GLException } - protected final void updateGLXProcAddressTable(int major, int minor, int ctp) { + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); if (DEBUG) { - System.err.println(getThreadName() + ": !!! Initializing GLX extension address table"); + System.err.println(getThreadName() + ": !!! Initializing GLX extension address table: "+key); } glXQueryExtensionsStringInitialized = false; glXQueryExtensionsStringAvailable = false; GLXExtProcAddressTable table = null; synchronized(mappedContextTypeObjectLock) { - table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( contextFQN ); + table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( key ); } if(null != table) { glXExtProcAddressTable = table; if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode()); + System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+key+") -> "+table.hashCode()); } } else { if (glXExtProcAddressTable == null) { @@ -480,9 +487,10 @@ public abstract class X11GLXContext extends GLContextImpl { } resetProcAddressTable(getGLXExtProcAddressTable()); synchronized(mappedContextTypeObjectLock) { - mappedGLXProcAddress.put(contextFQN, getGLXExtProcAddressTable()); + mappedGLXProcAddress.put(key, getGLXExtProcAddressTable()); if(DEBUG) { - System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+contextFQN+") -> "+getGLXExtProcAddressTable().hashCode()); + System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+key+") -> "+getGLXExtProcAddressTable().hashCode()); + Thread.dumpStack(); } } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 3abbcee57..709e2ddab 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -37,7 +37,11 @@ package com.jogamp.opengl.impl.x11.glx; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; import java.nio.*; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; @@ -47,10 +51,6 @@ import com.jogamp.common.JogampRuntimeException; import com.jogamp.common.util.*; import com.jogamp.nativewindow.impl.ProxySurface; import com.jogamp.nativewindow.impl.x11.*; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { @@ -72,6 +72,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } } + public static VersionNumber getGLXVersion(X11GraphicsDevice device) { + int[] major = new int[1]; + int[] minor = new int[1]; + GLXUtil.getGLXVersion(device.getHandle(), major, minor); + return new VersionNumber(major[0], minor[0], 0); + } + public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { return x11GLXDynamicLookupHelper; } @@ -90,204 +97,22 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT); - // Init shared resources via own thread + // Init shared resources off thread // Will be released via ShutdownHook - sharedResourcesRunner = new SharedResourcesRunner(); - sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner"); - sharedResourcesThread.setDaemon(true); // Allow JVM to exit, even if this one is running - sharedResourcesThread.start(); + sharedResourceImpl = new SharedResourceImplementation(); + sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl); + sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner"); + sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running + sharedResourceThread.start(); } - class SharedResourcesRunner implements Runnable { - boolean ready = false; - boolean released = false; - boolean shouldRelease = false; - String initConnection = null; - SharedResource result = null; - - public final void initializeAndWait(String connection) { - // wait until thread becomes ready to init new device, - // pass the device and release the sync - String threadName = Thread.currentThread().getName(); - if (DEBUG) { - System.err.println(threadName+ " initializeAndWait START: "+connection); - } - synchronized (this) { - while (!ready) { - try { - this.wait(); - } catch (InterruptedException ex) { } - } - if (DEBUG) { - System.err.println(threadName+ " initializeAndWait set command: "+connection); - } - initConnection = connection; - this.notifyAll(); - - // wait until thread has initialized the device - while (!ready || null != initConnection) { - try { - this.wait(); - } catch (InterruptedException ex) { } - } - if (DEBUG) { - System.err.println(threadName+ " initializeAndWait done: "+connection); - } - } - // done - } - - public final void releaseAndWait() { - synchronized (this) { - shouldRelease = true; - this.notifyAll(); - - while (!released) { - try { - this.wait(); - } catch (InterruptedException ex) { - } - } - } - } - - public final void run() { - String threadName = Thread.currentThread().getName(); - - synchronized (this) { - if (DEBUG) { - System.err.println(threadName+ " STARTED -> ready"); - } - - while (!shouldRelease) { - try { - // wait for stop or init - ready = true; - this.wait(); - } catch (InterruptedException ex) { } - ready = false; - - if(!shouldRelease && null!=initConnection) { - if (DEBUG) { - System.err.println(threadName+ " create Shared for: "+initConnection); - } - SharedResource sr = createSharedResource(initConnection); - if(null!=sr) { - synchronized(sharedMap) { - sharedMap.put(initConnection, sr); - } - } - if (DEBUG) { - String msg = "Info: (" + threadName + ") initializedSharedResource for device connection: "+initConnection+" -> ready"; - System.err.println(msg); - Throwable t = new Throwable(msg); - t.printStackTrace(); - } - } - initConnection = null; - notifyAll(); - } - - if (DEBUG) { - System.err.println(threadName+ " release START"); - } - - releaseSharedResources(); - - if (DEBUG) { - System.err.println(threadName+ " release END"); - } - - released = true; - ready = false; - notifyAll(); - } - } - - private final SharedResource createSharedResource(String connection) { - X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT); - sharedDevice.setCloseDisplay(true); - sharedDevice.lock(); - try { - String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); - X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0); - X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, - GLProfile.getDefault(sharedDevice)); - if (null == sharedScreen || null == sharedDrawable) { - throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")"); - } - X11GLXContext sharedContext; - VersionNumber glXVersion; - try { - X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); - ctx.makeCurrent(); - { - int[] major = new int[1]; - int[] minor = new int[1]; - GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor); - glXVersion = new VersionNumber(major[0], minor[0], 0); - } - ctx.release(); - sharedContext = ctx; - } catch (Throwable t) { - throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t); - } - if (null == sharedContext) { - throw new GLException("X11GLXDrawableFactory - Shared Context is null"); - } - if (DEBUG) { - System.err.println("!!! SharedDevice: "+sharedDevice); - System.err.println("!!! SharedScreen: "+sharedScreen); - System.err.println("!!! SharedContext: "+sharedContext); - System.err.println("!!! GLX Vendor: "+glXVendorName); - System.err.println("!!! GLX Version: "+glXVersion + - " >= 1.3: " + ( glXVersion.compareTo(versionOneThree) >= 0 ) ); - } - return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName); - } finally { - sharedDevice.unlock(); - } - } - - private final void releaseSharedResources() { - Collection/*<SharedResource>*/ sharedResources = sharedMap.values(); - for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) { - SharedResource sr = (SharedResource) iter.next(); - - if (DEBUG) { - System.err.println("!!! Shutdown Shared:"); - System.err.println("!!! Device : "+sr.device); - System.err.println("!!! Screen : "+sr.screen); - System.err.println("!!! Drawable: "+sr.drawable); - System.err.println("!!! CTX : "+sr.context); - } - - if (null != sr.context) { - // may cause JVM SIGSEGV: sharedContext.destroy(); - sr.context = null; - } - - if (null != sr.drawable) { - // may cause JVM SIGSEGV: sharedDrawable.destroy(); - sr.drawable = null; - } - - if (null != sr.screen) { - sr.screen = null; - } - - if (null != sr.device) { - sr.device.close(); - sr.device=null; - } - } - sharedMap.clear(); - } - } - Thread sharedResourcesThread = null; - SharedResourcesRunner sharedResourcesRunner=null; + X11GraphicsDevice defaultDevice; + SharedResourceImplementation sharedResourceImpl; + SharedResourceRunner sharedResourceRunner; + Thread sharedResourceThread; + HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); - static class SharedResource { + static class SharedResource implements SharedResourceRunner.Resource { X11GraphicsDevice device; X11GraphicsScreen screen; X11DummyGLXDrawable drawable; @@ -297,7 +122,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { boolean isGLXVendorNVIDIA; VersionNumber glXVersion; - SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, + SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, X11DummyGLXDrawable draw, X11GLXContext ctx, VersionNumber glXVer, String glXVendor) { device = dev; @@ -309,16 +134,119 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName); isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName); } - X11GraphicsDevice getDevice() { return device; } - X11GraphicsScreen getScreen() { return screen; } - X11GLXContext getContext() { return context; } - String getGLXVendorName() { return glXVendorName; } - boolean isGLXVendorATI() { return isGLXVendorATI; } - boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } - VersionNumber getGLXVersion() { return glXVersion; } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } + + final String getGLXVendorName() { return glXVendorName; } + final boolean isGLXVendorATI() { return isGLXVendorATI; } + final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } + final VersionNumber getGLXVersion() { return glXVersion; } + final boolean isGLXVersionGreaterEqualOneThree() { + return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + } + } + + class SharedResourceImplementation implements SharedResourceRunner.Implementation { + public void clear() { + synchronized(sharedMap) { + sharedMap.clear(); + } + } + public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.put(connection, resource); + } + } + public SharedResourceRunner.Resource mapGet(String connection) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.get(connection); + } + } + public Collection/*<Resource>*/ mapValues() { + synchronized(sharedMap) { + return sharedMap.values(); + } + } + + public SharedResourceRunner.Resource createSharedResource(String connection) { + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT); + sharedDevice.setCloseDisplay(true); + sharedDevice.lock(); + try { + String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + if (null == sharedScreen) { + throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); + } + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); + if (null == glp) { + throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); + } + X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp); + if (null == sharedDrawable) { + throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp); + } + X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null); + if (null == sharedContext) { + throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); + } + sharedContext.setSynchronized(true); + VersionNumber glXVersion = getGLXVersion(sharedDevice); + boolean madeCurrent = false; + sharedContext.makeCurrent(); + try { + madeCurrent = sharedContext.isCurrent(); + } finally { + sharedContext.release(); + } + if (DEBUG) { + System.err.println("!!! SharedDevice: " + sharedDevice); + System.err.println("!!! SharedScreen: " + sharedScreen); + System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); + System.err.println("!!! GLX Vendor: " + glXVendorName); + System.err.println("!!! GLX Version: " + glXVersion + + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0)); + } + return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName); + } catch (Throwable t) { + throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); + } finally { + sharedDevice.unlock(); + } + } + + public void releaseSharedResource(SharedResourceRunner.Resource shared) { + SharedResource sr = (SharedResource) shared; + if (DEBUG) { + System.err.println("!!! Shutdown Shared:"); + System.err.println("!!! Device : " + sr.device); + System.err.println("!!! Screen : " + sr.screen); + System.err.println("!!! Drawable: " + sr.drawable); + System.err.println("!!! CTX : " + sr.context); + } + + if (null != sr.context) { + // may cause JVM SIGSEGV: sharedContext.destroy(); + sr.context = null; + } + + if (null != sr.drawable) { + // may cause JVM SIGSEGV: sharedDrawable.destroy(); + sr.drawable = null; + } + + if (null != sr.screen) { + sr.screen = null; + } + + if (null != sr.device) { + sr.device.close(); + sr.device = null; + } + } } - HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); - X11GraphicsDevice defaultDevice; public final AbstractGraphicsDevice getDefaultDevice() { return defaultDevice; @@ -331,44 +259,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return false; } - HashSet devicesTried = new HashSet(); - private final boolean getDeviceTried(String connection) { - synchronized(devicesTried) { - return devicesTried.contains(connection); - } - } - private final void addDeviceTried(String connection) { - synchronized(devicesTried) { - devicesTried.add(connection); - } - } - - private SharedResource getOrCreateShared(AbstractGraphicsDevice device) { - String connection = device.getConnection(); - SharedResource sr; - synchronized(sharedMap) { - sr = (SharedResource) sharedMap.get(connection); - } - - if(null==sr && !getDeviceTried(connection)) { - addDeviceTried(connection); - if (DEBUG) { - System.err.println("getOrCreateShared() "+connection+": trying"); - } - sharedResourcesRunner.initializeAndWait(connection); - synchronized(sharedMap) { - sr = (SharedResource) sharedMap.get(connection); - } - if(DEBUG) { - Throwable t = new Throwable("getOrCreateSharedl() "+connection+": done"); - t.printStackTrace(); - } - } - return sr; - } - protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return sr.getContext(); } @@ -376,7 +268,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return sr.getDevice(); } @@ -384,53 +276,53 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } protected final long getOrCreateSharedDpy(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { return sr.getDevice().getHandle(); } return 0; } - protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); - if(null!=sr) { - return sr.getGLXVersion(); - } - return null; + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); } - protected final String getGLXVendorName(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + public final String getGLXVendorName(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { - return sr.getGLXVendorName(); + return ((SharedResource)sr).getGLXVendorName(); } return GLXUtil.getVendorName(device.getHandle()); } - protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + public final boolean isGLXVendorATI(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { - return sr.isGLXVendorATI(); + return ((SharedResource)sr).isGLXVendorATI(); } return GLXUtil.isVendorATI(device.getHandle()); } - protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { - SharedResource sr = getOrCreateShared(device); + public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { - return sr.isGLXVendorNVIDIA(); + return ((SharedResource)sr).isGLXVendorNVIDIA(); } return GLXUtil.isVendorNVIDIA(device.getHandle()); } protected final void shutdownInstance() { - sharedResourcesRunner.releaseAndWait(); + sharedResourceRunner.releaseAndWait(); // Don't really close pending Display connections, // since this may trigger a JVM exception X11Util.shutdown( false, DEBUG ); } + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { if (target == null) { throw new IllegalArgumentException("Null target"); @@ -458,15 +350,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { * The dummy context shall also use the same Display, * since switching Display in this regard is another ATI bug. */ - SharedResource sr = getOrCreateShared(device); + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); if( null!=sr && sr.isGLXVendorATI() && null == GLContext.getCurrent() ) { - synchronized(sr.context) { - sr.context.makeCurrent(); - try { - pbufferDrawable = new X11PbufferGLXDrawable(this, target); - } finally { - sr.context.release(); - } + sr.getContext().makeCurrent(); + try { + pbufferDrawable = new X11PbufferGLXDrawable(this, target); + } finally { + sr.getContext().release(); } } else { pbufferDrawable = new X11PbufferGLXDrawable(this, target); @@ -474,19 +364,26 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return pbufferDrawable; } - public final boolean glXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { - VersionNumber glXVersion = getGLXVersion(device); - return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.isGLXVersionGreaterEqualOneThree(); + } + if( device instanceof X11GraphicsDevice ) { + VersionNumber v = getGLXVersion( (X11GraphicsDevice) device); + return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ; + } + return false; } public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { if(null == device) { - SharedResource sr = getOrCreateShared(defaultDevice); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(defaultDevice); if(null!=sr) { device = sr.getDevice(); } } - return glXVersionGreaterEqualOneThree(device); + return isGLXVersionGreaterEqualOneThree(device); } protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, @@ -494,9 +391,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { GLCapabilitiesChooser chooser, int width, int height) { X11GraphicsScreen screen = null; - SharedResource sr = getOrCreateShared(device); + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); if(null!=sr) { - screen = sr.getScreen(); + screen = (X11GraphicsScreen) sr.getScreen(); } if(null==screen) { return null; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index 3dbaab21b..f7779ab28 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -33,10 +33,13 @@ package com.jogamp.opengl.impl.x11.glx; -import com.jogamp.common.nio.PointerBuffer; +import java.util.ArrayList; + import javax.media.nativewindow.*; import javax.media.nativewindow.x11.*; import javax.media.opengl.*; + +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.x11.*; @@ -44,17 +47,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public static final int MAX_ATTRIBS = 128; - private long fbConfig; - private int fbConfigID; private GLCapabilitiesChooser chooser; X11GLXGraphicsConfiguration(X11GraphicsScreen screen, - GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, - XVisualInfo info, long fbcfg, int fbcfgID) { - super(screen, capsChosen, capsRequested, info); + X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + super(screen, capsChosen, capsRequested, capsChosen.getXVisualInfo()); this.chooser=chooser; - fbConfig = fbcfg; - fbConfigID = fbcfgID; } static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) { @@ -70,23 +68,23 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if(null==glp) { glp = GLProfile.getDefault(x11Screen.getDevice()); } - GLCapabilitiesImmutable caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); if(null==caps) { throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); } - XVisualInfo xvi = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if(null==xvi) { - throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); - } - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } public Object clone() { return super.clone(); } - public long getFBConfig() { return fbConfig; } - public int getFBConfigID() { return fbConfigID; } + public final long getFBConfig() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfig(); + } + public final int getFBConfigID() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfigID(); + } void updateGraphicsConfiguration() { X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration) @@ -96,8 +94,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem // FIXME: setScreen( ... ); setXVisualInfo(newConfig.getXVisualInfo()); setChosenCapabilities(newConfig.getChosenCapabilities()); - fbConfig = newConfig.getFBConfig(); - fbConfigID = newConfig.getFBConfigID(); if(DEBUG) { System.err.println("!!! updateGraphicsConfiguration: "+this); } @@ -220,49 +216,63 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return true; } - static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { - boolean res; + static int FBCfgDrawableTypeBits(final long display, final long fbcfg) { + int val = 0; - if ( onscreen ) { - res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; - } else { - if ( usePBuffer ) { - res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; - } else { - res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ; - } - } + int[] tmp = new int[1]; + int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - return res; + if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + return val; } - static GLCapabilitiesImmutable GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleAvailable) { - int[] tmp = new int[1]; - int val; - val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); - if (val != GLX.GLX_RGBA_BIT) { - if(DEBUG) { - System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val)); - } - return null; + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); + } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); } - GLCapabilities res = new GLCapabilities(glp); - - val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); - if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) { - res.setOnscreen(onscreen); - res.setPBuffer(usePBuffer); - } else if(relaxed) { - res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); - res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); - } else { + return null; + } + + static boolean GLXFBConfig2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, long fbcfg, + int winattrmask, boolean isMultisampleAvailable) { + final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg); + int drawableTypeBits = winattrmask & allDrawableTypeBits; + + int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); + if(null == visualInfo) { if(DEBUG) { - System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")"); + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid)); } - return null; + // onscreen must have an XVisualInfo + drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT; } + + if( 0 == drawableTypeBits ) { + return false; + } + + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + + GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG); @@ -297,7 +307,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem try { res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); } catch (Exception e) {} - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); } private static String glXGetFBConfigErrorCode(int err) { @@ -352,26 +363,34 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return res; } - static GLCapabilitiesImmutable XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, - boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { + static boolean XVisualInfo2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, XVisualInfo info, + final int winattrmask, boolean isMultisampleEnabled) { + final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ; + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL"); } - return null; + return false; } val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); if (val == 0) { if(DEBUG) { System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA"); } - return null; + return false; } - GLCapabilities res = new GLCapabilities(glp); - res.setOnscreen (onscreen); - res.setPBuffer (usePBuffer); + + GLCapabilities res = new X11GLCapabilities(info, glp); + res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0); // Note: use of hardware acceleration is determined by @@ -393,7 +412,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); } - return res; + + return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits); } private static String glXGetConfigErrorCode(int err) { @@ -417,16 +437,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return tmp[tmp_offset]; } - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } - - static String toHexString(long val) { - return "0x"+Long.toHexString(val); - } - public String toString() { - return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) + + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(getFBConfigID()) + ",\n\trequested " + getRequestedCapabilities()+ ",\n\tchosen " + getChosenCapabilities()+ "]"; diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 327ecd0be..b391dc948 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -39,12 +39,13 @@ import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.x11.X11GraphicsScreen; +import javax.media.nativewindow.x11.X11GraphicsDevice; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; @@ -53,6 +54,12 @@ import com.jogamp.nativewindow.impl.x11.X11Lib; import com.jogamp.nativewindow.impl.x11.X11Util; import com.jogamp.nativewindow.impl.x11.XVisualInfo; import com.jogamp.opengl.impl.Debug; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits @@ -60,8 +67,9 @@ import com.jogamp.opengl.impl.Debug; to this one to change the accepted and returned types of the GraphicsDevice and GraphicsConfiguration abstractions. */ -public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator(); X11GLXGraphicsConfigurationFactory() { GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); @@ -88,6 +96,86 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen); } + protected static List/*<X11GLCapabilities>*/ getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) { + X11GLXDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); + X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + GLProfile glp = capsChosen.getGLProfile(); + + List/*GLCapabilitiesImmutable*/ availableCaps = null; + + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp); + } + if( null != availableCaps ) { + Collections.sort(availableCaps, XVisualIDComparator); + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) { + PointerBuffer fbcfgsL = null; + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] count = { -1 }; + ArrayList availableCaps = new ArrayList(); + + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) { + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + ArrayList availableCaps = new ArrayList(); + for (int i = 0; i < infos.length; i++) { + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } + } + return availableCaps; + } + + static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser, @@ -99,18 +187,16 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac if (capsChosen == null) { capsChosen = new GLCapabilities(null); } + X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice(); + X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); - if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) { - // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN - GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable(); - caps2.setDoubleBuffered(false); - capsChosen = caps2; - } - + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) ); boolean usePBuffer = capsChosen.isPBuffer(); - X11GLXGraphicsConfiguration res; - res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + X11GLXGraphicsConfiguration res = null; + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + } if(null==res) { if(usePBuffer) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen); @@ -138,14 +224,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } return null; } - XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); - if (visualInfo==null) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+toHexString(fbcfg)+")"); - return null; - } - GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); - return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), visualInfo, fbcfg, fbID); - + X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen, @@ -154,10 +234,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac X11GraphicsScreen x11Screen) { long recommendedFBConfig = -1; int recommendedIndex = -1; - int retFBID=-1; - GLCapabilitiesImmutable[] availableCaps = null; PointerBuffer fbcfgsL = null; - XVisualInfo retXVisualInfo = null; GLProfile glProfile = capsChosen.getGLProfile(); boolean onscreen = capsChosen.isOnscreen(); boolean usePBuffer = capsChosen.isPBuffer(); @@ -171,39 +248,39 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); int[] count = { -1 }; + ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); if (fbcfgsL != null && fbcfgsL.limit()>0) { - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } - if(availableCaps[0]!=null) { + if(availableCaps.size() > 0) { recommendedFBConfig = fbcfgsL.get(0); recommendedIndex=0; if (DEBUG) { System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex); System.err.println("!!! user caps " + capsChosen); - System.err.println("!!! fbcfg caps " + availableCaps[recommendedIndex]); - } - } else { - if (DEBUG) { - System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(recommendedFBConfig)); - System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); } + } else if (DEBUG) { + System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); + System.err.println("!!! user caps " + capsChosen); } } // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available - if(null == availableCaps) { + if( 0 == availableCaps.size() ) { + // reset .. + recommendedFBConfig = -1; + recommendedIndex = -1; + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<=0) { if(DEBUG) { @@ -212,78 +289,24 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac return null; } - availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { if(DEBUG) { System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); } - } else { - availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), - false, onscreen, usePBuffer, isMultisampleAvailable); } } } - - if( recommendedIndex < 1 && null==chooser) { - chooser = new DefaultGLCapabilitiesChooser(); - } - - int chosenIndex = recommendedIndex; - try { - if(null != chooser) { - chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex); - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig chooser: idx "+chosenIndex); - System.err.println("!!! user caps " + capsChosen); - System.err.println("!!! chosen caps " + availableCaps[chosenIndex]); - } - } - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - } - - if (chosenIndex < 0) { - // keep on going .. - // seek first available one .. - for(chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex]==null; chosenIndex++) { - // nop - } - if(chosenIndex==availableCaps.length) { - // give up .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); - } - return null; - } - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first available idx: "+chosenIndex); - System.err.println("!!! user caps " + capsChosen); - System.err.println("!!! fallback caps " + availableCaps[chosenIndex]); - } - } else if (chosenIndex >= availableCaps.length) { - if(DEBUG) { - System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (availableCaps.length - 1) + ", got "+chosenIndex+")"); + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); } return null; } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex)); - - retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex)); - if (retXVisualInfo==null) { - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosenIndex) +" (Continue: "+(false==availableCaps[chosenIndex].isOnscreen())+"):\n\t"+availableCaps[chosenIndex]); - } - if(availableCaps[chosenIndex].isOnscreen()) { - // Onscreen drawables shall have a XVisual .. - return null; - } - } - - return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosenIndex), retFBID); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen, @@ -294,16 +317,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac chooser = new DefaultGLCapabilitiesChooser(); } - // Until we have a rock-solid visual selection algorithm written - // in pure Java, we're going to provide the underlying window - // system's selection to the chooser as a hint - GLProfile glProfile = capsChosen.getGLProfile(); - boolean onscreen = capsChosen.isOnscreen(); - GLCapabilitiesImmutable[] caps = null; + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */); + ArrayList availableCaps = new ArrayList(); int recommendedIndex = -1; - XVisualInfo retXVisualInfo = null; - int chosen=-1; AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); @@ -311,8 +328,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int screen = x11Screen.getIndex(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen); - XVisualInfo[] infos = null; + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); if (DEBUG) { System.err.print("!!! glXChooseVisual recommended "); @@ -322,51 +339,39 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); } } + + // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available if 1st choice was successful int[] count = new int[1]; XVisualInfo template = XVisualInfo.create(); template.setScreen(screen); - infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null || infos.length<1) { throw new GLException("Error while enumerating available XVisualInfos"); } - caps = new GLCapabilitiesImmutable[infos.length]; + for (int i = 0; i < infos.length; i++) { - caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); - // Attempt to find the visual chosenIndex by glXChooseVisual - if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { - recommendedIndex = i; + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } else { + // Attempt to find the visual chosenIndex by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = availableCaps.size() - 1; + } } } - try { - chosen = chooser.chooseCapabilities(capsChosen, caps, recommendedIndex); - } catch (NativeWindowException e) { - if(DEBUG) { - e.printStackTrace(); - } - chosen = -1; - } - if (chosen < 0) { - // keep on going .. - if(DEBUG) { - System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); - } - chosen = 0; // default .. - } else if (chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - if (infos[chosen] == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); - } - retXVisualInfo = XVisualInfo.create(infos[chosen]); - return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capsReq, chooser, retXVisualInfo, 0, -1); - } - static String toHexString(int val) { - return "0x"+Integer.toHexString(val); - } + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); - static String toHexString(long val) { - return "0x"+Long.toHexString(val); + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java index 0fbe7a1c9..898a8a658 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -43,10 +43,8 @@ import javax.media.opengl.*; import com.jogamp.opengl.impl.*; import com.jogamp.nativewindow.impl.jawt.x11.*; import com.jogamp.nativewindow.impl.x11.*; -import com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory; -import java.awt.image.ColorModel; -public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { +public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); public X11AWTGLXGraphicsConfigurationFactory() { @@ -91,11 +89,11 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration displayHandle = X11Util.createDisplay(null); owner = true; if(DEBUG) { - System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); + System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); } } else { if(DEBUG) { - System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); + System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); } /** * May cause an exception on NVidia X11 Display destruction, @@ -153,15 +151,13 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration visualID = x11Config.getVisualID(); for (int i = 0; i < configs.length; i++) { gc = configs[i]; - if (gc != null) { - if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { - if(DEBUG) { - System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); - } - return new AWTGraphicsConfiguration(awtScreen, - x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), - gc, x11Config); + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { + if(DEBUG) { + System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); } + return new AWTGraphicsConfiguration(awtScreen, + x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + gc, x11Config); } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java index f22e11cb7..6073a75f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -43,11 +44,9 @@ import com.jogamp.opengl.impl.Debug; import com.jogamp.opengl.util.*; import com.jogamp.opengl.util.packrect.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.awt.*; import java.awt.AlphaComposite; import java.awt.Color; -import java.awt.Composite; // For debugging purposes import java.awt.EventQueue; @@ -71,7 +70,6 @@ import java.security.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; -import javax.media.opengl.glu.gl2.*; import javax.media.opengl.awt.*; @@ -720,7 +718,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1236,7 +1234,7 @@ public class TextRenderer { // The OpenGL spec is unclear about whether this changes the // buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER // binding - if (is15Available(gl)) { + if (getUseVertexArrays() && is15Available(gl)) { try { gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); } catch (Exception e) { @@ -1558,6 +1556,8 @@ public class TextRenderer { final int undefined = -2; FontRenderContext fontRenderContext; List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/(); + HashMap/*<String, GlyphVector>*/fullGlyphVectorCache = new HashMap/*<String, GlyphVector>*/(); + HashMap/*<Character, GlyphMetrics>*/glyphMetricsCache = new HashMap/*<Character, GlyphMetrics>*/(); // The mapping from unicode character to font-specific glyph ID int[] unicodes2Glyphs; // The mapping from glyph ID to Glyph @@ -1573,8 +1573,13 @@ public class TextRenderer { public List/*<Glyph>*/ getGlyphs(CharSequence inString) { glyphsOutput.clear(); - iter.initFromCharSequence(inString); - GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + GlyphVector fullRunGlyphVector; + fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString()); + if (fullRunGlyphVector == null) { + iter.initFromCharSequence(inString); + fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + fullGlyphVectorCache.put(inString.toString(), fullRunGlyphVector); + } boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0); if (complex || DISABLE_GLYPH_CACHE) { // Punt to the robust version of the renderer @@ -1585,7 +1590,13 @@ public class TextRenderer { int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs(); int i = 0; while (i < lengthInGlyphs) { - Glyph glyph = getGlyph(inString, fullRunGlyphVector, i); + Character letter = CharacterCache.valueOf(inString.charAt(i)); + GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter); + if (metrics == null) { + metrics = fullRunGlyphVector.getGlyphMetrics(i); + glyphMetricsCache.put(letter, metrics); + } + Glyph glyph = getGlyph(inString, metrics, i); if (glyph != null) { glyphsOutput.add(glyph); i++; @@ -1594,7 +1605,7 @@ public class TextRenderer { // the cache StringBuffer buf = new StringBuffer(); while (i < lengthInGlyphs && - getGlyph(inString, fullRunGlyphVector, i) == null) { + getGlyph(inString, fullRunGlyphVector.getGlyphMetrics(i), i) == null) { buf.append(inString.charAt(i++)); } glyphsOutput.add(new Glyph(buf.toString(), @@ -1645,7 +1656,7 @@ public class TextRenderer { // if the unicode or glyph ID would be out of bounds of the // glyph cache. private Glyph getGlyph(CharSequence inString, - GlyphVector fullRunGlyphVector, + GlyphMetrics glyphMetrics, int index) { char unicodeID = inString.charAt(index); @@ -1661,7 +1672,7 @@ public class TextRenderer { // Must fabricate the glyph singleUnicode[0] = unicodeID; GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode); - return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index)); + return getGlyph(unicodeID, gv, glyphMetrics); } // It's unclear whether this variant might produce less @@ -1698,6 +1709,26 @@ public class TextRenderer { return glyph; } } + + private static class CharacterCache { + private CharacterCache() { + } + + static final Character cache[] = new Character[127 + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new Character((char) i); + } + } + + public static Character valueOf(char c) { + if (c <= 127) { // must cache + return CharacterCache.cache[c]; + } + return new Character(c); + } + } class Pipelined_QuadRenderer { int mOutstandingGlyphsVerticesPipeline = 0; @@ -1712,7 +1743,7 @@ public class TextRenderer { mVertCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsVerts); mTexCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsTex); - usingVBOs = is15Available(gl); + usingVBOs = getUseVertexArrays() && is15Available(gl); if (usingVBOs) { try { @@ -1918,7 +1949,7 @@ public class TextRenderer { * rendering, or whether text is rendered using the OpenGL * immediate mode commands. Defaults to true. */ - public boolean getUseVertexArrays() { + public final boolean getUseVertexArrays() { return useVertexArrays; } @@ -1943,7 +1974,7 @@ public class TextRenderer { return smoothing; } - private boolean is15Available(GL gl) { + private final boolean is15Available(GL gl) { if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) { isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5"); checkFor_isExtensionAvailable_GL_VERSION_1_5 = true; diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java index bc5aa517e..86dca59f4 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -47,10 +48,8 @@ import java.awt.Rectangle; import java.awt.image.*; import javax.media.opengl.*; -import javax.media.opengl.glu.*; import javax.media.opengl.glu.gl2.*; import com.jogamp.opengl.util.texture.*; -import com.jogamp.opengl.util.texture.spi.*; import com.jogamp.opengl.util.texture.awt.*; /** Provides the ability to render into an OpenGL {@link diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java index 695fad5a9..ecba18147 100644 --- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java +++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java @@ -42,6 +42,7 @@ package javax.media.opengl; import javax.media.nativewindow.NativeWindowException; import com.jogamp.opengl.impl.Debug; +import java.util.List; import javax.media.nativewindow.CapabilitiesImmutable; /** <P> The default implementation of the {@link @@ -85,38 +86,40 @@ import javax.media.nativewindow.CapabilitiesImmutable; public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { private static final boolean DEBUG = Debug.debug("CapabilitiesChooser"); - public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, - int windowSystemRecommendedChoice) { - GLCapabilitiesImmutable _desired = (GLCapabilitiesImmutable) desired; - GLCapabilitiesImmutable[] _available = (GLCapabilitiesImmutable[]) available; - int availnum = 0; - - for (int i = 0; i < _available.length; i++) { - if(null != _available[i]) { availnum++; } + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { + if ( null == desired ) { + throw new NativeWindowException("Null desired capabilities"); + } + if ( 0 == available.size() ) { + throw new NativeWindowException("Empty available capabilities"); } + final GLCapabilitiesImmutable gldes = (GLCapabilitiesImmutable) desired; + final int availnum = available.size(); + if (DEBUG) { - System.err.println("Desired: " + _desired); - System.err.println("Available: Valid " + availnum + "/" + _available.length); - for (int i = 0; i < _available.length; i++) { - System.err.println(i + ": " + _available[i]); + System.err.println("Desired: " + gldes); + System.err.println("Available: " + availnum); + for (int i = 0; i < available.size(); i++) { + System.err.println(i + ": " + available.get(i)); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } if (windowSystemRecommendedChoice >= 0 && - windowSystemRecommendedChoice < _available.length && - _available[windowSystemRecommendedChoice] != null) { + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { if (DEBUG) { System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); - System.err.println(_available[windowSystemRecommendedChoice]); + System.err.println(available.get(windowSystemRecommendedChoice)); } return windowSystemRecommendedChoice; } // Create score array - int[] scores = new int[_available.length]; + int[] scores = new int[availnum]; int NO_SCORE = -9999999; int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000; int STENCIL_MISMATCH_PENALTY = 500; @@ -131,18 +134,18 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { scores[i] = NO_SCORE; } // Compute score for each - for (int i = 0; i < scores.length; i++) { - GLCapabilitiesImmutable cur = _available[i]; + for (int i = 0; i < availnum; i++) { + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur == null) { continue; } - if (_desired.isOnscreen() != cur.isOnscreen()) { + if (gldes.isOnscreen() != cur.isOnscreen()) { continue; } - if (!_desired.isOnscreen() && _desired.isPBuffer() && !cur.isPBuffer()) { + if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) { continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available } - if (_desired.getStereo() != cur.getStereo()) { + if (gldes.getStereo() != cur.getStereo()) { continue; } int score = 0; @@ -150,20 +153,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // (Note that this decides the direction of all other penalties) score += (COLOR_MISMATCH_PENALTY_SCALE * ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) - - (_desired.getRedBits() + _desired.getGreenBits() + _desired.getBlueBits() + _desired.getAlphaBits()))); + (gldes.getRedBits() + gldes.getGreenBits() + gldes.getBlueBits() + gldes.getAlphaBits()))); // Compute difference in depth buffer depth score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) * - Math.abs(cur.getDepthBits() - _desired.getDepthBits())); + Math.abs(cur.getDepthBits() - gldes.getDepthBits())); // Compute difference in accumulation buffer depth score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) * Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) - - (_desired.getAccumRedBits() + _desired.getAccumGreenBits() + _desired.getAccumBlueBits() + _desired.getAccumAlphaBits()))); + (gldes.getAccumRedBits() + gldes.getAccumGreenBits() + gldes.getAccumBlueBits() + gldes.getAccumAlphaBits()))); // Compute difference in stencil bits - score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - _desired.getStencilBits()); - if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) { + score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - gldes.getStencilBits()); + if (cur.getDoubleBuffered() != gldes.getDoubleBuffered()) { score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY; } - if ((_desired.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { + if ((gldes.getStencilBits() > 0) && (cur.getStencilBits() == 0)) { score += sign(score) * STENCIL_MISMATCH_PENALTY; } scores[i] = score; @@ -172,12 +175,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // non-hardware-accelerated visuals out boolean gotHW = false; int maxAbsoluteHWScore = 0; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (cur.getHardwareAccelerated()) { int absScore = Math.abs(score); if (!gotHW || @@ -188,12 +191,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } } if (gotHW) { - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; } - GLCapabilitiesImmutable cur = _available[i]; + GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i); if (!cur.getHardwareAccelerated()) { if (score <= 0) { score -= maxAbsoluteHWScore; @@ -207,7 +210,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.print("Scores: ["); - for (int i = 0; i < _available.length; i++) { + for (int i = 0; i < availnum; i++) { if (i > 0) { System.err.print(","); } @@ -219,7 +222,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { // Ready to select. Choose score closest to 0. int scoreClosestToZero = NO_SCORE; int chosenIndex = -1; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; @@ -238,7 +241,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (DEBUG) { System.err.println("Chosen index: " + chosenIndex); System.err.println("Chosen capabilities:"); - System.err.println(_available[chosenIndex]); + System.err.println(available.get(chosenIndex)); } return chosenIndex; @@ -250,4 +253,5 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { } return 1; } + } diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 82f83dc82..1ae9e40aa 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -143,6 +143,56 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return res; } + /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */ + public int compareTo(Object o) { + if ( ! ( o instanceof GLCapabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a GLCapabilities object: " + c); + } + + final GLCapabilities caps = (GLCapabilities) o; + + if(hardwareAccelerated && !caps.hardwareAccelerated) { + return 1; + } else if(!hardwareAccelerated && caps.hardwareAccelerated) { + return -1; + } + + if(stereo && !caps.stereo) { + return 1; + } else if(!stereo && caps.stereo) { + return -1; + } + + final int ms = sampleBuffers ? numSamples : 0; + final int xms = caps.sampleBuffers ? caps.numSamples : 0; + + if(ms > xms) { + return 1; + } else if( ms < xms ) { + return -1; + } + + if(stencilBits > caps.stencilBits) { + return 1; + } else if(stencilBits < caps.stencilBits) { + return -1; + } + + final int sc = super.compareTo(caps); // RGBA + if(0 != sc) { + return sc; + } + + if(depthBits > caps.depthBits) { + return 1; + } else if(depthBits < caps.depthBits) { + return -1; + } + + return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth + } + /** Returns the GL profile you desire or used by the drawable. */ public GLProfile getGLProfile() { return glProfile; @@ -158,11 +208,30 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbuffer; } - /** Enables or disables pbuffer usage. */ + /** + * Enables or disables pbuffer usage.<br> + * If enabled, onscreen := false. + * Defaults to false. + */ public void setPBuffer(boolean onOrOff) { + if(onOrOff) { + setOnscreen(false); + } pbuffer = onOrOff; } + /** + * Sets whether the drawable surface supports onscreen.<br> + * If enabled, pbuffer := false.<br> + * Defaults to true. + */ + public void setOnscreen(boolean onscreen) { + if(onscreen) { + setPBuffer(false); + } + super.setOnscreen(onscreen); + } + /** Indicates whether double-buffering is enabled. */ public boolean getDoubleBuffered() { return doubleBuffered; @@ -340,28 +409,54 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil return pbufferRenderToTextureRectangle; } + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + + int samples = sampleBuffers ? numSamples : 0 ; + + super.toString(sink); + + sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits); + sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples); + if(doubleBuffered) { + sink.append(", dbl"); + } else { + sink.append(", one"); + } + if(stereo) { + sink.append(", stereo"); + } else { + sink.append(", mono "); + } + if(hardwareAccelerated) { + sink.append(", hw, "); + } else { + sink.append(", sw, "); + } + sink.append(glProfile); + if(!isOnscreen()) { + if(pbuffer) { + sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0) + .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0) + .append(", float ").append(pbufferFloatingPointBuffers?1:0) + .append("]"); + } else { + sink.append(", pixmap"); + } + } + + return sink; + } + /** Returns a textual representation of this GLCapabilities object. */ public String toString() { StringBuffer msg = new StringBuffer(); - msg.append("GLCapabilities["); - msg.append(super.toString()); - msg.append(", GL profile: " + glProfile + - ", PBuffer: " + pbuffer + - ", DoubleBuffered: " + doubleBuffered + - ", Stereo: " + stereo + - ", HardwareAccelerated: " + hardwareAccelerated + - ", DepthBits: " + depthBits + - ", StencilBits: " + stencilBits + - ", Red Accum: " + accumRedBits + - ", Green Accum: " + accumGreenBits + - ", Blue Accum: " + accumBlueBits + - ", Alpha Accum: " + accumAlphaBits + - ", Multisample: " + sampleBuffers + - ", Num samples: "+(sampleBuffers ? numSamples : 0)); - msg.append(", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+ - ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+ - ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ "]"); + msg.append("GLCaps["); + toString(msg); + msg.append("]"); return msg.toString(); } } diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index 72073deef..4c9b737d5 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -40,10 +40,10 @@ package javax.media.opengl; -import com.jogamp.opengl.impl.Debug; import java.util.HashMap; import java.util.HashSet; import javax.media.nativewindow.AbstractGraphicsDevice; +import com.jogamp.opengl.impl.Debug; /** Abstraction for an OpenGL rendering context. In order to perform OpenGL rendering, a context must be "made current" on the current @@ -579,10 +579,6 @@ public abstract class GLContext { */ private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet(); - protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) { - return device.getUniqueID() + "-" + toHexString(compose8bit(major, minor, ctp, 0)); - } - protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) { return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0)); } diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index f9591e84d..500173cf2 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -40,14 +40,14 @@ package javax.media.opengl; -import com.jogamp.common.JogampRuntimeException; -import com.jogamp.common.impl.Debug; -import com.jogamp.common.util.ReflectionUtil; - import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; -import java.util.HashSet; +import java.util.List; + +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.impl.Debug; +import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; @@ -221,6 +221,9 @@ public abstract class GLDrawableFactory { } } + protected void enterThreadCriticalZone() {}; + protected void leaveThreadCriticalZone() {}; + protected abstract void shutdownInstance(); /** @@ -237,6 +240,24 @@ public abstract class GLDrawableFactory { */ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device); + protected final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device) { + if(null==device) { + device = getDefaultDevice(); + if(null==device) { + throw new InternalError("no default device"); + } + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: using default device : "+device); + } + } else if( !getIsDeviceCompatible(device) ) { + if (GLProfile.DEBUG) { + System.err.println("Info: GLDrawableFactory.validateDevice: device not compatible : "+device); + } + return null; + } + return device; + } + /** * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}, * or if a new shared context could be created and mapped. Otherwise return false.<br> @@ -256,24 +277,28 @@ public abstract class GLDrawableFactory { * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. */ protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) { - if(null==device) { - device = getDefaultDevice(); - if(null==device) { - throw new InternalError("no default device"); - } - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device); - } - } else if( !getIsDeviceCompatible(device) ) { - if (GLProfile.DEBUG) { - System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device); - } - return null; + device = validateDevice(device); + if(null!=device) { + return getOrCreateSharedContextImpl(device); } - return getOrCreateSharedContextImpl(device); + return null; } protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device); + /** + * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null + */ + public static GLDrawableFactory getDesktopFactory() { + return nativeOSFactory; + } + + /** + * Returns the sole GLDrawableFactory instance for EGL if exist or null + */ + public static GLDrawableFactory getEGLFactory() { + return eglFactory; + } + /** * Returns the sole GLDrawableFactory instance. * @@ -298,6 +323,34 @@ public abstract class GLDrawableFactory { throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+glProfileImplName); } + protected static GLDrawableFactory getFactoryImpl(AbstractGraphicsDevice device) throws GLException { + if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) { + return nativeOSFactory; + } + if(null != eglFactory && eglFactory.getIsDeviceCompatible(device)) { + return eglFactory; + } + throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device); + } + + /** + * Returns an array of available GLCapabilities for the device.<br> + * The list is sorted by the native ID, ascending.<br> + * The chosen GLProfile statement in the result may not refer to the maximum available profile + * due to implementation constraints, ie using the shared resource. + * + * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. + * @return A list of {@link javax.media.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available. + */ + public final List/*GLCapabilitiesImmutable*/ getAvailableCapabilities(AbstractGraphicsDevice device) { + device = validateDevice(device); + if(null!=device) { + return getAvailableCapabilitiesImpl(device); + } + return null; + } + protected abstract List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device); + //---------------------------------------------------------------------- // Methods to create high-level objects diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index c7b1e80cf..10d92b050 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -47,12 +47,13 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl; import com.jogamp.opengl.impl.GLDynamicLookupHelper; import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper; import com.jogamp.opengl.JoglVersion; -import java.util.HashMap; -import java.util.Iterator; -import java.security.*; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.opengl.fixedfunc.GLPointerFunc; import javax.media.nativewindow.NativeWindowFactory; +import java.util.HashMap; +import java.util.Iterator; +import java.security.*; +import java.util.List; /** * Specifies the the OpenGL profile. @@ -70,8 +71,13 @@ public class GLProfile { /** * Static one time initialization of JOGL. * <p> + * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br> + * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}. + * </p> + * <p> * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br> - * You may issue the call in your main function.<br> + * You may issue the call in your <code>main class</code> static block, which is the earliest point in your application/applet lifecycle, + * or within the <code>main function</code>.<br> * In case applications are able to initialize JOGL before any other UI action,<br> * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P> * <P> @@ -341,17 +347,35 @@ public class GLProfile { /** * All GL Profiles in the order of default detection. - * Desktop compatibility profiles (the one with fixed function pipeline) comes first. - * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! + * Desktop compatibility profiles (the one with fixed function pipeline) comes first + * from highest to lowest version. * * <ul> - * <li> GL2 - * <li> GL3bc * <li> GL4bc + * <li> GL3bc + * <li> GL2 * <li> GL2GL3 + * <li> GL4 * <li> GL3 + * <li> GL2ES2 + * <li> GLES2 + * <li> GL2ES1 + * <li> GLES1 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL2GL3, GL4, GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of maximum profiles. + * + * <ul> + * <li> GL4bc * <li> GL4 + * <li> GL3bc + * <li> GL3 + * <li> GL2 + * <li> GL2GL3 * <li> GL2ES2 * <li> GLES2 * <li> GL2ES1 @@ -359,7 +383,21 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL3bc, GL4bc, GL2GL3, GL3, GL4, GL2ES2, GLES2, GL2ES1, GLES1 }; + public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2, GL2ES1, GLES1 }; + + /** + * Order of minimum original desktop profiles. + * + * <ul> + * <li> GL2 + * <li> GL3bc + * <li> GL4bc + * <li> GL3 + * <li> GL4 + * </ul> + * + */ + public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 }; /** * Order of maximum fixed function profiles @@ -389,13 +427,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4, GL4bc, GL3, GL3bc, GL2, GL2ES2, GLES2 }; + public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2ES2, GLES2 }; /** * All GL2ES2 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES2 * <li> GL2 @@ -405,13 +441,11 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GL3, GL4, GLES2 }; + public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL4, GL3, GL2, GLES2 }; /** * All GL2ES1 Profiles in the order of default detection. * - * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available! - * * <ul> * <li> GL2ES1 * <li> GL2 @@ -421,7 +455,7 @@ public class GLProfile { * </ul> * */ - public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, GL3bc, GL4bc, GLES1 }; + public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL4bc, GL3bc, GL2, GLES1 }; /** * All GLES Profiles in the order of default detection. @@ -449,7 +483,48 @@ public class GLProfile { } /** - * Returns the highest profile, implementing the fixed function pipeline + * Returns the highest profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MAX + */ + public static GLProfile getMaximum(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MAX); + } + + /** Uses the default device */ + public static GLProfile getMaximum() + throws GLException + { + return get(GL_PROFILE_LIST_MAX); + } + + /** + * Returns the lowest desktop profile. + * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN_DESKTOP} + * + * @throws GLException if no implementation for the given profile is found. + * @see #GL_PROFILE_LIST_MIN_DESKTOP + */ + public static GLProfile getMinDesktop(AbstractGraphicsDevice device) + throws GLException + { + return get(device, GL_PROFILE_LIST_MIN_DESKTOP); + } + + /** Uses the default device */ + public static GLProfile getMinDesktop() + throws GLException + { + return get(GL_PROFILE_LIST_MIN_DESKTOP); + } + + + /** + * Returns the highest profile, implementing the fixed function pipeline. * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC} * * @throws GLException if no implementation for the given profile is found. @@ -1082,6 +1157,7 @@ public class GLProfile { * Throws an GLException if no profile could be found at all. */ private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) { + NativeWindowFactory.initSingleton(firstUIActionOnProcess); if(DEBUG) { System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess @@ -1092,8 +1168,6 @@ public class GLProfile { System.err.println(JoglVersion.getInstance()); } - NativeWindowFactory.initSingleton(firstUIActionOnProcess); - ClassLoader classloader = GLProfile.class.getClassLoader(); isAWTAvailable = NativeWindowFactory.isAWTAvailable() && @@ -1187,7 +1261,7 @@ public class GLProfile { boolean addedAnyProfile = initProfilesForDevice(defaultDesktopDevice) || initProfilesForDevice(defaultEGLDevice); - + if(DEBUG) { System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable); System.err.println("GLProfile.init has desktopFactory "+(null!=desktopFactory)); @@ -1196,8 +1270,8 @@ public class GLProfile { System.err.println("GLProfile.init has eglFactory "+(null!=eglFactory)); System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl); System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl); - System.err.println("GLProfile.init defaultDesktopDevice "+defaultDevice); - System.err.println("GLProfile.init defaultEGLDevice "+defaultDevice); + System.err.println("GLProfile.init defaultDesktopDevice "+defaultDesktopDevice); + System.err.println("GLProfile.init defaultEGLDevice "+defaultEGLDevice); System.err.println("GLProfile.init defaultDevice "+defaultDevice); } @@ -1211,10 +1285,22 @@ public class GLProfile { * @return true if any profile for the device exists, otherwise false */ private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) { + if(null == device) { + return false; + } + GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device); + factory.enterThreadCriticalZone(); + try { + return initProfilesForDeviceImpl(device); + } finally { + factory.leaveThreadCriticalZone(); + } + } + private static synchronized boolean initProfilesForDeviceImpl(AbstractGraphicsDevice device) { boolean isSet = GLContext.getAvailableGLVersionsSet(device); if(DEBUG) { - String msg = "Info: GLProfile.initProfilesForDevice: "+device.getConnection()+", isSet "+isSet; + String msg = "Info: GLProfile.initProfilesForDevice: "+device+", isSet "+isSet; Throwable t = new Throwable(msg); t.printStackTrace(); // System.err.println(msg); @@ -1234,7 +1320,7 @@ public class GLProfile { // hence querying all available GLProfiles boolean desktopSharedCtxAvail = desktopFactory.getIsSharedContextAvailable(device); if (DEBUG) { - System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": desktop Shared Ctx "+desktopSharedCtxAvail); + System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail); } if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) { // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent}, @@ -1243,13 +1329,8 @@ public class GLProfile { 2, GLContext.CTX_PROFILE_COMPAT, 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY); } - computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */); - addedDesktopProfile = null != GLProfile.getDefault(device); - } else if(DEBUG) { - System.err.println("GLProfile: DesktopFactory - Device is not available: "+device.getConnection()); - } - - if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) { + addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */); + } else if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) { // 1st pretend we have all EGL profiles .. computeProfileMap(device, false /* desktopCtxUndef*/, true /* eglCtxUndef */); @@ -1257,7 +1338,7 @@ public class GLProfile { // hence querying all available GLProfiles boolean eglSharedCtxAvail = eglFactory.getIsSharedContextAvailable(device); if (DEBUG) { - System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": egl Shared Ctx "+eglSharedCtxAvail); + System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail); } if(hasGLES2Impl && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) { // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent}, @@ -1273,10 +1354,12 @@ public class GLProfile { 1, GLContext.CTX_PROFILE_ES, 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY); } - computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */); - addedEGLProfile = null != GLProfile.get(device, GL_PROFILE_LIST_GLES); - } else if(DEBUG) { - System.err.println("GLProfile: EGLFactory - Device is not available: "+device.getConnection()); + addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */); + } else { + setProfileMap(device, new HashMap()); // empty + if(DEBUG) { + System.err.println("GLProfile: EGLFactory - Device is not available: "+device); + } } if(!GLContext.getAvailableGLVersionsSet(device)) { @@ -1288,9 +1371,16 @@ public class GLProfile { System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device)); if(addedDesktopProfile) { dumpGLInfo(desktopFactory, device); - } - if(addedEGLProfile) { + List/*<GLCapabilitiesImmutable>*/ availCaps = desktopFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + } else if(addedEGLProfile) { dumpGLInfo(eglFactory, device); + List/*<GLCapabilitiesImmutable>*/ availCaps = eglFactory.getAvailableCapabilities(device); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } } @@ -1299,16 +1389,12 @@ public class GLProfile { private static void dumpGLInfo(GLDrawableFactoryImpl factory, AbstractGraphicsDevice device) { GLContext ctx = factory.getOrCreateSharedContext(device); - AbstractGraphicsDevice nativeDevice = ctx.getGLDrawable().getNativeSurface() - .getGraphicsConfiguration().getNativeGraphicsConfiguration() - .getScreen().getDevice(); - nativeDevice.lock(); + System.err.println("GLProfile.dumpGLInfo: "+ctx); + ctx.makeCurrent(); try { - ctx.makeCurrent(); System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null)); - ctx.release(); } finally { - nativeDevice.unlock(); + ctx.release(); } } @@ -1359,7 +1445,7 @@ public class GLProfile { sb.append("]"); } - private static void computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) { + private static boolean computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) { if (DEBUG) { System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", eglCtxUndef "+eglCtxUndef); } @@ -1390,6 +1476,7 @@ public class GLProfile { _mappedProfiles.put(GL_DEFAULT, defaultGLProfile); } setProfileMap(device, _mappedProfiles); + return _mappedProfiles.size() > 0; } /** @@ -1489,11 +1576,10 @@ public class GLProfile { String deviceKey = device.getUniqueID(); HashMap map = (HashMap) deviceConn2ProfileMap.get(deviceKey); if(null==map) { - map = new HashMap(); - synchronized ( deviceConn2ProfileMap ) { - deviceConn2ProfileMap.put(deviceKey, map); - } initProfilesForDevice(device); + if( null == deviceConn2ProfileMap.get(deviceKey) ) { + throw new InternalError("initProfilesForDevice(..) didn't issue setProfileMap(..) on "+device); + } } return map; } diff --git a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java index d92cec389..d1e725b00 100644 --- a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java @@ -40,7 +40,6 @@ package javax.media.opengl.awt; import javax.media.opengl.*; -import javax.media.opengl.glu.*; public interface AWTGLAutoDrawable extends GLAutoDrawable, ComponentEvents { /** Requests a new width and height for this AWTGLAutoDrawable. */ diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 8b20b9ed1..acabe58a5 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -40,31 +40,62 @@ package javax.media.opengl.awt; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.nativewindow.NativeWindowVersion; -import javax.media.opengl.*; -import javax.media.nativewindow.*; -import javax.media.nativewindow.awt.*; - -import com.jogamp.opengl.impl.*; -import com.jogamp.opengl.JoglVersion; +import java.beans.Beans; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.awt.Canvas; import java.awt.Color; -import java.awt.Component; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.awt.Window; -import java.awt.event.WindowEvent; -import java.awt.event.WindowAdapter; -import java.awt.geom.*; -import java.beans.*; -import java.lang.reflect.*; -import java.security.*; +import java.awt.geom.Rectangle2D; + +import java.awt.EventQueue; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.awt.AWTGraphicsConfiguration; +import javax.media.nativewindow.awt.AWTGraphicsDevice; +import javax.media.nativewindow.awt.AWTGraphicsScreen; +import javax.media.nativewindow.awt.AWTWindowClosingProtocol; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLRunnable; +import javax.media.opengl.Threading; + +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.opengl.JoglVersion; + +import com.jogamp.common.util.locks.RecursiveLock; +import com.jogamp.opengl.impl.Debug; +import com.jogamp.opengl.impl.GLContextImpl; +import com.jogamp.opengl.impl.GLDrawableHelper; +import com.jogamp.opengl.impl.ThreadingImpl; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on our @@ -104,7 +135,7 @@ import java.security.*; * </ul> */ -public class GLCanvas extends Canvas implements AWTGLAutoDrawable { +public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol { private static final boolean DEBUG; private static final GLProfile defaultGLProfile; @@ -126,6 +157,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { private GLContext shareWith; private GraphicsDevice device; + private AWTWindowClosingProtocol awtWindowClosingProtocol = + new AWTWindowClosingProtocol(this, new Runnable() { + public void run() { + GLCanvas.this.destroy(); + } + }); + /** Creates a new GLCanvas component with a default set of OpenGL capabilities, using the default OpenGL capabilities selection mechanism, on the default screen device. */ @@ -202,33 +240,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { this.device = device; } - protected interface DestroyMethod { - public void destroyMethod(); - } - - /* package private */ final static Object addClosingListener(Component c, final DestroyMethod d) { - WindowAdapter cl = null; - Window w = getWindow(c); - if(null!=w) { - cl = new WindowAdapter() { - public void windowClosing(WindowEvent e) { - // we have to issue this call rigth away, - // otherwise the window gets destroyed - d.destroyMethod(); - } - }; - w.addWindowListener(cl); - } - return cl; - } - - private final static Window getWindow(Component c) { - while ( c!=null && ! ( c instanceof Window ) ) { - c = c.getParent(); - } - return (Window)c; - } - /** * Overridden to choose a GraphicsConfiguration on a parent container's * GraphicsDevice because both devices @@ -340,18 +351,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } public GLContext createContext(GLContext shareWith) { - return drawable.createContext(shareWith); + drawableSync.lock(); + try { + return (null != drawable) ? drawable.createContext(shareWith) : null; + } finally { + drawableSync.unlock(); + } } public void setRealized(boolean realized) { } public boolean isRealized() { - return ( null != drawable ) ? drawable.isRealized() : false; + drawableSync.lock(); + try { + return ( null != drawable ) ? drawable.isRealized() : false; + } finally { + drawableSync.unlock(); + } } - private Object closingListener = null; - private Object closingListenerLock = new Object(); + public int getDefaultCloseOperation() { + return awtWindowClosingProtocol.getDefaultCloseOperation(); + } + + public int setDefaultCloseOperation(int op) { + return awtWindowClosingProtocol.setDefaultCloseOperation(op); + } public void display() { if( !validateGLDrawable() ) { @@ -359,63 +385,63 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction, displayAction); - if(null==closingListener) { - synchronized(closingListenerLock) { - if(null==closingListener) { - closingListener=addClosingListener(this, new DestroyMethod() { - public void destroyMethod() { destroy(); } }); - } - } - } + + awtWindowClosingProtocol.addClosingListenerOneShot(); } private void dispose(boolean regenerate) { - if(DEBUG) { - Exception ex1 = new Exception("Info: dispose("+regenerate+") - start"); - ex1.printStackTrace(); - } - - if(null!=context) { - boolean animatorPaused = false; - GLAnimatorControl animator = getAnimator(); - if(null!=animator) { - // can't remove us from animator for recreational addNotify() - animatorPaused = animator.pause(); + drawableSync.lock(); + try { + if(DEBUG) { + Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " + + (null!=context) + ", hasDrawable " + (null!=drawable)); + ex1.printStackTrace(); } - disposeRegenerate=regenerate; - - if (Threading.isSingleThreaded() && - !Threading.isOpenGLThread()) { - // Workaround for termination issues with applets -- - // sun.applet.AppletPanel should probably be performing the - // remove() call on the EDT rather than on its own thread - // Hint: User should run remove from EDT. - if (ThreadingImpl.isAWTMode() && - Thread.holdsLock(getTreeLock())) { - // The user really should not be invoking remove() from this - // thread -- but since he/she is, we can not go over to the - // EDT at this point. Try to destroy the context from here. - if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); + if(null!=context) { + boolean animatorPaused = false; + GLAnimatorControl animator = getAnimator(); + if(null!=animator) { + // can't remove us from animator for recreational addNotify() + animatorPaused = animator.pause(); + } + + disposeRegenerate=regenerate; + + if (Threading.isSingleThreaded() && + !Threading.isOpenGLThread()) { + // Workaround for termination issues with applets -- + // sun.applet.AppletPanel should probably be performing the + // remove() call on the EDT rather than on its own thread + // Hint: User should run remove from EDT. + if (ThreadingImpl.isAWTMode() && + Thread.holdsLock(getTreeLock())) { + // The user really should not be invoking remove() from this + // thread -- but since he/she is, we can not go over to the + // EDT at this point. Try to destroy the context from here. + if(context.isCreated()) { + drawableHelper.invokeGL(drawable, context, disposeAction, null); + } + } else if(context.isCreated()) { + Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); + } + } else if(context.isCreated()) { + drawableHelper.invokeGL(drawable, context, disposeAction, null); } - } else if(context.isCreated()) { - Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction); - } - } else if(context.isCreated()) { - drawableHelper.invokeGL(drawable, context, disposeAction, null); - } - if(animatorPaused) { - animator.resume(); + if(animatorPaused) { + animator.resume(); + } + } + if(!regenerate) { + disposeAbstractGraphicsDevice(); } - } - if(!regenerate) { - disposeAbstractGraphicsDeviceAction.run(); - } - if(DEBUG) { - System.err.println("dispose("+regenerate+") - stop"); + if(DEBUG) { + System.err.println("dispose("+regenerate+") - stop"); + } + } finally { + drawableSync.unlock(); } } @@ -459,6 +485,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } + RecursiveLock drawableSync = new RecursiveLock(); + /** Overridden to track when this component is added to a container. Subclasses which override this method must call super.addNotify() in their addNotify() method in order to @@ -472,59 +500,71 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { ex1.printStackTrace(); } - /** - * 'super.addNotify()' determines the GraphicsConfiguration, - * while calling this class's overriden 'getGraphicsConfiguration()' method - * after which it creates the native peer. - * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration - * is being used in getGraphicsConfiguration(). - * This code order also allows recreation, ie re-adding the GLCanvas. - */ - awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device); - if(null==awtConfig) { - throw new GLException("Error: NULL AWTGraphicsConfiguration"); - } + drawableSync.lock(); + try { + /** + * 'super.addNotify()' determines the GraphicsConfiguration, + * while calling this class's overriden 'getGraphicsConfiguration()' method + * after which it creates the native peer. + * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration + * is being used in getGraphicsConfiguration(). + * This code order also allows recreation, ie re-adding the GLCanvas. + */ + awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device); + if(null==awtConfig) { + throw new GLException("Error: NULL AWTGraphicsConfiguration"); + } - if (!Beans.isDesignTime()) { - // no lock required, since this resource ain't available yet - drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()) - .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); - context = (GLContextImpl) drawable.createContext(shareWith); - context.setSynchronized(true); - } + if (!Beans.isDesignTime()) { + // no lock required, since this resource ain't available yet + drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()) + .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig)); + context = (GLContextImpl) drawable.createContext(shareWith); + context.setSynchronized(true); + } - // before native peer is valid: X11 - disableBackgroundErase(); + // before native peer is valid: X11 + disableBackgroundErase(); - // issues getGraphicsConfiguration() and creates the native peer - super.addNotify(); + // issues getGraphicsConfiguration() and creates the native peer + super.addNotify(); - // after native peer is valid: Windows - disableBackgroundErase(); + // after native peer is valid: Windows + disableBackgroundErase(); - validateGLDrawable(); + // init drawable by paint/display makes the init sequence more equal + // for all launch flavors (applet/javaws/..) + // validateGLDrawable(); - if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end"); + if(DEBUG) { + System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end: peer: "+getPeer()); + } + } finally { + drawableSync.unlock(); } } private boolean validateGLDrawable() { boolean realized = false; if (!Beans.isDesignTime()) { - if ( null != drawable ) { - realized = drawable.isRealized(); - if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) { - drawable.setRealized(true); - realized = true; - sendReshape=true; // ensure a reshape is being send .. - if(DEBUG) { - String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString(); - // System.err.println(msg); - Throwable t = new Throwable(msg); - t.printStackTrace(); + drawableSync.lock(); + try { + if ( null != drawable ) { + realized = drawable.isRealized(); + if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) { + drawable.setRealized(true); + realized = true; + sendReshape=true; // ensure a reshape is being send .. + if(DEBUG) { + String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString(); + // System.err.println(msg); + Throwable t = new Throwable(msg); + t.printStackTrace(); + } } } + } finally { + drawableSync.unlock(); } } return realized; @@ -544,18 +584,24 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { ex1.printStackTrace(); } + awtWindowClosingProtocol.removeClosingListener(); + if (Beans.isDesignTime()) { super.removeNotify(); } else { + drawableSync.lock(); try { dispose(false); } finally { + context=null; drawable=null; + awtConfig=null; super.removeNotify(); + drawableSync.unlock(); } } if(DEBUG) { - System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end"); + System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end, peer: "+getPeer()); } } @@ -662,15 +708,30 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } public NativeSurface getNativeSurface() { - return drawable.getNativeSurface(); + drawableSync.lock(); + try { + return (null != drawable) ? drawable.getNativeSurface() : null; + } finally { + drawableSync.unlock(); + } } public long getHandle() { - return drawable.getHandle(); + drawableSync.lock(); + try { + return (null != drawable) ? drawable.getHandle() : 0; + } finally { + drawableSync.unlock(); + } } public GLDrawableFactory getFactory() { - return drawable.getFactory(); + drawableSync.lock(); + try { + return (null != drawable) ? drawable.getFactory() : null; + } finally { + drawableSync.unlock(); + } } public String toString() { @@ -703,6 +764,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { if(null!=drawable) { drawable.setRealized(false); + drawable=null; } if(disposeRegenerate) { @@ -743,13 +805,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } boolean closed = adevice.close(); if(DEBUG) { - System.err.println("GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed); + System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed); } } + awtConfig=null; } } private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction(); + /** + * Disposes the AbstractGraphicsDevice within EDT, + * since resources created (X11: Display), must be destroyed in the same thread, where they have been created. + * + * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice) + */ + void disposeAbstractGraphicsDevice() { + if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) { + disposeAbstractGraphicsDeviceAction.run(); + } else { + try { + EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction); + } catch (InvocationTargetException e) { + throw new GLException(e.getTargetException()); + } catch (InterruptedException e) { + throw new GLException(e); + } + } + } + class InitAction implements Runnable { public void run() { drawableHelper.init(GLCanvas.this); @@ -851,20 +934,55 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } } - private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilitiesImmutable capsChosen, - GLCapabilitiesImmutable capsRequested, - GLCapabilitiesChooser chooser, - GraphicsDevice device) { + /** + * Issues the GraphicsConfigurationFactory's choosing facility within EDT, + * since resources created (X11: Display), must be destroyed in the same thread, where they have been created. + * + * @param capsChosen + * @param capsRequested + * @param chooser + * @param device + * @return the chosen AWTGraphicsConfiguration + * + * @see #disposeAbstractGraphicsDevice() + */ + private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen, + final GLCapabilitiesImmutable capsRequested, + final GLCapabilitiesChooser chooser, + final GraphicsDevice device) { // Make GLCanvas behave better in NetBeans GUI builder if (Beans.isDesignTime()) { return null; } - AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT); - AWTGraphicsConfiguration config = (AWTGraphicsConfiguration) - GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen, - capsRequested, - chooser, aScreen); + final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT); + AWTGraphicsConfiguration config = null; + + if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) { + config = (AWTGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen, + capsRequested, + chooser, aScreen); + } else { + try { + final ArrayList bucket = new ArrayList(1); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + AWTGraphicsConfiguration c = (AWTGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen, + capsRequested, + chooser, aScreen); + bucket.add(c); + } + }); + config = ( bucket.size() > 0 ) ? (AWTGraphicsConfiguration)bucket.get(0) : null ; + } catch (InvocationTargetException e) { + throw new GLException(e.getTargetException()); + } catch (InterruptedException e) { + throw new GLException(e); + } + } + if (config == null) { throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration"); } @@ -881,6 +999,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); + GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) ); Frame frame = new Frame("JOGL AWT Test"); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index c8bfe94d8..46c799d71 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -40,19 +40,57 @@ package javax.media.opengl.awt; -import javax.media.opengl.*; -import javax.media.nativewindow.*; - -import java.awt.*; -import java.awt.geom.*; -import java.awt.image.*; -import java.beans.*; -import java.nio.*; -import java.security.*; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.beans.Beans; +import java.security.AccessControlContext; +import java.security.AccessController; + +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; import javax.swing.JPanel; + +import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.awt.AWTWindowClosingProtocol; + +import javax.media.opengl.DefaultGLCapabilitiesChooser; +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GL2GL3; +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLPbuffer; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLRunnable; +import javax.media.opengl.Threading; import com.jogamp.opengl.util.FBObject; -import com.jogamp.opengl.impl.*; -import com.jogamp.opengl.impl.awt.*; +import com.jogamp.opengl.impl.Debug; +import com.jogamp.opengl.impl.GLContextImpl; +import com.jogamp.opengl.impl.GLDrawableFactoryImpl; +import com.jogamp.opengl.impl.GLDrawableHelper; +import com.jogamp.opengl.impl.GLDrawableImpl; +import com.jogamp.opengl.impl.ThreadingImpl; +import com.jogamp.opengl.impl.awt.Java2D; +import com.jogamp.opengl.impl.awt.Java2DGLContext; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on their @@ -85,7 +123,7 @@ import com.jogamp.opengl.impl.awt.*; * </P> */ -public class GLJPanel extends JPanel implements AWTGLAutoDrawable { +public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol { private static final boolean DEBUG = Debug.debug("GLJPanel"); private static final boolean VERBOSE = Debug.verbose(); @@ -129,8 +167,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { !Debug.isPropertyDefined("jogl.gljpanel.noogl", true, localACC); // For handling reshape events lazily - private int reshapeX; - private int reshapeY; + // private int reshapeX; + // private int reshapeY; private int reshapeWidth; private int reshapeHeight; @@ -139,6 +177,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { private int viewportX; private int viewportY; + private AWTWindowClosingProtocol awtWindowClosingProtocol = + new AWTWindowClosingProtocol(this, new Runnable() { + public void run() { + GLJPanel.this.destroy(); + } + }); + static { // Force eager initialization of part of the Java2D class since // otherwise it's likely it will try to be initialized while on @@ -255,6 +300,19 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null); } + if(!regenerate) { + AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); + String adeviceMsg=null; + if(DEBUG) { + adeviceMsg = adevice.toString(); + } + // boolean closed = adevice.close(); + boolean closed = false; + if (DEBUG) { + System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed); + } + } + backend.setContext(disposeContext); if(null==disposeContext) { isInitialized = false; @@ -352,6 +410,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { Exception ex1 = new Exception("Info: removeNotify - start"); ex1.printStackTrace(); } + + awtWindowClosingProtocol.removeClosingListener(); + dispose(false); if (backend != null) { backend.destroy(); @@ -374,8 +435,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { public void reshape(int x, int y, int width, int height) { super.reshape(x, y, width, height); - reshapeX = x; - reshapeY = y; + // reshapeX = x; + // reshapeY = y; reshapeWidth = width; reshapeHeight = height; handleReshape = true; @@ -560,17 +621,16 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // a different implementation -- try again } while (backend == null); - if(null==closingListener) { - synchronized(closingListenerLock) { - if(null==closingListener) { - closingListener=GLCanvas.addClosingListener(this, new GLCanvas.DestroyMethod() { - public void destroyMethod() { destroy(); } }); - } - } - } + awtWindowClosingProtocol.addClosingListenerOneShot(); + } + + public int getDefaultCloseOperation() { + return awtWindowClosingProtocol.getDefaultCloseOperation(); + } + + public int setDefaultCloseOperation(int op) { + return awtWindowClosingProtocol.setDefaultCloseOperation(op); } - private Object closingListener = null; - private Object closingListenerLock = new Object(); private void handleReshape() { panelWidth = reshapeWidth; @@ -656,16 +716,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { disposeDrawable.setRealized(true); disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith); disposeContext.setSynchronized(true); - } else { - AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice(); - String adeviceMsg=null; - if(DEBUG) { - adeviceMsg = adevice.toString(); - } - boolean closed = adevice.close(); - if (DEBUG) { - System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed); - } } } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/DefaultGraphicsConfigurationFactoryImpl.java index c53f4c88b..f77454fac 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/GraphicsConfigurationFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/DefaultGraphicsConfigurationFactoryImpl.java @@ -35,7 +35,7 @@ package com.jogamp.nativewindow.impl; import javax.media.nativewindow.*; -public class GraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { +public class DefaultGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory { protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) { return new DefaultGraphicsConfiguration(screen, capsChosen, capsRequested); diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java index 34f5d6267..860be6f95 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java @@ -34,7 +34,6 @@ package com.jogamp.nativewindow.impl; import com.jogamp.common.util.*; import java.lang.reflect.*; -import java.security.*; import javax.media.nativewindow.*; diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java index de766acbf..e0ad95e1f 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/ProxySurface.java @@ -47,14 +47,21 @@ import com.jogamp.common.util.locks.RecursiveLock; public class ProxySurface implements NativeSurface, SurfaceChangeable { private RecursiveLock recurLock = new RecursiveLock(); - protected int width, height, scrnIndex; - protected long surfaceHandle, displayHandle; protected AbstractGraphicsConfiguration config; + protected long displayHandle; + protected long surfaceHandle; + protected int scrnIndex; + protected int width, height; public ProxySurface(AbstractGraphicsConfiguration cfg) { + this(cfg, 0); + } + + public ProxySurface(AbstractGraphicsConfiguration cfg, long handle) { invalidate(); config = cfg; displayHandle=cfg.getScreen().getDevice().getHandle(); + surfaceHandle=handle; scrnIndex=cfg.getScreen().getIndex(); } @@ -96,6 +103,14 @@ public class ProxySurface implements NativeSurface, SurfaceChangeable { recurLock.unlock(); } + public final void validateSurfaceLocked() { + recurLock.validateLocked(); + } + + public final int getSurfaceRecursionCount() { + return recurLock.getRecursionCount(); + } + public final boolean isSurfaceLockedByOtherThread() { return recurLock.isLockedByOtherThread(); } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/awt/AWTMisc.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/awt/AWTMisc.java new file mode 100644 index 000000000..c61ae5531 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/awt/AWTMisc.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.nativewindow.impl.awt; + +import java.awt.Window; +import java.awt.Component; +import java.awt.Container; +import java.awt.Frame; +import javax.swing.JFrame; +import javax.swing.WindowConstants; + +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.WindowClosingProtocol; +import javax.swing.MenuSelectionManager; + +public class AWTMisc { + + public static final JFrame getJFrame(Component c) { + while (c != null && !(c instanceof JFrame)) { + c = c.getParent(); + } + return (JFrame) c; + } + + public static final Frame getFrame(Component c) { + while (c != null && !(c instanceof Frame)) { + c = c.getParent(); + } + return (Frame) c; + } + + public static final Window getWindow(Component c) { + while (c != null && !(c instanceof Window)) { + c = c.getParent(); + } + return (Window) c; + } + + public static final Container getContainer(Component c) { + while (c != null && !(c instanceof Container)) { + c = c.getParent(); + } + return (Container) c; + } + + /** + * Issue this when your non AWT toolkit gains focus to clear AWT menu path + */ + public static final void clearAWTMenus() { + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + + public final static int AWT2NWClosingOperation(int awtClosingOperation) { + switch (awtClosingOperation) { + case WindowConstants.DISPOSE_ON_CLOSE: + case WindowConstants.EXIT_ON_CLOSE: + return WindowClosingProtocol.DISPOSE_ON_CLOSE; + case WindowConstants.DO_NOTHING_ON_CLOSE: + case WindowConstants.HIDE_ON_CLOSE: + return WindowClosingProtocol.DO_NOTHING_ON_CLOSE; + default: + throw new NativeWindowException("Unhandled AWT Closing Operation: " + awtClosingOperation); + } + } + + public final static int getNWClosingOperation(Component c) { + JFrame jf = getJFrame(c); + int op = (null != jf) ? jf.getDefaultCloseOperation() : WindowConstants.DO_NOTHING_ON_CLOSE ; + return AWT2NWClosingOperation(op); + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java index 9f120e9ab..0c6fc3f55 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTUtil.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -37,13 +38,17 @@ package com.jogamp.nativewindow.impl.jawt; import com.jogamp.nativewindow.impl.*; +import java.awt.EventQueue; import javax.media.nativewindow.*; import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; import java.lang.reflect.*; import java.security.*; +import java.util.ArrayList; +import java.util.Map; public class JAWTUtil { protected static final boolean DEBUG = Debug.debug("JAWT"); @@ -110,10 +115,35 @@ public class JAWTUtil { jawtToolkitLock = new JAWTToolkitLock(); + // trigger native AWT toolkit / properties initialization + Map desktophints = null; + try { + if(EventQueue.isDispatchThread()) { + desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + } else { + final ArrayList desktophintsBucket = new ArrayList(1); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); + if(null!=_desktophints) { + desktophintsBucket.add(_desktophints); + } + } + }); + desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ; + } + } catch (InterruptedException ex) { + ex.printStackTrace(); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + if (DEBUG) { System.err.println("JAWTUtil: Has sun.awt.SunToolkit.awtLock/awtUnlock " + hasSunToolkitAWTLock); System.err.println("JAWTUtil: Has Java2D " + j2dExist); System.err.println("JAWTUtil: Is headless " + headlessMode); + int hints = ( null != desktophints ) ? desktophints.size() : 0 ; + System.err.println("JAWTUtil: AWT Desktop hints " + hints); } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java new file mode 100644 index 000000000..05d31a40e --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/Win32SunJDKReflection.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.nativewindow.impl.jawt.windows; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.awt.AWTGraphicsConfiguration; + +/** This class encapsulates the reflection routines necessary to peek + inside a few data structures in the AWT implementation on X11 for + the purposes of correctly enumerating the available visuals. */ + +public class Win32SunJDKReflection { + private static Class win32GraphicsDeviceClass; + private static Class win32GraphicsConfigClass; + private static Method win32GraphicsConfigGetConfigMethod; + private static Method win32GraphicsConfigGetVisualMethod; + private static boolean initted; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + win32GraphicsDeviceClass = Class.forName("sun.awt.Win32GraphicsDevice"); + win32GraphicsConfigClass = Class.forName("sun.awt.Win32GraphicsConfig"); + win32GraphicsConfigGetConfigMethod = win32GraphicsConfigClass.getDeclaredMethod("getConfig", new Class[] { win32GraphicsDeviceClass, int.class }); + win32GraphicsConfigGetConfigMethod.setAccessible(true); + win32GraphicsConfigGetVisualMethod = win32GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {}); + win32GraphicsConfigGetVisualMethod.setAccessible(true); + initted = true; + } catch (Exception e) { + // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5 + } + return null; + } + }); + } + + public static GraphicsConfiguration graphicsConfigurationGet(GraphicsDevice device, int pfdID) { + if (!initted) { + return null; + } + + try { + return (GraphicsConfiguration) win32GraphicsConfigGetConfigMethod.invoke(null, new Object[] { device, new Integer(pfdID) }); + } catch (Exception e) { + return null; + } + } + + public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) { + try { + if (config instanceof AWTGraphicsConfiguration) { + return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration()); + } + return 0; + } catch (Exception e) { + return 0; + } + } + + public static int graphicsConfigurationGetPixelFormatID(GraphicsConfiguration config) { + if (!initted) { + return 0; + } + + try { + return ((Integer) win32GraphicsConfigGetVisualMethod.invoke(config, null)).intValue(); + } catch (Exception e) { + return 0; + } + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java index 081975afb..b4a99624c 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11SunJDKReflection.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -39,12 +40,12 @@ package com.jogamp.nativewindow.impl.jawt.x11; -import com.jogamp.nativewindow.impl.x11.*; - import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.lang.reflect.*; -import java.security.*; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.awt.AWTGraphicsConfiguration; @@ -55,7 +56,6 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration; public class X11SunJDKReflection { private static Class x11GraphicsDeviceClass; - private static Method x11GraphicsDeviceGetScreenMethod; private static Method x11GraphicsDeviceGetDisplayMethod; private static Class x11GraphicsConfigClass; private static Method x11GraphicsConfigGetVisualMethod; @@ -66,8 +66,6 @@ public class X11SunJDKReflection { public Object run() { try { x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice"); - x11GraphicsDeviceGetScreenMethod = x11GraphicsDeviceClass.getDeclaredMethod("getScreen", new Class[] {}); - x11GraphicsDeviceGetScreenMethod.setAccessible(true); x11GraphicsDeviceGetDisplayMethod = x11GraphicsDeviceClass.getDeclaredMethod("getDisplay", new Class[] {}); x11GraphicsDeviceGetDisplayMethod.setAccessible(true); @@ -83,18 +81,6 @@ public class X11SunJDKReflection { }); } - public static int graphicsDeviceGetScreen(GraphicsDevice device) { - if (!initted) { - return 0; - } - - try { - return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, null)).intValue(); - } catch (Exception e) { - return 0; - } - } - public static long graphicsDeviceGetDisplay(GraphicsDevice device) { if (!initted) { return 0; diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClass.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClass.java new file mode 100644 index 000000000..a30a81948 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClass.java @@ -0,0 +1,44 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.nativewindow.impl.windows; + +public class RegisteredClass { + long hInstance; + String className; + + RegisteredClass(long hInst, String name) { + hInstance = hInst; + className = name; + } + + public final long getHandle() { return hInstance; } + public final String getName() { return className; } + + public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+"]"; } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClassFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClassFactory.java new file mode 100644 index 000000000..d04640747 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/windows/RegisteredClassFactory.java @@ -0,0 +1,133 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.nativewindow.impl.windows; + +import com.jogamp.nativewindow.impl.Debug; +import java.util.ArrayList; +import javax.media.nativewindow.NativeWindowException; + +public class RegisteredClassFactory { + static final boolean DEBUG = Debug.debug("RegisteredClass"); + private static ArrayList sharedClasses = new ArrayList(); + private String classBaseName; + long wndProc; + + private RegisteredClass sharedClass = null; + private int classIter = 0; + private int sharedRefCount = 0; + private Object sync = new Object(); + + /** + * Intended for a JVM shutdown hook, hence little synchronization + */ + public static void shutdownSharedClasses() { + synchronized(sharedClasses) { + for(int i=0; i<sharedClasses.size(); i++) { + RegisteredClass sc = (RegisteredClass) sharedClasses.get(i); + GDI.DestroyWindowClass(sc.getHandle(), sc.getName()); + if(DEBUG) { + System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc); + } + } + sharedClasses.clear(); + } + } + + public RegisteredClassFactory(String classBaseName, long wndProc) { + this.classBaseName = classBaseName; + this.wndProc = wndProc; + } + + public RegisteredClass getSharedClass() throws NativeWindowException { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + long hInstance = GDI.GetApplicationHandle(); + if( 0 == hInstance ) { + throw new NativeWindowException("Error: Null ModuleHandle for Application"); + } + String clazzName = null; + boolean registered = false; + while ( !registered && Integer.MAX_VALUE >= classIter ) { + // Retry with next clazz name, this could happen if more than one JVM is running + clazzName = classBaseName + classIter; + classIter++; + registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc); + } + if( !registered ) { + throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName); + } + sharedClass = new RegisteredClass(hInstance, clazzName); + synchronized(sharedClasses) { + sharedClasses.add(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass); + } + } else if ( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + sharedRefCount++; + } + return sharedClass; + } + + public void releaseSharedClass() { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + return; + } + sharedRefCount--; + if( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + if( 0 == sharedRefCount ) { + GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName()); + synchronized(sharedClasses) { + sharedClasses.remove(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass); + } + sharedClass = null; + sharedRefCount = 0; + classIter = 0; + } + } + } + + public int getSharedRefCount() { + return sharedRefCount; + } +} diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java index f3b7f4a4e..c56f632d8 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -34,10 +34,11 @@ package com.jogamp.nativewindow.impl.x11; import com.jogamp.common.util.LongObjectHashMap; +import com.jogamp.nativewindow.impl.Debug; +import com.jogamp.nativewindow.impl.NWJNILibLoader; import javax.media.nativewindow.*; -import com.jogamp.nativewindow.impl.*; import java.nio.Buffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java index e844c4f3e..79d69c703 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java +++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java @@ -44,7 +44,7 @@ package javax.media.nativewindow; must support, such as color depth per channel. It currently contains the minimal number of routines which allow configuration on all supported window systems. */ -public class Capabilities implements CapabilitiesImmutable, Cloneable { +public class Capabilities implements CapabilitiesImmutable, Cloneable, Comparable { private int redBits = 8; private int greenBits = 8; private int blueBits = 8; @@ -114,6 +114,30 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable { return res; } + /** comparing RGBA values only */ + public int compareTo(Object o) { + if ( ! ( o instanceof Capabilities ) ) { + Class c = (null != o) ? o.getClass() : null ; + throw new ClassCastException("Not a Capabilities object: " + c); + } + + final Capabilities caps = (Capabilities) o; + + final int a = ( alphaBits > 0 ) ? alphaBits : 1; + final int rgba = redBits * greenBits * blueBits * a; + + final int xa = ( caps.alphaBits ) > 0 ? caps.alphaBits : 1; + final int xrgba = caps.redBits * caps.greenBits * caps.blueBits * xa; + + if(rgba > xrgba) { + return 1; + } else if(rgba < xrgba) { + return -1; + } + + return 0; // they are equal: RGBA + } + /** Returns the number of bits requested for the color buffer's red component. On some systems only the color depth, which is the sum of the red, green, and blue bits, is considered. */ @@ -274,25 +298,31 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable { A value of -1 is interpreted as any value. */ public void setTransparentAlphaValue(int transValueAlpha) { transparentValueAlpha=transValueAlpha; } + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + if(onscreen) { + sink.append("on-scr"); + } else { + sink.append("offscr"); + } + sink.append(", rgba ").append(redBits).append("/").append(greenBits).append("/").append(blueBits).append("/").append(alphaBits); + if(backgroundOpaque) { + sink.append(", opaque"); + } else { + sink.append(", trans-rgba 0x").append(Integer.toHexString(transparentValueRed)).append("/").append(Integer.toHexString(transparentValueGreen)).append("/").append(Integer.toHexString(transparentValueBlue)).append("/").append(Integer.toHexString(transparentValueAlpha)); + } + return sink; + } /** Returns a textual representation of this Capabilities object. */ public String toString() { StringBuffer msg = new StringBuffer(); - msg.append("Capabilities["); - msg.append("Onscreen: "+ onscreen + - ", Red: " + redBits + - ", Green: " + greenBits + - ", Blue: " + blueBits + - ", Alpha: " + alphaBits + - ", Opaque: " + backgroundOpaque); - if(!backgroundOpaque) { - msg.append(", Transparent RGBA: [0x"+ Integer.toHexString(transparentValueRed)+ - " 0x"+ Integer.toHexString(transparentValueGreen)+ - " 0x"+ Integer.toHexString(transparentValueBlue)+ - " 0x"+ Integer.toHexString(transparentValueAlpha)+"] "); - } - msg.append("]"); + msg.append("Caps["); + toString(msg); + msg.append("]"); return msg.toString(); } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java index 94b0f68af..a306363dc 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesChooser.java @@ -39,6 +39,8 @@ package javax.media.nativewindow; +import java.util.List; + /** Provides a mechanism by which applications can customize the window type selection for a given {@link Capabilities}. Developers can implement this interface and pass an instance into @@ -63,6 +65,6 @@ public interface CapabilitiesChooser { choice to some other CapabilitiesChooser object. */ public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, + List /*<CapabilitiesImmutable>*/ available, int windowSystemRecommendedChoice); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java index 72828b9f0..3aae8c8fb 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java +++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java @@ -109,6 +109,9 @@ public interface CapabilitiesImmutable extends WriteCloneable { /** hash code over the immutable attributes of both objects */ int hashCode(); + /** Return a textual representation of this object. Use the given StringBuffer [optional]. */ + StringBuffer toString(StringBuffer sink); + /** Returns a textual representation of this object. */ String toString(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java index 856c29420..b43db8292 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -39,6 +40,8 @@ package javax.media.nativewindow; +import java.util.List; + /** <P> The default implementation of the {@link CapabilitiesChooser} interface, which provides consistent visual selection behavior across platforms. The precise algorithm is @@ -63,37 +66,38 @@ package javax.media.nativewindow; public class DefaultCapabilitiesChooser implements CapabilitiesChooser { private static final boolean DEBUG = false; // FIXME: Debug.debug("DefaultCapabilitiesChooser"); - public int chooseCapabilities(CapabilitiesImmutable desired, - CapabilitiesImmutable[] available, - int windowSystemRecommendedChoice) { + public int chooseCapabilities(final CapabilitiesImmutable desired, + final List /*<CapabilitiesImmutable>*/ available, + final int windowSystemRecommendedChoice) { if (DEBUG) { System.err.println("Desired: " + desired); - for (int i = 0; i < available.length; i++) { - System.err.println("Available " + i + ": " + available[i]); + for (int i = 0; i < available.size(); i++) { + System.err.println("Available " + i + ": " + available.get(i)); } System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice); } + final int availnum = available.size(); if (windowSystemRecommendedChoice >= 0 && - windowSystemRecommendedChoice < available.length && - available[windowSystemRecommendedChoice] != null) { + windowSystemRecommendedChoice < availnum && + null != available.get(windowSystemRecommendedChoice)) { if (DEBUG) { System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice); - System.err.println(available[windowSystemRecommendedChoice]); + System.err.println(available.get(windowSystemRecommendedChoice)); } return windowSystemRecommendedChoice; } // Create score array - int[] scores = new int[available.length]; + int[] scores = new int[availnum]; int NO_SCORE = -9999999; int COLOR_MISMATCH_PENALTY_SCALE = 36; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { scores[i] = NO_SCORE; } // Compute score for each - for (int i = 0; i < scores.length; i++) { - CapabilitiesImmutable cur = available[i]; + for (int i = 0; i < availnum; i++) { + CapabilitiesImmutable cur = (CapabilitiesImmutable) available.get(i); if (cur == null) { continue; } @@ -107,7 +111,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { if (DEBUG) { System.err.print("Scores: ["); - for (int i = 0; i < available.length; i++) { + for (int i = 0; i < availnum; i++) { if (i > 0) { System.err.print(","); } @@ -119,7 +123,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { // Ready to select. Choose score closest to 0. int scoreClosestToZero = NO_SCORE; int chosenIndex = -1; - for (int i = 0; i < scores.length; i++) { + for (int i = 0; i < availnum; i++) { int score = scores[i]; if (score == NO_SCORE) { continue; @@ -138,7 +142,7 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser { if (DEBUG) { System.err.println("Chosen index: " + chosenIndex); System.err.println("Chosen capabilities:"); - System.err.println(available[chosenIndex]); + System.err.println(available.get(chosenIndex)); } return chosenIndex; diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java index 47110add9..c728c1634 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java @@ -32,6 +32,8 @@ package javax.media.nativewindow; +import com.jogamp.common.util.ReflectionUtil; + public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphicsConfiguration { private AbstractGraphicsScreen screen; protected CapabilitiesImmutable capabilitiesChosen; @@ -39,8 +41,16 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics public DefaultGraphicsConfiguration(AbstractGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) { + if(null == screen) { + throw new NativeWindowException("Null screen"); + } + if(null == capsChosen) { + throw new NativeWindowException("Null chosen caps"); + } + if(null == capsRequested) { + throw new NativeWindowException("Null requested caps"); + } this.screen = screen; - this.capabilitiesChosen = capsChosen; this.capabilitiesRequested = capsRequested; } @@ -96,9 +106,17 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics } public String toString() { - return getClass().toString()+"[" + screen + + return ReflectionUtil.getBaseName(getClass())+"[" + screen + ",\n\tchosen " + capabilitiesChosen+ ",\n\trequested " + capabilitiesRequested+ "]"; } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java index cb367f939..3d9f6d6ca 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java @@ -33,6 +33,7 @@ package javax.media.nativewindow; +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.impl.NativeWindowFactoryImpl; public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice { @@ -143,7 +144,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice } public String toString() { - return getClass().toString()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]"; + return ReflectionUtil.getBaseName(getClass())+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+"]"; } /** diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java index 065385ae3..7b7a89bff 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsScreen.java @@ -32,6 +32,8 @@ package javax.media.nativewindow; +import com.jogamp.common.util.ReflectionUtil; + public class DefaultGraphicsScreen implements Cloneable, AbstractGraphicsScreen { AbstractGraphicsDevice device; private int idx; @@ -62,6 +64,6 @@ public class DefaultGraphicsScreen implements Cloneable, AbstractGraphicsScreen } public String toString() { - return getClass().toString()+"["+device+", idx "+idx+"]"; + return ReflectionUtil.getBaseName(getClass())+"["+device+", idx "+idx+"]"; } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index c061f597f..ad1bc3634 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -33,10 +33,13 @@ package javax.media.nativewindow; -import java.util.*; +import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.nativewindow.impl.Debug; +import com.jogamp.nativewindow.impl.DefaultGraphicsConfigurationFactoryImpl; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; -import com.jogamp.common.util.*; -import com.jogamp.nativewindow.impl.*; /** * Provides the mechanism by which the graphics configuration for a @@ -65,6 +68,18 @@ public abstract class GraphicsConfigurationFactory { initialize(); } + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + + protected static String toHexString(int val) { + return "0x" + Integer.toHexString(val); + } + + protected static String toHexString(long val) { + return "0x" + Long.toHexString(val); + } + /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ protected GraphicsConfigurationFactory() { @@ -88,7 +103,7 @@ public abstract class GraphicsConfigurationFactory { // AWTGraphicsDevice instances -- the OpenGL binding will take // care of handling AWTGraphicsDevices on X11 platforms (as // well as X11GraphicsDevices in non-AWT situations) - registerFactory(abstractGraphicsDeviceClass, new GraphicsConfigurationFactoryImpl()); + registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl()); } /** Returns the factory for use with the given type of @@ -232,4 +247,5 @@ public abstract class GraphicsConfigurationFactory { chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) throws IllegalArgumentException, NativeWindowException; + } diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index a36440873..5d36df6ed 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -49,7 +49,7 @@ import java.lang.reflect.Method; hardware-accelerated rendering using the OpenGL API. */ public abstract class NativeWindowFactory { - protected static final boolean DEBUG = Debug.debug("NativeWindow"); + protected static final boolean DEBUG; /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/ public static final String TYPE_EGL = "EGL"; @@ -80,6 +80,7 @@ public abstract class NativeWindowFactory { public static final String AWTComponentClassName = "java.awt.Component" ; public static final String JAWTUtilClassName = "com.jogamp.nativewindow.impl.jawt.JAWTUtil" ; public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; + public static final String GDIClassName = "com.jogamp.nativewindow.impl.windows.GDI"; public static final String X11JAWTToolkitLockClassName = "com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock" ; public static final String X11ToolkitLockClassName = "com.jogamp.nativewindow.impl.x11.X11ToolkitLock" ; private static Class jawtUtilClass; @@ -113,13 +114,41 @@ public abstract class NativeWindowFactory { static { JVMUtil.initSingleton(); + DEBUG = Debug.debug("NativeWindow"); + if(DEBUG) { + Throwable td = new Throwable(Thread.currentThread().getName()+" - Info: NativeWindowFactory.<init>"); + td.printStackTrace(); + } } static boolean initialized = false; + private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { + String clazzName = null; + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + clazzName = X11UtilClassName; + } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) { + clazzName = GDIClassName; + } + if( null != clazzName ) { + ReflectionUtil.callStaticMethod(clazzName, "initSingleton", + new Class[] { boolean.class }, + new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + } + } + /** * Static one time initialization of this factory.<br> - * This initialization method <b>must be called</b> once by the program or utilizing modules!<br> + * This initialization method <b>must be called</b> once by the program or utilizing modules! + * <p> + * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking: + * <ul> + * <li> {@link #getDefaultToolkitLock() getDefaultToolkitLock() }</li> + * <li> {@link #getDefaultToolkitLock(java.lang.String) getDefaultToolkitLock(type) }</li> + * <li> {@link #createDefaultToolkitLock(java.lang.String, long) createDefaultToolkitLock(type, dpyHandle) }</li> + * <li> {@link #createDefaultToolkitLockNoAWT(java.lang.String, long) createDefaultToolkitLockNoAWT(type, dpyHandle) }</li> + * </ul> + * </p> * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, * otherwise <code>false</code>. */ @@ -128,8 +157,7 @@ public abstract class NativeWindowFactory { initialized = true; if(DEBUG) { - Throwable td = new Throwable("Info: NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); - td.printStackTrace(); + System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")"); } // Gather the windowing OS first @@ -144,15 +172,14 @@ public abstract class NativeWindowFactory { nativeWindowingTypeCustom = nativeOSNameCustom; } - ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + final ClassLoader cl = NativeWindowFactory.class.getClassLoader(); - if( TYPE_X11.equals(nativeWindowingTypePure) ) { - // explicit initialization of X11Util - ReflectionUtil.callStaticMethod(X11UtilClassName, "initSingleton", - new Class[] { boolean.class }, - new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + if(firstUIActionOnProcess) { + // X11 initialization before possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); } isFirstUIActionOnProcess = firstUIActionOnProcess; + isAWTAvailable = false; // may be set to true below if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && @@ -180,16 +207,13 @@ public abstract class NativeWindowFactory { // AWT is only available in case all above classes are available // and AWT is not int headless mode isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE); - } else { - isAWTAvailable = false; } - } else { - isAWTAvailable = false; } - } else { - isAWTAvailable = false; } - + if(!firstUIActionOnProcess) { + // X11 initialization after possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); + } registeredFactories = Collections.synchronizedMap(new HashMap()); // register our default factory -> NativeWindow @@ -270,10 +294,7 @@ public abstract class NativeWindowFactory { /** * Provides the system default {@link ToolkitLock}, a singleton instance. * <br> - * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} - * in case of a <b>X11 system</b> <em>and</em> <b>AWT availability</b> and if - * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> - * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + * @see #getDefaultToolkitLock(java.lang.String) */ public static ToolkitLock getDefaultToolkitLock() { return getDefaultToolkitLock(getNativeWindowType(false)); @@ -282,15 +303,27 @@ public abstract class NativeWindowFactory { /** * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance. * <br> - * This is a {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} - * in case of a <b>X11 type</b> or <b>AWT type / X11 system</b> <em>and</em> <b>AWT availability</b> and if - * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> - * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If native <b>X11 type</b> with or w/o AWT</li> + * <ul> + * <li> If <b>AWT available</b> </li> + * <ul> + * <li> return {@link com.jogamp.nativewindow.impl.jawt.JAWTToolkitLock} </li> + * </ul> + * </ul> + * </ul> + * <li> Otherwise return {@link com.jogamp.nativewindow.impl.NullToolkitLock} </li> + * </ul> */ public static ToolkitLock getDefaultToolkitLock(String type) { - if( isAWTAvailable() && !isFirstUIActionOnProcess() && - ( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) ) { - return getAWTToolkitLock(); + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) { + if( isAWTAvailable() ) { + return getAWTToolkitLock(); + } + } } return NativeWindowFactoryImpl.getNullToolkitLock(); } @@ -308,39 +341,63 @@ public abstract class NativeWindowFactory { public static ToolkitLock getNullToolkitLock() { return NativeWindowFactoryImpl.getNullToolkitLock(); } + /** * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. * <br> - * This is a {@link com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock} - * in case of a <b>X11 type</b> <em>and</em> <b>AWT availability</b> and if - * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> - * or a {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock} - * in case of a <b>X11 type</b> <em>and</em> <b>no AWT availability</b> and if - * this factory has been initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>, <br> - * otherwise {@link com.jogamp.nativewindow.impl.NullToolkitLock} is returned. + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If <b>X11 type</b> </li> + * <ul> + * <li> If <b>AWT available</b> </li> + * <ul> + * <li> return {@link com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock} </li> + * </ul> + * <li> If <b>AWT not available</b> </li> + * <ul> + * <li> return {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock} </li> + * </ul> + * </ul> + * </ul> + * <li> Otherwise return {@link com.jogamp.nativewindow.impl.NullToolkitLock} </li> + * </ul> */ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { - if( TYPE_X11 == type ) { - if( 0== deviceHandle ) { - throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); - } - if( !isFirstUIActionOnProcess() ) { + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); + } if( isAWTAvailable() ) { return createX11AWTToolkitLock(deviceHandle); - } else { - return createX11ToolkitLock(deviceHandle); } + return createX11ToolkitLock(deviceHandle); } } return NativeWindowFactoryImpl.getNullToolkitLock(); } + /** + * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. + * <br> + * <ul> + * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> + * <ul> + * <li>If <b>X11 type</b> </li> + * <ul> + * <li> return {@link com.jogamp.nativewindow.impl.x11.X11ToolkitLock} </li> + * </ul> + * </ul> + * <li> Otherwise return {@link com.jogamp.nativewindow.impl.NullToolkitLock} </li> + * </ul> + */ public static ToolkitLock createDefaultToolkitLockNoAWT(String type, long deviceHandle) { - if( TYPE_X11 == type ) { - if( 0== deviceHandle ) { - throw new RuntimeException("JAWTUtil.createDefaultToolkitLockNoAWT() called with NULL device but on X11"); - } - if( !isFirstUIActionOnProcess() ) { + if( !isFirstUIActionOnProcess() ) { + if( TYPE_X11 == type ) { + if( 0== deviceHandle ) { + throw new RuntimeException("JAWTUtil.createDefaultToolkitLockNoAWT() called with NULL device but on X11"); + } return createX11ToolkitLock(deviceHandle); } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java new file mode 100644 index 000000000..949aee79c --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/WindowClosingProtocol.java @@ -0,0 +1,66 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow; + +/** + * Protocol for handling window closing events. + * <p> + * The implementation shall obey either the user value set by this interface,<br> + * an underlying toolkit set user value or it's default, eg. {@link #DO_NOTHING_ON_CLOSE DO_NOTHING_ON_CLOSE} within an AWT environment.<br> + * If none of the above determines the operation, + * this protocol default behavior {@link #DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.</p> + */ +public interface WindowClosingProtocol { + /** + * Dispose resources on native window close operation.<br> + * This is the default behavior in case no underlying toolkit defines otherwise. + */ + int DISPOSE_ON_CLOSE = 1; + + /** + * Do nothing on native window close operation.<br> + * This is the default behavior within an AWT environment. + */ + int DO_NOTHING_ON_CLOSE = 0; + + /** + * @return the current close operation value + * @see #DISPOSE_ON_CLOSE + * @see #DO_NOTHING_ON_CLOSE + */ + int getDefaultCloseOperation(); + + /** + * @param op the new close operation value + * @return the previous close operation value + * @see #DISPOSE_ON_CLOSE + * @see #DO_NOTHING_ON_CLOSE + */ + int setDefaultCloseOperation(int op); +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java index c3d10de10..e428bb0b1 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java @@ -40,6 +40,7 @@ package javax.media.nativewindow.awt; +import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.*; import java.awt.Component; import java.awt.GraphicsConfiguration; @@ -155,7 +156,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple } public String toString() { - return getClass().toString()+"[" + getScreen() + + return ReflectionUtil.getBaseName(getClass())+"[" + getScreen() + ",\n\tchosen " + capabilitiesChosen+ ",\n\trequested " + capabilitiesRequested+ ",\n\t" + config + diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java index cc4cd464f..2638ae18a 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java @@ -39,6 +39,7 @@ package javax.media.nativewindow.awt; +import com.jogamp.common.util.ReflectionUtil; import javax.media.nativewindow.*; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; @@ -91,7 +92,7 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl } public String toString() { - return getClass().toString()+"[type "+getType()+"[subType "+getSubType()+"], connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; + return ReflectionUtil.getBaseName(getClass())+"[type "+getType()+"[subType "+getSubType()+"], connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]"; } } diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java new file mode 100644 index 000000000..a0e9efa49 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTWindowClosingProtocol.java @@ -0,0 +1,138 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.awt; + +import java.awt.Component; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import javax.media.nativewindow.WindowClosingProtocol; +import com.jogamp.nativewindow.impl.awt.AWTMisc; + +public class AWTWindowClosingProtocol implements WindowClosingProtocol { + + private Component comp; + private Runnable closingOperation; + private volatile boolean closingListenerSet = false; + private Object closingListenerLock = new Object(); + private int defaultCloseOperation = DISPOSE_ON_CLOSE; + private boolean defaultCloseOperationSetByUser = false; + + public AWTWindowClosingProtocol(Component comp, Runnable closingOperation) { + this.comp = comp; + this.closingOperation = closingOperation; + } + + class WindowClosingAdapter extends WindowAdapter { + public void windowClosing(WindowEvent e) { + int op = AWTWindowClosingProtocol.this.getDefaultCloseOperation(); + + if( DISPOSE_ON_CLOSE == op ) { + // we have to issue this call right away, + // otherwise the window gets destroyed + closingOperation.run(); + } + } + } + WindowListener windowClosingAdapter = new WindowClosingAdapter(); + + final boolean addClosingListenerImpl() { + Window w = AWTMisc.getWindow(comp); + if(null!=w) { + w.addWindowListener(windowClosingAdapter); + return true; + } + return false; + } + + /** + * Adds this closing listener to the components Window if exist and only one time.<br> + * Hence you may call this method every time to ensure it has been set, + * ie in case the Window parent is not available yet. + * + * @return + */ + public final boolean addClosingListenerOneShot() { + if(!closingListenerSet) { + synchronized(closingListenerLock) { + if(!closingListenerSet) { + closingListenerSet=addClosingListenerImpl(); + return closingListenerSet; + } + } + } + return false; + } + + public final boolean removeClosingListener() { + if(closingListenerSet) { + synchronized(closingListenerLock) { + if(closingListenerSet) { + Window w = AWTMisc.getWindow(comp); + if(null!=w) { + w.removeWindowListener(windowClosingAdapter); + closingListenerSet = false; + return true; + } + } + } + } + return false; + } + + /** + * + * @return the user set close operation if set by {@link #setDefaultCloseOperation(int) setDefaultCloseOperation(int)}, + * otherwise return the AWT/Swing close operation value translated to + * a {@link WindowClosingProtocol} value . + */ + public final int getDefaultCloseOperation() { + int op = -1; + synchronized(closingListenerLock) { + if(defaultCloseOperationSetByUser) { + op = defaultCloseOperation; + } + } + if(0 <= op) { + return op; + } + // User didn't determine the behavior, use underlying AWT behavior + return AWTMisc.getNWClosingOperation(comp); + } + + public final int setDefaultCloseOperation(int op) { + synchronized(closingListenerLock) { + int _op = defaultCloseOperation; + defaultCloseOperation = op; + defaultCloseOperationSetByUser = true; + return _op; + } + } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java index 07171e141..7b5f19047 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java @@ -33,6 +33,8 @@ package javax.media.nativewindow.x11; import javax.media.nativewindow.*; + +import com.jogamp.common.util.ReflectionUtil; import com.jogamp.nativewindow.impl.x11.XVisualInfo; /** Encapsulates a graphics configuration, or OpenGL pixel format, on @@ -68,7 +70,7 @@ public class X11GraphicsConfiguration extends DefaultGraphicsConfiguration imple } public String toString() { - return getClass().toString()+"["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + + return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ",\n\tchosen " + capabilitiesChosen+ ",\n\trequested " + capabilitiesRequested+ "]"; diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java index 949afe5bd..33799d717 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java @@ -32,13 +32,18 @@ package javax.media.nativewindow.x11; +import com.jogamp.nativewindow.impl.Debug; import com.jogamp.nativewindow.impl.x11.X11Util; -import javax.media.nativewindow.*; +import javax.media.nativewindow.DefaultGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ToolkitLock; /** Encapsulates a graphics device on X11 platforms. */ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable { + public static final boolean DEBUG = Debug.debug("GraphicsDevice"); boolean closeDisplay = false; /** Constructs a new X11GraphicsDevice corresponding to the given connection and default @@ -78,10 +83,16 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl public void setCloseDisplay(boolean close) { closeDisplay = close; + if(DEBUG && close) { + System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.setCloseDisplay(true): "+this); + } } public boolean close() { // FIXME: shall we respect the unitID ? if(closeDisplay && 0 != handle) { + if(DEBUG) { + System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this); + } X11Util.closeDisplay(handle); handle = 0; return true; diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c new file mode 100644 index 000000000..e357045d6 --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.c @@ -0,0 +1,57 @@ + +#include "NativewindowCommon.h" + +static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buffer); + (*env)->FatalError(env, buffer); +} + +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); +} + +int NativewindowCommon_init(JNIEnv *env) { + if(NULL==runtimeExceptionClz) { + jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + NativewindowCommon_FatalError(env, "Nativewindow: can't find %s", ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + NativewindowCommon_FatalError(env, "Nativewindow: can't use %s", ClazzNameRuntimeException); + } + return 1; + } + return 0; +} + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h new file mode 100644 index 000000000..5dc5debef --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.h @@ -0,0 +1,15 @@ + +#ifndef NATIVEWINDOW_COMMON_H +#define NATIVEWINDOW_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +int NativewindowCommon_init(JNIEnv *env); + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...); +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); + +#endif diff --git a/src/nativewindow/native/windows/GDImisc.c b/src/nativewindow/native/windows/GDImisc.c index 427e15d4a..798edcbbf 100644 --- a/src/nativewindow/native/windows/GDImisc.c +++ b/src/nativewindow/native/windows/GDImisc.c @@ -29,6 +29,7 @@ #include <stdio.h> +#include "NativewindowCommon.h" #include "com_jogamp_nativewindow_impl_windows_GDI.h" // #define VERBOSE_ON 1 @@ -39,19 +40,6 @@ #define DBG_PRINT(args...) #endif -static void _FatalError(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); -} - static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; static const char * const ClazzAnyCstrName = "<init>"; static const char * const ClazzNamePointCstrSignature = "(II)V"; @@ -59,74 +47,176 @@ static const char * const ClazzNamePointCstrSignature = "(II)V"; static jclass pointClz = NULL; static jmethodID pointCstr = NULL; -#define NATIVEWINDOW_DUMMY_WINDOW_NAME "__nativewindow_dummy_window" -static ATOM nativewindowClass = 0; +HINSTANCE GetApplicationHandle() { + return GetModuleHandle(NULL); +} -LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - return DefWindowProc(hWnd,uMsg,wParam,lParam); +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc) + * C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc); + */ +JNIEXPORT jboolean JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_CreateWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + WNDCLASS wc; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + ZeroMemory( &wc, sizeof( wc ) ); + if( GetClassInfo( hInstance, clazzName, &wc ) ) { + // registered already + res = JNI_TRUE; + } else { + // register now + ZeroMemory( &wc, sizeof( wc ) ); + wc.style = CS_HREDRAW | CS_VREDRAW ; + wc.lpfnWndProc = (WNDPROC) (intptr_t) wndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor( NULL, IDC_ARROW); + wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = clazzName; + res = ( 0 != RegisterClass( &wc ) ) ? JNI_TRUE : JNI_FALSE ; + } + +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; +} + +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className) + * C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className); + */ +JNIEXPORT jboolean JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_DestroyWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + res = ( 0 != UnregisterClass( clazzName, hInstance ) ) ? JNI_TRUE : JNI_FALSE ; + +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; } -HWND CreateDummyWindow0(HINSTANCE hInstance, int x, int y, int width, int height ) { - DWORD dwExStyle; - DWORD dwStyle; - HWND hWnd; - - dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - dwStyle = WS_OVERLAPPEDWINDOW; - if( !(hWnd=CreateWindowEx( dwExStyle, - NATIVEWINDOW_DUMMY_WINDOW_NAME, - NATIVEWINDOW_DUMMY_WINDOW_NAME, - dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - x, y, width, height, - NULL, NULL, hInstance, NULL ) ) ) { - return( 0 ); - } - return( hWnd ); + +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, java.lang.String windowName, int x, int y, int width, int height) + * C function: HANDLE CreateDummyWindow0(HANDLE hInstance, LPCSTR className, LPCSTR windowName, int x, int y, int width, int height); + */ +JNIEXPORT jlong JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_CreateDummyWindow0 + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* wndClassName = NULL; + const TCHAR* wndName = NULL; + DWORD dwExStyle; + DWORD dwStyle; + HWND hWnd; + +#ifdef UNICODE + wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName); + wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); +#else + wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL); + wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); +#endif + + dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dwStyle = WS_OVERLAPPEDWINDOW; + + hWnd = CreateWindowEx( dwExStyle, + wndClassName, + wndName, + dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + x, y, width, height, + NULL, NULL, hInstance, NULL ); + +#ifdef UNICODE + free((void*) wndClassName); + free((void*) wndName); +#else + (*env)->ReleaseStringUTFChars(env, jWndClassName, wndClassName); + (*env)->ReleaseStringUTFChars(env, jWndName, wndName); +#endif + + return (jlong) (intptr_t) hWnd; } + /* * Class: com_jogamp_nativewindow_impl_windows_GDI * Method: initIDs0 * Signature: ()Z */ -JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_windows_GDI_initIDs0 +JNIEXPORT jboolean JNICALL Java_com_jogamp_nativewindow_impl_windows_GDI_initIDs0 (JNIEnv *env, jclass clazz) { - if(NULL==pointClz) { + if(NativewindowCommon_init(env)) { jclass c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't find %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't find %s", ClazzNamePoint); } pointClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==pointClz) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't use %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't use %s", ClazzNamePoint); } pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); if(NULL==pointCstr) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't fetch %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't fetch %s.%s %s", ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } } - HINSTANCE hInstance = GetModuleHandle(NULL); - if( !nativewindowClass ) { - WNDCLASS wc; - ZeroMemory( &wc, sizeof( wc ) ); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) DummyWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = NATIVEWINDOW_DUMMY_WINDOW_NAME; - if( !(nativewindowClass = RegisterClass( &wc )) ) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: RegisterClass Failed: %d", GetLastError() ); - } - } - return (jlong) hInstance; + return JNI_TRUE; +} + +LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +/* + * Class: com_jogamp_nativewindow_impl_windows_GDI + * Method: getDummyWndProc0 + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_windows_GDI_getDummyWndProc0 + (JNIEnv *env, jclass clazz) +{ + return (jlong) (intptr_t) DummyWndProc; } /* diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index efb20c54e..0d92880b3 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -80,6 +80,7 @@ Bool XF86VidModeSetGammaRamp( #define RTLD_DEFAULT NULL #endif +#include "NativewindowCommon.h" #include "com_jogamp_nativewindow_impl_x11_X11Lib.h" // #define VERBOSE_ON 1 @@ -93,107 +94,66 @@ Bool XF86VidModeSetGammaRamp( /* Need to pull this in as we don't have a stub header for it */ extern Bool XineramaEnabled(Display* display); -static void _FatalError(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); -} - static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer"; -static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; static const char * const ClazzAnyCstrName = "<init>"; static const char * const ClazzNamePointCstrSignature = "(II)V"; static jclass clazzBuffers = NULL; static jmethodID cstrBuffers = NULL; static jclass clazzByteBuffer = NULL; -static jclass clazzRuntimeException=NULL; static jclass pointClz = NULL; static jmethodID pointCstr = NULL; static void _initClazzAccess(JNIEnv *env) { jclass c; - if(NULL!=clazzRuntimeException) return ; - - c = (*env)->FindClass(env, ClazzNameRuntimeException); - if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameRuntimeException); - } - clazzRuntimeException = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==clazzRuntimeException) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameRuntimeException); - } + if(!NativewindowCommon_init(env)) return; c = (*env)->FindClass(env, ClazzNameBuffers); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameBuffers); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameBuffers); } clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==clazzBuffers) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameBuffers); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameBuffers); } c = (*env)->FindClass(env, ClazzNameByteBuffer); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer); } clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer); } cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); if(NULL==cstrBuffers) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't create %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't create %s.%s %s", ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); } c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNamePoint); } pointClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==pointClz) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNamePoint); } pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); if(NULL==pointCstr) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't fetch %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't fetch %s.%s %s", ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } } -static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - if(NULL!=unlockDisplay) { - XUnlockDisplay(unlockDisplay); - } - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - (*env)->ThrowNew(env, clazzRuntimeException, buffer); -} - static JNIEnv * x11ErrorHandlerJNIEnv = NULL; static XErrorHandler origErrorHandler = NULL ; static int errorHandlerBlocked = 0 ; @@ -208,7 +168,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) // Since the X11 Error may happen anytime, a exception could mess up the JVM completely. // Experienced this for remote displays issuing non supported commands, eg. glXCreateContextAttribsARB(..) // - _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", + NativewindowCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", dpy, e->error_code, strerror(errno)); #endif @@ -256,7 +216,7 @@ static XIOErrorHandler origIOErrorHandler = NULL; static int x11IOErrorHandler(Display *dpy) { fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, XDisplayName(NULL), strerror(errno)); - // _FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); + // NativewindowCommon_FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); if(NULL!=origIOErrorHandler) { origIOErrorHandler(dpy); } @@ -315,7 +275,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBu jobject jbyteSource; jobject jbyteCopy; if(0==arg0) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } if (arg2 != NULL) { _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0); @@ -344,7 +304,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) { jlong r; if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) ); @@ -360,7 +320,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } XLockDisplay((Display *) (intptr_t) display); } @@ -373,7 +333,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } XUnlockDisplay((Display *) (intptr_t) display); } @@ -387,7 +347,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) { int _res; if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); _res = XCloseDisplay((Display *) (intptr_t) display); @@ -420,12 +380,12 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy Screen* scrn; if(NULL==dpy) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); return 0; } if(visualID<0) { - _throwNewRuntimeException(NULL, env, "invalid VisualID .."); + NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; } @@ -450,7 +410,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy if (visual==NULL) { x11ErrorHandlerEnable(dpy, 0, env); - _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!"); + NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } @@ -515,7 +475,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummy Window w = (Window) window; if(NULL==dpy) { - _throwNewRuntimeException(NULL, env, "invalid display connection.."); + NativewindowCommon_throwNewRuntimeException(env, "invalid display connection.."); return; } diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 99db47168..9fe5089be 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -36,13 +36,14 @@ import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.SurfaceUpdatedListener; +import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.Insets; /** * Specifying the public Window functionality for the * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}. */ -public interface Window extends NativeWindow { +public interface Window extends NativeWindow, WindowClosingProtocol { public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent"); public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent"); public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent"); diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index bee81624a..18213f94f 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -38,21 +38,36 @@ import java.awt.EventQueue; import java.awt.Graphics; import java.awt.KeyboardFocusManager; -import javax.media.nativewindow.*; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.WindowClosingProtocol; +import javax.media.nativewindow.awt.AWTWindowClosingProtocol; +import com.jogamp.nativewindow.impl.awt.AWTMisc; import com.jogamp.newt.event.awt.AWTAdapter; import com.jogamp.newt.event.awt.AWTParentWindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.Window; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.impl.Debug; +import javax.swing.MenuSelectionManager; -public class NewtCanvasAWT extends java.awt.Canvas { +public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol { public static final boolean DEBUG = Debug.debug("Window"); NativeWindow nativeWindow = null; Window newtChild = null; + int newtChildCloseOp; AWTAdapter awtAdapter = null; + private AWTWindowClosingProtocol awtWindowClosingProtocol = + new AWTWindowClosingProtocol(this, new Runnable() { + public void run() { + NewtCanvasAWT.this.destroy(); + } + }); + /** * Instantiates a NewtCanvas without a NEWT child.<br> */ @@ -97,12 +112,18 @@ public class NewtCanvasAWT extends java.awt.Canvas { } FocusAction focusAction = new FocusAction(); + WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() { + public void windowGainedFocus(WindowEvent arg0) { + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + }; + /** sets a new NEWT child, provoking reparenting on the NEWT level. */ public NewtCanvasAWT setNEWTChild(Window child) { if(newtChild!=child) { newtChild = child; if(null!=nativeWindow) { - java.awt.Container cont = getContainer(this); + java.awt.Container cont = AWTMisc.getContainer(this); // reparent right away, addNotify has been called already reparentWindow( (null!=newtChild) ? true : false, cont ); } @@ -119,24 +140,37 @@ public class NewtCanvasAWT extends java.awt.Canvas { * or {@link #addNotify()} hasn't been called yet.*/ public NativeWindow getNativeWindow() { return nativeWindow; } - void setWindowAdapter(boolean attach) { + public int getDefaultCloseOperation() { + return awtWindowClosingProtocol.getDefaultCloseOperation(); + } + + public int setDefaultCloseOperation(int op) { + return awtWindowClosingProtocol.setDefaultCloseOperation(op); + } + + void configureNewtChild(boolean attach) { if(null!=awtAdapter) { awtAdapter.removeFrom(this); awtAdapter=null; } - if(attach && null!=newtChild) { - awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this); - } - } - - static java.awt.Container getContainer(java.awt.Component comp) { - while( null != comp ) { - if( comp instanceof java.awt.Container ) { - return (java.awt.Container) comp; + if( null != newtChild ) { + if(attach) { + awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this); + if(newtChild.isValid()) { + newtChild.addWindowListener(clearAWTMenusOnNewtFocus); + } + newtChild.setFocusAction(focusAction); // enable AWT focus traversal + newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE); + awtWindowClosingProtocol.addClosingListenerOneShot(); + } else { + if(newtChild.isValid()) { + newtChild.removeWindowListener(clearAWTMenusOnNewtFocus); + } + newtChild.setFocusAction(null); + newtChild.setDefaultCloseOperation(newtChildCloseOp); + awtWindowClosingProtocol.removeClosingListener(); } - comp = comp.getParent(); } - return null; } public void addNotify() { @@ -150,7 +184,7 @@ public class NewtCanvasAWT extends java.awt.Canvas { // after native peer is valid: Windows disableBackgroundErase(); - java.awt.Container cont = getContainer(this); + java.awt.Container cont = AWTMisc.getContainer(this); if(DEBUG) { // if ( isShowing() == false ) -> Container was not visible yet. // if ( isShowing() == true ) -> Container is already visible. @@ -161,7 +195,7 @@ public class NewtCanvasAWT extends java.awt.Canvas { } public void removeNotify() { - java.awt.Container cont = getContainer(this); + java.awt.Container cont = AWTMisc.getContainer(this); if(DEBUG) { System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont); } @@ -187,13 +221,12 @@ public class NewtCanvasAWT extends java.awt.Canvas { newtChild.setSize(w, h); newtChild.reparentWindow(nativeWindow); newtChild.setVisible(true); - setWindowAdapter(true); + configureNewtChild(true); newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener newtChild.windowRepaint(0, 0, w, h); - newtChild.setFocusAction(focusAction); // enable AWT focus traversal } } else { - setWindowAdapter(false); + configureNewtChild(false); nativeWindow = null; newtChild.setVisible(false); newtChild.reparentWindow(null); @@ -213,10 +246,11 @@ public class NewtCanvasAWT extends java.awt.Canvas { */ public final void destroy() { if(null!=newtChild) { - java.awt.Container cont = getContainer(this); + java.awt.Container cont = AWTMisc.getContainer(this); if(DEBUG) { System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont); } + configureNewtChild(false); nativeWindow = null; newtChild.setVisible(false); newtChild.reparentWindow(null); @@ -229,11 +263,13 @@ public class NewtCanvasAWT extends java.awt.Canvas { } public void paint(Graphics g) { + awtWindowClosingProtocol.addClosingListenerOneShot(); if(null!=newtChild) { newtChild.windowRepaint(0, 0, getWidth(), getHeight()); } } public void update(Graphics g) { + awtWindowClosingProtocol.addClosingListenerOneShot(); if(null!=newtChild) { newtChild.windowRepaint(0, 0, getWidth(), getHeight()); } diff --git a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java index 88b165a8d..8542820c4 100644 --- a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java @@ -52,6 +52,10 @@ public class TraceWindowAdapter implements WindowListener { System.err.println(e); if(null!=downstream) { downstream.windowDestroyNotify(e); } } + public void windowDestroyed(WindowEvent e) { + System.err.println(e); + if(null!=downstream) { downstream.windowDestroyed(e); } + } public void windowGainedFocus(WindowEvent e) { System.err.println(e); if(null!=downstream) { downstream.windowGainedFocus(e); } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java index a1ad43a13..b9e487e9b 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java @@ -36,6 +36,8 @@ public abstract class WindowAdapter implements WindowListener } public void windowDestroyNotify(WindowEvent e) { } + public void windowDestroyed(WindowEvent e) { + } public void windowGainedFocus(WindowEvent e) { } public void windowLostFocus(WindowEvent e) { diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java index 2742e0d95..f3d62d8c6 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java @@ -46,6 +46,7 @@ public class WindowEvent extends NEWTEvent { public static final int EVENT_WINDOW_GAINED_FOCUS = 103; public static final int EVENT_WINDOW_LOST_FOCUS = 104; public static final int EVENT_WINDOW_REPAINT = 105; + public static final int EVENT_WINDOW_DESTROYED = 106; public WindowEvent(int eventType, Object source, long when) { super(eventType, source, when); @@ -54,11 +55,12 @@ public class WindowEvent extends NEWTEvent { public static String getEventTypeString(int type) { switch(type) { case EVENT_WINDOW_RESIZED: return "WINDOW_RESIZED"; - case EVENT_WINDOW_MOVED: return "WINDOW_MOVED"; - case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY"; - case EVENT_WINDOW_GAINED_FOCUS: return "EVENT_WINDOW_GAINED_FOCUS"; - case EVENT_WINDOW_LOST_FOCUS: return "EVENT_WINDOW_LOST_FOCUS"; - case EVENT_WINDOW_REPAINT: return "EVENT_WINDOW_REPAINT"; + case EVENT_WINDOW_MOVED: return "WINDOW_MOVED"; + case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY"; + case EVENT_WINDOW_GAINED_FOCUS: return "EVENT_WINDOW_GAINED_FOCUS"; + case EVENT_WINDOW_LOST_FOCUS: return "EVENT_WINDOW_LOST_FOCUS"; + case EVENT_WINDOW_REPAINT: return "EVENT_WINDOW_REPAINT"; + case EVENT_WINDOW_DESTROYED: return "EVENT_WINDOW_DESTROYED"; default: return "unknown (" + type + ")"; } } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java index 0d201a2a4..e841a06cf 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowListener.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java @@ -44,6 +44,9 @@ public interface WindowListener extends NEWTEventListener { /** Window will be destroyed. Release of resources is recommended. */ public void windowDestroyNotify(WindowEvent e); + /** Window has been destroyed.*/ + public void windowDestroyed(WindowEvent e); + /** Window gained focus. */ public void windowGainedFocus(WindowEvent e); diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java index 8e33285bf..20c0d15d1 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java @@ -39,7 +39,7 @@ class AWTNewtEventFactory { map.setKeyNotFoundValue(-1); // n/a map.put(java.awt.event.WindowEvent.WINDOW_OPENED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED); map.put(java.awt.event.WindowEvent.WINDOW_CLOSING, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - // n/a map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_CLOSED); + map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROYED); // n/a map.put(java.awt.event.WindowEvent.WINDOW_ICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED); // n/a map.put(java.awt.event.WindowEvent.WINDOW_DEICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED); map.put(java.awt.event.WindowEvent.WINDOW_ACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS); diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index eb46ef99e..74186f70f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -34,6 +34,9 @@ package com.jogamp.newt.impl; +import java.util.ArrayList; +import java.lang.reflect.Method; + import com.jogamp.common.util.ReflectionUtil; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Display; @@ -52,8 +55,6 @@ import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.WindowUpdateEvent; -import java.util.ArrayList; -import java.lang.reflect.Method; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.CapabilitiesChooser; @@ -372,6 +373,26 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer protected void unlockSurfaceImpl() { } //---------------------------------------------------------------------- + // WindowClosingProtocol implementation + // + private Object closingListenerLock = new Object(); + private int defaultCloseOperation = DISPOSE_ON_CLOSE; + + public int getDefaultCloseOperation() { + synchronized (closingListenerLock) { + return defaultCloseOperation; + } + } + + public int setDefaultCloseOperation(int op) { + synchronized (closingListenerLock) { + int _op = defaultCloseOperation; + defaultCloseOperation = op; + return _op; + } + } + + //---------------------------------------------------------------------- // Window: Native implementation // @@ -466,11 +487,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public final void unlockSurface() { // may throw RuntimeException if not locked windowLock.validateLocked(); + AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice(); try { unlockSurfaceImpl(); } finally { - screen.getDisplay().getGraphicsDevice().unlock(); + adevice.unlock(); } windowLock.unlock(); } @@ -586,11 +608,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer public void run() { windowLock.lock(); try { - if(DEBUG_IMPLEMENTATION) { - String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+" -> "+visible+", parentWindowHandle "+toHexString(WindowImpl.this.parentWindowHandle)+", parentWindow "+(null!=WindowImpl.this.parentWindow)/*+", "+this*/); - System.err.println(msg); - } - if(null!=lifecycleHook) { lifecycleHook.resetCounter(); } @@ -651,6 +668,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // fast-path: not realized yet, make visible, but zero size return; } + + if(DEBUG_IMPLEMENTATION) { + String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow)/*+", "+this*/); + System.err.println(msg); + Thread.dumpStack(); + } VisibleAction visibleAction = new VisibleAction(visible); runOnEDTIfAvail(true, visibleAction); } @@ -737,11 +760,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(null!=lifecycleHook) { + // send synced destroy notification for proper cleanup, eg GLWindow/OpenGL lifecycleHook.destroyActionInLock(); } closeAndInvalidate(); + // send synced destroyed notification + sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROYED); + if(DEBUG_IMPLEMENTATION) { System.err.println("Window.destroy() END "+getThreadName()/*+", "+WindowImpl.this*/); } @@ -2006,6 +2033,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY: l.windowDestroyNotify(e); break; + case WindowEvent.EVENT_WINDOW_DESTROYED: + l.windowDestroyed(e); + break; case WindowEvent.EVENT_WINDOW_GAINED_FOCUS: l.windowGainedFocus(e); break; @@ -2097,9 +2127,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("Window.windowDestroyNotify START "+getThreadName()); } - enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + // send synced destroy notifications + enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - if(handleDestroyNotify && isValid()) { + if(handleDestroyNotify && DISPOSE_ON_CLOSE == defaultCloseOperation && isValid()) { destroy(); } @@ -2108,13 +2139,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - protected void windowDestroyed() { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyed "+getThreadName()); - } - closeAndInvalidate(); - } - public void windowRepaint(int x, int y, int width, int height) { if(DEBUG_IMPLEMENTATION) { System.err.println("Window.windowRepaint "+getThreadName()+" - "+x+"/"+y+" "+width+"x"+height); diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java b/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java new file mode 100644 index 000000000..f31d1bc0f --- /dev/null +++ b/src/newt/classes/com/jogamp/newt/impl/awt/opengl/VersionApplet.java @@ -0,0 +1,174 @@ +package com.jogamp.newt.impl.awt.opengl; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.TextArea; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import java.util.List; + +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLEventListener; + +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.newt.NewtVersion; +import com.jogamp.opengl.JoglVersion; + +public class VersionApplet extends Applet { + static { + GLProfile.initSingleton(false); + } + TextArea tareaVersion; + TextArea tareaCaps; + GLCanvas canvas; + + public static void main(String[] args) { + Frame frame = new Frame("JOGL Version Applet"); + frame.setSize(800, 600); + frame.setLayout(new BorderLayout()); + + VersionApplet va = new VersionApplet(); + frame.addWindowListener(new ClosingWindowAdapter(frame, va)); + + va.init(); + frame.add(va, BorderLayout.CENTER); + frame.validate(); + + frame.setVisible(true); + va.start(); + } + + static class ClosingWindowAdapter extends WindowAdapter { + Frame f; + VersionApplet va; + public ClosingWindowAdapter(Frame f, VersionApplet va) { + this.f = f; + this.va = va; + } + public void windowClosing(WindowEvent ev) { + f.setVisible(false); + va.stop(); + va.destroy(); + f.remove(va); + f.dispose(); + System.exit(0); + } + } + + private synchronized void my_init() { + if(null != canvas) { return; } + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities glcaps = new GLCapabilities(glp); + + setLayout(new BorderLayout()); + String s; + + tareaVersion = new TextArea(120, 60); + s = VersionUtil.getPlatformInfo().toString(); + System.err.println(s); + tareaVersion.append(s); + + s = GlueGenVersion.getInstance().toString(); + System.err.println(s); + tareaVersion.append(s); + + s = NativeWindowVersion.getInstance().toString(); + System.err.println(s); + tareaVersion.append(NativeWindowVersion.getInstance().toString()); + + s = JoglVersion.getInstance().toString(); + System.err.println(s); + tareaVersion.append(s); + + s = NewtVersion.getInstance().toString(); + System.err.println(s); + tareaVersion.append(s); + + tareaCaps = new TextArea(120, 20); + GLDrawableFactory factory = GLDrawableFactory.getFactory(glp); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + s = ((GLCapabilitiesImmutable) availCaps.get(i)).toString(); + System.err.println(s); + tareaCaps.append(s); + tareaCaps.append(Platform.getNewline()); + } + + Container grid = new Container(); + grid.setLayout(new GridLayout(2, 1)); + grid.add(tareaVersion); + grid.add(tareaCaps); + add(grid, BorderLayout.CENTER); + + canvas = new GLCanvas(glcaps); + canvas.addGLEventListener(new GLInfo()); + canvas.setSize(10, 10); + add(canvas, BorderLayout.SOUTH); + validate(); + } + + private synchronized void my_release() { + if(null!=canvas) { + remove(canvas); + canvas.destroy(); + canvas = null; + remove(tareaVersion); + tareaVersion=null; + } + } + + public void init() { + System.err.println("VersionApplet: init() - begin"); + my_init(); + System.err.println("VersionApplet: init() - end"); + } + + public void start() { + System.err.println("VersionApplet: start() - begin"); + System.err.println("VersionApplet: start() - end"); + } + + public void stop() { + System.err.println("VersionApplet: stop() - begin"); + System.err.println("VersionApplet: stop() - end"); + } + + public void destroy() { + System.err.println("VersionApplet: destroy() - start"); + my_release(); + System.err.println("VersionApplet: destroy() - end"); + } + + class GLInfo implements GLEventListener { + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); + String s = JoglVersion.getInstance().getGLInfo(gl, null).toString(); + System.err.println(s); + tareaVersion.append(s); + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + } + + public void display(GLAutoDrawable drawable) { + } + + public void dispose(GLAutoDrawable drawable) { + } + } + +} diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index c01139b78..e789a0dc9 100644 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -166,7 +166,6 @@ public class MacWindow extends WindowImpl { setWindowHandle(0); nsViewLock.unlock(); } - windowDestroyed(); // No OSX hook for DidClose, so do it here } public final long getSurfaceHandle() { diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java index 372859208..af32d1693 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -33,73 +34,61 @@ package com.jogamp.newt.impl.windows; -import javax.media.nativewindow.*; -import javax.media.nativewindow.windows.*; -import com.jogamp.newt.*; -import com.jogamp.newt.impl.*; +import com.jogamp.nativewindow.impl.windows.RegisteredClass; +import com.jogamp.nativewindow.impl.windows.RegisteredClassFactory; +import com.jogamp.newt.impl.DisplayImpl; +import com.jogamp.newt.impl.NEWTJNILibLoader; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.windows.WindowsGraphicsDevice; public class WindowsDisplay extends DisplayImpl { - protected static final String WINDOW_CLASS_NAME = "NewtWindowClass"; - private static int windowClassAtom; - private static long hInstance; + private static final String newtClassBaseName = "_newt_clazz" ; + private static RegisteredClassFactory sharedClassFactory; static { NEWTJNILibLoader.loadNEWT(); if (!WindowsWindow.initIDs0()) { throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs"); - } + } + sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowsWindow.getNewtWndProc0()); } public static void initSingleton() { // just exist to ensure static init has been run } + private RegisteredClass sharedClass; public WindowsDisplay() { } protected void createNativeImpl() { + sharedClass = sharedClassFactory.getSharedClass(); aDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT); } protected void closeNativeImpl() { - // Can't do .. only at application shutdown - // UnregisterWindowClass0(getWindowClassAtom(), getHInstance()); + sharedClassFactory.releaseSharedClass(); } protected void dispatchMessagesNative() { DispatchMessages0(); } - protected static synchronized int getWindowClassAtom() { - if(0 == windowClassAtom) { - windowClassAtom = RegisterWindowClass0(WINDOW_CLASS_NAME, getHInstance()); - if (0 == windowClassAtom) { - throw new NativeWindowException("Error while registering window class"); - } - } - return windowClassAtom; + protected long getHInstance() { + return sharedClass.getHandle(); } - protected static synchronized long getHInstance() { - if(0 == hInstance) { - hInstance = LoadLibraryW0("newt"); - if (0 == hInstance) { - throw new NativeWindowException("Error finding HINSTANCE for \"newt\""); - } - } - return hInstance; + protected String getWindowClassName() { + return sharedClass.getName(); } //---------------------------------------------------------------------- // Internals only // - private static native long LoadLibraryW0(String libraryName); - private static native int RegisterWindowClass0(String windowClassName, long hInstance); - private static native void UnregisterWindowClass0(int wndClassAtom, long hInstance); - private static native void DispatchMessages0(); } diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index d4f4f77ea..5ab0a5b79 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -35,8 +35,9 @@ package com.jogamp.newt.impl.windows; import com.jogamp.nativewindow.impl.windows.GDI; -import javax.media.nativewindow.*; import com.jogamp.newt.impl.WindowImpl; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; @@ -56,7 +57,7 @@ public class WindowsWindow extends WindowImpl { protected int lockSurfaceImpl() { if( 0 != getWindowHandle() && 0 == hdc ) { - hdc = GetDC0(getWindowHandle()); + hdc = GDI.GetDC(getWindowHandle()); hmon = MonitorFromWindow0(getWindowHandle()); } return ( 0 != hdc ) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY; @@ -64,7 +65,7 @@ public class WindowsWindow extends WindowImpl { protected void unlockSurfaceImpl() { if ( 0 != hdc && 0 != getWindowHandle() && getWindowLockRecursionCount() == 0) { - ReleaseDC0(getWindowHandle(), hdc); + GDI.ReleaseDC(getWindowHandle(), hdc); hdc=0; } } @@ -97,9 +98,8 @@ public class WindowsWindow extends WindowImpl { if (config == null) { throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); } - setWindowHandle(CreateWindow0(getParentWindowHandle(), - display.getWindowClassAtom(), display.WINDOW_CLASS_NAME, display.getHInstance(), - 0, undecorated, x, y, width, height)); + setWindowHandle(CreateWindow0(display.getHInstance(), display.getWindowClassName(), display.getWindowClassName(), + getParentWindowHandle(), 0, undecorated, x, y, width, height)); if (getWindowHandle() == 0) { throw new NativeWindowException("Error creating window"); } @@ -116,7 +116,7 @@ public class WindowsWindow extends WindowImpl { if (hdc != 0) { if(windowHandleClose != 0) { try { - ReleaseDC0(windowHandleClose, hdc); + GDI.ReleaseDC(windowHandleClose, hdc); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); @@ -128,7 +128,7 @@ public class WindowsWindow extends WindowImpl { } if(windowHandleClose != 0) { try { - DestroyWindow0(windowHandleClose); + GDI.DestroyWindow(windowHandleClose); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t); @@ -140,11 +140,6 @@ public class WindowsWindow extends WindowImpl { } } - protected void windowDestroyed() { - windowHandleClose = 0; - super.windowDestroyed(); - } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { setVisible0(getWindowHandle(), visible, (getParentWindowHandle()==0)?true:false, x, y, width, height); visibleChanged(visible); @@ -177,14 +172,11 @@ public class WindowsWindow extends WindowImpl { // Internals only // protected static native boolean initIDs0(); - private native long CreateWindow0(long parentWindowHandle, - int wndClassAtom, String wndName, - long hInstance, long visualID, - boolean isUndecorated, - int x, int y, int width, int height); - private native void DestroyWindow0(long windowHandle); - private native long GetDC0(long windowHandle); - private native void ReleaseDC0(long windowHandle, long hdc); + protected static native long getNewtWndProc0(); + + private native long CreateWindow0(long hInstance, String wndClassName, String wndName, + long parentWindowHandle, long visualID, boolean isUndecorated, + int x, int y, int width, int height); private native long MonitorFromWindow0(long windowHandle); private native void setVisible0(long windowHandle, boolean visible, boolean top, int x, int y, int width, int height); private native void reconfigureWindow0(long parentWindowHandle, long windowHandle, diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java index 1aaffacb5..af05c0356 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java @@ -76,9 +76,8 @@ public class X11Display extends DisplayImpl { throw e; } aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock()); - // aDevice = new X11GraphicsDevice(handle, NativeWindowFactory.createDefaultToolkitLockNoAWT(NativeWindowFactory.TYPE_X11, handle)); - // aDevice = new X11GraphicsDevice(handle); - + // aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.createDefaultToolkitLockNoAWT(NativeWindowFactory.TYPE_X11, handle)); + // aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT); } protected void closeNativeImpl() { diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index 73c6eb351..b8f1a0c95 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -87,11 +87,6 @@ public class X11Window extends WindowImpl { } } - protected void windowDestroyed() { - windowHandleClose = 0; - super.windowDestroyed(); - } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { setVisible0(getDisplayHandle(), getWindowHandle(), visible, x, y, width, height); } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 358a3d4ce..6886fc71b 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -34,18 +34,22 @@ package com.jogamp.newt.opengl; +import java.util.List; + import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionUtil; import com.jogamp.nativewindow.NativeWindowVersion; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.impl.WindowImpl; + import javax.media.nativewindow.*; import javax.media.nativewindow.util.Point; +import javax.media.nativewindow.util.Insets; import javax.media.opengl.*; + import com.jogamp.opengl.impl.GLDrawableHelper; import com.jogamp.opengl.JoglVersion; -import javax.media.nativewindow.util.Insets; /** * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface, @@ -85,24 +89,26 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } public void windowDestroyNotify(WindowEvent e) { - // Is an animator thread perform rendering? - if (GLWindow.this.helper.isExternalAnimatorRunning()) { - // Pause animations before initiating safe destroy. - GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator(); - boolean isPaused = ctrl.pause(); - destroy(); - if(isPaused) { - ctrl.resume(); + if( DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) { + // Is an animator thread perform rendering? + if (GLWindow.this.helper.isExternalAnimatorRunning()) { + // Pause animations before initiating safe destroy. + GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator(); + boolean isPaused = ctrl.pause(); + destroy(); + if(isPaused) { + ctrl.resume(); + } + } else if (GLWindow.this.window.isSurfaceLockedByOtherThread()) { + // Surface is locked by another thread + // Flag that destroy should be performed on the next + // attempt to display. + sendDestroy = true; + } else { + // Without an external thread animating or locking the + // surface, we are safe. + destroy (); } - } else if (GLWindow.this.window.isSurfaceLockedByOtherThread()) { - // Surface is locked by another thread - // Flag that destroy should be performed on the next - // attempt to display. - sendDestroy = true; - } else { - // Without an external thread animating or locking the - // surface, we are safe. - destroy (); } } }); @@ -152,6 +158,17 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { } //---------------------------------------------------------------------- + // WindowClosingProtocol implementation + // + public int getDefaultCloseOperation() { + return window.getDefaultCloseOperation(); + } + + public int setDefaultCloseOperation(int op) { + return window.setDefaultCloseOperation(op); + } + + //---------------------------------------------------------------------- // Window Access // @@ -882,7 +899,14 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer { System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); System.err.println(NewtVersion.getInstance()); - GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault() ); + + GLProfile glp = GLProfile.getDefault(); + GLDrawableFactory factory = GLDrawableFactory.getFactory(glp); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } + GLCapabilitiesImmutable caps = new GLCapabilities( glp ); GLWindow glWindow = GLWindow.create(caps); glWindow.setSize(128, 128); diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index 33af4d963..50ad22b5a 100644 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -94,7 +94,6 @@ static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; @@ -137,8 +136,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes { DBG_PRINT( "event window close : src: %p\n", userData); (*env)->CallVoidMethod(env, javaWindow, windowDestroyNotifyID); - // Called by Window.java: DestroyWindow(wnd); - // (*env)->CallVoidMethod(env, javaWindow, windowDestroyedID); } break; case KD_EVENT_WINDOWPROPERTY_CHANGE: @@ -213,14 +210,12 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); if (windowCreatedID == NULL || sizeChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || sendMouseEventID == NULL || sendKeyEventID == NULL) { DBG_PRINT( "initIDs failed\n" ); diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 2d8a84b4b..cba69498a 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -80,7 +80,6 @@ static jmethodID visibleChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; @implementation NewtView - (void) setJNIEnv: (JNIEnv*) theEnv @@ -142,9 +141,8 @@ static jmethodID windowDestroyedID = NULL; positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); if (sendMouseEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID && - positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID) + positionChangedID && focusChangedID && windowDestroyNotifyID) { return YES; } @@ -456,7 +454,6 @@ static jint mods2JavaMods(NSUInteger mods) (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID); // Can't issue call here - locked window state, done from Java method - // (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyedID); // No OSX hook for DidClose, so do it here // EOL .. (*env)->DeleteGlobalRef(env, javaWindowObject); diff --git a/src/newt/native/WindowEvent.h b/src/newt/native/WindowEvent.h index 6274f9443..05491b43c 100644 --- a/src/newt/native/WindowEvent.h +++ b/src/newt/native/WindowEvent.h @@ -2,11 +2,12 @@ #ifndef _WINDOW_EVENT_H_ #define _WINDOW_EVENT_H_ -#define EVENT_WINDOW_RESIZED = 100; -#define EVENT_WINDOW_MOVED = 101; -#define EVENT_WINDOW_DESTROY_NOTIFY = 102; -#define EVENT_WINDOW_GAINED_FOCUS = 103; -#define EVENT_WINDOW_LOST_FOCUS = 104; -#define EVENT_WINDOW_REPAINT = 105; // TODO +#define EVENT_WINDOW_RESIZED 100 +#define EVENT_WINDOW_MOVED 101 +#define EVENT_WINDOW_DESTROY_NOTIFY 102 +#define EVENT_WINDOW_GAINED_FOCUS 103 +#define EVENT_WINDOW_LOST_FOCUS 104 +#define EVENT_WINDOW_REPAINT 105 +#define EVENT_WINDOW_DESTROYED 106 #endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index b282ec9b2..998743e75 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -124,7 +124,6 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID enqueueMouseEventID = NULL; static jmethodID sendMouseEventID = NULL; @@ -820,8 +819,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, // // The signal pipeline for destruction is: // Java::DestroyWindow(wnd) _or_ window-close-button -> - // WM_CLOSE -> Java::windowDestroyNotify -> W_DESTROY -> Java::windowDestroyed -> - // Java::CleanupWindowResources() + // WM_CLOSE -> Java::windowDestroyNotify -> W_DESTROY case WM_CLOSE: (*env)->CallVoidMethod(env, window, windowDestroyNotifyID); break; @@ -834,7 +832,6 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, SetWindowLongPtr(wnd, GWLP_USERDATA, (intptr_t) NULL); #endif free(wud); wud=NULL; - (*env)->CallVoidMethod(env, window, windowDestroyedID); (*env)->DeleteGlobalRef(env, window); } break; @@ -1047,71 +1044,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Dispatch } /* - * Class: com_jogamp_newt_impl_windows_WindowsDisplay - * Method: LoadLibraryW - * Signature: (Ljava/lang/String;)J - */ -JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_LoadLibraryW0 - (JNIEnv *env, jclass clazz, jstring dllName) -{ - jchar* _dllName = NewtCommon_GetNullTerminatedStringChars(env, dllName); - HMODULE lib = LoadLibraryW(_dllName); - free(_dllName); - return (jlong) (intptr_t) lib; -} - -/* - * Class: com_jogamp_newt_impl_windows_WindowsDisplay - * Method: RegisterWindowClass - * Signature: (Ljava/lang/String;J)I - */ -JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_RegisterWindowClass0 - (JNIEnv *env, jclass clazz, jstring wndClassName, jlong hInstance) -{ - ATOM res; - WNDCLASS wc; -#ifndef UNICODE - const char* _wndClassName = NULL; -#endif - - /* register class */ - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)wndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - /* This cast is legal because the HMODULE for a DLL is the same as - its HINSTANCE -- see MSDN docs for DllMain */ - wc.hInstance = (HINSTANCE) (intptr_t) hInstance; - wc.hIcon = NULL; - wc.hCursor = LoadCursor( NULL, IDC_ARROW); - wc.hbrBackground = GetStockObject(BLACK_BRUSH); - wc.lpszMenuName = NULL; -#ifdef UNICODE - wc.lpszClassName = NewtCommon_GetNullTerminatedStringChars(env, wndClassName); -#else - _wndClassName = (*env)->GetStringUTFChars(env, wndClassName, NULL); - wc.lpszClassName = strdup(_wndClassName); - (*env)->ReleaseStringUTFChars(env, wndClassName, _wndClassName); -#endif - res = RegisterClass(&wc); - - free((void *)wc.lpszClassName); - - return (jint)res; -} - -/* - * Class: com_jogamp_newt_impl_windows_WindowsDisplay - * Method: CleanupWindowResources - * Signature: (java/lang/String;J)V - */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_UnregisterWindowClass0 - (JNIEnv *env, jclass clazz, jint wndClassAtom, jlong hInstance) -{ - UnregisterClass(MAKEINTATOM(wndClassAtom), (HINSTANCE) (intptr_t) hInstance); -} - -/* * Class: com_jogamp_newt_impl_windows_WindowsScreen * Method: getWidthImpl * Signature: (I)I @@ -1332,7 +1264,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); @@ -1347,7 +1278,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || windowRepaintID == NULL || enqueueMouseEventID == NULL || sendMouseEventID == NULL || @@ -1363,15 +1293,27 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI /* * Class: com_jogamp_newt_impl_windows_WindowsWindow + * Method: getNewtWndProc0 + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_getNewtWndProc0 + (JNIEnv *env, jclass clazz) +{ + return (jlong) (intptr_t) wndProc; +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: CreateWindow - * Signature: (JILjava/lang/String;JJZIIII)J */ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWindow0 - (JNIEnv *env, jobject obj, jlong parent, jint wndClassAtom, jstring jWndName, jlong hInstance, jlong visualID, - jboolean bIsUndecorated, - jint jx, jint jy, jint defaultWidth, jint defaultHeight) + (JNIEnv *env, jobject obj, + jlong hInstance, jstring jWndClassName, jstring jWndName, + jlong parent, jlong visualID, jboolean bIsUndecorated, + jint jx, jint jy, jint defaultWidth, jint defaultHeight) { HWND parentWindow = (HWND) (intptr_t) parent; + const TCHAR* wndClassName = NULL; const TCHAR* wndName = NULL; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_TABSTOP; int x=(int)jx, y=(int)jy; @@ -1379,8 +1321,10 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi HWND window = NULL; #ifdef UNICODE + wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName); wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); #else + wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL); wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); #endif @@ -1400,13 +1344,13 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi (void) visualID; // FIXME: use the visualID .. - window = CreateWindow(MAKEINTATOM(wndClassAtom), wndName, windowStyle, + window = CreateWindow(wndClassName, wndName, windowStyle, x, y, width, height, parentWindow, NULL, (HINSTANCE) (intptr_t) hInstance, NULL); - DBG_PRINT("*** WindowsWindow: CreateWindow thread 0xX, parent %p, window %p, %d/%d %dx%d\n", + DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d\n", (int)GetCurrentThreadId(), parentWindow, window, x, y, width, height); if (NULL == window) { @@ -1427,8 +1371,10 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi } #ifdef UNICODE + free((void*) wndClassName); free((void*) wndName); #else + (*env)->ReleaseStringUTFChars(env, jWndClassName, wndClassName); (*env)->ReleaseStringUTFChars(env, jWndName, wndName); #endif @@ -1437,40 +1383,6 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi /* * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: DestroyWindow - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_DestroyWindow0 - (JNIEnv *env, jobject obj, jlong window) -{ - DBG_PRINT("*** WindowsWindow: DestroyWindow thread 0x%X, window %p\n", (int)GetCurrentThreadId(), window); - DestroyWindow((HWND) (intptr_t) window); -} - -/* - * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: GetDC - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_GetDC0 - (JNIEnv *env, jobject obj, jlong window) -{ - return (jlong) (intptr_t) GetDC((HWND) (intptr_t) window); -} - -/* - * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: ReleaseDC - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_ReleaseDC0 - (JNIEnv *env, jobject obj, jlong window, jlong dc) -{ - ReleaseDC((HWND) (intptr_t) window, (HDC) (intptr_t) dc); -} - -/* - * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: MonitorFromWindow * Signature: (J)J */ diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 15418269e..d30e5de59 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -147,7 +147,6 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID windowReparentedID = NULL; static jmethodID enqueueMouseEventID = NULL; @@ -624,7 +623,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event); if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) { // ignore child destroy notification - (*env)->CallVoidMethod(env, jwindow, windowDestroyedID); } break; case CreateNotify: @@ -1191,7 +1189,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); windowReparentedID = (*env)->GetMethodID(env, clazz, "windowReparented", "(J)V"); enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V"); @@ -1206,7 +1203,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 focusChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || windowRepaintID == NULL || windowReparentedID == NULL || enqueueMouseEventID == NULL || @@ -1394,8 +1390,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 (*env)->DeleteGlobalRef(env, jwindow); DBG_PRINT( "X11: CloseWindow END\n"); - - (*env)->CallVoidMethod(env, obj, windowDestroyedID); } static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) diff --git a/src/test/com/jogamp/newt/impl/WindowImplAccess.java b/src/test/com/jogamp/newt/impl/WindowImplAccess.java new file mode 100644 index 000000000..5a90c8094 --- /dev/null +++ b/src/test/com/jogamp/newt/impl/WindowImplAccess.java @@ -0,0 +1,52 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.impl; + +import com.jogamp.newt.Window; +import com.jogamp.newt.opengl.GLWindow; + +/** + * Allows access to protected methods of WindowImpl + */ +public class WindowImplAccess { + public static final void windowDestroyNotify(Window win) { + WindowImpl winImpl = null; + if(win instanceof GLWindow) { + GLWindow glwin = (GLWindow) win; + winImpl = (WindowImpl) glwin.getWindow(); + } else if(win instanceof WindowImpl) { + winImpl = (WindowImpl) win; + } else { + throw new RuntimeException("Given Window not a GLWindow, not WindowImpl, but "+win.getClass()); + } + winImpl.windowDestroyNotify(); + } +} + + diff --git a/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java b/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java new file mode 100644 index 000000000..ceee2c876 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/bugs/Bug427GLJPanelTest1.java @@ -0,0 +1,72 @@ +package com.jogamp.opengl.test.bugs;
+
+import javax.swing.*;
+import java.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+public class Bug427GLJPanelTest1 extends JFrame implements GLEventListener {
+
+ public Bug427GLJPanelTest1() {
+ super("Bug427GLJPanelTest1");
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new BorderLayout());
+
+ setSize(600, 600);
+ setLocation(40, 40);
+ setVisible(true);
+
+ GLProfile glp = GLProfile.getDefault();
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(true);
+ caps.setHardwareAccelerated(true);
+
+ GLJPanel panel = new GLJPanel(caps);
+ panel.addGLEventListener(this);
+
+ add(panel, BorderLayout.CENTER);
+ }
+
+ public static void main(String[] args) {
+ Bug427GLJPanelTest1 demo = new Bug427GLJPanelTest1();
+ demo.setVisible(true);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT);
+ gl.glBegin(GL.GL_TRIANGLES);
+
+ gl.glColor3f(1, 0, 0);
+ gl.glVertex3f(0.25f, 0.25f, 0);
+
+ gl.glColor3f(0, 1, 0);
+ gl.glVertex3f(0.5f, 0.25f, 0);
+
+ gl.glColor3f(0, 0, 1);
+ gl.glVertex3f(0.25f, 0.5f, 0);
+
+ gl.glEnd();
+ gl.glFlush();
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glClearColor(0, 0, 0, 0);
+ gl.glMatrixMode(GL2.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(0, 1, 0, 1, -1, 1);
+ }
+
+ public void reshape(GLAutoDrawable glDrawable, int x, int y, int w, int h) {
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ }
+}
diff --git a/test/Issue326Test1.java b/src/test/com/jogamp/opengl/test/bugs/Issue326Test1.java index adf2861d0..4c2b54755 100644 --- a/test/Issue326Test1.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue326Test1.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + import java.awt.Frame; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; diff --git a/test/Issue326Test2.java b/src/test/com/jogamp/opengl/test/bugs/Issue326Test2.java index b87eee21b..8960c9658 100644 --- a/test/Issue326Test2.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue326Test2.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + import java.awt.Font; import java.awt.Frame; import java.awt.event.*; diff --git a/test/Issue344Base.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java index 8d0c3b0e1..c3401fec3 100644 --- a/test/Issue344Base.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Base.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + import java.awt.BorderLayout; import java.awt.Font; import java.awt.Frame; diff --git a/test/Issue344Test1.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Test1.java index c0608ed6e..f0da7cbf8 100644 --- a/test/Issue344Test1.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Test1.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + public class Issue344Test1 extends Issue344Base { protected String getText() { // test 1 - weird artifacts appear with a large font & long string diff --git a/test/Issue344Test2.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Test2.java index b0900438c..bb1acf2de 100644 --- a/test/Issue344Test2.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Test2.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + public class Issue344Test2 extends Issue344Base { protected String getText() { // test 2 - unicode hangs program with a large font & long string diff --git a/test/Issue344Test3.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Test3.java index 381bf0a1c..bb73d84ec 100644 --- a/test/Issue344Test3.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Test3.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + public class Issue344Test3 extends Issue344Base { protected String getText() { // test 3 - slight rendering artifacts around very large letters diff --git a/test/Issue344Test4.java b/src/test/com/jogamp/opengl/test/bugs/Issue344Test4.java index 1e077d2fd..de4c37a40 100644 --- a/test/Issue344Test4.java +++ b/src/test/com/jogamp/opengl/test/bugs/Issue344Test4.java @@ -1,3 +1,5 @@ +package com.jogamp.opengl.test.bugs; + public class Issue344Test4 extends Issue344Base { protected String getText() { // test 4 - unicode letter as second-to-last is rendered incorrectly diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java index 742c0174c..13af808c0 100644 --- a/src/junit/com/jogamp/test/junit/jogl/acore/TestGLProfile01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java @@ -26,60 +26,51 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.acore; +package com.jogamp.opengl.test.junit.jogl.acore; -import com.jogamp.common.GlueGenVersion; -import com.jogamp.common.util.VersionUtil; -import com.jogamp.nativewindow.NativeWindowVersion; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.DumpGLInfo; +import java.io.IOException; +import java.util.List; import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.AfterClass; import org.junit.Test; import javax.media.opengl.*; -import com.jogamp.newt.*; -import com.jogamp.newt.opengl.*; -import com.jogamp.newt.*; +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.VersionUtil; +import com.jogamp.nativewindow.NativeWindowVersion; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.DumpGLInfo; import com.jogamp.opengl.JoglVersion; -import java.io.IOException; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.*; public class TestGLProfile01NEWT extends UITestCase { - static GLProfile glp; - - @BeforeClass - public static void initClass() { - GLProfile.initSingleton(true); - glp = GLProfile.getDefault(); - Assert.assertNotNull(glp); - } - - @AfterClass - public static void releaseClass() { - } @Test - public void test00Version() { + public void test00Version() throws InterruptedException { System.err.println(VersionUtil.getPlatformInfo()); System.err.println(GlueGenVersion.getInstance()); System.err.println(NativeWindowVersion.getInstance()); System.err.println(JoglVersion.getInstance()); System.err.println(NewtVersion.getInstance()); + + GLDrawableFactory factory = GLDrawableFactory.getFactory(GLProfile.getDefault()); + List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null); + for(int i=0; i<availCaps.size(); i++) { + System.err.println(availCaps.get(i)); + } } @Test - public void test01GLProfileDefault() { + public void test01GLProfileDefault() throws InterruptedException { System.out.println("GLProfile "+GLProfile.glAvailabilityToString()); GLProfile glp = GLProfile.getDefault(); dumpVersion(glp); } @Test - public void test02GLProfileMaxFixedFunc() { + public void test02GLProfileMaxFixedFunc() throws InterruptedException { // Assuming at least one fixed profile is available GLProfile glp = GLProfile.getMaxFixedFunc(); System.out.println("GLProfile getMaxFixedFunc(): "+glp); @@ -105,7 +96,7 @@ public class TestGLProfile01NEWT extends UITestCase { } @Test - public void test03GLProfileMaxProgrammable() { + public void test03GLProfileMaxProgrammable() throws InterruptedException { // Assuming at least one programmable profile is available GLProfile glp = GLProfile.getMaxProgrammable(); System.out.println("GLProfile getMaxProgrammable(): "+glp); @@ -131,7 +122,7 @@ public class TestGLProfile01NEWT extends UITestCase { } @Test - public void test04GLProfileGL2ES1() { + public void test04GLProfileGL2ES1() throws InterruptedException { if(!GLProfile.isGL2ES1Available()) { System.out.println("GLProfile GL2ES1 n/a"); return; @@ -142,7 +133,7 @@ public class TestGLProfile01NEWT extends UITestCase { } @Test - public void test05GLProfileGL2ES2() { + public void test05GLProfileGL2ES2() throws InterruptedException { if(!GLProfile.isGL2ES2Available()) { System.out.println("GLProfile GL2ES2 n/a"); return; @@ -152,7 +143,7 @@ public class TestGLProfile01NEWT extends UITestCase { dumpVersion(glp); } - protected void dumpVersion(GLProfile glp) { + protected void dumpVersion(GLProfile glp) throws InterruptedException { GLCapabilities caps = new GLCapabilities(glp); GLWindow glWindow = GLWindow.create(caps); Assert.assertNotNull(glWindow); @@ -162,7 +153,9 @@ public class TestGLProfile01NEWT extends UITestCase { glWindow.setSize(128, 128); glWindow.setVisible(true); + glWindow.display(); + Thread.sleep(100); glWindow.invalidate(); } diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/TestSharedContextListAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java index b44158dce..6d9801d48 100644 --- a/src/junit/com/jogamp/test/junit/jogl/acore/TestSharedContextListAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.acore; +package com.jogamp.opengl.test.junit.jogl.acore; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLDrawableFactory; @@ -35,10 +35,12 @@ import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import java.awt.Frame; +import javax.swing.SwingUtilities; import org.junit.Assert; import org.junit.BeforeClass; @@ -76,17 +78,15 @@ public class TestSharedContextListAWT extends UITestCase { Assert.assertNotNull(sharedDrawable); sharedDrawable.destroy(); } + protected Frame createFrame(int x, int y, boolean useShared) { + return new Frame("Shared Gears AWT Test: "+x+"/"+y+" shared "+useShared); + } - protected Frame runTestGL(Animator animator, int x, int y, boolean useShared) { - Frame frame = new Frame("Shared Gears AWT Test: "+x+"/"+y+" shared "+useShared); - Assert.assertNotNull(frame); - - GLCanvas glCanvas = new GLCanvas(caps, useShared ? sharedDrawable.getContext() : null); + protected GLCanvas runTestGL(final Frame frame, final Animator animator, final int x, final int y, final boolean useShared) + throws InterruptedException + { + final GLCanvas glCanvas = new GLCanvas(caps, useShared ? sharedDrawable.getContext() : null); Assert.assertNotNull(glCanvas); - frame.add(glCanvas); - frame.setSize(width, height); - frame.setLocation(x, y); - Gears gears = new Gears(); if(useShared) { gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3()); @@ -95,27 +95,55 @@ public class TestSharedContextListAWT extends UITestCase { animator.add(glCanvas); - frame.setVisible(true); - - return frame; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.add(glCanvas); + frame.pack(); + frame.setSize(width, height); + frame.setLocation(x, y); + frame.validate(); + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); + + return glCanvas; } @Test public void test01() throws InterruptedException { initShared(); + + Frame f1 = createFrame(0, 0, true); + Frame f2 = createFrame(width, 0, true); + Frame f3 = createFrame(0, height, false); + Animator animator = new Animator(); - Frame f1 = runTestGL(animator, 0, 0, true); - Frame f2 = runTestGL(animator, width, 0, true); - Frame f3 = runTestGL(animator, 0, height, false); + + GLCanvas glc1 = runTestGL(f1, animator, 0, 0, true); + GLCanvas glc2 = runTestGL(f2, animator, width, 0, true); + GLCanvas glc3 = runTestGL(f3, animator, 0, height, false); + animator.start(); while(animator.isAnimating() && animator.getDuration()<duration) { Thread.sleep(100); } animator.stop(); + + // here we go again: On AMD/X11 the create/destroy sequence must be the same + // even though this is agains the chicken/egg logic here .. + releaseShared(); + f1.dispose(); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc1, false)); + f2.dispose(); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc2, false)); + f3.dispose(); - releaseShared(); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc3, false)); + + // see above .. + //releaseShared(); } static long duration = 500; // ms diff --git a/src/junit/com/jogamp/test/junit/jogl/acore/TestSharedContextListNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java index cccd91b4c..f5c950646 100644 --- a/src/junit/com/jogamp/test/junit/jogl/acore/TestSharedContextListNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.acore; +package com.jogamp.opengl.test.junit.jogl.acore; import com.jogamp.newt.opengl.GLWindow; import javax.media.opengl.GLCapabilities; @@ -35,8 +35,8 @@ import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import org.junit.Assert; import org.junit.BeforeClass; @@ -111,10 +111,17 @@ public class TestSharedContextListNEWT extends UITestCase { Thread.sleep(100); } animator.stop(); + + // here we go again: On AMD/X11 the create/destroy sequence must be the same + // even though this is agains the chicken/egg logic here .. + releaseShared(); + f1.destroy(); f2.destroy(); f3.destroy(); - releaseShared(); + + // see above .. + // releaseShared(); } static long duration = 500; // ms diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java index 0fef76c7d..83561eb97 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT01GLn.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java @@ -26,15 +26,15 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.awt; +package com.jogamp.opengl.test.junit.jogl.awt; import javax.media.opengl.GLProfile; import javax.media.opengl.GLCapabilities; import javax.media.opengl.awt.GLCanvas; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import java.awt.Frame; @@ -84,6 +84,7 @@ public class TestAWT01GLn extends UITestCase { protected void runTestGL(GLCapabilities caps) throws InterruptedException { glCanvas = new GLCanvas(caps); Assert.assertNotNull(glCanvas); + glCanvas.addGLEventListener(new Gears()); frame.add(glCanvas); // Revalidate size/layout. @@ -92,8 +93,6 @@ public class TestAWT01GLn extends UITestCase { frame.setSize(512, 512); frame.validate(); - glCanvas.addGLEventListener(new Gears()); - try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT02WindowClosing.java index 6132f8232..535f0e99e 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT02WindowClosing.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT02WindowClosing.java @@ -26,9 +26,9 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.awt; +package com.jogamp.opengl.test.junit.jogl.awt; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import javax.media.opengl.GLProfile; import java.awt.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java index a2f66859f..2faf8fa66 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT03GLCanvasRecreate01.java @@ -26,15 +26,15 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.awt; +package com.jogamp.opengl.test.junit.jogl.awt; import javax.media.opengl.GLProfile; import javax.media.opengl.awt.GLCanvas; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.MiscUtils; import java.awt.Frame; import java.awt.Label; diff --git a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java index 74ca0a3e7..8f642dfc9 100644 --- a/src/junit/com/jogamp/test/junit/jogl/awt/TestSwingAWT01GLn.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestSwingAWT01GLn.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.awt; +package com.jogamp.opengl.test.junit.jogl.awt; import java.lang.reflect.InvocationTargetException; import javax.media.opengl.GLProfile; @@ -34,8 +34,8 @@ import javax.media.opengl.GLCapabilities; import javax.media.opengl.awt.GLCanvas; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import java.awt.Frame; import java.awt.Window; import javax.swing.JFrame; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java new file mode 100644 index 000000000..fc19a6842 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TestAWTTextRendererUseVertexArrayBug464.java @@ -0,0 +1,155 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.awt.GLCanvas; +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.util.UITestCase; + +import java.awt.Frame; +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.Test; + +/* + * Unit tests for Bug464 + * Some ATI-Drivers crash the JVM if VBO-related glFunctions are called. This test checks + * if TextRenderer calls any of these functions while it's useVertexArray variable is set + * to false. + * 2D- and 3D-TextRendering is tested by creating a GLCanvas showing a simple line of text + * while filtering all glFunction calls by using a modified version of TraceGL2. + * VBO-related function are logged to the disallowedMethodCalls String of the GLEventListener + * instead of being executed (to prevent JVM crashes). Therefore, if the + * disallowedMethodCalls isn't an empty String after the test, the test fails. + * + * Other classes related to this test: + * TestTextRendererGLEventListener01 + * TestTextRendererTraceGL2Mock01 + */ + +public class TestAWTTextRendererUseVertexArrayBug464 extends UITestCase { + static GLProfile glp; + static GLCapabilities caps; + + private GLCanvas glCanvas; + private Frame frame; + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + glp = GLProfile.get(GLProfile.GL2); + Assert.assertNotNull(glp); + caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + } + + @Before + public void initTest() { + glCanvas = new GLCanvas(caps); + + frame = new Frame("TextRenderer Test"); + Assert.assertNotNull(frame); + frame.add(glCanvas); + frame.setSize(512, 512); + frame.setVisible(true); + + } + + @After + public void cleanupTest() { + frame.setVisible(false); + frame.remove(glCanvas); + glCanvas=null; + Assert.assertNotNull(frame); + frame.dispose(); + frame=null; + } + + @Test + public void testTextRendererDraw2D() throws InterruptedException { + + TextRendererGLEventListener01 listener = new TextRendererGLEventListener01(1); + Assert.assertNotNull(listener); + glCanvas.addGLEventListener(listener); + Animator animator = new Animator(glCanvas); + + animator.start(); + + Thread.sleep(500); // 500 ms + + animator.stop(); + + String disallowedMethods = listener.getDisallowedMethodCalls(); + if (!disallowedMethods.equals("")) { + Assert.fail("Following VBO-related glMethods have been called: "+ disallowedMethods); + } + } + + @Test + public void testTextRendererDraw3D() throws InterruptedException { + + TextRendererGLEventListener01 listener = new TextRendererGLEventListener01(2); + Assert.assertNotNull(listener); + glCanvas.addGLEventListener(listener); + Animator animator = new Animator(glCanvas); + + animator.start(); + + Thread.sleep(500); // 500 ms + + animator.stop(); + + String disallowedMethods = listener.getDisallowedMethodCalls(); + if (!disallowedMethods.equals("")) { + Assert.fail("Following VBO-related glMethods have been called: "+ disallowedMethods); + } + } + + public static void main(String args[]) throws IOException { + String tstname = TestAWTTextRendererUseVertexArrayBug464.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java new file mode 100644 index 000000000..b14704142 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererGLEventListener01.java @@ -0,0 +1,124 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import java.awt.Font; +import java.io.OutputStream; +import java.io.PrintStream; + +import com.jogamp.opengl.util.awt.TextRenderer; +import javax.media.opengl.GL2ES1; +import javax.media.opengl.GL2; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; + +/* + * Unit tests for Bug464 + * GLEventListener for unit test TestAWTTextRendererUseVertexArrayBug464. The display + * method renders the String "ABC123#+?" to the lower left corner of the canvas. + * + * The testNumber variable is used to switch between 2D- and 3D-textrendering in the display + * method. + * The disallowedMethodCalls variable is used to log VBO-related glFunction calls during + * the execution of the test. + * + * Other classes related to this test: + * TestAWTTextRendererUseVertexArrayBug464 + * TextRendererTraceGL2Mock01 + */ + +public class TextRendererGLEventListener01 implements GLEventListener { + private GLU glu = new GLU(); + private TextRenderer renderer; + private String text; + private String disallowedMethodCalls; + private int testNumber; + + public TextRendererGLEventListener01(int testNumber) { + this.disallowedMethodCalls = ""; + this.testNumber = testNumber; + } + + public void init(GLAutoDrawable drawable) { + renderer = new TextRenderer(new Font("SansSerif", Font.BOLD, 36)); + renderer.setUseVertexArrays(false); + Assert.assertNotNull(renderer); + Assert.assertFalse(renderer.getUseVertexArrays()); + + text = "ABC123#+?"; + + PrintStream nullStream = new PrintStream(new OutputStream(){ public void write(int b){}}); + drawable.setGL(new TextRendererTraceGL2Mock01(drawable.getGL().getGL2(), nullStream, this)); + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + GL2 gl = drawable.getGL().getGL2(); + gl.glMatrixMode(GL2ES1.GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluOrtho2D(0, 1, 0, 1); + gl.glMatrixMode(GL2ES1.GL_MODELVIEW); + gl.glLoadIdentity(); + } + + public void dispose(GLAutoDrawable drawable) { + renderer.dispose(); + } + + public void display(GLAutoDrawable drawable) { + if (disallowedMethodCalls.equals("")) { + if (testNumber == 1) { + renderer.beginRendering(drawable.getWidth(), drawable.getHeight()); + renderer.setColor(1.0f, 1.0f, 1.0f, 1.0f); + renderer.draw(text, 0, 0); + renderer.endRendering(); + } + if (testNumber == 2) { + renderer.begin3DRendering(); + renderer.setColor(1.0f, 1.0f, 1.0f, 1.0f); + renderer.draw3D(text, 0, 0, 0, 0.002f); + renderer.end3DRendering(); + } + } + } + + public void disallowedMethodCalled (String method) { + if (!disallowedMethodCalls.equals("")) { + disallowedMethodCalls += ", "; + } + disallowedMethodCalls += method; + } + + public String getDisallowedMethodCalls() { + return this.disallowedMethodCalls; + } +} + diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java new file mode 100644 index 000000000..63258a574 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/text/TextRendererTraceGL2Mock01.java @@ -0,0 +1,137 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.awt.text; + +import java.io.PrintStream; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import javax.media.opengl.GL2; +import javax.media.opengl.TraceGL2; + +import com.jogamp.common.nio.Buffers; + +/* + * Unit tests for Bug464 + * Modified Version of TraceGL2 for unit test TestAWTTextRendererUseVertexArrayBug464. + * This class overrides all glFunctions related to VBO's according to + * http://code.google.com/p/glextensions/wiki/GL_ARB_vertex_buffer_object: + * glBindBuffer (glBindBufferARB) + * glDeleteBuffers (glDeleteBuffersARB) + * glGenBuffers (glGenBuffersARB) + * glIsBuffer (glIsBufferARB) + * glBufferData (glBufferDataARB) + * glBufferSubData (glBufferSubDataARB) + * glGetBufferSubData (glGetBufferSubDataARB) + * glMapBuffer (glMapBufferARB) + * glUnmapBuffer (glUnmapBufferARB) + * glGetBufferParameteriv (glGetBufferParameterivARB) + * glGetBufferPointerv (glGetBufferPointervARB) + * Calls to the overridden methods are logged to the disallowedMethodCalls variable of + * the GLEventListener instead of being passed to the downstreamGL object. + * + * Other classes related to this test: + * TestAWTTextRendererUseVertexArrayBug464 + * TextRendererGLEventListener01 + */ + +public class TextRendererTraceGL2Mock01 extends TraceGL2 { + + TextRendererGLEventListener01 listener; + + public TextRendererTraceGL2Mock01(GL2 downstreamGL2, PrintStream stream, TextRendererGLEventListener01 listener) { + super(downstreamGL2, stream); + this.listener = listener; + } + + @Override + public void glGetBufferSubData(int arg0, long arg1, long arg2, Buffer arg3) { + listener.disallowedMethodCalled("glGetBufferSubData"); + } + + @Override + public ByteBuffer glMapBuffer(int arg0, int arg1) { + listener.disallowedMethodCalled("glMapBuffer"); + return Buffers.newDirectByteBuffer(0); + } + + @Override + public void glGetBufferParameteriv(int arg0, int arg1, IntBuffer arg2) { + listener.disallowedMethodCalled("glGetBufferParameteriv"); + } + + @Override + public boolean glUnmapBuffer(int arg0) { + listener.disallowedMethodCalled("glUnmapBuffer"); + return false; + } + + @Override + public void glGenBuffers(int arg0, IntBuffer arg1) { + listener.disallowedMethodCalled("glGenBuffers"); + } + + @Override + public void glGenBuffers(int arg0, int[] arg1, int arg2) { + listener.disallowedMethodCalled("glGenBuffers"); + } + + @Override + public boolean glIsBuffer(int arg0) { + listener.disallowedMethodCalled("glIsBuffer"); + return false; + } + + @Override + public void glBindBuffer(int arg0, int arg1) { + listener.disallowedMethodCalled("glBindBuffer"); + } + + @Override + public void glDeleteBuffers(int arg0, int[] arg1, int arg2) { + listener.disallowedMethodCalled("glDeleteBuffers"); + } + + @Override + public void glBufferSubData(int arg0, long arg1, long arg2, Buffer arg3) { + listener.disallowedMethodCalled("glBufferSubData"); + } + + @Override + public void glGetBufferParameteriv(int arg0, int arg1, int[] arg2, int arg3) { + listener.disallowedMethodCalled("glGetBufferParameteriv"); + } + + @Override + public void glBufferData(int arg0, long arg1, Buffer arg2, int arg3) { + listener.disallowedMethodCalled("glBufferData"); + } + +} diff --git a/src/junit/com/jogamp/test/junit/jogl/caps/MultisampleChooser01.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java index 7dcde18c9..c2182b8b7 100644 --- a/src/junit/com/jogamp/test/junit/jogl/caps/MultisampleChooser01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleChooser01.java @@ -37,18 +37,19 @@ * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ -package com.jogamp.test.junit.jogl.caps; +package com.jogamp.opengl.test.junit.jogl.caps; +import java.util.List; import javax.media.opengl.DefaultGLCapabilitiesChooser; import javax.media.opengl.GLCapabilitiesImmutable; class MultisampleChooser01 extends DefaultGLCapabilitiesChooser { - public int chooseCapabilities(GLCapabilitiesImmutable desired, GLCapabilitiesImmutable[] available, int windowSystemRecommendedChoice) { + public int chooseCapabilities(GLCapabilitiesImmutable desired, List/*<GLCapabilitiesImmutable>*/ available, int windowSystemRecommendedChoice) { boolean anyHaveSampleBuffers = false; - for (int i = 0; i < available.length; i++) { - GLCapabilitiesImmutable caps = available[i]; - if (caps != null && caps.getSampleBuffers()) { + for (int i = 0; i < available.size(); i++) { + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) available.get(i); + if ( caps.getSampleBuffers() ) { anyHaveSampleBuffers = true; break; } @@ -57,7 +58,8 @@ class MultisampleChooser01 extends DefaultGLCapabilitiesChooser { if (!anyHaveSampleBuffers) { System.err.println("WARNING: antialiasing will be disabled because none of the available pixel formats had it to offer"); } else { - if (!available[selection].getSampleBuffers()) { + GLCapabilitiesImmutable selected = (GLCapabilitiesImmutable) available.get(selection); + if (!selected.getSampleBuffers()) { System.err.println("WARNING: antialiasing will be disabled because the DefaultGLCapabilitiesChooser didn't supply it"); } } diff --git a/src/junit/com/jogamp/test/junit/jogl/caps/MultisampleDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java index e399de0bc..a9995d8e8 100644 --- a/src/junit/com/jogamp/test/junit/jogl/caps/MultisampleDemo01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java @@ -38,7 +38,7 @@ * and developed by Kenneth Bradley Russell and Christopher John Kline. */ -package com.jogamp.test.junit.jogl.caps; +package com.jogamp.opengl.test.junit.jogl.caps; import com.jogamp.opengl.impl.x11.glx.GLX; import com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfiguration; diff --git a/src/junit/com/jogamp/test/junit/jogl/caps/TestMultisampleAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleAWT.java index c6e7f08fa..53047611d 100755 --- a/src/junit/com/jogamp/test/junit/jogl/caps/TestMultisampleAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleAWT.java @@ -38,13 +38,13 @@ * and developed by Kenneth Bradley Russell and Christopher John Kline. */ -package com.jogamp.test.junit.jogl.caps; +package com.jogamp.opengl.test.junit.jogl.caps; -import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.MiscUtils; import java.awt.*; import javax.media.opengl.*; import javax.media.opengl.awt.GLCanvas; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.AbstractGraphicsScreen; import javax.media.nativewindow.GraphicsConfigurationFactory; diff --git a/src/junit/com/jogamp/test/junit/jogl/caps/TestMultisampleNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleNEWT.java index c060828ec..8285a6699 100755 --- a/src/junit/com/jogamp/test/junit/jogl/caps/TestMultisampleNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleNEWT.java @@ -38,10 +38,10 @@ * and developed by Kenneth Bradley Russell and Christopher John Kline. */ -package com.jogamp.test.junit.jogl.caps; +package com.jogamp.opengl.test.junit.jogl.caps; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.MiscUtils; import javax.media.opengl.*; import org.junit.Test; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquare.java index be416f01d..eaf697a10 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/es1/RedSquare.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/RedSquare.java @@ -1,4 +1,4 @@ -package com.jogamp.test.junit.jogl.demos.es1; +package com.jogamp.opengl.test.junit.jogl.demos.es1; import com.jogamp.common.nio.Buffers; import java.nio.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/es2/RedSquare0.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquare0.java index 229635ae5..f062a7375 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/es2/RedSquare0.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquare0.java @@ -25,14 +25,14 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.es2; +package com.jogamp.opengl.test.junit.jogl.demos.es2; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.GLArrayDataWrapper; import com.jogamp.opengl.util.PMVMatrix; -import com.jogamp.test.junit.jogl.demos.es2.shader.RedSquareShader; -import com.jogamp.test.junit.util.GLSLSimpleProgram; +import com.jogamp.opengl.test.junit.jogl.demos.es2.shader.RedSquareShader; +import com.jogamp.opengl.test.junit.util.GLSLSimpleProgram; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.nio.FloatBuffer; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/es2/shader/RedSquareShader.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.java index 5a365be11..3ef62df31 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/es2/shader/RedSquareShader.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader/RedSquareShader.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.es2.shader; +package com.jogamp.opengl.test.junit.jogl.demos.es2.shader; public class RedSquareShader { public static String VERTEX_SHADER_TEXT = diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java index 78846250f..dd28b4e40 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/Gears.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/Gears.java @@ -1,5 +1,5 @@ -package com.jogamp.test.junit.jogl.demos.gl2.gears; +package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears; import javax.media.opengl.*; @@ -137,6 +137,7 @@ public class Gears implements GLEventListener { public void dispose(GLAutoDrawable drawable) { System.err.println("Gears: Dispose"); + setGears(0, 0, 0); } public void display(GLAutoDrawable drawable) { diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java index 3e7e5988b..d04ce3849 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.gl2.gears; +package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears; import javax.media.opengl.*; import com.jogamp.opengl.util.Animator; @@ -36,8 +36,8 @@ import com.jogamp.newt.event.awt.AWTWindowAdapter; import com.jogamp.newt.event.TraceKeyAdapter; import com.jogamp.newt.event.TraceWindowAdapter; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.QuitAdapter; import java.awt.Frame; import org.junit.Assert; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWT.java index 8b3273a0f..40e2ae933 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/TestGearsGLJPanelAWT.java @@ -26,13 +26,13 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.gl2.gears; +package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears; import javax.media.opengl.*; import com.jogamp.opengl.util.FPSAnimator; import javax.media.opengl.awt.GLJPanel; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import java.awt.AWTException; import java.awt.BorderLayout; import java.lang.reflect.InvocationTargetException; @@ -106,7 +106,7 @@ public class TestGearsGLJPanelAWT extends UITestCase { } } ); } - @Ignore("not ready yet") @Test + @Test public void test01() throws AWTException, InterruptedException, InvocationTargetException { diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java index d83deea4b..588fe725f 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNEWT.java @@ -26,17 +26,17 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.gl2.gears.newt; +package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.QuitAdapter; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; diff --git a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/newt/TestGearsNewtAWTWrapper.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNewtAWTWrapper.java index d0b8cc7de..939a85631 100644 --- a/src/junit/com/jogamp/test/junit/jogl/demos/gl2/gears/newt/TestGearsNewtAWTWrapper.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/gears/newt/TestGearsNewtAWTWrapper.java @@ -26,15 +26,15 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.demos.gl2.gears.newt; +package com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.newt; import javax.media.nativewindow.*; import javax.media.opengl.*; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.QuitAdapter; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import com.jogamp.newt.*; import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java index 9b6194ca6..8897dc6fe 100644 --- a/src/junit/com/jogamp/test/junit/jogl/drawable/TestDrawable01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java @@ -26,9 +26,9 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.drawable; +package com.jogamp.opengl.test.junit.jogl.drawable; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import org.junit.Assert; import org.junit.Before; diff --git a/src/junit/com/jogamp/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java index f1b4297e2..ed2f5d3cb 100644 --- a/src/junit/com/jogamp/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java @@ -26,11 +26,11 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.glsl; +package com.jogamp.opengl.test.junit.jogl.glsl; -import com.jogamp.test.junit.jogl.demos.es2.RedSquare0; -import com.jogamp.test.junit.util.GLSLSimpleProgram; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquare0; +import com.jogamp.opengl.test.junit.util.GLSLSimpleProgram; +import com.jogamp.opengl.test.junit.util.UITestCase; import javax.media.opengl.GLCapabilities; @@ -43,8 +43,8 @@ import org.junit.Test; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.jogl.demos.es2.shader.RedSquareShader; -import com.jogamp.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.es2.shader.RedSquareShader; +import com.jogamp.opengl.test.junit.util.MiscUtils; import java.io.IOException; import javax.media.opengl.GL2ES2; diff --git a/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java index 8da48dccd..be4873ff6 100644 --- a/src/junit/com/jogamp/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java @@ -1,6 +1,6 @@ -package com.jogamp.test.junit.jogl.glsl; +package com.jogamp.opengl.test.junit.jogl.glsl; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import java.io.ByteArrayOutputStream; import java.io.PrintStream; diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java new file mode 100755 index 000000000..34b30f04e --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectDoubleNOUI.java @@ -0,0 +1,57 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.glu; + +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Julien Gouesse + */ +public class TestGluUnprojectDoubleNOUI { + + @Test + public void test(){ + final GLU glu = new GLU(); + final int[] pickedPoint = new int[]{400,300}; + final double pickedPointDepth = 0; + final double[] sceneModelViewValues = new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final double[] projectionValues = new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final int[] viewport = new int[]{0,0,800,600}; + final double[] objCoords = new double[]{Double.NaN,Double.NaN,Double.NaN}; + glu.gluUnProject(pickedPoint[0], pickedPoint[1], pickedPointDepth, sceneModelViewValues, 0, projectionValues, 0, viewport, 0, objCoords, 0); + Assert.assertTrue(!Double.isNaN(objCoords[0])&&!Double.isNaN(objCoords[1])&&!Double.isNaN(objCoords[2])); + } + + public static void main(String args[]) { + org.junit.runner.JUnitCore.main(TestGluUnprojectDoubleNOUI.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java new file mode 100755 index 000000000..9e48a2000 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glu/TestGluUnprojectFloatNOUI.java @@ -0,0 +1,58 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.glu; + +import javax.media.opengl.glu.GLU; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Julien Gouesse + */ +public class TestGluUnprojectFloatNOUI { + + + @Test + public void test(){ + final GLU glu = new GLU(); + final int[] pickedPoint = new int[]{400,300}; + final float pickedPointDepth = 0; + final float[] sceneModelViewValues = new float[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final float[] projectionValues = new float[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + final int[] viewport = new int[]{0,0,800,600}; + final float[] objCoords = new float[]{Float.NaN,Float.NaN,Float.NaN}; + glu.gluUnProject(pickedPoint[0], pickedPoint[1], pickedPointDepth, sceneModelViewValues, 0, projectionValues, 0, viewport, 0, objCoords, 0); + Assert.assertTrue(!Double.isNaN(objCoords[0])&&!Double.isNaN(objCoords[1])&&!Double.isNaN(objCoords[2])); + } + + public static void main(String args[]) { + org.junit.runner.JUnitCore.main(TestGluUnprojectFloatNOUI.class.getName()); + } +} diff --git a/src/junit/com/jogamp/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java b/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java index fef0e5ad6..21a97363c 100644 --- a/src/junit/com/jogamp/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java @@ -26,10 +26,10 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.newt; +package com.jogamp.opengl.test.junit.jogl.newt; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; import java.lang.reflect.InvocationTargetException; import javax.media.opengl.GLAutoDrawable; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBuffer2File.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBuffer2File.java index b09d27702..95e7d6e53 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBuffer2File.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBuffer2File.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import java.io.IOException; import javax.media.opengl.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBuffer2Screen.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBuffer2Screen.java index 5d414c708..96a830a53 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBuffer2Screen.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBuffer2Screen.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import java.nio.*; import javax.media.opengl.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBufferBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java index 63215223a..71a73a7e1 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBufferBase.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferBase.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import javax.media.opengl.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBufferUtil.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferUtil.java index f10a60a45..d4fa0d654 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/ReadBufferUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/ReadBufferUtil.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import com.jogamp.opengl.util.GLBuffers; import java.nio.*; diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/Surface2File.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java index c5d770bb8..3ad2c4213 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/Surface2File.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/Surface2File.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import javax.media.opengl.*; @@ -72,7 +72,7 @@ public class Surface2File implements SurfaceUpdatedListener { File file = File.createTempFile(basename + shotNum + "-", ".ppm"); TextureIO.write(readBufferUtil.getTextureData(), file); - System.out.println("Wrote: " + file.getAbsolutePath() + ", ..."); + System.err.println("Wrote: " + file.getAbsolutePath() + ", ..."); shotNum++; readBufferUtil.rewindPixelBuffer(); } diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java index a57ea5777..6a02bc03b 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; import com.jogamp.newt.Display; @@ -38,7 +38,6 @@ import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.opengl.GLWindow; import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -46,11 +45,11 @@ import org.junit.Test; import javax.media.opengl.*; import javax.media.nativewindow.*; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; import java.io.IOException; -public class TestOffscreen01NEWT extends UITestCase { +public class TestOffscreen01GLPBufferNEWT extends UITestCase { static GLProfile glpDefault; static GLDrawableFactory glDrawableFactory; static int width, height; @@ -87,25 +86,14 @@ public class TestOffscreen01NEWT extends UITestCase { window.setSize(width, height); GLWindow glWindow = GLWindow.create(window); Assert.assertNotNull(glWindow); - try { - glWindow.setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + glWindow.setVisible(true); + GLEventListener demo = new RedSquare(); WindowUtilNEWT.setDemoFields(demo, window, glWindow, false); glWindow.addGLEventListener(demo); while ( glWindow.getTotalFrames() < 2) { - try { - glWindow.display(); - } catch (Throwable t) { - // stop test and ignore if pbuffer cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + glWindow.display(); } if(null!=glWindow) { @@ -192,28 +180,17 @@ public class TestOffscreen01NEWT extends UITestCase { windows[i].setSize(width, height); glWindows[i] = GLWindow.create(windows[i]); Assert.assertNotNull(glWindows[i]); - try { - glWindows[i].setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + glWindows[i].setVisible(true); + demos[i] = new RedSquare(); WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false); glWindows[i].addGLEventListener(demos[i]); } - try { - while ( glWindows[0].getTotalFrames() < 2) { - for(i=0; i<winnum; i++) { - glWindows[i].display(); - } + while ( glWindows[0].getTotalFrames() < 2) { + for(i=0; i<winnum; i++) { + glWindows[i].display(); } - } catch (Throwable t) { - // stop test and ignore if pbuffer cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); } for(i=0; i<winnum; i++) { @@ -257,31 +234,18 @@ public class TestOffscreen01NEWT extends UITestCase { windows[i].setSize(width, height); glWindows[i] = GLWindow.create(windows[i]); Assert.assertNotNull(glWindows[i]); - try { - glWindows[i].setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + glWindows[i].setVisible(true); demos[i] = new RedSquare(); WindowUtilNEWT.setDemoFields(demos[i], windows[i], glWindows[i], false); glWindows[i].addGLEventListener(demos[i]); } - try { - while ( glWindows[0].getTotalFrames() < 2) { - for(i=0; i<winnum; i++) { - glWindows[i].display(); - } + while ( glWindows[0].getTotalFrames() < 2) { + for(i=0; i<winnum; i++) { + glWindows[i].display(); } - } catch (Throwable t) { - // stop test and ignore if pbuffer cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); } - for(i=0; i<winnum; i++) { if(null!=glWindows[i]) { glWindows[i].destroy(); @@ -316,13 +280,7 @@ public class TestOffscreen01NEWT extends UITestCase { window.setSize(width, height); GLWindow glWindow = GLWindow.create(window); Assert.assertNotNull(glWindow); - try { - glWindow.setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + glWindow.setVisible(true); GLWindow windowOnScreen = null; WindowListener wl=null; @@ -332,13 +290,7 @@ public class TestOffscreen01NEWT extends UITestCase { GLEventListener demo = new RedSquare(); Assert.assertNotNull(demo); - try { - WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/); - } catch (Throwable t) { - // stop test and ignore if pbuffer cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } + WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/); if(null!=windowOnScreen) { windowOnScreen.destroy(); @@ -357,122 +309,8 @@ public class TestOffscreen01NEWT extends UITestCase { } } - @Test - public void test11OffscreenWindowPixmap() { - // Offscreen doesn't work on >= GL3 (ATI) - GLProfile glp = GLProfile.get(GLProfile.GL2); - Assert.assertNotNull(glp); - GLCapabilities caps = new GLCapabilities(glp); - Assert.assertNotNull(caps); - - GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false); - - Display display = NewtFactory.createDisplay(null); // local display - Assert.assertNotNull(display); - Screen screen = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen); - Window window = NewtFactory.createWindow(screen, caps2); - Assert.assertNotNull(window); - window.setSize(width, height); - GLWindow glWindow = GLWindow.create(window); - Assert.assertNotNull(glWindow); - try { - glWindow.setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } - GLEventListener demo = new RedSquare(); - WindowUtilNEWT.setDemoFields(demo, window, glWindow, false); - glWindow.addGLEventListener(demo); - - while ( glWindow.getTotalFrames() < 2) { - try { - glWindow.display(); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } - } - - if(null!=glWindow) { - glWindow.destroy(); - } - if(null!=window) { - window.destroy(); - } - if(null!=screen) { - screen.destroy(); - } - if(null!=display) { - display.destroy(); - } - } - - @Test - public void test14OffscreenSnapshotWithDemoPixmap() { - // Offscreen doesn't work on >= GL3 (ATI) - GLProfile glp = GLProfile.get(GLProfile.GL2); - Assert.assertNotNull(glp); - GLCapabilities caps = new GLCapabilities(glp); - Assert.assertNotNull(caps); - - GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false); - - System.out.println("Create Window 1"); - Display display = NewtFactory.createDisplay(null); // local display - Assert.assertNotNull(display); - Screen screen = NewtFactory.createScreen(display, 0); // screen 0 - Assert.assertNotNull(screen); - Window window = NewtFactory.createWindow(screen, caps2); - Assert.assertNotNull(window); - window.setSize(width, height); - GLWindow glWindow = GLWindow.create(window); - Assert.assertNotNull(glWindow); - try { - glWindow.setVisible(true); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } - - GLWindow windowOnScreen = null; - WindowListener wl=null; - MouseListener ml=null; - SurfaceUpdatedListener ul=null; - - GLEventListener demo = new RedSquare(); - Assert.assertNotNull(demo); - - try { - WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/); - } catch (Throwable t) { - // stop test and ignore if pixmap cannot be used - t.printStackTrace(); - Assume.assumeNoException(t); - } - - if(null!=windowOnScreen) { - windowOnScreen.destroy(); - } - if(null!=glWindow) { - glWindow.destroy(); - } - if(null!=window) { - window.destroy(); - } - if(null!=screen) { - screen.destroy(); - } - if(null!=display) { - display.destroy(); - } - } public static void main(String args[]) throws IOException { - String tstname = TestOffscreen01NEWT.class.getName(); + String tstname = TestOffscreen01GLPBufferNEWT.class.getName(); org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { tstname, "filtertrace=true", diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java new file mode 100644 index 000000000..d92b4ffbf --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java @@ -0,0 +1,184 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.offscreen; + + +import com.jogamp.newt.Display; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.Window; +import com.jogamp.newt.event.MouseListener; +import com.jogamp.newt.event.WindowListener; +import com.jogamp.newt.opengl.GLWindow; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; + +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import java.io.IOException; + +public class TestOffscreen02BitmapNEWT extends UITestCase { + static GLProfile glpDefault; + static GLDrawableFactory glDrawableFactory; + static int width, height; + GLCapabilities capsDefault; + + @BeforeClass + public static void initClass() { + GLProfile.initSingleton(true); + glpDefault = GLProfile.getDefault(); + Assert.assertNotNull(glpDefault); + glDrawableFactory = GLDrawableFactory.getFactory(glpDefault); + System.out.println("INFO: PBuffer supported: "+ glDrawableFactory.canCreateGLPbuffer(null)); + width = 640; + height = 480; + } + + @AfterClass + public static void releaseClass() { + } + + @Before + public void init() { + capsDefault = new GLCapabilities(glpDefault); + Assert.assertNotNull(capsDefault); + } + + @Test + public void test11OffscreenWindowPixmap() { + // Offscreen doesn't work on >= GL3 (ATI) + GLProfile glp = GLProfile.get(GLProfile.GL2); + Assert.assertNotNull(glp); + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + + GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false); + + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + Window window = NewtFactory.createWindow(screen, caps2); + Assert.assertNotNull(window); + window.setSize(width, height); + GLWindow glWindow = GLWindow.create(window); + Assert.assertNotNull(glWindow); + glWindow.setVisible(true); + + GLEventListener demo = new RedSquare(); + WindowUtilNEWT.setDemoFields(demo, window, glWindow, false); + glWindow.addGLEventListener(demo); + + while ( glWindow.getTotalFrames() < 2) { + glWindow.display(); + } + + if(null!=glWindow) { + glWindow.destroy(); + } + if(null!=window) { + window.destroy(); + } + if(null!=screen) { + screen.destroy(); + } + if(null!=display) { + display.destroy(); + } + } + + @Test + public void test14OffscreenSnapshotWithDemoPixmap() { + // Offscreen doesn't work on >= GL3 (ATI) + GLProfile glp = GLProfile.get(GLProfile.GL2); + Assert.assertNotNull(glp); + GLCapabilities caps = new GLCapabilities(glp); + Assert.assertNotNull(caps); + + GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, false, false); + + Display display = NewtFactory.createDisplay(null); // local display + Assert.assertNotNull(display); + Screen screen = NewtFactory.createScreen(display, 0); // screen 0 + Assert.assertNotNull(screen); + Window window = NewtFactory.createWindow(screen, caps2); + Assert.assertNotNull(window); + window.setSize(width, height); + GLWindow glWindow = GLWindow.create(window); + Assert.assertNotNull(glWindow); + glWindow.setVisible(true); + + GLWindow windowOnScreen = null; + WindowListener wl=null; + MouseListener ml=null; + SurfaceUpdatedListener ul=null; + + GLEventListener demo = new RedSquare(); + Assert.assertNotNull(demo); + + WindowUtilNEWT.run(glWindow, demo, windowOnScreen, wl, ml, ul, 2, true /*snapshot*/, false /*debug*/); + + if(null!=windowOnScreen) { + windowOnScreen.destroy(); + } + if(null!=glWindow) { + glWindow.destroy(); + } + if(null!=window) { + window.destroy(); + } + if(null!=screen) { + screen.destroy(); + } + if(null!=display) { + display.destroy(); + } + } + public static void main(String args[]) throws IOException { + String tstname = TestOffscreen02BitmapNEWT.class.getName(); + org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { + tstname, + "filtertrace=true", + "haltOnError=false", + "haltOnFailure=false", + "showoutput=true", + "outputtoformatters=true", + "logfailedtests=true", + "logtestlistenerevents=true", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", + "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); + } + +} diff --git a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java index cfe956c61..4420a5107 100644 --- a/src/junit/com/jogamp/test/junit/jogl/offscreen/WindowUtilNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java @@ -26,9 +26,9 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.offscreen; +package com.jogamp.opengl.test.junit.jogl.offscreen; -import com.jogamp.test.junit.util.*; +import com.jogamp.opengl.test.junit.util.*; import org.junit.Assert; @@ -95,9 +95,9 @@ public class WindowUtilNEWT { } if(debug) { - System.out.println("+++++++++++++++++++++++++++"); - System.out.println(windowOffScreen); - System.out.println("+++++++++++++++++++++++++++"); + System.err.println("+++++++++++++++++++++++++++"); + System.err.println(windowOffScreen); + System.err.println("+++++++++++++++++++++++++++"); } while ( windowOffScreen.getTotalFrames() < frames) { diff --git a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/texture/TestTexture01AWT.java index 2eb66663c..bd83799d4 100644 --- a/src/junit/com/jogamp/test/junit/jogl/texture/TestTexture01AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/texture/TestTexture01AWT.java @@ -26,11 +26,11 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.texture; +package com.jogamp.opengl.test.junit.jogl.texture; -import com.jogamp.test.junit.jogl.util.texture.gl2.TextureGL2ListenerDraw1; +import com.jogamp.opengl.test.junit.jogl.util.texture.gl2.TextureGL2ListenerDraw1; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; import javax.media.opengl.GLProfile; import javax.media.opengl.GLCapabilities; diff --git a/src/junit/com/jogamp/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java index a0c0fc7f6..b41dde645 100644 --- a/src/junit/com/jogamp/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/gl2/TextureGL2ListenerDraw1.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.jogl.util.texture.gl2; +package com.jogamp.opengl.test.junit.jogl.util.texture.gl2; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureCoords; diff --git a/src/junit/com/jogamp/test/junit/newt/TestCloseNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java index 1899a6b81..69f9da052 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestCloseNewtAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java @@ -26,13 +26,12 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Test; +import org.junit.Assert; import java.lang.reflect.InvocationTargetException; -import java.awt.EventQueue; -import java.awt.Toolkit; import javax.swing.JFrame; import javax.swing.SwingUtilities; @@ -45,7 +44,8 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; public class TestCloseNewtAWT extends UITestCase { @@ -92,29 +92,14 @@ public class TestCloseNewtAWT extends UITestCase { } } - class NEWTWindowClosingAdapter extends WindowAdapter { - public void windowDestroyNotify(WindowEvent e) { - System.err.println("Destroy NEWT: windowDestroyNotify "+Thread.currentThread() + ", "+ e); - } - } - - class AWTClosingWindowAdapter extends java.awt.event.WindowAdapter { - public void windowClosing(WindowEvent ev) { - System.err.println("Destroy AWT: windowClosing "+Thread.currentThread() + ", "+ ev); - } - } - - @Test public void testCloseNewtAWT() throws InterruptedException, InvocationTargetException { newtWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault())); - newtWindow.addWindowListener(new NEWTWindowClosingAdapter()); newtCanvas = new MyCanvas(newtWindow); SwingUtilities.invokeLater(new Runnable() { public void run() { frame = new JFrame("NEWT Close Test"); - frame.addWindowListener(new AWTClosingWindowAdapter()); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.getContentPane().add(newtCanvas); frame.pack(); @@ -124,11 +109,7 @@ public class TestCloseNewtAWT extends UITestCase { }); Thread.sleep(1000); - // programatically issue windowClosing - Toolkit tk = Toolkit.getDefaultToolkit(); - EventQueue evtQ = tk.getSystemEventQueue(); - evtQ.postEvent(new java.awt.event.WindowEvent(frame, java.awt.event.WindowEvent.WINDOW_CLOSING)); - Thread.sleep(200); + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true)); GLProfile.shutdown(); } diff --git a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java index 94f915834..9343e2dd8 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.lang.reflect.*; import java.util.ArrayList; @@ -48,9 +48,9 @@ import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.MiscUtils; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestDisplayLifecycle01NEWT extends UITestCase { static GLProfile glp; diff --git a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java index 9fc6e3bc9..d17c5f025 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestDisplayLifecycle02NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.lang.reflect.*; import java.util.ArrayList; @@ -48,9 +48,9 @@ import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.MiscUtils; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestDisplayLifecycle02NEWT extends UITestCase { static GLProfile glp; diff --git a/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotAWTBug.java b/src/test/com/jogamp/opengl/test/junit/newt/TestEventSourceNotAWTBug.java index ff791b03a..67dd2a33c 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestEventSourceNotAWTBug.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestEventSourceNotAWTBug.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; import org.junit.Before; @@ -45,8 +45,8 @@ import javax.swing.WindowConstants; import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; /** * This simple program will throw a {@link RuntimeException} when the application is closed. diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java index d597af889..047df5cf7 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWTRobot.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; import org.junit.AfterClass; @@ -51,9 +51,9 @@ import org.junit.Test; import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.util.*; +import com.jogamp.opengl.test.junit.util.*; public class TestFocus01SwingAWTRobot extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java index b96279cac..15e4c3ad8 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWTRobot.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.lang.reflect.*; @@ -53,8 +53,8 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestFocus02SwingAWTRobot extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java index 2769dc550..f9571574e 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows00NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; import org.junit.BeforeClass; @@ -39,9 +39,9 @@ import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.MiscUtils; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import javax.media.nativewindow.AbstractGraphicsDevice; public class TestGLWindows00NEWT extends UITestCase { diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java index e2c65adb8..5be97714d 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; import org.junit.BeforeClass; @@ -39,9 +39,9 @@ import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.MiscUtils; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestGLWindows01NEWT extends UITestCase { static GLProfile glp; diff --git a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java index e73181604..6582a96c0 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestGLWindows02NEWTAnimated.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; @@ -41,9 +41,9 @@ import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.util.MiscUtils; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestGLWindows02NEWTAnimated extends UITestCase { static GLProfile glp; diff --git a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java index 4407ffef1..b2068d976 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestListenerCom01AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.lang.reflect.*; import java.util.ArrayList; @@ -56,9 +56,9 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestListenerCom01AWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java index fc5327c9d..6b501e31d 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestRemoteGLWindows01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; import org.junit.Assume; @@ -40,8 +40,8 @@ import com.jogamp.newt.*; import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeWindowException; @@ -49,6 +49,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { static GLProfile glp; static int width, height; static long durationPerTest = 100; // ms + static String remoteDisplay = "nowhere:0.0"; @BeforeClass public static void initClass() { @@ -59,7 +60,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { glp = GLProfile.getDefault(); } - static GLWindow createWindow(Screen screen, GLCapabilities caps) + static GLWindow createWindow(Screen screen, GLCapabilities caps, GLEventListener demo) throws InterruptedException { Assert.assertNotNull(caps); @@ -74,8 +75,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { glWindow = GLWindow.create(caps); Assert.assertNotNull(glWindow); } - - GLEventListener demo = new Gears(); + glWindow.addGLEventListener(demo); glWindow.setSize(512, 512); @@ -96,42 +96,49 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { @Test public void testRemoteWindow01() throws InterruptedException { + Animator animator = new Animator(); GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - GLWindow window1 = createWindow(null, caps); // local + GLWindow window1 = createWindow(null, caps, new Gears(1)); // local with vsync Assert.assertEquals(true,window1.isNativeValid()); Assert.assertEquals(true,window1.isVisible()); AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice(); System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1)); - Animator animator1 = new Animator(window1); - animator1.start(); + animator.add(window1); + // Remote Display/Device/Screen/Window .. // Eager initialization of NEWT Display -> AbstractGraphicsDevice -> GLProfile (device) - Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display + Display display2; // remote display + AbstractGraphicsDevice device2; + Screen screen2; + GLWindow window2; try { - display2.createNative(); + display2 = NewtFactory.createDisplay(remoteDisplay); // remote display + display2.createNative(); + System.err.println(display2); + device2 = display2.getGraphicsDevice(); + System.err.println(device2); + GLProfile.initProfiles(device2); // just to make sure + System.err.println(""); + System.err.println("GLProfiles window2: "+device2.getConnection()+": "+GLProfile.glAvailabilityToString(device2)); + screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + window2 = createWindow(screen2, caps, new Gears(0)); // remote, no vsync } catch (NativeWindowException nwe) { System.err.println(nwe); Assume.assumeNoException(nwe); destroyWindow(window1); return; } - AbstractGraphicsDevice device2 = display2.getGraphicsDevice(); - GLProfile.initProfiles(device2); // just to make sure - System.err.println(""); - System.err.println("GLProfiles window2: "+device2.getConnection()+": "+GLProfile.glAvailabilityToString(device2)); - Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 - GLWindow window2 = createWindow(screen2, caps); // remote Assert.assertEquals(true,window2.isNativeValid()); Assert.assertEquals(true,window2.isVisible()); - Animator animator2 = new Animator(window2); - animator2.start(); + animator.add(window2); + animator.start(); - for(int state=0; state*100<durationPerTest; state++) { + while(animator.getDuration()<durationPerTest) { Thread.sleep(100); } @@ -151,9 +158,12 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { durationPerTest = atoi(args[++i]); + } else if(args[i].equals("-display")) { + remoteDisplay = args[++i]; } } System.out.println("durationPerTest: "+durationPerTest); + System.out.println("display: "+remoteDisplay); String tstname = TestRemoteGLWindows01NEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java index bfb012e3c..9c44545f2 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestRemoteWindow01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import org.junit.Assert; @@ -39,10 +39,11 @@ import javax.media.nativewindow.*; import com.jogamp.newt.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; public class TestRemoteWindow01NEWT extends UITestCase { static int width, height; + static String remoteDisplay = "nowhere:0.0"; @BeforeClass public static void initClass() { @@ -109,18 +110,23 @@ public class TestRemoteWindow01NEWT extends UITestCase { Assert.assertEquals(true,window1.isNativeValid()); Assert.assertEquals(true,window1.isVisible()); - Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display + // Remote Display/Device/Screen/Window .. + Display display2; + AbstractGraphicsDevice device2; + Screen screen2; + Window window2; try { + display2 = NewtFactory.createDisplay(remoteDisplay); display2.createNative(); + screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); + window2.setVisible(true); } catch (NativeWindowException nwe) { System.err.println(nwe); Assume.assumeNoException(nwe); destroyWindow(display1, screen1, window1); return; } - Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 - Window window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); - window2.setVisible(true); Assert.assertEquals(true,window2.isNativeValid()); Assert.assertEquals(true,window2.isVisible()); @@ -132,6 +138,12 @@ public class TestRemoteWindow01NEWT extends UITestCase { } public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-display")) { + remoteDisplay = args[++i]; + } + } + System.out.println("display: "+remoteDisplay); String tstname = TestRemoteWindow01NEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/junit/com/jogamp/test/junit/newt/TestScreenMode00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java index 9f39274c5..846013b1d 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestScreenMode00NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.io.IOException; import javax.media.nativewindow.NativeWindowFactory; @@ -45,8 +45,8 @@ import com.jogamp.newt.ScreenMode; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.util.MonitorMode; import com.jogamp.newt.util.ScreenModeUtil; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; import java.util.Iterator; import java.util.List; import javax.media.nativewindow.Capabilities; diff --git a/src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java index de4def2fa..ffff682dc 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestScreenMode01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.io.IOException; import javax.media.nativewindow.NativeWindowFactory; @@ -46,8 +46,8 @@ import com.jogamp.newt.Window; import com.jogamp.newt.ScreenMode; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.util.ScreenModeUtil; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; import java.util.List; import javax.media.nativewindow.util.Dimension; diff --git a/src/junit/com/jogamp/test/junit/newt/TestScreenMode02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java index 011af6330..2ec0490f0 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestScreenMode02NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.io.IOException; import javax.media.nativewindow.NativeWindowFactory; @@ -46,8 +46,8 @@ import com.jogamp.newt.Window; import com.jogamp.newt.ScreenMode; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.util.ScreenModeUtil; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.UITestCase; import java.util.List; import javax.media.nativewindow.util.Dimension; diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java new file mode 100644 index 000000000..581877e50 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java @@ -0,0 +1,160 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import org.junit.Test; +import org.junit.Assert; + +import java.lang.reflect.InvocationTargetException; +import java.awt.Frame; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol01AWT extends UITestCase { + + @Test + public void testCloseFrameGLCanvas() throws InterruptedException, InvocationTargetException { + final Frame frame = new Frame("testCloseFrameGLCanvas AWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + final GLCanvas glCanvas = new GLCanvas(caps); + glCanvas.addGLEventListener(new Gears()); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.add(glCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP (default) + // + int op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // nop + Thread.sleep(100); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isDisplayable()); + + // + // close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose + // + glCanvas.setDefaultCloseOperation(WindowClosingProtocol.DISPOSE_ON_CLOSE); + op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // no frame close + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, false)); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(false, glCanvas.isRealized()); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.dispose(); + } }); + } + + @Test + public void testCloseJFrameGLCanvas() throws InterruptedException, InvocationTargetException { + final JFrame frame = new JFrame("testCloseJFrameGLCanvas AWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + GLCanvas glCanvas = new GLCanvas(caps); + glCanvas.addGLEventListener(new Gears()); + frame.getContentPane().add(glCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP / HIDE (default) + // + Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation()); + int op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); // nop + Thread.sleep(100); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isDisplayable()); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true)); + + // + // close with op (JFrame): DISPOSE_ON_CLOSE -- GLCanvas --> dispose + // + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation()); + op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true)); + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, false)); + Assert.assertEquals(false, frame.isDisplayable()); + Assert.assertEquals(false, glCanvas.isValid()); + Assert.assertEquals(false, glCanvas.isDisplayable()); + Assert.assertEquals(false, glCanvas.isRealized()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol01AWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java new file mode 100644 index 000000000..8f5baece9 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java @@ -0,0 +1,96 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import java.lang.reflect.InvocationTargetException; + +import org.junit.Test; +import org.junit.Assert; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import com.jogamp.newt.opengl.GLWindow; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol02NEWT extends UITestCase { + + @Test + public void testCloseGLWindow() throws InterruptedException, InvocationTargetException { + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + final GLWindow glWindow = GLWindow.create(caps); + final AWTRobotUtil.WindowClosingListener windowClosingListener = AWTRobotUtil.addClosingListener(glWindow); + + glWindow.addGLEventListener(new Gears()); + glWindow.setSize(512, 512); + glWindow.setVisible(true); + Assert.assertEquals(true, glWindow.isVisible()); + + // CHECK DEFAULT .. + int op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP + // + glWindow.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE); + op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, false)); // nop + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(true, glWindow.isNativeValid()); + Assert.assertEquals(true, windowClosingListener.isWindowClosing()); + windowClosingListener.reset(); + + // + // close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose + // + glWindow.setDefaultCloseOperation(WindowClosingProtocol.DISPOSE_ON_CLOSE); + op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(glWindow, true)); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(false, glWindow.isNativeValid()); + Assert.assertEquals(true, windowClosingListener.isWindowClosing()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol02NEWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java new file mode 100644 index 000000000..a10730680 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java @@ -0,0 +1,115 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.opengl.GLWindow; +import org.junit.Test; +import org.junit.Assert; + +import java.lang.reflect.InvocationTargetException; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol03NewtAWT extends UITestCase { + + @Test + public void testCloseJFrameNewtCanvasAWT() throws InterruptedException, InvocationTargetException { + final JFrame frame = new JFrame("testCloseJFrameNewtCanvasAWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + final GLWindow glWindow = GLWindow.create(caps); + final AWTRobotUtil.WindowClosingListener windowClosingListener = AWTRobotUtil.addClosingListener(glWindow); + + glWindow.addGLEventListener(new Gears()); + + NewtCanvasAWT newtCanvas = new NewtCanvasAWT(glWindow); + + frame.getContentPane().add(newtCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + frame.setVisible(true); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP / HIDE (default) + // + Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation()); + int op = newtCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, false)); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, newtCanvas.isValid()); + Assert.assertEquals(true, newtCanvas.isDisplayable()); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(true, glWindow.isNativeValid()); + Assert.assertEquals(true, windowClosingListener.isWindowClosing()); + windowClosingListener.reset(); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op (JFrame): DISPOSE_ON_CLOSE -- newtCanvas -- glWindow --> dispose + // + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation()); + op = newtCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true)); + Assert.assertEquals(false, frame.isDisplayable()); + Assert.assertEquals(false, newtCanvas.isValid()); + Assert.assertEquals(false, newtCanvas.isDisplayable()); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(false, glWindow.isNativeValid()); + Assert.assertEquals(true, windowClosingListener.isWindowClosing()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol03NewtAWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java index 033542bea..5ac6041ac 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import java.lang.reflect.*; import java.util.ArrayList; @@ -45,7 +45,7 @@ import javax.media.nativewindow.*; import com.jogamp.newt.*; import java.io.IOException; -import com.jogamp.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.UITestCase; public class TestWindows01NEWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/WindowEventCom1.java b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom1.java index 74b2ed176..609d443aa 100644 --- a/src/junit/com/jogamp/test/junit/newt/WindowEventCom1.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom1.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import com.jogamp.newt.event.*; diff --git a/src/junit/com/jogamp/test/junit/newt/WindowEventCom2.java b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom2.java index 551c84acb..d15a3ccd8 100644 --- a/src/junit/com/jogamp/test/junit/newt/WindowEventCom2.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom2.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import com.jogamp.newt.event.*; diff --git a/src/junit/com/jogamp/test/junit/newt/WindowEventCom3.java b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom3.java index 0c097fc4f..87e5eccbb 100644 --- a/src/junit/com/jogamp/test/junit/newt/WindowEventCom3.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/WindowEventCom3.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt; +package com.jogamp.opengl.test.junit.newt; import com.jogamp.newt.event.*; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/GLRunnableDummy.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/GLRunnableDummy.java index 2459c8687..d518616b1 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/GLRunnableDummy.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/GLRunnableDummy.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import org.junit.Assert; import org.junit.Before; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/KeyAction.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java index 4948ce9f4..3313ec65c 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/KeyAction.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/KeyAction.java @@ -27,7 +27,7 @@ */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import com.jogamp.newt.event.*; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java index 21c0a479c..5173d0f22 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import org.junit.Assert; @@ -42,9 +42,9 @@ import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01NEWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java index fd52c86a1..424fff0e2 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01aAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -58,9 +58,9 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01aAWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java index 89cefa8b1..2b8d34423 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01bAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -58,9 +58,9 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01bAWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java index b79f4c57c..7321c6ba2 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -57,9 +57,9 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting01cAWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java index fb2c74455..1c155f75a 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting01cSwingAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; @@ -51,8 +51,8 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; public class TestParenting01cSwingAWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java index 6c9e5b2b2..20388e295 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -56,9 +56,9 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02AWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java index 23e3e1c44..b9bd2d93d 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting02NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java @@ -27,7 +27,7 @@ */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -51,9 +51,9 @@ import com.jogamp.newt.opengl.*; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.es1.RedSquare; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting02NEWT extends UITestCase { static int width, height; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java index 00a78a14f..7da30cf18 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03AWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -60,8 +60,8 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting03AWT extends UITestCase { static Dimension size; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java index 5f42d9f7e..34d95d8ee 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/TestParenting03bAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03bAWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import java.lang.reflect.*; import java.util.ArrayList; @@ -60,8 +60,8 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import java.io.IOException; -import com.jogamp.test.junit.util.*; -import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.*; +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; public class TestParenting03bAWT extends UITestCase { static Dimension size; diff --git a/src/junit/com/jogamp/test/junit/newt/parenting/WindowAction.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java index bcfb29440..05793b96e 100644 --- a/src/junit/com/jogamp/test/junit/newt/parenting/WindowAction.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.newt.parenting; +package com.jogamp.opengl.test.junit.newt.parenting; import com.jogamp.newt.event.*; @@ -40,5 +40,8 @@ class WindowAction extends WindowAdapter { public void windowDestroyNotify(WindowEvent e) { eventFifo.put(e); } + public void windowDestroyed(WindowEvent e) { + eventFifo.put(e); + } } diff --git a/src/junit/com/jogamp/test/junit/util/AWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java index 174152639..a24127772 100644 --- a/src/junit/com/jogamp/test/junit/util/AWTFocusAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTFocusAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; diff --git a/src/junit/com/jogamp/test/junit/util/AWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java index 8e255acb6..ed09ecd8c 100644 --- a/src/junit/com/jogamp/test/junit/util/AWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTKeyAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; public class AWTKeyAdapter extends java.awt.event.KeyAdapter implements EventCountAdapter { diff --git a/src/junit/com/jogamp/test/junit/util/AWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java index d78b3ed61..7fa201512 100644 --- a/src/junit/com/jogamp/test/junit/util/AWTMouseAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTMouseAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; public class AWTMouseAdapter extends java.awt.event.MouseAdapter implements EventCountAdapter { String prefix; diff --git a/src/junit/com/jogamp/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index c49de3e1f..4a2a181ed 100644 --- a/src/junit/com/jogamp/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -26,18 +26,21 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; +import com.jogamp.newt.impl.WindowImplAccess; import java.lang.reflect.InvocationTargetException; import java.awt.AWTException; import java.awt.Component; import java.awt.Container; +import java.awt.EventQueue; import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; -import java.awt.Window; +import java.awt.Toolkit; import java.awt.event.InputEvent; +import javax.media.opengl.awt.GLCanvas; import javax.swing.JFrame; public class AWTRobotUtil { @@ -92,7 +95,7 @@ public class AWTRobotUtil { * * @return True if the Window became the global focused Window within TIME_OUT */ - public static boolean toFront(Robot robot, Window window) + public static boolean toFront(Robot robot, final java.awt.Window window) throws AWTException, InterruptedException, InvocationTargetException { if(null == robot) { @@ -104,12 +107,11 @@ public class AWTRobotUtil { robot.mouseMove( (int) p0.getX(), (int) p0.getY() ); robot.delay(ROBOT_DELAY); - final Window f_window = window; javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { - f_window.setVisible(true); - f_window.toFront(); - f_window.requestFocus(); + window.setVisible(true); + window.toFront(); + window.requestFocus(); }}); robot.delay(ROBOT_DELAY); @@ -126,22 +128,12 @@ public class AWTRobotUtil { */ public static void centerMouse(Robot robot, Object obj) throws AWTException, InterruptedException, InvocationTargetException { - Component comp = null; - com.jogamp.newt.Window win = null; if(null == robot) { robot = new Robot(); robot.setAutoWaitForIdle(true); } - if(obj instanceof com.jogamp.newt.Window) { - win = (com.jogamp.newt.Window) obj; - } else if(obj instanceof Component) { - comp = (Component) obj; - } else { - throw new RuntimeException("Neither AWT nor NEWT: "+obj); - } - Point p0 = getCenterLocation(obj, false); System.err.println("robot pos: "+p0); @@ -334,5 +326,158 @@ public class AWTRobotUtil { return false; } + /** + * + * @return True if the Component becomes <code>visible</code> within TIME_OUT + */ + public static boolean waitForVisible(Object obj, boolean visible) throws InterruptedException { + int wait; + if(obj instanceof Component) { + Component comp = (Component) obj; + for (wait=0; wait<POLL_DIVIDER && visible != comp.isVisible(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + for (wait=0; wait<POLL_DIVIDER && visible != win.isVisible(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } + return wait<POLL_DIVIDER; + } + + /** + * + * @return True if the Component becomes realized (not displayable, native invalid) within TIME_OUT + */ + public static boolean waitForRealized(Object obj, boolean realized) throws InterruptedException { + int wait; + if(obj instanceof GLCanvas) { + GLCanvas comp = (GLCanvas) obj; + for (wait=0; wait<POLL_DIVIDER && realized != comp.isRealized(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else if (obj instanceof Component) { + Component comp = (Component) obj; + for (wait=0; wait<POLL_DIVIDER && realized != comp.isDisplayable(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + for (wait=0; wait<POLL_DIVIDER && realized != win.isNativeValid(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } + return wait<POLL_DIVIDER; + } + + /** + * Programmatically issue windowClosing on AWT or NEWT. + * Wait until the window is closing within TIME_OUT. + * + * @param obj either an AWT Window (Frame, JFrame) or NEWT Window + * @param willClose indicating that the window will close, hence this method waits for the window to be closed + * @return True if the Window is closing and closed (if willClose is true), each within TIME_OUT + * @throws InterruptedException + */ + public static boolean closeWindow(Object obj, boolean willClose) throws InterruptedException, InvocationTargetException { + WindowClosingListener closingListener = addClosingListener(obj); + if(obj instanceof java.awt.Window) { + final java.awt.Window win = (java.awt.Window) obj; + Toolkit tk = Toolkit.getDefaultToolkit(); + final EventQueue evtQ = tk.getSystemEventQueue(); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + evtQ.postEvent(new java.awt.event.WindowEvent(win, java.awt.event.WindowEvent.WINDOW_CLOSING)); + } }); + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + WindowImplAccess.windowDestroyNotify(win); + } + int wait; + for (wait=0; wait<POLL_DIVIDER && !closingListener.isWindowClosing(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + if(wait<POLL_DIVIDER && willClose) { + for (wait=0; wait<POLL_DIVIDER && !closingListener.isWindowClosed(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } + return wait<POLL_DIVIDER; + } + + public static WindowClosingListener addClosingListener(Object obj) throws InterruptedException { + WindowClosingListener cl = null; + if(obj instanceof java.awt.Window) { + java.awt.Window win = (java.awt.Window) obj; + AWTWindowClosingAdapter acl = new AWTWindowClosingAdapter(); + win.addWindowListener(acl); + cl = acl; + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + NEWTWindowClosingAdapter ncl = new NEWTWindowClosingAdapter(); + win.addWindowListener(ncl); + cl = ncl; + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } + return cl; + } + public static interface WindowClosingListener { + void reset(); + public boolean isWindowClosing(); + public boolean isWindowClosed(); + } + static class AWTWindowClosingAdapter + extends java.awt.event.WindowAdapter implements WindowClosingListener + { + volatile boolean closing = false; + volatile boolean closed = false; + + public void reset() { + closing = false; + closed = false; + } + public boolean isWindowClosing() { + return closing; + } + public boolean isWindowClosed() { + return closed; + } + public void windowClosing(java.awt.event.WindowEvent e) { + closing = true; + } + public void windowClosed(java.awt.event.WindowEvent e) { + closed = true; + } + } + static class NEWTWindowClosingAdapter + extends com.jogamp.newt.event.WindowAdapter implements WindowClosingListener + { + volatile boolean closing = false; + volatile boolean closed = false; + + public void reset() { + closing = false; + closed = false; + } + public boolean isWindowClosing() { + return closing; + } + public boolean isWindowClosed() { + return closed; + } + public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent e) { + closing = true; + } + public void windowDestroyed(com.jogamp.newt.event.WindowEvent e) { + closed = true; + } + } + } diff --git a/src/junit/com/jogamp/test/junit/util/DumpGLInfo.java b/src/test/com/jogamp/opengl/test/junit/util/DumpGLInfo.java index fd7844f67..d31bf3421 100644 --- a/src/junit/com/jogamp/test/junit/util/DumpGLInfo.java +++ b/src/test/com/jogamp/opengl/test/junit/util/DumpGLInfo.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import javax.media.opengl.*; diff --git a/src/junit/com/jogamp/test/junit/util/EventCountAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java index e0561218a..105d2503e 100644 --- a/src/junit/com/jogamp/test/junit/util/EventCountAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; public interface EventCountAdapter { diff --git a/src/junit/com/jogamp/test/junit/util/EventCountAdapterUtil.java b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapterUtil.java index 40b192a01..d919d7cb6 100644 --- a/src/junit/com/jogamp/test/junit/util/EventCountAdapterUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/EventCountAdapterUtil.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import java.util.List; import java.util.Iterator; diff --git a/src/junit/com/jogamp/test/junit/util/GLSLSimpleProgram.java b/src/test/com/jogamp/opengl/test/junit/util/GLSLSimpleProgram.java index 82be0eb45..bcafc02f7 100644 --- a/src/junit/com/jogamp/test/junit/util/GLSLSimpleProgram.java +++ b/src/test/com/jogamp/opengl/test/junit/util/GLSLSimpleProgram.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import com.jogamp.opengl.util.glsl.ShaderUtil; import java.io.ByteArrayOutputStream; diff --git a/src/junit/com/jogamp/test/junit/util/MiscUtils.java b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java index bb2abcd87..506fe2d97 100644 --- a/src/junit/com/jogamp/test/junit/util/MiscUtils.java +++ b/src/test/com/jogamp/opengl/test/junit/util/MiscUtils.java @@ -27,7 +27,7 @@ */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import java.lang.reflect.*; diff --git a/src/junit/com/jogamp/test/junit/util/NEWTFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java index 5cbd9fd15..9ee74aeff 100644 --- a/src/junit/com/jogamp/test/junit/util/NEWTFocusAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTFocusAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; diff --git a/src/junit/com/jogamp/test/junit/util/NEWTKeyAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java index 73caa1846..ba1a2f3f5 100644 --- a/src/junit/com/jogamp/test/junit/util/NEWTKeyAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTKeyAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; diff --git a/src/junit/com/jogamp/test/junit/util/NEWTMouseAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java index fc5c653f2..617d951ec 100644 --- a/src/junit/com/jogamp/test/junit/util/NEWTMouseAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTMouseAdapter.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; diff --git a/src/junit/com/jogamp/test/junit/util/QuitAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java index 258132582..77996bf1e 100644 --- a/src/junit/com/jogamp/test/junit/util/QuitAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java @@ -26,9 +26,8 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; -import com.jogamp.opengl.util.Animator; import com.jogamp.newt.event.*; public class QuitAdapter extends WindowAdapter implements WindowListener, KeyListener { diff --git a/src/junit/com/jogamp/test/junit/util/SingletonInstance.java b/src/test/com/jogamp/opengl/test/junit/util/SingletonInstance.java index 997742cf6..7e3b9ebc0 100644 --- a/src/junit/com/jogamp/test/junit/util/SingletonInstance.java +++ b/src/test/com/jogamp/opengl/test/junit/util/SingletonInstance.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import java.io.File; import java.io.IOException; diff --git a/src/junit/com/jogamp/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java index 8baa716b7..b01ba1be9 100644 --- a/src/junit/com/jogamp/test/junit/util/UITestCase.java +++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.test.junit.util; +package com.jogamp.opengl.test.junit.util; import org.junit.Before; import org.junit.BeforeClass; diff --git a/test/native/displayMultiple01.c b/src/test/native/displayMultiple01.c index d51453687..d51453687 100644 --- a/test/native/displayMultiple01.c +++ b/src/test/native/displayMultiple01.c diff --git a/test/native/displayMultiple02.c b/src/test/native/displayMultiple02.c index 1bfe95b95..1bfe95b95 100644 --- a/test/native/displayMultiple02.c +++ b/src/test/native/displayMultiple02.c diff --git a/test/native/glExtensionsListGL2.c b/src/test/native/glExtensionsListGL2.c index 89815e9c0..89815e9c0 100644 --- a/test/native/glExtensionsListGL2.c +++ b/src/test/native/glExtensionsListGL2.c diff --git a/test/native/glExtensionsListGL3.c b/src/test/native/glExtensionsListGL3.c index c531577e8..c531577e8 100644 --- a/test/native/glExtensionsListGL3.c +++ b/src/test/native/glExtensionsListGL3.c diff --git a/test/native/make.sh b/src/test/native/make.sh index 20bd49e4a..20bd49e4a 100755 --- a/test/native/make.sh +++ b/src/test/native/make.sh |