summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/DRIHack.java127
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/Debug.java140
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java390
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java188
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java169
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java602
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java126
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java293
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java377
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java180
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java179
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java320
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java238
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java275
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp189
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase199
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/NativeLibLoader.java109
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java1057
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java234
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java62
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java129
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java125
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java569
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java52
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java299
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java225
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java113
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java271
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java73
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java73
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java99
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java306
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java298
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java90
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java82
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java62
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java99
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java1041
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java244
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java835
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java342
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java109
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java161
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java231
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java84
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java216
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java56
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java130
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java359
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java250
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java111
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java155
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java101
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java146
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java90
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java139
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java88
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java155
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java330
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java439
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java129
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java279
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java638
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java319
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java114
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java66
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java154
-rwxr-xr-xsrc/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java134
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java555
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java285
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java416
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java340
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java77
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java150
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java68
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java64
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java100
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java157
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java150
87 files changed, 18909 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java b/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java
new file mode 100755
index 000000000..ede966259
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/DRIHack.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2006 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;
+
+import java.io.*;
+import java.security.*;
+import com.jogamp.gluegen.runtime.*;
+
+/**
+ * Helper class for working around problems with open-source DRI
+ * drivers. In the current DRI implementation it is required that the
+ * symbols in libGL.so.1.2 be globally visible to be accessible from
+ * other libraries that are dynamically loaded by the implementation.
+ * Applications may typically satisfy this need either by linking
+ * against libGL.so on the command line (-lGL) or by dlopen'ing
+ * libGL.so.1.2 with the RTLD_GLOBAL flag. The JOGL implementation
+ * links against libGL on all platforms rather than forcing all OpenGL
+ * entry points to be called through a function pointer. This allows
+ * the JOGL library to link directly to core 1.1 OpenGL entry points
+ * like glVertex3f, while calling through function pointers for entry
+ * points from later OpenGL versions as well as from
+ * extensions. However, because libjogl.so (which links against
+ * libGL.so) is loaded by the JVM, and because the JVM implicitly uses
+ * RTLD_LOCAL in the implementation of System.loadLibrary(), this
+ * means via transitivity that the symbols for libGL.so have only
+ * RTLD_LOCAL visibility to the rest of the application, so the DRI
+ * drivers can not find the symbols required. <P>
+ *
+ * There are at least two possible solutions. One would be to change
+ * the JOGL implementation to call through function pointers uniformly
+ * so that it does not need to link against libGL.so. This is
+ * possible, but requires changes to GlueGen and also is not really
+ * necessary in any other situation than with the DRI drivers. Another
+ * solution is to force the first load of libGL.so.1.2 to be done
+ * dynamically with RTLD_GLOBAL before libjogl.so is loaded and causes
+ * libGL.so.1.2 to be loaded again. The NativeLibrary class in the
+ * GlueGen runtime has this property, and we use it to implement this
+ * workaround.
+ */
+
+public class DRIHack {
+ private static final boolean DEBUG = Debug.debug("DRIHack");
+ private static boolean driHackNeeded;
+ private static NativeLibrary oglLib;
+
+ public static void begin() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String os = Debug.getProperty("os.name", false).toLowerCase();
+ // Do DRI hack on all Linux distributions for best robustness
+ driHackNeeded =
+ (os.startsWith("linux") ||
+ new File("/usr/lib/dri").exists() ||
+ new File("/usr/X11R6/lib/modules/dri").exists());
+ // Allow manual overriding for now as a workaround for
+ // problems seen in some situations -- needs more investigation
+ if (Debug.getProperty("jogl.drihack.disable", true) != null) {
+ driHackNeeded = false;
+ }
+ return null;
+ }
+ });
+
+ if (driHackNeeded) {
+ if (DEBUG) {
+ System.err.println("Beginning DRI hack");
+ }
+
+ // Try a few different variants for best robustness
+ // In theory probably only the first is necessary
+ oglLib = NativeLibrary.open("libGL.so.1", null);
+ if (DEBUG && oglLib != null) System.err.println(" Found libGL.so.1");
+ if (oglLib == null) {
+ oglLib = NativeLibrary.open("/usr/lib/libGL.so.1", null);
+ if (DEBUG && oglLib != null) System.err.println(" Found /usr/lib/libGL.so.1");
+ }
+ }
+ }
+
+ public static void end() {
+ if (oglLib != null) {
+ if (DEBUG) {
+ System.err.println("Ending DRI hack");
+ }
+
+ oglLib.close();
+ oglLib = null;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/Debug.java b/src/jogl/classes/com/jogamp/opengl/impl/Debug.java
new file mode 100644
index 000000000..82a5f2ff2
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/Debug.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003-2005 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;
+
+import java.security.*;
+
+/** Helper routines for logging and debugging. */
+
+public class Debug {
+ // Some common properties
+ private static boolean verbose;
+ private static boolean debugAll;
+ private static AccessControlContext localACC;
+
+ static {
+ localACC=AccessController.getContext();
+ verbose = isPropertyDefined("jogl.verbose", true);
+ debugAll = isPropertyDefined("jogl.debug", true);
+ if (verbose) {
+ Package p = Package.getPackage("javax.media.opengl");
+ System.err.println("JOGL specification version " + p.getSpecificationVersion());
+ System.err.println("JOGL implementation version " + p.getImplementationVersion());
+ System.err.println("JOGL implementation vendor " + p.getImplementationVendor());
+ }
+ }
+
+ static int getIntProperty(final String property, final boolean jnlpAlias) {
+ return getIntProperty(property, jnlpAlias, localACC);
+ }
+
+ public static int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ int i=0;
+ try {
+ Integer iv = Integer.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ i = iv.intValue();
+ } catch (NumberFormatException nfe) {}
+ return i;
+ }
+
+ static boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
+ return getBooleanProperty(property, jnlpAlias, localACC);
+ }
+
+ public static boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ Boolean b = Boolean.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ return b.booleanValue();
+ }
+
+ static boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
+ return isPropertyDefined(property, jnlpAlias, localACC);
+ }
+
+ public static boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ return (Debug.getProperty(property, jnlpAlias, acc) != null) ? true : false;
+ }
+
+ static String getProperty(final String property, final boolean jnlpAlias) {
+ return getProperty(property, jnlpAlias, localACC);
+ }
+
+ public static String getProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ String s=null;
+ if(null!=acc && acc.equals(localACC)) {
+ s = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String val=null;
+ try {
+ val = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==val && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ val = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ return val;
+ }
+ });
+ } else {
+ try {
+ s = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==s && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ s = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ }
+ return s;
+ }
+ public static final String jnlp_prefix = "jnlp." ;
+
+ public static boolean verbose() {
+ return verbose;
+ }
+
+ public static boolean debugAll() {
+ return debugAll;
+ }
+
+ public static boolean debug(String subcomponent) {
+ return debugAll() || isPropertyDefined("jogl.debug." + subcomponent, true);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java
new file mode 100644
index 000000000..f36c4f749
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ExtensionAvailabilityCache.java
@@ -0,0 +1,390 @@
+/*
+ * 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;
+
+import javax.media.opengl.*;
+import java.util.*;
+// FIXME: refactor Java SE dependencies
+//import java.util.regex.*;
+import java.lang.reflect.*;
+
+/**
+ * A utility object intended to be used by implementations to act as a cache
+ * of which OpenGL extensions are currently available on both the host machine
+ * and display.
+ */
+public final class ExtensionAvailabilityCache {
+ private static final boolean DEBUG = Debug.debug("ExtensionAvailabilityCache");
+ private static final boolean DEBUG_AVAILABILITY = Debug.isPropertyDefined("ExtensionAvailabilityCache", true);
+
+ ExtensionAvailabilityCache(GLContextImpl context)
+ {
+ this.context = context;
+ }
+
+ /**
+ * Flush the cache. The cache will be rebuilt lazily as calls to {@link
+ * #isExtensionAvailable(String)} are received.
+ */
+ public void flush()
+ {
+ if(DEBUG) {
+ System.out.println("ExtensionAvailabilityCache: Flush availability OpenGL "+majorVersion+"."+minorVersion);
+ }
+ availableExtensionCache.clear();
+ initialized = false;
+ majorVersion = 1;
+ minorVersion = 0;
+ }
+
+ /**
+ * Flush the cache and rebuild the cache.
+ */
+ public void reset() {
+ flush();
+ initAvailableExtensions();
+ }
+
+ public boolean isInitialized() {
+ return initialized && !availableExtensionCache.isEmpty() ;
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ initAvailableExtensions();
+ return availableExtensionCache.contains(mapGLExtensionName(glExtensionName));
+ }
+
+ public String getPlatformExtensionsString() {
+ initAvailableExtensions();
+ return glXExtensions;
+ }
+
+ public String getGLExtensions() {
+ initAvailableExtensions();
+ if(DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: getGLExtensions() called");
+ }
+ return glExtensions;
+ }
+
+ public int getMajorVersion() {
+ initAvailableExtensions();
+ return majorVersion;
+ }
+
+ public int getMinorVersion() {
+ initAvailableExtensions();
+ return minorVersion;
+ }
+
+ private void initAvailableExtensions() {
+ // if hash is empty (meaning it was flushed), pre-cache it with the list
+ // of extensions that are in the GL_EXTENSIONS string
+ if (availableExtensionCache.isEmpty() || !initialized) {
+ GL gl = context.getGL();
+
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Pre-caching init "+gl+", GL_VERSION "+gl.glGetString(GL.GL_VERSION));
+ }
+
+ // Set version
+ Version version = new Version(gl.glGetString(GL.GL_VERSION));
+ if (version.isValid()) {
+ majorVersion = version.getMajor();
+ minorVersion = version.getMinor();
+
+ if( !gl.isGL3() &&
+ ( majorVersion > 3 ||
+ ( majorVersion == 3 && minorVersion >= 1 ) ) ) {
+ // downsize version to 3.0 in case we are not using GL3 (3.1)
+ majorVersion = 3;
+ minorVersion = 0;
+ }
+ }
+
+ boolean useGetStringi = false;
+
+ if ( majorVersion > 3 ||
+ ( majorVersion == 3 && minorVersion >= 0 ) ||
+ gl.isGL3() ) {
+ if ( ! gl.isGL2GL3() ) {
+ if(DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: GL >= 3.1 usage, but no GL2GL3 interface: "+gl.getClass().getName());
+ }
+ } else if ( ! gl.isFunctionAvailable("glGetStringi") ) {
+ if(DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: GL >= 3.1 usage, but no glGetStringi");
+ }
+ } else {
+ useGetStringi = true;
+ }
+ }
+
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Pre-caching extension availability OpenGL "+majorVersion+"."+minorVersion+
+ ", use "+ ( useGetStringi ? "glGetStringi" : "glGetString" ) );
+ }
+
+ StringBuffer sb = new StringBuffer();
+ if(useGetStringi) {
+ GL2GL3 gl2gl3 = gl.getGL2GL3();
+ int[] numExtensions = { 0 } ;
+ gl2gl3.glGetIntegerv(gl2gl3.GL_NUM_EXTENSIONS, numExtensions, 0);
+ for (int i = 0; i < numExtensions[0]; i++) {
+ sb.append(gl2gl3.glGetStringi(gl2gl3.GL_EXTENSIONS, i));
+ if(i < numExtensions[0]) {
+ sb.append(" ");
+ }
+ }
+ } else {
+ sb.append(gl.glGetString(GL.GL_EXTENSIONS));
+ }
+ glExtensions = sb.toString();
+ glXExtensions = context.getPlatformExtensionsString();
+
+ sb.append(" ");
+ sb.append(glXExtensions);
+
+ String allAvailableExtensions = sb.toString();
+ if (DEBUG_AVAILABILITY) {
+ System.err.println("ExtensionAvailabilityCache: Available extensions: " + allAvailableExtensions);
+ System.err.println("ExtensionAvailabilityCache: GL vendor: " + gl.glGetString(GL.GL_VENDOR));
+ }
+ StringTokenizer tok = new StringTokenizer(allAvailableExtensions);
+ while (tok.hasMoreTokens()) {
+ String availableExt = tok.nextToken().trim();
+ availableExt = availableExt.intern();
+ availableExtensionCache.add(availableExt);
+ if (DEBUG_AVAILABILITY) {
+ System.err.println("ExtensionAvailabilityCache: Available: " + availableExt);
+ }
+ }
+
+ // Put GL version strings in the table as well
+ // FIXME: this needs to be adjusted when the major rev changes
+ // beyond the known ones
+ int major = majorVersion;
+ int minor = minorVersion;
+ while (major > 0) {
+ while (minor >= 0) {
+ availableExtensionCache.add("GL_VERSION_" + major + "_" + minor);
+ if (DEBUG) {
+ System.err.println("ExtensionAvailabilityCache: Added GL_VERSION_" + major + "_" + minor + " to known extensions");
+ }
+ --minor;
+ }
+
+ switch (major) {
+ case 3:
+ if(gl.isGL3()) {
+ // GL3 is a GL 3.1 forward compatible context,
+ // hence no 2.0, 1.0 - 1.5 GL versions are supported.
+ major=0;
+ }
+ // Restart loop at version 2.1
+ minor = 1;
+ break;
+ case 2:
+ // Restart loop at version 1.5
+ minor = 5;
+ break;
+ case 1:
+ break;
+ }
+
+ --major;
+ }
+
+ // put a dummy var in here so that the cache is no longer empty even if
+ // no extensions are in the GL_EXTENSIONS string
+ availableExtensionCache.add("<INTERNAL_DUMMY_PLACEHOLDER>");
+
+ initialized = true;
+ }
+ }
+
+ // FIXME: hack to re-enable GL_NV_vertex_array_range extension after
+ // recent upgrade to new wglext.h and glxext.h headers
+ private static String mapGLExtensionName(String extensionName) {
+ if (extensionName != null &&
+ (extensionName.equals("WGL_NV_vertex_array_range") ||
+ extensionName.equals("GLX_NV_vertex_array_range")))
+ return "GL_NV_vertex_array_range";
+ return extensionName;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private boolean initialized = false;
+ private int majorVersion = 1;
+ private int minorVersion = 0;
+ private String glExtensions = null;
+ private String glXExtensions = null;
+ private HashSet availableExtensionCache = new HashSet(50);
+ private GLContextImpl context;
+
+ /**
+ * A class for storing and comparing OpenGL version numbers.
+ * This only works for desktop OpenGL at the moment.
+ */
+ private static class Version implements Comparable
+ {
+ private boolean valid;
+ private int major, minor, sub;
+ public Version(int majorRev, int minorRev, int subMinorRev)
+ {
+ major = majorRev;
+ minor = minorRev;
+ sub = subMinorRev;
+ }
+
+ /**
+ * @param versionString must be of the form "GL_VERSION_X" or
+ * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z" or "X.Y", where X, Y,
+ * and Z are integers.
+ *
+ * @exception IllegalArgumentException if the argument is not a valid
+ * OpenGL version identifier
+ */
+ public Version(String versionString)
+ {
+ try
+ {
+ if (versionString.startsWith("GL_VERSION_"))
+ {
+ StringTokenizer tok = new StringTokenizer(versionString, "_");
+
+ tok.nextToken(); // GL_
+ tok.nextToken(); // VERSION_
+ if (!tok.hasMoreTokens()) { major = 0; return; }
+ major = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { minor = 0; return; }
+ minor = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { sub = 0; return; }
+ sub = Integer.valueOf(tok.nextToken()).intValue();
+ }
+ else
+ {
+ int radix = 10;
+ if (versionString.length() > 2) {
+ if (Character.isDigit(versionString.charAt(0)) &&
+ versionString.charAt(1) == '.' &&
+ Character.isDigit(versionString.charAt(2))) {
+ major = Character.digit(versionString.charAt(0), radix);
+ minor = Character.digit(versionString.charAt(2), radix);
+
+ // See if there's version-specific information which might
+ // imply a more recent OpenGL version
+ StringTokenizer tok = new StringTokenizer(versionString, " ");
+ if (tok.hasMoreTokens()) {
+ tok.nextToken();
+ if (tok.hasMoreTokens()) {
+ String token = tok.nextToken();
+ int i = 0;
+ while (i < token.length() && !Character.isDigit(token.charAt(i))) {
+ i++;
+ }
+ if (i < token.length() - 2 &&
+ Character.isDigit(token.charAt(i)) &&
+ token.charAt(i+1) == '.' &&
+ Character.isDigit(token.charAt(i+2))) {
+ int altMajor = Character.digit(token.charAt(i), radix);
+ int altMinor = Character.digit(token.charAt(i+2), radix);
+ // Avoid possibly confusing situations by putting some
+ // constraints on the upgrades we do to the major and
+ // minor versions
+ if ((altMajor == major && altMinor > minor) ||
+ altMajor == major + 1) {
+ major = altMajor;
+ minor = altMinor;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ valid = true;
+ }
+ catch (Exception e)
+ {
+ // FIXME: refactor desktop OpenGL dependencies and make this
+ // class work properly for OpenGL ES
+ System.err.println("ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: "+e);
+ major = 1;
+ minor = 0;
+ /*
+ throw (IllegalArgumentException)
+ new IllegalArgumentException(
+ "Illegally formatted version identifier: \"" + versionString + "\"")
+ .initCause(e);
+ */
+ }
+ }
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public int compareTo(Object o)
+ {
+ Version vo = (Version)o;
+ if (major > vo.major) return 1;
+ else if (major < vo.major) return -1;
+ else if (minor > vo.minor) return 1;
+ else if (minor < vo.minor) return -1;
+ else if (sub > vo.sub) return 1;
+ else if (sub < vo.sub) return -1;
+
+ return 0; // they are equal
+ }
+
+ public int getMajor() {
+ return major;
+ }
+
+ public int getMinor() {
+ return minor;
+ }
+
+ } // end class Version
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java
new file mode 100755
index 000000000..48affa534
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferSizeTracker.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2006 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;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible the sizes of allocated OpenGL buffer
+ * objects. When glMapBuffer or glMapBufferARB is called, in order to
+ * turn the resulting base address into a java.nio.ByteBuffer, we need
+ * to know the size in bytes of the allocated OpenGL buffer object.
+ * Previously we would compute this size by using
+ * glGetBufferParameterivARB with a pname of GL_BUFFER_SIZE, but
+ * it appears doing so each time glMapBuffer is called is too costly
+ * on at least Apple's new multithreaded OpenGL implementation. <P>
+ *
+ * Instead we now try to track the sizes of allocated buffer objects.
+ * We watch calls to glBindBuffer to see which buffer is bound to
+ * which target and to glBufferData to see how large the buffer's
+ * allocated size is. When glMapBuffer is called, we consult our table
+ * of buffer sizes to see if we can return an answer without a glGet
+ * call. <P>
+ *
+ * We share the GLBufferSizeTracker objects among all GLContexts for
+ * which sharing is enabled, because the namespace for buffer objects
+ * is the same for these contexts. <P>
+ *
+ * Tracking the state of which buffer objects are bound is done in the
+ * GLBufferStateTracker and is not completely trivial. In the face of
+ * calls to glPushClientAttrib / glPopClientAttrib we currently punt
+ * and re-fetch the bound buffer object for the state in question;
+ * see, for example, glVertexPointer and the calls down to
+ * GLBufferStateTracker.getBoundBufferObject(). Note that we currently
+ * ignore new binding targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV;
+ * the fact that new binding targets may be added in the future makes
+ * it impossible to cache state for these new targets. <P>
+ *
+ * Ignoring new binding targets, the primary situation in which we may
+ * not be able to return a cached answer is in the case of an error,
+ * where glBindBuffer may not have been called before trying to call
+ * glBufferData. Also, if external native code modifies a buffer
+ * object, we may return an incorrect answer. (FIXME: this case
+ * requires more thought, and perhaps stochastic and
+ * exponential-fallback checking. However, note that it can only occur
+ * in the face of external native code which requires that the
+ * application be signed anyway, so there is no security risk in this
+ * area.)
+ */
+
+public class GLBufferSizeTracker {
+ // Map from buffer names to sizes.
+ // Note: should probably have some way of shrinking this map, but
+ // can't just make it a WeakHashMap because nobody holds on to the
+ // keys; would have to always track creation and deletion of buffer
+ // objects, which is probably sub-optimal. The expected usage
+ // pattern of buffer objects indicates that the fact that this map
+ // never shrinks is probably not that bad.
+ private Map/*<Integer,Integer>*/ bufferSizeMap =
+ Collections.synchronizedMap(new HashMap/*<Integer,Integer>*/());
+
+ private static final boolean DEBUG = Debug.debug("GLBufferSizeTracker");
+
+ public GLBufferSizeTracker() {
+ }
+
+ public void setBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target,
+ GL caller,
+ int size) {
+ // Need to do some similar queries to getBufferSize below
+ int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target);
+ if (valid) {
+ if (buffer == 0) {
+ // FIXME: this really should not happen if we know what's
+ // going on. Very likely there is an OpenGL error in the
+ // application if we get here. Could silently return 0, but it
+ // seems better to get an early warning that something is
+ // wrong.
+ throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" +
+ Integer.toHexString(target));
+ }
+ bufferSizeMap.put(new Integer(buffer), new Integer(size));
+ }
+ // We don't know the current buffer state. Note that the buffer
+ // state tracker will have made the appropriate OpenGL query if it
+ // didn't know what was going on, so at this point we have nothing
+ // left to do except drop this piece of information on the floor.
+ }
+
+ public int getBufferSize(GLBufferStateTracker bufferStateTracker,
+ int target,
+ GL caller) {
+ // See whether we know what buffer is currently bound to the given
+ // state
+ int buffer = bufferStateTracker.getBoundBufferObject(target, caller);
+ boolean valid = bufferStateTracker.isBoundBufferObjectKnown(target);
+ if (valid) {
+ if (buffer == 0) {
+ // FIXME: this really should not happen if we know what's
+ // going on. Very likely there is an OpenGL error in the
+ // application if we get here. Could silently return 0, but it
+ // seems better to get an early warning that something is
+ // wrong.
+ throw new GLException("Error: no OpenGL buffer object appears to be bound to target 0x" +
+ Integer.toHexString(target));
+ }
+ // See whether we know the size of this buffer object; at this
+ // point we almost certainly should if the application is
+ // written correctly
+ Integer key = new Integer(buffer);
+ Integer sz = (Integer) bufferSizeMap.get(key);
+ if (sz == null) {
+ // For robustness, try to query this value from the GL as we used to
+ int[] tmp = new int[1];
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ if (tmp[0] == 0) {
+ // Assume something is wrong rather than silently going along
+ throw new GLException("Error: buffer size returned by glGetBufferParameteriv was zero; probably application error");
+ }
+ // Assume we just don't know what's happening
+ sz = new Integer(tmp[0]);
+ bufferSizeMap.put(key, sz);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): made slow query to cache size " +
+ tmp[0] +
+ " for buffer " +
+ buffer);
+ }
+ }
+ return sz.intValue();
+ }
+ // We don't know what's going on in this case; query the GL for an answer
+ int[] tmp = new int[1];
+ caller.glGetBufferParameteriv(target, GL.GL_BUFFER_SIZE, tmp, 0);
+ if (DEBUG) {
+ System.err.println("GLBufferSizeTracker.getBufferSize(): no cached buffer information");
+ }
+ return tmp[0];
+ }
+
+ // This should be called on any major event where we might start
+ // producing wrong answers, such as OpenGL context creation and
+ // destruction if we don't know whether there are other currently-
+ // created contexts that might be keeping the buffer objects alive
+ // that we're dealing with
+ public void clearCachedBufferSizes() {
+ bufferSizeMap.clear();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java
new file mode 100755
index 000000000..df8d673a1
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLBufferStateTracker.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2006 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;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible which OpenGL buffer object is bound
+ * to which binding target in the current OpenGL context.
+ * GLBufferStateTracker objects are allocated on a per-OpenGL-context basis.
+ * This class is used to verify that e.g. the vertex
+ * buffer object extension is in use when the glVertexPointer variant
+ * taking a long as argument is called. <P>
+ *
+ * Note that because the enumerated value used for the binding of a
+ * buffer object (e.g. GL_ARRAY_BUFFER) is different than that used to
+ * query the binding using glGetIntegerv (e.g.
+ * GL_ARRAY_BUFFER_BINDING), then in the face of new binding targets
+ * being added to the GL (e.g. GL_TRANSFORM_FEEDBACK_BUFFER_NV) it is
+ * impossible to set up a query of the buffer object currently bound
+ * to a particular state. It turns out that for some uses, such as
+ * finding the size of the currently bound buffer, this doesn't
+ * matter, though of course without knowing the buffer object we can't
+ * re-associate the queried size with the buffer object ID. <P>
+ *
+ * Because the namespace of buffer objects is the unsigned integers
+ * with 0 reserved by the GL, and because we have to be able to return
+ * both 0 and other integers as valid answers from
+ * getBoundBufferObject(), we need a second query, which is to ask
+ * whether we know the state of the binding for a given target. For
+ * "unknown" targets such as GL_TRANSFORM_FEEDBACK_BUFFER_NV we return
+ * false from this, but we also clear the valid bit and later refresh
+ * the binding state if glPushClientAttrib / glPopClientAttrib are
+ * called, since we don't want the complexity of tracking stacks of
+ * these attributes.
+ *
+ */
+
+public class GLBufferStateTracker {
+ private static final boolean DEBUG = Debug.debug("GLBufferStateTracker");
+
+ private static final Integer arrayBufferEnum = new Integer(GL.GL_ARRAY_BUFFER);
+ private static final Integer elementArrayBufferEnum = new Integer(GL.GL_ELEMENT_ARRAY_BUFFER);
+ private static final Integer pixelPackBufferEnum = new Integer(GL2.GL_PIXEL_PACK_BUFFER);
+ private static final Integer pixelUnpackBufferEnum = new Integer(GL2.GL_PIXEL_UNPACK_BUFFER);
+ private static final Integer zero = new Integer(0);
+
+ // Maps binding targets to buffer objects. A null value indicates
+ // that the binding is unknown. A zero value indicates that it is
+ // known that no buffer is bound to the target.
+ private Map/*<Integer,Integer>*/ bindingMap = new HashMap/*<Integer,Integer>*/();
+
+ private int[] bufTmp = new int[1];
+
+ public GLBufferStateTracker() {
+ // Start with known unbound targets for known keys
+ bindingMap.put(arrayBufferEnum, zero);
+ bindingMap.put(elementArrayBufferEnum, zero);
+ bindingMap.put(pixelPackBufferEnum, zero);
+ bindingMap.put(pixelUnpackBufferEnum, zero);
+ }
+
+ public void setBoundBufferObject(int target, int buffer) {
+ bindingMap.put(box(target), box(buffer));
+ }
+
+ /** Note: returns an unspecified value if the binding for the
+ specified target (e.g. GL_ARRAY_BUFFER) is currently unknown.
+ You must use isBoundBufferObjectKnown() to see whether the
+ return value is valid. */
+ public int getBoundBufferObject(int target, GL caller) {
+ Integer value = (Integer) bindingMap.get(box(target));
+ if (value == null) {
+ // User probably either called glPushClientAttrib /
+ // glPopClientAttrib or is querying an unknown target. See
+ // whether we know how to fetch this state.
+ boolean gotQueryTarget = true;
+ int queryTarget = 0;
+ switch (target) {
+ case GL.GL_ARRAY_BUFFER: queryTarget = GL.GL_ARRAY_BUFFER_BINDING; break;
+ case GL.GL_ELEMENT_ARRAY_BUFFER: queryTarget = GL.GL_ELEMENT_ARRAY_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_PACK_BUFFER: queryTarget = GL2.GL_PIXEL_PACK_BUFFER_BINDING; break;
+ case GL2.GL_PIXEL_UNPACK_BUFFER: queryTarget = GL2.GL_PIXEL_UNPACK_BUFFER_BINDING; break;
+ default: gotQueryTarget = false; break;
+ }
+ if (gotQueryTarget) {
+ caller.glGetIntegerv(queryTarget, bufTmp, 0);
+ if (DEBUG) {
+ System.err.println("GLBufferStateTracker.getBoundBufferObject(): queried bound buffer " +
+ bufTmp[0] +
+ " for query target 0x" + Integer.toHexString(queryTarget));
+ }
+ setBoundBufferObject(target, bufTmp[0]);
+ // Try once more
+ return getBoundBufferObject(target, caller);
+ }
+ return 0;
+ }
+ return value.intValue();
+ }
+
+ /** Indicates whether the binding state for the specified target is
+ currently known. Should be called after getBoundBufferObject()
+ because that method may change the answer for a given target. */
+ public boolean isBoundBufferObjectKnown(int target) {
+ return (bindingMap.get(box(target)) != null);
+ }
+
+ /** Clears out the known/unknown state of the various buffer object
+ binding states. These will be refreshed later on an as-needed
+ basis. This is called by the implementations of
+ glPushClientAttrib / glPopClientAttrib. Might want to call this
+ from GLContext.makeCurrent() in the future to possibly increase
+ the robustness of these caches in the face of external native
+ code manipulating OpenGL state. */
+ public void clearBufferObjectState() {
+ bindingMap.clear();
+ }
+
+ // FIXME: could largely remove this and use Integer.valueOf() in JDK 5
+ private static Integer box(int key) {
+ switch (key) {
+ case 0: return zero;
+ case GL.GL_ARRAY_BUFFER: return arrayBufferEnum;
+ case GL.GL_ELEMENT_ARRAY_BUFFER: return elementArrayBufferEnum;
+ case GL2.GL_PIXEL_PACK_BUFFER: return pixelPackBufferEnum;
+ case GL2.GL_PIXEL_UNPACK_BUFFER: return pixelUnpackBufferEnum;
+ default: return new Integer(key);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
new file mode 100644
index 000000000..32a32e322
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
@@ -0,0 +1,602 @@
+/*
+ * 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;
+
+import java.nio.*;
+import java.lang.reflect.*;
+
+import javax.media.opengl.*;
+import com.sun.nativewindow.impl.NWReflection;
+import com.jogamp.gluegen.runtime.*;
+import com.jogamp.gluegen.runtime.opengl.*;
+
+public abstract class GLContextImpl extends GLContext {
+ protected GLContextLock lock = new GLContextLock();
+ protected static final boolean DEBUG = Debug.debug("GLContext");
+ protected static final boolean VERBOSE = Debug.verbose();
+ // NOTE: default sense of GLContext optimization disabled in JSR-231
+ // 1.0 beta 5 due to problems on X11 platforms (both Linux and
+ // Solaris) when moving and resizing windows. Apparently GLX tokens
+ // get sent to the X server under the hood (and out from under the
+ // cover of the AWT lock) in these situations. Users requiring
+ // multi-screen X11 applications can manually enable this flag. It
+ // basically had no tangible effect on the Windows or Mac OS X
+ // platforms anyway in particular with the disabling of the
+ // GLWorkerThread which we found to be necessary in 1.0 beta 4.
+ protected boolean optimizationEnabled = Debug.isPropertyDefined("jogl.GLContext.optimize", true);
+
+ // Cache of the functions that are available to be called at the current
+ // moment in time
+ protected ExtensionAvailabilityCache extensionAvailability;
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private ProcAddressTable glProcAddressTable;
+
+ // Tracks creation and initialization of buffer objects to avoid
+ // repeated glGet calls upon glMapBuffer operations
+ private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
+ private GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+ private GLStateTracker glStateTracker = new GLStateTracker();
+
+ protected GLDrawableImpl drawable;
+ protected GLDrawableImpl drawableRead;
+
+ protected GL gl;
+
+ public GLContextImpl(GLDrawableImpl drawable, GLDrawableImpl drawableRead, GLContext shareWith) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
+ if (shareWith != null) {
+ GLContextShareSet.registerSharing(this, shareWith);
+ }
+ GLContextShareSet.registerForBufferObjectSharing(shareWith, this);
+ // This must occur after the above calls into the
+ // GLContextShareSet, which set up state needed by the GL object
+ setGL(createGL(drawable.getGLProfile()));
+
+ this.drawable = drawable;
+ setGLDrawableRead(drawableRead);
+ }
+
+ public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public void setGLDrawableRead(GLDrawable read) {
+ boolean lockHeld = lock.isHeld();
+ if(lockHeld) {
+ release();
+ }
+ drawableRead = ( null != read ) ? (GLDrawableImpl) read : drawable;
+ if(lockHeld) {
+ makeCurrent();
+ }
+ }
+
+ public GLDrawable getGLDrawable() {
+ return drawable;
+ }
+
+ public GLDrawable getGLDrawableRead() {
+ return drawableRead;
+ }
+
+ public GLDrawableImpl getDrawableImpl() {
+ return (GLDrawableImpl) getGLDrawable();
+ }
+
+ public int makeCurrent() throws GLException {
+ // Support calls to makeCurrent() over and over again with
+ // different contexts without releasing them
+ // Could implement this more efficiently without explicit
+ // releasing of the underlying context; would require more error
+ // checking during the makeCurrentImpl phase
+ GLContext current = getCurrent();
+ if (current != null) {
+ if (current == this) {
+ // Assume we don't need to make this context current again
+ // For Mac OS X, however, we need to update the context to track resizes
+ update();
+ return CONTEXT_CURRENT;
+ } else {
+ current.release();
+ }
+ }
+
+ if (GLWorkerThread.isStarted() &&
+ !GLWorkerThread.isWorkerThread()) {
+ // Kick the GLWorkerThread off its current context
+ GLWorkerThread.invokeLater(new Runnable() { public void run() {} });
+ }
+
+ lock.lock();
+ int res = 0;
+ try {
+ res = makeCurrentImpl();
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if ((tracker != null) &&
+ (res == CONTEXT_CURRENT_NEW)) {
+ // Increase reference count of GLObjectTracker
+ tracker.ref();
+ }
+ */
+ } catch (GLException e) {
+ lock.unlock();
+ throw(e);
+ }
+ if (res == CONTEXT_NOT_CURRENT) {
+ lock.unlock();
+ } else {
+ if(res == CONTEXT_CURRENT_NEW) {
+ // check if the drawable's and the GL's GLProfile are equal
+ // throws an GLException if not
+ getGLDrawable().getGLProfile().verifyEquality(gl.getGLProfile());
+ }
+ setCurrent(this);
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+
+ // Try cleaning up any stale server-side OpenGL objects
+ // FIXME: not sure what to do here if this throws
+ if (deletedObjectTracker != null) {
+ deletedObjectTracker.clean(getGL());
+ }
+ */
+ }
+ return res;
+ }
+
+ protected abstract int makeCurrentImpl() throws GLException;
+
+ public void release() throws GLException {
+ if (!lock.isHeld()) {
+ throw new GLException("Context not current on current thread");
+ }
+ setCurrent(null);
+ try {
+ releaseImpl();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ protected abstract void releaseImpl() throws GLException;
+
+ public void destroy() {
+ if (lock.isHeld()) {
+ // release current context
+ release();
+ }
+
+ // Must hold the lock around the destroy operation to make sure we
+ // don't destroy the context out from under another thread rendering to it
+ lock.lock();
+ try {
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if (tracker != null) {
+ // Don't need to do anything for contexts that haven't been
+ // created yet
+ if (isCreated()) {
+ // If we are tracking creation and destruction of server-side
+ // OpenGL objects, we must decrement the reference count of the
+ // GLObjectTracker upon context destruction.
+ //
+ // Note that we can only eagerly delete these server-side
+ // objects if there is another context currrent right now
+ // which shares textures and display lists with this one.
+ tracker.unref(deletedObjectTracker);
+ }
+ }
+ */
+
+ // Because we don't know how many other contexts we might be
+ // sharing with (and it seems too complicated to implement the
+ // GLObjectTracker's ref/unref scheme for the buffer-related
+ // optimizations), simply clear the cache of known buffers' sizes
+ // when we destroy contexts
+ if (bufferSizeTracker != null) {
+ bufferSizeTracker.clearCachedBufferSizes();
+ }
+
+ if (bufferStateTracker != null) {
+ bufferStateTracker.clearBufferObjectState();
+ }
+
+ if (glStateTracker != null) {
+ glStateTracker.clearStates(false);
+ }
+
+ destroyImpl();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ protected abstract void destroyImpl() throws GLException;
+
+ // This is only needed for Mac OS X on-screen contexts
+ protected void update() throws GLException {
+ }
+
+ public boolean isSynchronized() {
+ return !lock.getFailFastMode();
+ }
+
+ public void setSynchronized(boolean isSynchronized) {
+ lock.setFailFastMode(!isSynchronized);
+ }
+
+ public final GL getGL() {
+ return gl;
+ }
+
+ public GL setGL(GL gl) {
+ if(DEBUG) {
+ String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():new String("<null>");
+ String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():new String("<null>");
+ Exception e = new Exception("setGL: "+Thread.currentThread()+", "+sgl1+" -> "+sgl2);
+ e.printStackTrace();
+ }
+ this.gl = gl;
+ return gl;
+ }
+
+ public abstract Object getPlatformGLExtensions();
+
+ //----------------------------------------------------------------------
+ // Helpers for various context implementations
+ //
+
+ private Object createInstance(GLProfile glp, String suffix, Class[] cstrArgTypes, Object[] cstrArgs) {
+ return NWReflection.createInstance(glp.getGLImplBaseClassName()+suffix, cstrArgTypes, cstrArgs);
+ }
+
+ /** Create the GL for this context. */
+ protected GL createGL(GLProfile glp) {
+ GL gl = (GL) createInstance(glp, "Impl", new Class[] { GLProfile.class, GLContextImpl.class }, new Object[] { glp, this } );
+
+ /* FIXME: refactor dependence on Java 2D / JOGL bridge
+ if (tracker != null) {
+ gl.setObjectTracker(tracker);
+ }
+ */
+ return gl;
+ }
+
+ public final ProcAddressTable getGLProcAddressTable() {
+ return glProcAddressTable;
+ }
+
+ /**
+ * Shall return the platform extension ProcAddressTable,
+ * ie for GLXExt, EGLExt, ..
+ */
+ public abstract ProcAddressTable getPlatformExtProcAddressTable();
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, binds this pbuffer to its texture target.
+ */
+ public abstract void bindPbufferToTexture();
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, releases this pbuffer from its texture target.
+ */
+ public abstract void releasePbufferFromTexture();
+
+ public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
+
+ public void setSwapInterval(final int interval) {
+ GLContext current = getCurrent();
+ if (current != this) {
+ throw new GLException("This context is not current. Current context: "+current+
+ ", this context "+this);
+ }
+ setSwapIntervalImpl(interval);
+ }
+
+ protected int currentSwapInterval = -1; // default: not set yet ..
+
+ public int getSwapInterval() {
+ return currentSwapInterval;
+ }
+
+ protected void setSwapIntervalImpl(final int interval) {
+ // nop per default ..
+ }
+
+ /** Maps the given "platform-independent" function name to a real function
+ name. Currently this is only used to map "glAllocateMemoryNV" and
+ associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */
+ protected abstract String mapToRealGLFunctionName(String glFunctionName);
+
+ /** Maps the given "platform-independent" extension name to a real
+ function name. Currently this is only used to map
+ "GL_ARB_pbuffer" and "GL_ARB_pixel_format" to "WGL_ARB_pbuffer"
+ and "WGL_ARB_pixel_format" (not yet mapped to X11). */
+ protected abstract String mapToRealGLExtensionName(String glExtensionName);
+
+ /** Helper routine which resets a ProcAddressTable generated by the
+ GLEmitter by looking up anew all of its function pointers. */
+ protected void resetProcAddressTable(Object table) {
+ GLProcAddressHelper.resetProcAddressTable(table, getDrawableImpl().getDynamicLookupHelper() );
+ }
+
+ /** Indicates whether the underlying OpenGL context has been
+ created. This is used to manage sharing of display lists and
+ textures between contexts. */
+ public abstract boolean isCreated();
+
+ /**
+ * Sets the OpenGL implementation class and
+ * the cache of which GL functions are available for calling through this
+ * context. See {@link #isFunctionAvailable(String)} for more information on
+ * the definition of "available".
+ *
+ * @param force force the setting, even if is already being set.
+ * This might be usefull if you change the OpenGL implementation.
+ */
+ protected void setGLFunctionAvailability(boolean force) {
+ if(null!=this.gl && null!=glProcAddressTable && !force) {
+ return; // already done and not forced
+ }
+ if(null==this.gl || force) {
+ setGL(createGL(getGLDrawable().getGLProfile()));
+ }
+
+ updateGLProcAddressTable();
+ }
+
+ /**
+ * Updates the cache of which GL functions are available for calling through this
+ * context. See {@link #isFunctionAvailable(String)} for more information on
+ * the definition of "available".
+ */
+ protected void updateGLProcAddressTable() {
+ if(null==this.gl) {
+ throw new GLException("setGLFunctionAvailability not called yet");
+ }
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing OpenGL extension address table for " + this);
+ }
+ if (glProcAddressTable == null) {
+ glProcAddressTable = (ProcAddressTable) createInstance(gl.getGLProfile(), "ProcAddressTable", new Class[0], null);
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ }
+ resetProcAddressTable(getGLProcAddressTable());
+
+ extensionAvailability.reset();
+ }
+
+ /**
+ * Returns true if the specified OpenGL core- or extension-function can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isFunctionAvailable(String)} for more details.
+ *
+ * @param glFunctionName the name of the OpenGL function (e.g., use
+ * "glPolygonOffsetEXT" or "glPolygonOffset" to check if the {@link
+ * javax.media.opengl.GL#glPolygonOffset(float,float)} is available).
+ */
+ public boolean isFunctionAvailable(String glFunctionName) {
+ if(isCreated()) {
+ // Check GL 1st (cached)
+ ProcAddressTable pTable = getGLProcAddressTable();
+ try {
+ if(0!=pTable.getAddressFor(glFunctionName)) {
+ return true;
+ }
+ } catch (Exception e) {}
+
+ // Check platform extensions 2nd (cached)
+ pTable = getPlatformExtProcAddressTable();
+ try {
+ if(0!=pTable.getAddressFor(glFunctionName)) {
+ return true;
+ }
+ } catch (Exception e) {}
+ }
+ // dynamic function lookup at last incl name aliasing (not cached)
+ DynamicLookupHelper dynLookup = getDrawableImpl().getDynamicLookupHelper();
+ String tmpBase = GLExtensionNames.normalizeVEN(GLExtensionNames.normalizeARB(glFunctionName, true), true);
+ long addr = 0;
+ int variants = GLExtensionNames.getFuncNamePermutationNumber(tmpBase);
+ for(int i = 0; 0==addr && i < variants; i++) {
+ String tmp = GLExtensionNames.getFuncNamePermutation(tmpBase, i);
+ try {
+ addr = dynLookup.dynamicLookupFunction(tmp);
+ } catch (Exception e) { }
+ }
+ if(0!=addr) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the specified OpenGL extension can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isExtensionAvailable(String)} for more details.
+ *
+ * @param glExtensionName the name of the OpenGL extension (e.g.,
+ * "GL_VERTEX_PROGRAM_ARB").
+ */
+ public boolean isExtensionAvailable(String glExtensionName) {
+ return extensionAvailability.isExtensionAvailable(mapToRealGLExtensionName(glExtensionName));
+ }
+
+ public String getPlatformExtensionsString() {
+ return extensionAvailability.getPlatformExtensionsString();
+ }
+
+ public String getGLExtensions() {
+ return extensionAvailability.getGLExtensions();
+ }
+
+ public int getMajorVersion() {
+ return extensionAvailability.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return extensionAvailability.getMinorVersion();
+ }
+
+ public boolean isExtensionCacheInitialized() {
+ return extensionAvailability.isInitialized();
+ }
+
+ /** Indicates which floating-point pbuffer implementation is in
+ use. Returns one of GLPbuffer.APPLE_FLOAT, GLPbuffer.ATI_FLOAT,
+ or GLPbuffer.NV_FLOAT. */
+ public int getFloatingPointMode() throws GLException {
+ throw new GLException("Not supported on non-pbuffer contexts");
+ }
+
+ /** On some platforms the mismatch between OpenGL's coordinate
+ system (origin at bottom left) and the window system's
+ coordinate system (origin at top left) necessitates a vertical
+ flip of pixels read from offscreen contexts. */
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ /** Only called for offscreen contexts; needed by glReadPixels */
+ public abstract int getOffscreenContextPixelDataType();
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+
+ //----------------------------------------------------------------------
+ // Helpers for buffer object optimizations
+
+ public void setBufferSizeTracker(GLBufferSizeTracker bufferSizeTracker) {
+ this.bufferSizeTracker = bufferSizeTracker;
+ }
+
+ public GLBufferSizeTracker getBufferSizeTracker() {
+ return bufferSizeTracker;
+ }
+
+ public GLBufferStateTracker getBufferStateTracker() {
+ return bufferStateTracker;
+ }
+
+ public GLStateTracker getGLStateTracker() {
+ return glStateTracker;
+ }
+
+ //---------------------------------------------------------------------------
+ // Helpers for context optimization where the last context is left
+ // current on the OpenGL worker thread
+ //
+
+ public boolean isOptimizable() {
+ return optimizationEnabled;
+ }
+
+ public boolean hasWaiters() {
+ return lock.hasWaiters();
+ }
+
+ /* FIXME: needed only by the Java 2D / JOGL bridge; refactor
+
+ public GLContextImpl(GLContext shareWith) {
+ this(shareWith, false);
+ }
+
+ public GLContextImpl(GLContext shareWith, boolean dontShareWithJava2D) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
+ GLContext shareContext = shareWith;
+ if (!dontShareWithJava2D) {
+ shareContext = Java2D.filterShareContext(shareWith);
+ }
+ if (shareContext != null) {
+ GLContextShareSet.registerSharing(this, shareContext);
+ }
+ // Always indicate real behind-the-scenes sharing to track deleted objects
+ if (shareContext == null) {
+ shareContext = Java2D.filterShareContext(shareWith);
+ }
+ GLContextShareSet.registerForObjectTracking(shareWith, this, shareContext);
+ GLContextShareSet.registerForBufferObjectSharing(shareWith, this);
+ // This must occur after the above calls into the
+ // GLContextShareSet, which set up state needed by the GL object
+ setGL(createGL());
+ }
+
+ //---------------------------------------------------------------------------
+ // Helpers for integration with Java2D/OpenGL pipeline when FBOs are
+ // being used
+ //
+
+ public void setObjectTracker(GLObjectTracker tracker) {
+ this.tracker = tracker;
+ }
+
+ public GLObjectTracker getObjectTracker() {
+ return tracker;
+ }
+
+ public void setDeletedObjectTracker(GLObjectTracker deletedObjectTracker) {
+ this.deletedObjectTracker = deletedObjectTracker;
+ }
+
+ public GLObjectTracker getDeletedObjectTracker() {
+ return deletedObjectTracker;
+ }
+
+ // Tracks creation and deletion of server-side OpenGL objects when
+ // the Java2D/OpenGL pipeline is active and using FBOs to render
+ private GLObjectTracker tracker;
+ // Supports deletion of these objects when no other context is
+ // current which can support immediate deletion of them
+ private GLObjectTracker deletedObjectTracker;
+
+ */
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
new file mode 100644
index 000000000..56a5b023f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextLock.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import javax.media.opengl.*;
+
+/** Implements the makeCurrent / release locking behavior of the
+ GLContext class. When "fail fast mode" is enabled, attempts to
+ lock the same GLContextLock on more than one thread cause
+ GLException to be raised. This lock is not recursive. Attempts to
+ lock it more than once on a given thread will cause GLException to
+ be raised. */
+
+public class GLContextLock {
+ private Object lock = new Object();
+ private Thread owner;
+ private boolean failFastMode = true;
+ private volatile int waiters;
+
+ /** Locks this GLContextLock on the current thread. If fail fast
+ mode is enabled and the GLContextLock is already owned by
+ another thread, throws GLException. */
+ public void lock() throws GLException {
+ synchronized(lock) {
+ Thread current = Thread.currentThread();
+ if (owner == null) {
+ owner = current;
+ } else if (owner != current) {
+ while (owner != null) {
+ if (failFastMode) {
+ throw new GLException("Attempt to make context current on thread " + current +
+ " which is already current on thread " + owner);
+ } else {
+ try {
+ ++waiters;
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ } finally {
+ --waiters;
+ }
+ }
+ }
+ owner = current;
+ } else {
+ throw new GLException("Attempt to make the same context current twice on thread " + current);
+ }
+ }
+ }
+
+ /** Unlocks this GLContextLock. */
+ public void unlock() throws GLException {
+ synchronized (lock) {
+ Thread current = Thread.currentThread();
+ if (owner == current) {
+ owner = null;
+ lock.notifyAll();
+ } else {
+ if (owner != null) {
+ throw new GLException("Attempt by thread " + current +
+ " to release context owned by thread " + owner);
+ } else {
+ throw new GLException("Attempt by thread " + current +
+ " to release unowned context");
+ }
+ }
+ }
+ }
+
+ /** Indicates whether this lock is held by the current thread. */
+ public boolean isHeld() {
+ synchronized(lock) {
+ Thread current = Thread.currentThread();
+ return (owner == current);
+ }
+ }
+
+ public void setFailFastMode(boolean onOrOff) {
+ failFastMode = onOrOff;
+ }
+
+ public boolean getFailFastMode() {
+ return failFastMode;
+ }
+
+ public boolean hasWaiters() {
+ return (waiters != 0);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java
new file mode 100644
index 000000000..abeb231f4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextShareSet.java
@@ -0,0 +1,293 @@
+/*
+ * 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.GraphicsConfiguration;
+// import java.awt.GraphicsDevice;
+// import java.awt.GraphicsEnvironment;
+import java.lang.ref.*;
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Provides a mechanism by which OpenGL contexts can share textures
+ and display lists in the face of multithreading and asynchronous
+ context creation as is inherent in the AWT and Swing. */
+
+public class GLContextShareSet {
+ // FIXME: refactor Java SE dependencies
+ // private static boolean forceTracking = Debug.isPropertyDefined("jogl.glcontext.forcetracking");
+ private static final boolean DEBUG = Debug.debug("GLContextShareSet");
+
+ // This class is implemented with a WeakHashMap that goes from the
+ // contexts as keys to a complex data structure as value that tracks
+ // context creation and deletion.
+
+ private static Map/*<GLContext, ShareSet>*/ shareMap = new WeakHashMap();
+ private static Object dummyValue = new Object();
+
+ private static class ShareSet {
+ private Map allShares = new WeakHashMap();
+ private Map createdShares = new WeakHashMap();
+ private Map destroyedShares = new WeakHashMap();
+
+ public void add(GLContext ctx) {
+ if (allShares.put(ctx, dummyValue) == null) {
+ // FIXME: downcast to GLContextImpl undesirable
+ if (((GLContextImpl) ctx).isCreated()) {
+ createdShares.put(ctx, dummyValue);
+ } else {
+ destroyedShares.put(ctx, dummyValue);
+ }
+ }
+ }
+
+ public GLContext getCreatedShare(GLContext ignore) {
+ for (Iterator iter = createdShares.keySet().iterator(); iter.hasNext(); ) {
+ GLContext ctx = (GLContext) iter.next();
+ if (ctx != ignore) {
+ return ctx;
+ }
+ }
+ return null;
+ }
+
+ public void contextCreated(GLContext ctx) {
+ Object res = destroyedShares.remove(ctx);
+ assert res != null : "State of ShareSet corrupted; thought context " +
+ ctx + " should have been in destroyed set but wasn't";
+ res = createdShares.put(ctx, dummyValue);
+ assert res == null : "State of ShareSet corrupted; thought context " +
+ ctx + " shouldn't have been in created set but was";
+ }
+
+ public void contextDestroyed(GLContext ctx) {
+ Object res = createdShares.remove(ctx);
+ assert res != null : "State of ShareSet corrupted; thought context " +
+ ctx + " should have been in created set but wasn't";
+ res = destroyedShares.put(ctx, dummyValue);
+ assert res == null : "State of ShareSet corrupted; thought context " +
+ ctx + " shouldn't have been in destroyed set but was";
+ }
+ }
+
+ /** Indicate that contexts <code>share1</code> and
+ <code>share2</code> will share textures and display lists. Both
+ must be non-null. */
+ public static synchronized void registerSharing(GLContext share1, GLContext share2) {
+ if (share1 == null || share2 == null) {
+ throw new IllegalArgumentException("Both share1 and share2 must be non-null");
+ }
+ ShareSet share = entryFor(share1);
+ if (share == null) {
+ share = entryFor(share2);
+ }
+ if (share == null) {
+ share = new ShareSet();
+ }
+ share.add(share1);
+ share.add(share2);
+ addEntry(share1, share);
+ addEntry(share2, share);
+ }
+
+ public static synchronized GLContext getShareContext(GLContext contextToCreate) {
+ ShareSet share = entryFor(contextToCreate);
+ if (share == null) {
+ return null;
+ }
+ return share.getCreatedShare(contextToCreate);
+ }
+
+ public static synchronized void contextCreated(GLContext context) {
+ ShareSet share = entryFor(context);
+ if (share != null) {
+ share.contextCreated(context);
+ }
+ }
+
+ public static synchronized void contextDestroyed(GLContext context) {
+ ShareSet share = entryFor(context);
+ if (share != null) {
+ share.contextDestroyed(context);
+ }
+ }
+
+ /** In order to avoid glGet calls for buffer object checks related
+ to glVertexPointer, etc. calls as well as glMapBuffer calls, we
+ need to share the same GLBufferSizeTracker object between
+ contexts sharing textures and display lists. For now we keep
+ this mechanism orthogonal to the GLObjectTracker to hopefully
+ keep things easier to understand. (The GLObjectTracker is
+ currently only needed in a fairly esoteric case, when the
+ Java2D/JOGL bridge is active, but the GLBufferSizeTracker
+ mechanism is now always required.) */
+ public static void registerForBufferObjectSharing(GLContext olderContextOrNull, GLContext newContext) {
+ // FIXME: downcasts to GLContextImpl undesirable
+ GLContextImpl older = (GLContextImpl) olderContextOrNull;
+ GLContextImpl newer = (GLContextImpl) newContext;
+ GLBufferSizeTracker tracker = null;
+ if (older != null) {
+ tracker = older.getBufferSizeTracker();
+ assert (tracker != null)
+ : "registerForBufferObjectSharing was not called properly for the older context, or has a bug in it";
+ }
+ if (tracker == null) {
+ tracker = new GLBufferSizeTracker();
+ }
+ newer.setBufferSizeTracker(tracker);
+ }
+
+ // FIXME: refactor Java SE dependencies
+ // /** Indicates that the two supplied contexts (which must be able to
+ // share textures and display lists) should be in the same
+ // namespace for tracking of server-side object creation and
+ // deletion. Because the sharing necessary behind the scenes is
+ // different than that requested at the user level, the two notions
+ // are different. This must be called immediately after the
+ // creation of the new context (which is the second argument)
+ // before any server-side OpenGL objects have been created in that
+ // context. */
+ // public static void registerForObjectTracking(GLContext olderContextOrNull,
+ // GLContext newContext,
+ // GLContext realShareContext) {
+ // if (isObjectTrackingEnabled() || isObjectTrackingDebuggingEnabled()) {
+ // GLContextImpl impl1 = null;
+ // GLContextImpl impl2 = null;
+ // GLObjectTracker tracker = null;
+ //
+ // synchronized (GLContextShareSet.class) {
+ // if (olderContextOrNull != null &&
+ // newContext != null) {
+ // if (entryFor(olderContextOrNull) != entryFor(newContext)) {
+ // throw new IllegalArgumentException("old and new contexts must be able to share textures and display lists");
+ // }
+ // }
+ //
+ // // FIXME: downcast to GLContextImpl undesirable
+ // impl1 = (GLContextImpl) olderContextOrNull;
+ // impl2 = (GLContextImpl) newContext;
+ //
+ // GLObjectTracker deletedObjectTracker = null;
+ // GLContextImpl shareImpl = (GLContextImpl) realShareContext;
+ // // Before we zap the "user-level" object trackers, make sure
+ // // that all contexts in the share set share the destroyed object
+ // // tracker
+ // if (shareImpl != null) {
+ // deletedObjectTracker = shareImpl.getDeletedObjectTracker();
+ // }
+ // if (deletedObjectTracker == null) {
+ // // Must create one and possibly set it up in the older context
+ // deletedObjectTracker = new GLObjectTracker();
+ // if (DEBUG) {
+ // System.err.println("Created deletedObjectTracker " + deletedObjectTracker + " because " +
+ // ((shareImpl == null) ? "shareImpl was null" : "shareImpl's (" + shareImpl + ") deletedObjectTracker was null"));
+ // }
+ //
+ // if (shareImpl != null) {
+ // // FIXME: think should really assert in this case
+ // shareImpl.setDeletedObjectTracker(deletedObjectTracker);
+ // if (DEBUG) {
+ // System.err.println("Set deletedObjectTracker " + deletedObjectTracker + " in shareImpl context " + shareImpl);
+ // }
+ // }
+ // }
+ // impl2.setDeletedObjectTracker(deletedObjectTracker);
+ // if (DEBUG) {
+ // System.err.println("Set deletedObjectTracker " + deletedObjectTracker + " in impl2 context " + impl2);
+ // }
+ // }
+ //
+ // // Must not hold lock around this operation
+ // // Don't share object trackers with the primordial share context from Java2D
+ // if (Java2D.isOGLPipelineActive()) {
+ // // FIXME: probably need to do something different here
+ // // Need to be able to figure out the GraphicsDevice for the
+ // // older context if it's on-screen
+ // GraphicsDevice device = GraphicsEnvironment.
+ // getLocalGraphicsEnvironment().
+ // getDefaultScreenDevice();
+ // GLContext j2dShareContext = Java2D.getShareContext(device);
+ // if (impl1 != null && impl1 == j2dShareContext) {
+ // impl1 = null;
+ // }
+ // }
+ //
+ // synchronized (GLContextShareSet.class) {
+ // if (impl1 != null) {
+ // tracker = impl1.getObjectTracker();
+ // assert (tracker != null)
+ // : "registerForObjectTracking was not called properly for the older context";
+ // }
+ // if (tracker == null) {
+ // tracker = new GLObjectTracker();
+ // }
+ // // Note that we don't assert that the tracker is non-null for
+ // // impl2 because the way we use this functionality we actually
+ // // overwrite the initially-set object tracker in the new context
+ // impl2.setObjectTracker(tracker);
+ // }
+ // }
+ // }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+
+
+ private static ShareSet entryFor(GLContext context) {
+ return (ShareSet) shareMap.get(context);
+ }
+
+ private static void addEntry(GLContext context, ShareSet share) {
+ if (shareMap.get(context) == null) {
+ shareMap.put(context, share);
+ }
+ }
+
+ // FIXME: refactor Java SE dependencies
+ // private static boolean isObjectTrackingEnabled() {
+ // return ((Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) ||
+ // isObjectTrackingDebuggingEnabled());
+ // }
+ //
+ // private static boolean isObjectTrackingDebuggingEnabled() {
+ // return forceTracking;
+ // }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
new file mode 100644
index 000000000..20d0c8072
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -0,0 +1,377 @@
+/*
+ * 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;
+
+import java.nio.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.gluegen.runtime.*;
+import com.sun.nativewindow.impl.NWReflection;
+import java.lang.reflect.*;
+
+/** Extends GLDrawableFactory with a few methods for handling
+ typically software-accelerated offscreen rendering (Device
+ Independent Bitmaps on Windows, pixmaps on X11). Direct access to
+ these GLDrawables is not supplied directly to end users, though
+ they may be instantiated by the GLJPanel implementation. */
+public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
+ protected static final boolean DEBUG = Debug.debug("GLDrawableFactory");
+
+ //---------------------------------------------------------------------------
+ // Dispatching GLDrawable construction in respect to the NativeWindow Capabilities
+ //
+ public GLDrawable createGLDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities caps = (GLCapabilities) target.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLDrawable result = null;
+ if(caps.isOnscreen()) {
+ if(caps.isPBuffer()) {
+ throw new IllegalArgumentException("Onscreen target can't be PBuffer: "+caps);
+ }
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
+ }
+ result = createOnscreenDrawable(target);
+ } else {
+ if( ! ( target instanceof SurfaceChangeable ) ) {
+ throw new IllegalArgumentException("Passed NativeWindow must implement SurfaceChangeable for offscreen: "+target);
+ }
+ if(caps.isPBuffer() && canCreateGLPbuffer()) {
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> PbufferDrawable: "+target);
+ }
+ result = createGLPbufferDrawable(target);
+ }
+ if(null==result) {
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable: "+target);
+ }
+ result = createOffscreenDrawable(target);
+ }
+ }
+ if(DEBUG) {
+ System.out.println("GLDrawableFactoryImpl.createGLDrawable: "+result);
+ }
+ return result;
+ }
+
+ //---------------------------------------------------------------------------
+ //
+ // Onscreen GLDrawable construction
+ //
+
+ protected abstract GLDrawableImpl createOnscreenDrawable(NativeWindow target);
+
+ //---------------------------------------------------------------------------
+ //
+ // PBuffer GLDrawable construction
+ //
+
+ /** Target must implement SurfaceChangeable */
+ protected abstract GLDrawableImpl createGLPbufferDrawableImpl(NativeWindow target);
+
+ protected GLDrawableImpl createGLPbufferDrawable(NativeWindow target) {
+ if (!canCreateGLPbuffer()) {
+ throw new GLException("Pbuffer support not available with current graphics card");
+ }
+ return createGLPbufferDrawableImpl(target);
+ }
+
+ public GLDrawable createGLPbufferDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height) {
+ if(height<=0 || height<=0) {
+ throw new GLException("Width and height of pbuffer must be positive (were (" +
+ width + ", " + height + "))");
+ }
+ capabilities.setDoubleBuffered(false); // FIXME
+ capabilities.setOnscreen(false);
+ capabilities.setPBuffer(true);
+ return createGLPbufferDrawable( createOffscreenWindow(capabilities, chooser, height, height) );
+ }
+
+ public GLPbuffer createGLPbuffer(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height,
+ GLContext shareWith) {
+ return new GLPbufferImpl( (GLDrawableImpl) createGLPbufferDrawable(capabilities, chooser, height, height),
+ shareWith);
+ }
+
+
+ //---------------------------------------------------------------------------
+ //
+ // Offscreen GLDrawable construction
+ //
+
+ protected abstract GLDrawableImpl createOffscreenDrawable(NativeWindow target) ;
+
+ public GLDrawable createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ int width,
+ int height) {
+ if(width<=0 || height<=0) {
+ throw new GLException("Width and height of pbuffer must be positive (were (" +
+ width + ", " + height + "))");
+ }
+ capabilities.setDoubleBuffered(false); // FIXME
+ capabilities.setOnscreen(false);
+ capabilities.setPBuffer(false);
+ return createOffscreenDrawable( createOffscreenWindow(capabilities, chooser, width, height) );
+ }
+
+ /**
+ * creates an offscreen NativeWindow, which must implement SurfaceChangeable as well,
+ * so the windowing system related implementation is able to set the surface handle.
+ */
+ protected abstract NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser,
+ int width, int height);
+
+ protected GLDrawableFactoryImpl() {
+ super();
+ }
+
+ protected void maybeDoSingleThreadedWorkaround(Runnable action) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(action);
+ } else {
+ action.run();
+ }
+ }
+
+ /**
+ * Returns the sole GLDrawableFactoryImpl instance.
+ *
+ * @param glProfile GLProfile to determine the factory type, ie EGLDrawableFactory,
+ * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL.
+ */
+ public static GLDrawableFactoryImpl getFactoryImpl(GLProfile glp) {
+ return (GLDrawableFactoryImpl) getFactory(glp);
+ }
+
+ // Helper function for more lazily loading the GLU library;
+ // apparently can't use System.loadLibrary on UNIX because it uses
+ // RTLD_LOCAL and we need to call dlsym(RTLD_DEFAULT)
+ public abstract void loadGLULibrary();
+
+ //----------------------------------------------------------------------
+ // Support for locking and unlocking the toolkit -- needed only on X11 platforms
+ //
+
+ public void lockToolkit() {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ }
+
+ public void unlockToolkit() {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ //---------------------------------------------------------------------------
+ // Support for Java2D/JOGL bridge on Mac OS X; the external
+ // GLDrawable mechanism in the public API is sufficient to
+ // implement this functionality on all other platforms
+ //
+
+ public abstract boolean canCreateContextOnJava2DSurface();
+
+ public abstract GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException;
+
+ //----------------------------------------------------------------------
+ // Gamma adjustment support
+ // Thanks to the LWJGL team for illustrating how to make these
+ // adjustments on various OSs.
+
+ /*
+ * Portions Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT OWNER 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.
+ */
+
+ /**
+ * Sets the gamma, brightness, and contrast of the current main
+ * display. Returns true if the settings were changed, false if
+ * not. If this method returns true, the display settings will
+ * automatically be reset upon JVM exit (assuming the JVM does not
+ * crash); if the user wishes to change the display settings back to
+ * normal ahead of time, use resetDisplayGamma(). Throws
+ * IllegalArgumentException if any of the parameters were
+ * out-of-bounds.
+ *
+ * @param gamma The gamma value, typically > 1.0 (default value is
+ * 1.0)
+ * @param brightness The brightness value between -1.0 and 1.0,
+ * inclusive (default value is 0)
+ * @param contrast The contrast, greater than 0.0 (default value is 1)
+ * @throws IllegalArgumentException if any of the parameters were
+ * out-of-bounds
+ */
+ public boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ if ((brightness < -1.0f) || (brightness > 1.0f)) {
+ throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0");
+ }
+ if (contrast < 0) {
+ throw new IllegalArgumentException("Contrast must be greater than 0.0");
+ }
+ // FIXME: ensure gamma is > 1.0? Are smaller / negative values legal?
+ int rampLength = getGammaRampLength();
+ if (rampLength == 0) {
+ return false;
+ }
+ float[] gammaRamp = new float[rampLength];
+ for (int i = 0; i < rampLength; i++) {
+ float intensity = (float) i / (float) (rampLength - 1);
+ // apply gamma
+ float rampEntry = (float) java.lang.Math.pow(intensity, gamma);
+ // apply brightness
+ rampEntry += brightness;
+ // apply contrast
+ rampEntry = (rampEntry - 0.5f) * contrast + 0.5f;
+ // Clamp entry to [0, 1]
+ if (rampEntry > 1.0f)
+ rampEntry = 1.0f;
+ else if (rampEntry < 0.0f)
+ rampEntry = 0.0f;
+ gammaRamp[i] = rampEntry;
+ }
+ registerGammaShutdownHook();
+ return setGammaRamp(gammaRamp);
+ }
+
+ public synchronized void resetDisplayGamma() {
+ if (gammaShutdownHook == null) {
+ throw new IllegalArgumentException("Should not call this unless setDisplayGamma called first");
+ }
+ resetGammaRamp(originalGammaRamp);
+ unregisterGammeShutdownHook();
+ }
+
+ //------------------------------------------------------
+ // Gamma-related methods to be implemented by subclasses
+ //
+
+ /** Returns the length of the computed gamma ramp for this OS and
+ hardware. Returns 0 if gamma changes are not supported. */
+ protected int getGammaRampLength() {
+ return 0;
+ }
+
+ /** Sets the gamma ramp for the main screen. Returns false if gamma
+ ramp changes were not supported. */
+ protected boolean setGammaRamp(float[] ramp) {
+ return false;
+ }
+
+ /** Gets the current gamma ramp. This is basically an opaque value
+ used only on some platforms to reset the gamma ramp to its
+ original settings. */
+ protected Buffer getGammaRamp() {
+ return null;
+ }
+
+ /** Resets the gamma ramp, potentially using the specified Buffer as
+ data to restore the original values. */
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ }
+
+ // Shutdown hook mechanism for resetting gamma
+ private boolean gammaShutdownHookRegistered;
+ private Thread gammaShutdownHook;
+ private Buffer originalGammaRamp;
+ private synchronized void registerGammaShutdownHook() {
+ if (gammaShutdownHookRegistered)
+ return;
+ if (gammaShutdownHook == null) {
+ gammaShutdownHook = new Thread(new Runnable() {
+ public void run() {
+ synchronized (GLDrawableFactoryImpl.this) {
+ resetGammaRamp(originalGammaRamp);
+ }
+ }
+ });
+ originalGammaRamp = getGammaRamp();
+ }
+ Runtime.getRuntime().addShutdownHook(gammaShutdownHook);
+ gammaShutdownHookRegistered = true;
+ }
+
+ private synchronized void unregisterGammeShutdownHook() {
+ if (!gammaShutdownHookRegistered)
+ return;
+ if (gammaShutdownHook == null) {
+ throw new InternalError("Error in gamma shutdown hook logic");
+ }
+ Runtime.getRuntime().removeShutdownHook(gammaShutdownHook);
+ gammaShutdownHookRegistered = false;
+ // Leave the original gamma ramp data alone
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
new file mode 100644
index 000000000..7a4e84081
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -0,0 +1,180 @@
+/*
+ * 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;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Encapsulates the implementation of most of the GLAutoDrawable's
+ methods to be able to share it between GLCanvas and GLJPanel. */
+
+public class GLDrawableHelper {
+ private volatile List listeners = new ArrayList();
+ private static final boolean DEBUG = Debug.debug("GLDrawableHelper");
+ private static final boolean VERBOSE = Debug.verbose();
+ private static final boolean NVIDIA_CRASH_WORKAROUND = Debug.isPropertyDefined("jogl.nvidia.crash.workaround", true);
+ private boolean autoSwapBufferMode = true;
+
+ public GLDrawableHelper() {
+ }
+
+ public synchronized String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("GLEventListeners num "+listeners.size()+" [");
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public synchronized void addGLEventListener(GLEventListener listener) {
+ List newListeners = (List) ((ArrayList) listeners).clone();
+ newListeners.add(listener);
+ listeners = newListeners;
+ }
+
+ public synchronized void removeGLEventListener(GLEventListener listener) {
+ List newListeners = (List) ((ArrayList) listeners).clone();
+ newListeners.remove(listener);
+ listeners = newListeners;
+ }
+
+ public synchronized void dispose(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).dispose(drawable);
+ }
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).init(drawable);
+ }
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).display(drawable);
+ }
+ }
+
+ public void reshape(GLAutoDrawable drawable,
+ int x, int y, int width, int height) {
+ for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
+ ((GLEventListener) iter.next()).reshape(drawable, x, y, width, height);
+ }
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ autoSwapBufferMode = onOrOff;
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return autoSwapBufferMode;
+ }
+
+ private static final ThreadLocal perThreadInitAction = new ThreadLocal();
+ /** Principal helper method which runs a Runnable with the context
+ made current. This could have been made part of GLContext, but a
+ desired goal is to be able to implement the GLCanvas in terms of
+ the GLContext's public APIs, and putting it into a separate
+ class helps ensure that we don't inadvertently use private
+ methods of the GLContext or its implementing classes. */
+ public void invokeGL(GLDrawable drawable,
+ GLContext context,
+ Runnable runnable,
+ Runnable initAction) {
+ if(null==context) {
+ if (DEBUG) {
+ Exception e = new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): NULL GLContext");
+ e.printStackTrace();
+ }
+ return;
+ }
+ // Support for recursive makeCurrent() calls as well as calling
+ // other drawables' display() methods from within another one's
+ GLContext lastContext = GLContext.getCurrent();
+ Runnable lastInitAction = (Runnable) perThreadInitAction.get();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+
+ int res = 0;
+ try {
+ res = context.makeCurrent();
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ if(null!=initAction) {
+ perThreadInitAction.set(initAction);
+ if (res == GLContext.CONTEXT_CURRENT_NEW) {
+ if (DEBUG) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+ }
+ initAction.run();
+ }
+ }
+ if(null!=runnable) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running runnable");
+ }
+ runnable.run();
+ if (autoSwapBufferMode) {
+ if (drawable != null) {
+ drawable.swapBuffers();
+ }
+ }
+ }
+ }
+ } finally {
+ try {
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ context.release();
+ }
+ } catch (Exception e) {
+ }
+ if (lastContext != null) {
+ int res2 = lastContext.makeCurrent();
+ if (res2 == GLContext.CONTEXT_CURRENT_NEW) {
+ lastInitAction.run();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
new file mode 100644
index 000000000..20bf20c20
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
@@ -0,0 +1,179 @@
+/*
+ * 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;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+public abstract class GLDrawableImpl implements GLDrawable {
+ protected static final boolean DEBUG = Debug.debug("GLDrawable");
+
+ protected GLDrawableImpl(GLDrawableFactory factory,
+ NativeWindow comp,
+ boolean realized) {
+ this.factory = factory;
+ this.component = comp;
+ this.realized = realized;
+ this.requestedCapabilities = (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getRequestedCapabilities(); // a copy ..
+ }
+
+ /**
+ * Returns the DynamicLookupHelper
+ */
+ public abstract DynamicLookupHelper getDynamicLookupHelper();
+
+ public GLDrawableFactoryImpl getFactoryImpl() {
+ return (GLDrawableFactoryImpl) getFactory();
+ }
+
+ /** For offscreen GLDrawables (pbuffers and "pixmap" drawables),
+ indicates that native resources should be reclaimed. */
+ public void destroy() {
+ throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
+ }
+
+ public void swapBuffers() throws GLException {
+ GLCapabilities caps = (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!component.surfaceSwap()) {
+ swapBuffersImpl();
+ }
+ } else {
+ GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFinish();
+ }
+ }
+ component.surfaceUpdated(this, component, System.currentTimeMillis());
+ }
+
+ protected abstract void swapBuffersImpl();
+
+ public static String toHexString(long hex) {
+ return GLContextImpl.toHexString(hex);
+ }
+
+ public GLProfile getGLProfile() {
+ return requestedCapabilities.getGLProfile();
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ return (GLCapabilities)component.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); // a copy
+ }
+
+ public GLCapabilities getRequestedGLCapabilities() {
+ return requestedCapabilities;
+ }
+
+ public NativeWindow getNativeWindow() {
+ return component;
+ }
+
+ public GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ public void setRealized(boolean realized) {
+ if ( this.realized != realized ) {
+ if(DEBUG) {
+ System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" -> "+realized);
+ }
+ this.realized = realized;
+ setRealizedImpl();
+ } else if(DEBUG) {
+ System.err.println("setRealized: "+getClass().getName()+" "+this.realized+" == "+realized);
+ }
+ }
+ protected abstract void setRealizedImpl();
+
+ public boolean getRealized() {
+ return realized;
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ /** Returns the current height of this GLDrawable. */
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public int lockSurface() throws GLException {
+ if (!realized) {
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ return component.lockSurface();
+ }
+
+ public void unlockSurface() {
+ component.unlockSurface();
+ }
+
+ public boolean isSurfaceLocked() {
+ return component.isSurfaceLocked();
+ }
+
+ public String toString() {
+ return getClass().getName()+"[realized "+getRealized()+
+ ",\n\tfactory "+getFactory()+
+ ",\n\twindow "+getNativeWindow()+
+ ",\n\trequested "+getRequestedGLCapabilities()+
+ ",\n\tchosen "+getChosenGLCapabilities()+"]";
+ }
+
+ protected GLDrawableFactory factory;
+ protected NativeWindow component;
+ protected GLCapabilities requestedCapabilities;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // addNotify() is called on the component.
+ protected boolean realized;
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
new file mode 100644
index 000000000..dd8d980a6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
@@ -0,0 +1,320 @@
+/*
+ * 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;
+
+/**
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.event.*;
+import java.beans.PropertyChangeListener;
+ */
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+
+/** Platform-independent class exposing pbuffer functionality to
+ applications. This class is not exposed in the public API as it
+ would probably add no value; however it implements the GLDrawable
+ interface so can be interacted with via its display() method. */
+
+public class GLPbufferImpl implements GLPbuffer {
+ private GLDrawableImpl pbufferDrawable;
+ private GLContextImpl context;
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private int floatMode;
+
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable,
+ GLContext parentContext) {
+ GLCapabilities caps = (GLCapabilities)
+ pbufferDrawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if(caps.isOnscreen()) {
+ if(caps.isPBuffer()) {
+ throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
+ }
+ throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
+ } else {
+ if(!caps.isPBuffer()) {
+ throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
+ }
+ }
+ this.pbufferDrawable = pbufferDrawable;
+ context = (GLContextImpl) pbufferDrawable.createContext(parentContext);
+ context.setSynchronized(true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return pbufferDrawable.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public NativeWindow getNativeWindow() {
+ return pbufferDrawable.getNativeWindow();
+ }
+
+ public GLDrawableFactory getFactory() {
+ return pbufferDrawable.getFactory();
+ }
+
+ public int getWidth() {
+ return pbufferDrawable.getWidth();
+ }
+
+ public int getHeight() {
+ return pbufferDrawable.getHeight();
+ }
+
+ public void display() {
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction,
+ false);
+ }
+
+ public void repaint() {
+ display();
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setContext(GLContext ctx) {
+ context=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GLDrawable getDrawable() {
+ return pbufferDrawable;
+ }
+
+ public GL getGL() {
+ return getContext().getGL();
+ }
+
+ public GL setGL(GL gl) {
+ return getContext().setGL(gl);
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ drawableHelper.setAutoSwapBufferMode(onOrOff);
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return drawableHelper.getAutoSwapBufferMode();
+ }
+
+ public void swapBuffers() {
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction, false);
+ }
+
+ public void bindTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
+ context.bindPbufferToTexture();
+ }
+
+ public void releaseTexture() {
+ // Doesn't make much sense to try to do this on the event dispatch
+ // thread given that it has to be called while the context is current
+ context.releasePbufferFromTexture();
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getChosenGLCapabilities();
+ }
+
+ public GLCapabilities getRequestedGLCapabilities() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getRequestedGLCapabilities();
+ }
+
+ public GLProfile getGLProfile() {
+ if (pbufferDrawable == null)
+ return null;
+
+ return pbufferDrawable.getGLProfile();
+ }
+
+ private boolean surfaceLocked = false;
+
+ public int lockSurface() throws GLException {
+ surfaceLocked=true;
+ return NativeWindow.LOCK_SUCCESS;
+ }
+
+ public void unlockSurface() {
+ surfaceLocked=false;
+ }
+
+ public boolean isSurfaceLocked() {
+ return surfaceLocked;
+ }
+
+ //----------------------------------------------------------------------
+ // No-ops for ComponentEvents
+ //
+
+ /*
+ public void addComponentListener(ComponentListener l) {}
+ public void removeComponentListener(ComponentListener l) {}
+ public void addFocusListener(FocusListener l) {}
+ public void removeFocusListener(FocusListener l) {}
+ public void addHierarchyBoundsListener(HierarchyBoundsListener l) {}
+ public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {}
+ public void addHierarchyListener(HierarchyListener l) {}
+ public void removeHierarchyListener(HierarchyListener l) {}
+ public void addInputMethodListener(InputMethodListener l) {}
+ public void removeInputMethodListener(InputMethodListener l) {}
+ public void addKeyListener(KeyListener l) {}
+ public void removeKeyListener(KeyListener l) {}
+ public void addMouseListener(MouseListener l) {}
+ public void removeMouseListener(MouseListener l) {}
+ public void addMouseMotionListener(MouseMotionListener l) {}
+ public void removeMouseMotionListener(MouseMotionListener l) {}
+ public void addMouseWheelListener(MouseWheelListener l) {}
+ public void removeMouseWheelListener(MouseWheelListener l) {}
+ public void addPropertyChangeListener(PropertyChangeListener listener) {}
+ public void removePropertyChangeListener(PropertyChangeListener listener) {}
+ public void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {}
+ public void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {}
+ */
+
+ public void destroy() {
+ // FIXME: not calling event listeners .. see GLAutoDrawable spec
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(destroyAction);
+ } else {
+ destroyAction.run();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ if (floatMode == 0) {
+ throw new GLException("Pbuffer not initialized, or floating-point support not requested");
+ }
+ return floatMode;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction,
+ boolean isReshape) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(eventDispatchThreadAction);
+ } else {
+ drawableHelper.invokeGL(pbufferDrawable, context, invokeGLAction, initAction);
+ }
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ floatMode = context.getFloatingPointMode();
+ drawableHelper.init(GLPbufferImpl.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ drawableHelper.display(GLPbufferImpl.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class SwapBuffersAction implements Runnable {
+ public void run() {
+ pbufferDrawable.swapBuffers();
+ }
+ }
+ private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ // Workaround for ATI driver bugs related to multithreading issues
+ // like simultaneous rendering via Animators to canvases that are
+ // being resized on the AWT event dispatch thread
+ class DisplayOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(pbufferDrawable, context, displayAction, initAction);
+ }
+ }
+ private DisplayOnEventDispatchThreadAction displayOnEventDispatchThreadAction =
+ new DisplayOnEventDispatchThreadAction();
+ class SwapBuffersOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(pbufferDrawable, context, swapBuffersAction, initAction);
+ }
+ }
+ private SwapBuffersOnEventDispatchThreadAction swapBuffersOnEventDispatchThreadAction =
+ new SwapBuffersOnEventDispatchThreadAction();
+
+ class DestroyAction implements Runnable {
+ public void run() {
+ if (null != context) {
+ context.destroy();
+ }
+ pbufferDrawable.destroy();
+ }
+ }
+ private DestroyAction destroyAction = new DestroyAction();
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java
new file mode 100755
index 000000000..744e7b924
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLStateTracker.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2006 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;
+
+import java.util.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks as closely as possible OpenGL states.
+ * GLStateTracker objects are allocated on a per-OpenGL-context basis.
+ * <p>
+ * Currently supported states: PixelStorei
+ */
+
+public class GLStateTracker {
+ private static final boolean DEBUG = Debug.debug("GLStateTracker");
+
+ private volatile boolean enabled = true;
+
+ private Map/*<Integer,Integer>*/ pixelStateMap = new HashMap/*<Integer,Integer>*/();
+
+ static class SavedState {
+ SavedState() {
+ this.pixelStateMap = null;
+ }
+ void putPixelStateMap(Map pixelStateMap) {
+ this.pixelStateMap = new HashMap();
+ this.pixelStateMap.putAll(pixelStateMap);
+ }
+ Map getPixelStateMap() { return pixelStateMap; }
+
+ private Map pixelStateMap;
+ // private Map otherStateMap;
+ }
+ private List/*<SavedState>*/ stack = new ArrayList();
+
+ public GLStateTracker() {
+ resetStates();
+ }
+
+ public void clearStates(boolean enable) {
+ enabled = enable;
+ pixelStateMap.clear();
+ }
+
+ public void setEnabled(boolean on) {
+ enabled = on;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public boolean getInt(int pname, int[] params, int params_offset) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ Integer value = (Integer) pixelStateMap.get(key);
+ if(null!=value) {
+ params[params_offset] = value.intValue();
+ } else {
+ GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+ throw re;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean getInt(int pname, java.nio.IntBuffer params, int dummy) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ Integer value = (Integer) pixelStateMap.get(key);
+ if(null!=value) {
+ params.put(params.position(), value.intValue());
+ } else {
+ GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+ throw re;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setInt(int pname, int param) {
+ if(enabled) {
+ Integer key = boxKey(pname);
+ if(null!=key) {
+ pixelStateMap.put(key, boxInt(param));
+ }
+ }
+ }
+
+ public void pushAttrib(int flags) {
+ if(enabled) {
+ SavedState state = new SavedState();
+ if( 0 != (flags&GL2.GL_CLIENT_PIXEL_STORE_BIT) ) {
+ state.putPixelStateMap(pixelStateMap);
+ }
+ stack.add(0, state);
+ }
+ }
+
+ public void popAttrib() {
+ if(enabled) {
+ if(stack.size()==0) {
+ throw new GLException("stack contains no elements");
+ }
+ SavedState state = (SavedState) stack.remove(0);
+ if(null==state) {
+ throw new GLException("null stack element (remaining stack size "+stack.size()+")");
+ }
+
+ Map/*<Integer,Integer>*/ pixelStateMapNew = new HashMap/*<Integer,Integer>*/();
+ if ( null != state.getPixelStateMap() ) {
+ pixelStateMapNew.putAll(state.getPixelStateMap());
+ }
+ pixelStateMap = pixelStateMapNew;
+ }
+ }
+
+ private static final Integer GL_PACK_SWAP_BYTES = new Integer(GL2GL3.GL_PACK_SWAP_BYTES);
+ private static final Integer GL_PACK_LSB_FIRST = new Integer(GL2GL3.GL_PACK_LSB_FIRST);
+ private static final Integer GL_PACK_ROW_LENGTH = new Integer(GL2GL3.GL_PACK_ROW_LENGTH);
+ private static final Integer GL_PACK_SKIP_ROWS = new Integer(GL2GL3.GL_PACK_SKIP_ROWS);
+ private static final Integer GL_PACK_SKIP_PIXELS = new Integer(GL2GL3.GL_PACK_SKIP_PIXELS);
+ private static final Integer GL_PACK_ALIGNMENT = new Integer(GL.GL_PACK_ALIGNMENT);
+ private static final Integer GL_PACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_PACK_IMAGE_HEIGHT);
+ private static final Integer GL_PACK_SKIP_IMAGES = new Integer(GL2GL3.GL_PACK_SKIP_IMAGES);
+
+ private static final Integer GL_UNPACK_SWAP_BYTES = new Integer(GL2GL3.GL_UNPACK_SWAP_BYTES);
+ private static final Integer GL_UNPACK_LSB_FIRST = new Integer(GL2GL3.GL_UNPACK_LSB_FIRST);
+ private static final Integer GL_UNPACK_ROW_LENGTH = new Integer(GL2GL3.GL_UNPACK_ROW_LENGTH);
+ private static final Integer GL_UNPACK_SKIP_ROWS = new Integer(GL2GL3.GL_UNPACK_SKIP_ROWS);
+ private static final Integer GL_UNPACK_SKIP_PIXELS = new Integer(GL2GL3.GL_UNPACK_SKIP_PIXELS);
+ private static final Integer GL_UNPACK_ALIGNMENT = new Integer(GL.GL_UNPACK_ALIGNMENT);
+ private static final Integer GL_UNPACK_IMAGE_HEIGHT = new Integer(GL2GL3.GL_UNPACK_IMAGE_HEIGHT);
+ private static final Integer GL_UNPACK_SKIP_IMAGES = new Integer(GL2GL3.GL_UNPACK_SKIP_IMAGES);
+
+ private static final Integer zero = new Integer(0);
+ private static final Integer one = new Integer(1);
+
+ private static Integer boxKey(int key) {
+ switch (key) {
+ case 0: return zero;
+ case GL2GL3.GL_PACK_SWAP_BYTES: return GL_PACK_SWAP_BYTES;
+ case GL2GL3.GL_PACK_LSB_FIRST: return GL_PACK_LSB_FIRST;
+ case GL2GL3.GL_PACK_ROW_LENGTH: return GL_PACK_ROW_LENGTH;
+ case GL2GL3.GL_PACK_SKIP_ROWS: return GL_PACK_SKIP_ROWS;
+ case GL2GL3.GL_PACK_SKIP_PIXELS: return GL_PACK_SKIP_PIXELS;
+ case GL.GL_PACK_ALIGNMENT: return GL_PACK_ALIGNMENT;
+ case GL2GL3.GL_PACK_IMAGE_HEIGHT: return GL_PACK_IMAGE_HEIGHT;
+ case GL2GL3.GL_PACK_SKIP_IMAGES: return GL_PACK_SKIP_IMAGES;
+
+ case GL2GL3.GL_UNPACK_SWAP_BYTES: return GL_UNPACK_SWAP_BYTES;
+ case GL2GL3.GL_UNPACK_LSB_FIRST: return GL_UNPACK_LSB_FIRST;
+ case GL2GL3.GL_UNPACK_ROW_LENGTH: return GL_UNPACK_ROW_LENGTH;
+ case GL2GL3.GL_UNPACK_SKIP_ROWS: return GL_UNPACK_SKIP_ROWS;
+ case GL2GL3.GL_UNPACK_SKIP_PIXELS: return GL_UNPACK_SKIP_PIXELS;
+ case GL.GL_UNPACK_ALIGNMENT: return GL_UNPACK_ALIGNMENT;
+ case GL2GL3.GL_UNPACK_IMAGE_HEIGHT: return GL_UNPACK_IMAGE_HEIGHT;
+ case GL2GL3.GL_UNPACK_SKIP_IMAGES: return GL_UNPACK_SKIP_IMAGES;
+
+ default: return null;
+ }
+ }
+
+ public void resetStates() {
+ pixelStateMap.clear();
+
+ pixelStateMap.put(GL_PACK_SWAP_BYTES, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_PACK_LSB_FIRST, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_PACK_ROW_LENGTH, zero);
+ pixelStateMap.put(GL_PACK_SKIP_ROWS, zero);
+ pixelStateMap.put(GL_PACK_SKIP_PIXELS, zero);
+ pixelStateMap.put(GL_PACK_ALIGNMENT, new Integer(4));
+ pixelStateMap.put(GL_PACK_IMAGE_HEIGHT, zero);
+ pixelStateMap.put(GL_PACK_SKIP_IMAGES, zero);
+
+ pixelStateMap.put(GL_UNPACK_SWAP_BYTES, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_UNPACK_LSB_FIRST, zero /* GL_FALSE */);
+ pixelStateMap.put(GL_UNPACK_ROW_LENGTH, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_ROWS, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_PIXELS, zero);
+ pixelStateMap.put(GL_UNPACK_ALIGNMENT, new Integer(4));
+ pixelStateMap.put(GL_UNPACK_IMAGE_HEIGHT, zero);
+ pixelStateMap.put(GL_UNPACK_SKIP_IMAGES, zero);
+ }
+
+ private static Integer boxInt(int value) {
+ switch (value) {
+ case 0: return zero;
+ case 1: return one;
+
+ default: return new Integer(value);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java
new file mode 100755
index 000000000..768eea3f7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLWorkerThread.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2006 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;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.*;
+import java.util.*;
+import javax.media.opengl.*;
+
+/** Singleton thread upon which all OpenGL work is performed by
+ default. Unfortunately many vendors' OpenGL drivers are not really
+ thread-safe and stability is much improved by performing OpenGL
+ work on at most one thread. This is the default behavior of the
+ GLAutoDrawable implementations according to the {@link
+ javax.media.opengl.Threading Threading} class. The GLWorkerThread
+ replaces the original AWT event queue thread-based mechanism for
+ two reasons: first, more than one AWT event queue thread may be
+ spawned, for example if a dialog is being shown; second, it avoids
+ blocking the AWT event queue thread during OpenGL rendering. */
+
+public class GLWorkerThread {
+ private static volatile boolean started;
+ private static volatile Thread thread;
+ private static Object lock;
+ private static volatile boolean shouldTerminate;
+ private static volatile Throwable exception;
+
+ // The Runnable to execute immediately on the worker thread
+ private static volatile Runnable work;
+ // Queue of Runnables to be asynchronously invoked
+ private static List queue = new LinkedList();
+
+ /** Should only be called by Threading class if creation of the
+ GLWorkerThread was requested via the opengl.1thread system
+ property. */
+ public static void start() {
+ if (!started) {
+ synchronized (GLWorkerThread.class) {
+ if (!started) {
+ lock = new Object();
+ thread = new Thread(new WorkerRunnable(),
+ "JOGL GLWorkerThread");
+ thread.setDaemon(true);
+ started = true;
+ synchronized (lock) {
+ thread.start();
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ /*
+
+ // Note: it appears that there is a bug in NVidia's current
+ // drivers where if a context was ever made current on a
+ // given thread and that thread has exited before program
+ // exit, a crash occurs in the drivers. Releasing the
+ // context from the given thread does not work around the
+ // problem.
+ //
+ // For the time being, we're going to work around this
+ // problem by not terminating the GLWorkerThread. In theory,
+ // shutting down the GLWorkerThread cleanly could be a good
+ // general solution to the problem of needing to
+ // cooperatively terminate all Animators at program exit.
+ //
+ // It appears that this doesn't even work around all of the
+ // kinds of crashes. Causing the context to be unilaterally
+ // released from the GLWorkerThread after each invocation
+ // seems to work around all of the kinds of crashes seen.
+ //
+ // These appear to be similar to the kinds of crashes seen
+ // when the Java2D/OpenGL pipeline terminates, and those are
+ // a known issue being fixed, so presumably these will be
+ // fixed in NVidia's next driver set.
+
+ // Install shutdown hook to terminate daemon thread more or
+ // less cooperatively
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ // Already terminating (?)
+ return;
+ }
+ synchronized (lockTemp) {
+ shouldTerminate = true;
+ lockTemp.notifyAll();
+ try {
+ lockTemp.wait(500);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ });
+ return null;
+ }
+ });
+
+ */
+
+ } else {
+ throw new RuntimeException("Should not start GLWorkerThread twice");
+ }
+ }
+ }
+ }
+
+ public static void invokeAndWait(Runnable runnable)
+ throws InvocationTargetException, InterruptedException {
+ if (!started) {
+ throw new RuntimeException("May not invokeAndWait on worker thread without starting it first");
+ }
+
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ return; // Terminating
+ }
+
+ synchronized (lockTemp) {
+ if (thread == null) {
+ // Terminating
+ return;
+ }
+
+ work = runnable;
+ lockTemp.notifyAll();
+ lockTemp.wait();
+ if (exception != null) {
+ Throwable localException = exception;
+ exception = null;
+ throw new InvocationTargetException(localException);
+ }
+ }
+ }
+
+ public static void invokeLater(Runnable runnable) {
+ if (!started) {
+ throw new RuntimeException("May not invokeLater on worker thread without starting it first");
+ }
+
+ Object lockTemp = lock;
+ if (lockTemp == null) {
+ return; // Terminating
+ }
+
+ synchronized (lockTemp) {
+ if (thread == null) {
+ // Terminating
+ return;
+ }
+
+ queue.add(runnable);
+ lockTemp.notifyAll();
+ }
+ }
+
+ /** Indicates whether the OpenGL worker thread was started, i.e.,
+ whether it is currently in use. */
+ public static boolean isStarted() {
+ return started;
+ }
+
+ /** Indicates whether the current thread is the OpenGL worker
+ thread. */
+ public static boolean isWorkerThread() {
+ return (Thread.currentThread() == thread);
+ }
+
+ static class WorkerRunnable implements Runnable {
+ public void run() {
+ // Notify starting thread that we're ready
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+
+ while (!shouldTerminate) {
+ synchronized (lock) {
+ while (!shouldTerminate &&
+ (work == null) &&
+ queue.isEmpty()) {
+ try {
+ // Avoid race conditions with wanting to release contexts on this thread
+ lock.wait(1000);
+ } catch (InterruptedException e) {
+ }
+
+ if (GLContext.getCurrent() != null) {
+ // Test later to see whether we need to release this context
+ break;
+ }
+ }
+
+ if (shouldTerminate) {
+ lock.notifyAll();
+ thread = null;
+ lock = null;
+ return;
+ }
+
+ if (work != null) {
+ try {
+ work.run();
+ } catch (Throwable t) {
+ exception = t;
+ } finally {
+ work = null;
+ lock.notifyAll();
+ }
+ }
+
+ while (!queue.isEmpty()) {
+ try {
+ Runnable curAsync = (Runnable) queue.remove(0);
+ curAsync.run();
+ } catch (Throwable t) {
+ System.out.println("Exception occurred on JOGL OpenGL worker thread:");
+ t.printStackTrace();
+ }
+ }
+
+ // See about releasing current context
+ GLContext curContext = GLContext.getCurrent();
+ if (curContext != null &&
+ (curContext instanceof GLContextImpl)) {
+ GLContextImpl impl = (GLContextImpl) curContext;
+ if (impl.hasWaiters()) {
+ impl.release();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp
new file mode 100644
index 000000000..4a0eaa22b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javame_cdc_fp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009 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.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.*;
+import java.nio.*;
+
+/** Internal copy of selected routines from BufferUtil to avoid
+ outward dependencies on com.jogamp.opengl.util package. */
+public class InternalBufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-type)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase
new file mode 100644
index 000000000..655fa95de
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/InternalBufferUtil.java.javase
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2009 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.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.*;
+import java.nio.*;
+
+/** Internal copy of selected routines from BufferUtil to avoid
+ outward dependencies on com.jogamp.opengl.util package. */
+public class InternalBufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+ public static final int SIZEOF_LONG = 8;
+ public static final int SIZEOF_DOUBLE = 8;
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ /** Allocates a new direct DoubleBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static DoubleBuffer newDoubleBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_DOUBLE);
+ return bb.asDoubleBuffer();
+ }
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-ByteBuffer)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/NativeLibLoader.java b/src/jogl/classes/com/jogamp/opengl/impl/NativeLibLoader.java
new file mode 100644
index 000000000..aa71a37da
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/NativeLibLoader.java
@@ -0,0 +1,109 @@
+/*
+ * 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.sun.nativewindow.impl.NativeLibLoaderBase;
+
+public class NativeLibLoader extends NativeLibLoaderBase {
+ public static void loadNEWT() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("newt", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadGLDesktop() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_gl2", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadGLDesktopES12() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_gl2es12", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadES2() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_es2", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadES1() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("jogl_es1", nativeOSPreload, true);
+ return null;
+ }
+ });
+ }
+
+ public static void loadCgImpl() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String[] preload = { "nativewindow", "cg", "cgGL" };
+ loadLibrary("jogl_cg", preload, true);
+ return null;
+ }
+ });
+ }
+
+ private static final String[] nativeOSPreload = { "nativewindow_x11" };
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java
new file mode 100755
index 000000000..dbd84c9de
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ProjectFloat.java
@@ -0,0 +1,1057 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-13 22:20:29 -0700 (Fri, 13 Mar 2009) $ $Revision: 1867 $
+** $Header$
+*/
+
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT OWNER 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.
+ */
+
+/*
+ * 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.
+ */
+package com.jogamp.opengl.impl;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+/**
+ * ProjectFloat.java
+ * <p/>
+ * <p/>
+ * Created 11-jan-2004
+ *
+ * @author Erik Duijs
+ * @author Kenneth Russell
+ */
+public class ProjectFloat {
+ private static final float[] IDENTITY_MATRIX =
+ new float[] {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f };
+
+ private static final float[] ZERO_MATRIX =
+ new float[] {
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f };
+
+ // Note that we have cloned parts of the implementation in order to
+ // support incoming Buffers. The reason for this is to avoid loading
+ // non-direct buffer subclasses unnecessarily, because doing so can
+ // cause performance decreases on direct buffer operations, at least
+ // on the current HotSpot JVM. It would be nicer (and make the code
+ // simpler) to simply have the array-based entry points delegate to
+ // the versions taking Buffers by wrapping the arrays.
+
+ // Array-based implementation
+ private final float[] matrix = new float[16];
+ private final float[][] tempInvertMatrix = new float[4][4];
+
+ private final float[] in = new float[4];
+ private final float[] out = new float[4];
+
+ private final float[] forward = new float[3];
+ private final float[] side = new float[3];
+ private final float[] up = new float[3];
+
+ // Buffer-based implementation
+ private FloatBuffer locbuf;
+ private final FloatBuffer matrixBuf;
+ private final FloatBuffer tempInvertMatrixBuf;
+
+ private final FloatBuffer inBuf;
+ private final FloatBuffer outBuf;
+
+ private final FloatBuffer forwardBuf;
+ private final FloatBuffer sideBuf;
+ private final FloatBuffer upBuf;
+
+ public ProjectFloat() {
+ // Use direct buffers to avoid loading indirect buffer
+ // implementations for applications trying to avoid doing so.
+ // Slice up one big buffer because some NIO implementations
+ // allocate a huge amount of memory to back even the smallest of
+ // buffers.
+ locbuf = InternalBufferUtil.newFloatBuffer(2*16+2*4+3*3);
+ int pos = 0;
+ int sz = 16;
+ matrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ tempInvertMatrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 4;
+ inBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ outBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 3;
+ forwardBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sideBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
+ }
+
+ private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ public static void gluMakeIdentityf(FloatBuffer m) {
+ int oldPos = m.position();
+ m.put(IDENTITY_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an zero matrix
+ */
+ public static void gluMakeZero(FloatBuffer m) {
+ int oldPos = m.position();
+ m.put(ZERO_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ public static void gluMakeIdentityf(float[] m) {
+ for (int i = 0; i < 16; i++) {
+ m[i] = IDENTITY_MATRIX[i];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecf
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecf(float[] matrix, int matrix_offset, float[] in, float[] out) {
+ for (int i = 0; i < 4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i+matrix_offset] +
+ in[1] * matrix[1*4+i+matrix_offset] +
+ in[2] * matrix[2*4+i+matrix_offset] +
+ in[3] * matrix[3*4+i+matrix_offset];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecf
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecf(FloatBuffer matrix, FloatBuffer in, FloatBuffer out) {
+ int inPos = in.position();
+ int outPos = out.position();
+ int matrixPos = matrix.position();
+ for (int i = 0; i < 4; i++) {
+ out.put(i + outPos,
+ in.get(0+inPos) * matrix.get(0*4+i+matrixPos) +
+ in.get(1+inPos) * matrix.get(1*4+i+matrixPos) +
+ in.get(2+inPos) * matrix.get(2*4+i+matrixPos) +
+ in.get(3+inPos) * matrix.get(3*4+i+matrixPos));
+ }
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ public boolean gluInvertMatrixf(float[] src, float[] inverse) {
+ int i, j, k, swap;
+ float t;
+ float[][] temp = tempInvertMatrix;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp[i][j] = src[i*4+j];
+ }
+ }
+ gluMakeIdentityf(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i*4+k];
+ inverse[i*4+k] = inverse[swap*4+k];
+ inverse[swap*4+k] = t;
+ }
+ }
+
+ if (temp[i][i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i*4+k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k] * t;
+ inverse[j*4+k] -= inverse[i*4+k]*t;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ public boolean gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) {
+ int i, j, k, swap;
+ float t;
+
+ int srcPos = src.position();
+ int invPos = inverse.position();
+
+ FloatBuffer temp = tempInvertMatrixBuf;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp.put(i*4+j, src.get(i*4+j + srcPos));
+ }
+ }
+ gluMakeIdentityf(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp.get(i*4+k);
+ temp.put(i*4+k, temp.get(swap*4+k));
+ temp.put(swap*4+k, t);
+
+ t = inverse.get(i*4+k + invPos);
+ inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
+ inverse.put(swap*4+k + invPos, t);
+ }
+ }
+
+ if (temp.get(i*4+i) == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp.get(i*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(i*4+k, temp.get(i*4+k) / t);
+ inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp.get(j*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
+ inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void gluMultMatricesf(float[] a, int a_offset, float[] b, int b_offset, float[] r) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r[i*4+j] =
+ a[i*4+0+a_offset]*b[0*4+j+b_offset] +
+ a[i*4+1+a_offset]*b[1*4+j+b_offset] +
+ a[i*4+2+a_offset]*b[2*4+j+b_offset] +
+ a[i*4+3+a_offset]*b[3*4+j+b_offset];
+ }
+ }
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ public static void gluMultMatricesf(FloatBuffer a, FloatBuffer b, FloatBuffer r) {
+ int aPos = a.position();
+ int bPos = b.position();
+ int rPos = r.position();
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r.put(i*4+j + rPos,
+ a.get(i*4+0+aPos)*b.get(0*4+j+bPos) +
+ a.get(i*4+1+aPos)*b.get(1*4+j+bPos) +
+ a.get(i*4+2+aPos)*b.get(2*4+j+bPos) +
+ a.get(i*4+3+aPos)*b.get(3*4+j+bPos));
+ }
+ }
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ public static void normalize(float[] v) {
+ float r;
+
+ r = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ if ( r == 0.0 || r == 1.0)
+ return;
+
+ r = 1.0f / r;
+
+ v[0] *= r;
+ v[1] *= r;
+ v[2] *= r;
+
+ return;
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ public static void normalize(FloatBuffer v) {
+ float r;
+
+ int vPos = v.position();
+
+ r = (float) Math.sqrt(v.get(0+vPos) * v.get(0+vPos) +
+ v.get(1+vPos) * v.get(1+vPos) +
+ v.get(2+vPos) * v.get(2+vPos));
+ if ( r == 0.0 || r == 1.0)
+ return;
+
+ r = 1.0f / r;
+
+ v.put(0+vPos, v.get(0+vPos) * r);
+ v.put(1+vPos, v.get(1+vPos) * r);
+ v.put(2+vPos, v.get(2+vPos) * r);
+
+ return;
+ }
+
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(float[] v1, float[] v2, float[] result) {
+ result[0] = v1[1] * v2[2] - v1[2] * v2[1];
+ result[1] = v1[2] * v2[0] - v1[0] * v2[2];
+ result[2] = v1[0] * v2[1] - v1[1] * v2[0];
+ }
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(FloatBuffer v1, FloatBuffer v2, FloatBuffer result) {
+ int v1Pos = v1.position();
+ int v2Pos = v2.position();
+ int rPos = result.position();
+
+ result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos));
+ result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos));
+ result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos));
+ }
+
+ /**
+ * Method gluOrtho2D.
+ *
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ */
+ public void gluOrtho2D(GLMatrixFunc gl, float left, float right, float bottom, float top) {
+ gl.glOrthof(left, right, bottom, top, -1, 1);
+ }
+
+ /**
+ * Method gluPerspective.
+ *
+ * @param fovy
+ * @param aspect
+ * @param zNear
+ * @param zFar
+ */
+ public void gluPerspective(GLMatrixFunc gl, float fovy, float aspect, float zNear, float zFar) {
+ float sine, cotangent, deltaZ;
+ float radians = fovy / 2 * (float) Math.PI / 180;
+
+ deltaZ = zFar - zNear;
+ sine = (float) Math.sin(radians);
+
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return;
+ }
+
+ cotangent = (float) Math.cos(radians) / sine;
+
+ gluMakeIdentityf(matrixBuf);
+
+ matrixBuf.put(0 * 4 + 0, cotangent / aspect);
+ matrixBuf.put(1 * 4 + 1, cotangent);
+ matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+ matrixBuf.put(2 * 4 + 3, -1);
+ matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+ matrixBuf.put(3 * 4 + 3, 0);
+
+ gl.glMultMatrixf(matrixBuf);
+ }
+
+ /**
+ * Method gluLookAt
+ *
+ * @param eyex
+ * @param eyey
+ * @param eyez
+ * @param centerx
+ * @param centery
+ * @param centerz
+ * @param upx
+ * @param upy
+ * @param upz
+ */
+ public void gluLookAt(GLMatrixFunc gl,
+ float eyex,
+ float eyey,
+ float eyez,
+ float centerx,
+ float centery,
+ float centerz,
+ float upx,
+ float upy,
+ float upz) {
+ FloatBuffer forward = this.forwardBuf;
+ FloatBuffer side = this.sideBuf;
+ FloatBuffer up = this.upBuf;
+
+ forward.put(0, centerx - eyex);
+ forward.put(1, centery - eyey);
+ forward.put(2, centerz - eyez);
+
+ up.put(0, upx);
+ up.put(1, upy);
+ up.put(2, upz);
+
+ normalize(forward);
+
+ /* Side = forward x up */
+ cross(forward, up, side);
+ normalize(side);
+
+ /* Recompute up as: up = side x forward */
+ cross(side, forward, up);
+
+ gluMakeIdentityf(matrixBuf);
+ matrixBuf.put(0 * 4 + 0, side.get(0));
+ matrixBuf.put(1 * 4 + 0, side.get(1));
+ matrixBuf.put(2 * 4 + 0, side.get(2));
+
+ matrixBuf.put(0 * 4 + 1, up.get(0));
+ matrixBuf.put(1 * 4 + 1, up.get(1));
+ matrixBuf.put(2 * 4 + 1, up.get(2));
+
+ matrixBuf.put(0 * 4 + 2, -forward.get(0));
+ matrixBuf.put(1 * 4 + 2, -forward.get(1));
+ matrixBuf.put(2 * 4 + 2, -forward.get(2));
+
+ gl.glMultMatrixf(matrixBuf);
+ gl.glTranslatef(-eyex, -eyey, -eyez);
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(float objx,
+ float objy,
+ float objz,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float[] win_pos,
+ int win_pos_offset ) {
+
+ float[] in = this.in;
+ float[] out = this.out;
+
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0f;
+
+ __gluMultMatrixVecf(modelMatrix, modelMatrix_offset, in, out);
+ __gluMultMatrixVecf(projMatrix, projMatrix_offset, out, in);
+
+ if (in[3] == 0.0f)
+ return false;
+
+ in[3] = (1.0f / in[3]) * 0.5f;
+
+ // Map x, y and z to range 0-1
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
+
+ // Map x,y to viewport
+ win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+ win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+ win_pos[2+win_pos_offset] = in[2];
+
+ return true;
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(float objx,
+ float objy,
+ float objz,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ FloatBuffer win_pos) {
+
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ in.put(0, objx);
+ in.put(1, objy);
+ in.put(2, objz);
+ in.put(3, 1.0f);
+
+ __gluMultMatrixVecf(modelMatrix, in, out);
+ __gluMultMatrixVecf(projMatrix, out, in);
+
+ if (in.get(3) == 0.0f)
+ return false;
+
+ in.put(3, (1.0f / in.get(3)) * 0.5f);
+
+ // Map x, y and z to range 0-1
+ in.put(0, in.get(0) * in.get(3) + 0.5f);
+ in.put(1, in.get(1) * in.get(3) + 0.5f);
+ in.put(2, in.get(2) * in.get(3) + 0.5f);
+
+ // Map x,y to viewport
+ int vPos = viewport.position();
+ int wPos = win_pos.position();
+ win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
+ win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
+ win_pos.put(2+wPos, in.get(2));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(float winx,
+ float winy,
+ float winz,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float[] obj_pos,
+ int obj_pos_offset) {
+ float[] in = this.in;
+ float[] out = this.out;
+
+ gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!gluInvertMatrixf(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0f;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecf(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ out[3] = 1.0f / out[3];
+
+ obj_pos[0+obj_pos_offset] = out[0] * out[3];
+ obj_pos[1+obj_pos_offset] = out[1] * out[3];
+ obj_pos[2+obj_pos_offset] = out[2] * out[3];
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(float winx,
+ float winy,
+ float winz,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ FloatBuffer obj_pos) {
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
+
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, 1.0f);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ int oPos = obj_pos.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecf(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0f)
+ return false;
+
+ out.put(3, 1.0f / out.get(3));
+
+ obj_pos.put(0+oPos, out.get(0) * out.get(3));
+ obj_pos.put(1+oPos, out.get(1) * out.get(3));
+ obj_pos.put(2+oPos, out.get(2) * out.get(3));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(float winx,
+ float winy,
+ float winz,
+ float clipw,
+ float[] modelMatrix,
+ int modelMatrix_offset,
+ float[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ float near,
+ float far,
+ float[] obj_pos,
+ int obj_pos_offset ) {
+ float[] in = this.in;
+ float[] out = this.out;
+
+ gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!gluInvertMatrixf(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = clipw;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+ in[2] = (in[2] - near) / (far - near);
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecf(matrix, 0, in, out);
+
+ if (out[3] == 0.0f)
+ return false;
+
+ obj_pos[0+obj_pos_offset] = out[0];
+ obj_pos[1+obj_pos_offset] = out[1];
+ obj_pos[2+obj_pos_offset] = out[2];
+ obj_pos[3+obj_pos_offset] = out[3];
+ return true;
+ }
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(float winx,
+ float winy,
+ float winz,
+ float clipw,
+ FloatBuffer modelMatrix,
+ FloatBuffer projMatrix,
+ IntBuffer viewport,
+ float near,
+ float far,
+ FloatBuffer obj_pos) {
+ FloatBuffer in = this.inBuf;
+ FloatBuffer out = this.outBuf;
+
+ gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
+
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, clipw);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+ in.put(2, (in.get(2) - near) / (far - near));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecf(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0f)
+ return false;
+
+ int oPos = obj_pos.position();
+ obj_pos.put(0+oPos, out.get(0));
+ obj_pos.put(1+oPos, out.get(1));
+ obj_pos.put(2+oPos, out.get(2));
+ obj_pos.put(3+oPos, out.get(3));
+ return true;
+ }
+
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ */
+ public void gluPickMatrix(GLMatrixFunc gl,
+ float x,
+ float y,
+ float deltaX,
+ float deltaY,
+ IntBuffer viewport) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ int vPos = viewport.position();
+ gl.glTranslatef((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
+ (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
+ 0);
+ gl.glScalef(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0f);
+ }
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ * @param viewport_offset
+ */
+ public void gluPickMatrix(GLMatrixFunc gl,
+ float x,
+ float y,
+ float deltaX,
+ float deltaY,
+ int[] viewport,
+ int viewport_offset) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ gl.glTranslatef((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
+ (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
+ 0);
+ gl.glScalef(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0f);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp
new file mode 100644
index 000000000..f686bea92
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javame_cdc_fp
@@ -0,0 +1,10 @@
+package com.jogamp.opengl.impl;
+
+public class SystemUtil {
+
+ /** Wrapper for System.getenv(), which doesn't work on platforms
+ earlier than JDK 5 */
+ public static String getenv(String variableName) {
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase
new file mode 100644
index 000000000..dbb717a32
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SystemUtil.java.javase
@@ -0,0 +1,18 @@
+package com.jogamp.opengl.impl;
+
+public class SystemUtil {
+
+ private static volatile boolean getenvSupported = true;
+ /** Wrapper for System.getenv(), which doesn't work on platforms
+ earlier than JDK 5 */
+ public static String getenv(String variableName) {
+ if (getenvSupported) {
+ try {
+ return System.getenv(variableName);
+ } catch (Error e) {
+ getenvSupported = false;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java
new file mode 100644
index 000000000..2576c8ae8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingImpl.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2009 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.
+ *
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.media.nativewindow.NativeWindowFactory;
+import com.sun.nativewindow.impl.NWReflection;
+import javax.media.opengl.GLException;
+
+/** Implementation of the {@link javax.media.opengl.Threading} class. */
+
+public class ThreadingImpl {
+ public static final int AWT = 1;
+ public static final int WORKER = 2;
+
+ protected static final boolean DEBUG = Debug.debug("Threading");
+
+ private static boolean singleThreaded = true;
+ private static int mode;
+ private static boolean hasAWT;
+ // We need to know whether we're running on X11 platforms to change
+ // our behavior when the Java2D/JOGL bridge is active
+ private static boolean _isX11;
+
+ private static final ThreadingPlugin threadingPlugin;
+
+ static {
+ Object threadingPluginTmp =
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String workaround = Debug.getProperty("jogl.1thread", true);
+ // Default to using the AWT thread on all platforms except
+ // Windows. On OS X there is instability apparently due to
+ // using the JAWT on non-AWT threads. On X11 platforms there
+ // are potential deadlocks which can be caused if the AWT
+ // EventQueue thread hands work off to the GLWorkerThread
+ // while holding the AWT lock. The optimization of
+ // makeCurrent / release calls isn't worth these stability
+ // problems.
+ hasAWT = NWReflection.isClassAvailable("java.awt.Canvas") &&
+ NWReflection.isClassAvailable("javax.media.opengl.awt.GLCanvas");
+
+ String osType = NativeWindowFactory.getNativeWindowType(false);
+ _isX11 = NativeWindowFactory.TYPE_X11.equals(osType);
+ // boolean isWindows = NativeWindowFactory.TYPE_WINDOWS.equals(osType);
+
+ // int defaultMode = (isWindows ? WORKER : ( hasAWT ? AWT : WORKER ) );
+ int defaultMode = ( hasAWT ? AWT : WORKER );
+
+ mode = defaultMode;
+ if (workaround != null) {
+ workaround = workaround.toLowerCase();
+ if (workaround.equals("true") ||
+ workaround.equals("auto")) {
+ // Nothing to do; singleThreaded and mode already set up
+ } else if (workaround.equals("worker")) {
+ singleThreaded = true;
+ mode = WORKER;
+ } else if (workaround.equals("awt")) {
+ singleThreaded = true;
+ mode = AWT;
+ } else {
+ singleThreaded = false;
+ }
+ }
+ printWorkaroundNotice();
+
+ Object threadingPluginObj=null;
+ // try to fetch the AWTThreadingPlugin
+ try {
+ threadingPluginObj = NWReflection.createInstance("com.jogamp.opengl.impl.awt.AWTThreadingPlugin");
+ } catch (Throwable t) { }
+ return threadingPluginObj;
+ }
+ });
+ threadingPlugin = (ThreadingPlugin) threadingPluginTmp;
+ if(DEBUG) {
+ System.err.println("Threading: hasAWT "+hasAWT+", mode "+((mode==AWT)?"AWT":"WORKER")+", plugin "+threadingPlugin);
+ }
+ }
+
+ /** No reason to ever instantiate this class */
+ private ThreadingImpl() {}
+
+ public static boolean isX11() { return _isX11; }
+ public static int getMode() { return mode; }
+
+ /** If an implementation of the javax.media.opengl APIs offers a
+ multithreading option but the default behavior is single-threading,
+ this API provides a mechanism for end users to disable single-threading
+ in this implementation. Users are strongly discouraged from
+ calling this method unless they are aware of all of the
+ consequences and are prepared to enforce some amount of
+ threading restrictions in their applications. Disabling
+ single-threading, for example, may have unintended consequences
+ on GLAutoDrawable implementations such as GLCanvas, GLJPanel and
+ GLPbuffer. Currently there is no supported way to re-enable it
+ once disabled, partly to discourage careless use of this
+ method. This method should be called as early as possible in an
+ application. */
+ public static void disableSingleThreading() {
+ singleThreaded = false;
+ if (Debug.verbose()) {
+ System.err.println("Application forced disabling of single-threading of javax.media.opengl implementation");
+ }
+ }
+
+ /** Indicates whether OpenGL work is being automatically forced to a
+ single thread in this implementation. */
+ public static boolean isSingleThreaded() {
+ return singleThreaded;
+ }
+
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public static boolean isOpenGLThread() throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException("Should only call this in single-threaded mode");
+ }
+
+ if(null!=threadingPlugin) {
+ return threadingPlugin.isOpenGLThread();
+ }
+
+ switch (mode) {
+ case AWT:
+ return true;
+ case WORKER:
+ return GLWorkerThread.isWorkerThread();
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public static void invokeOnOpenGLThread(Runnable r) throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException ("Should only call this in single-threaded mode");
+ }
+
+ if (isOpenGLThread()) {
+ throw new GLException ("Should only call this from other threads than the OpenGL thread");
+ }
+
+ if(null!=threadingPlugin) {
+ threadingPlugin.invokeOnOpenGLThread(r);
+ return;
+ }
+
+ switch (mode) {
+ case AWT:
+ r.run();
+ break;
+
+ case WORKER:
+ if (!GLWorkerThread.isStarted()) {
+ synchronized (GLWorkerThread.class) {
+ if (!GLWorkerThread.isStarted()) {
+ GLWorkerThread.start();
+ }
+ }
+ }
+ try {
+ GLWorkerThread.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ break;
+
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** This is a workaround for AWT-related deadlocks which only seem
+ to show up in the context of applets */
+ public static boolean isAWTMode() {
+ return (mode == AWT);
+ }
+
+ private static void printWorkaroundNotice() {
+ if (singleThreaded && Debug.verbose()) {
+ System.err.println("Using " +
+ (mode == AWT ? "AWT" : "OpenGL worker") +
+ " thread for performing OpenGL work in javax.media.opengl implementation");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java
new file mode 100644
index 000000000..37e4aac70
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/ThreadingPlugin.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import javax.media.opengl.*;
+
+public interface ThreadingPlugin {
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public boolean isOpenGLThread() throws GLException;
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public void invokeOnOpenGLThread(Runnable r) throws GLException;
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java
new file mode 100755
index 000000000..07bf2f2db
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTThreadingPlugin.java
@@ -0,0 +1,129 @@
+/*
+ * 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.awt;
+
+import javax.media.opengl.*;
+
+import java.awt.event.*;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+
+import com.jogamp.opengl.impl.*;
+
+public class AWTThreadingPlugin implements ThreadingPlugin {
+
+ public AWTThreadingPlugin() {}
+
+ public boolean isOpenGLThread() throws GLException {
+ switch (ThreadingImpl.getMode()) {
+ case ThreadingImpl.AWT:
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (ThreadingImpl.isX11() && EventQueue.isDispatchThread()));
+ } else {
+ return EventQueue.isDispatchThread();
+ }
+ case ThreadingImpl.WORKER:
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (ThreadingImpl.isX11() && GLWorkerThread.isWorkerThread()));
+ } else {
+ return GLWorkerThread.isWorkerThread();
+ }
+ default:
+ throw new InternalError("Illegal single-threading mode " + ThreadingImpl.getMode());
+ }
+ }
+
+ public void invokeOnOpenGLThread(Runnable r) throws GLException {
+ switch (ThreadingImpl.getMode()) {
+ case ThreadingImpl.AWT:
+ // FIXME: ideally should run all OpenGL work on the Java2D QFT
+ // thread when it's enabled, but unfortunately there are
+ // deadlock issues on X11 platforms when making our
+ // heavyweight OpenGL contexts current on the QFT because we
+ // perform the JAWT lock inside the makeCurrent()
+ // implementation, which attempts to grab the AWT lock on the
+ // QFT which is not allowed. For now, on X11 platforms,
+ // continue to perform this work on the EDT.
+ if (Java2D.isOGLPipelineActive() && !ThreadingImpl.isX11()) {
+ Java2D.invokeWithOGLContextCurrent(null, r);
+ } else {
+ try {
+ EventQueue.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+ break;
+
+ case ThreadingImpl.WORKER:
+ if (!GLWorkerThread.isStarted()) {
+ synchronized (GLWorkerThread.class) {
+ if (!GLWorkerThread.isStarted()) {
+ GLWorkerThread.start();
+ }
+ }
+ }
+ try {
+ GLWorkerThread.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ break;
+
+ default:
+ throw new InternalError("Illegal single-threading mode " + ThreadingImpl.getMode());
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
new file mode 100644
index 000000000..306f6cee7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+package com.jogamp.opengl.impl.awt;
+
+import com.sun.nativewindow.impl.jawt.*;
+
+import com.jogamp.opengl.impl.*;
+
+import javax.media.opengl.*;
+
+import java.lang.reflect.*;
+import java.awt.GraphicsEnvironment;
+
+public class AWTUtil {
+ // See whether we're running in headless mode
+ private static boolean headlessMode;
+ private static Class j2dClazz = null;
+ private static Method isOGLPipelineActive = null;
+ private static Method isQueueFlusherThread = null;
+ private static boolean j2dOk = false;
+
+ static {
+ lockedToolkit = false;
+ headlessMode = GraphicsEnvironment.isHeadless();
+ if(!headlessMode) {
+ try {
+ j2dClazz = Class.forName("com.jogamp.opengl.impl.awt.Java2D");
+ isOGLPipelineActive = j2dClazz.getMethod("isOGLPipelineActive", null);
+ isQueueFlusherThread = j2dClazz.getMethod("isQueueFlusherThread", null);
+ j2dOk = true;
+ } catch (Exception e) {}
+ }
+ }
+
+ private static boolean lockedToolkit;
+
+ public static synchronized void lockToolkit() throws GLException {
+ if (lockedToolkit) {
+ throw new GLException("Toolkit already locked");
+ }
+ lockedToolkit = true;
+
+ if (headlessMode) {
+ // Workaround for running (to some degree) in headless
+ // environments but still supporting rendering via pbuffers
+ // For full correctness, would need to implement a Lock class
+ return;
+ }
+
+ if(j2dOk) {
+ try {
+ if( !((Boolean)isOGLPipelineActive.invoke(null, null)).booleanValue() ||
+ !((Boolean)isQueueFlusherThread.invoke(null, null)).booleanValue() ) {
+ JAWTUtil.lockToolkit();
+ }
+ } catch (Exception e) { j2dOk=false; }
+ }
+ if(!j2dOk) {
+ JAWTUtil.lockToolkit();
+ }
+ }
+
+ public static synchronized void unlockToolkit() {
+ if (lockedToolkit) {
+ lockedToolkit = false;
+ if (headlessMode) {
+ // Workaround for running (to some degree) in headless
+ // environments but still supporting rendering via pbuffers
+ // For full correctness, would need to implement a Lock class
+ return;
+ }
+
+ if(j2dOk) {
+ try {
+ if( !((Boolean)isOGLPipelineActive.invoke(null, null)).booleanValue() ||
+ !((Boolean)isQueueFlusherThread.invoke(null, null)).booleanValue() ) {
+ JAWTUtil.unlockToolkit();
+ }
+ } catch (Exception e) { j2dOk=false; }
+ }
+ if(!j2dOk) {
+ JAWTUtil.unlockToolkit();
+ }
+ }
+ }
+
+ public static boolean isToolkitLocked() {
+ return JAWTUtil.isToolkitLocked();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
new file mode 100755
index 000000000..b871c66a7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2D.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2003-2005 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.awt;
+
+import com.jogamp.opengl.impl.*;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.lang.reflect.*;
+import java.security.*;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+/** Defines integration with the Java2D OpenGL pipeline. This
+ integration is only supported in 1.6 and is highly experimental. */
+
+public class Java2D {
+ private static boolean DEBUG = Debug.debug("Java2D");
+ private static boolean VERBOSE = Debug.verbose();
+ private static boolean isHeadless;
+ private static boolean isOGLPipelineActive;
+ private static Method invokeWithOGLContextCurrentMethod;
+ private static Method isQueueFlusherThreadMethod;
+ private static Method getOGLViewportMethod;
+ private static Method getOGLScissorBoxMethod;
+ private static Method getOGLSurfaceIdentifierMethod;
+ // This one is currently optional and is only in very recent Mustang builds
+ private static Method getOGLTextureTypeMethod;
+
+ // The following methods and fields are needed for proper support of
+ // Frame Buffer Objects in the Java2D/OpenGL pipeline
+ // (-Dsun.java2d.opengl.fbobject=true)
+ private static boolean fbObjectSupportInitialized;
+ private static Method invokeWithOGLSharedContextCurrentMethod;
+ private static Method getOGLSurfaceTypeMethod;
+
+ // Publicly-visible constants for OpenGL surface types
+ public static final int UNDEFINED = getOGLUtilitiesIntField("UNDEFINED");
+ public static final int WINDOW = getOGLUtilitiesIntField("WINDOW");
+ public static final int PBUFFER = getOGLUtilitiesIntField("PBUFFER");
+ public static final int TEXTURE = getOGLUtilitiesIntField("TEXTURE");
+ public static final int FLIP_BACKBUFFER = getOGLUtilitiesIntField("FLIP_BACKBUFFER");
+ public static final int FBOBJECT = getOGLUtilitiesIntField("FBOBJECT");
+
+ // If FBOs are enabled in the Java2D/OpenGL pipeline, all contexts
+ // created by JOGL must share textures and display lists with the
+ // Java2D contexts in order to access the frame buffer object for
+ // potential rendering, and to simultaneously support sharing of
+ // textures and display lists with one another. Java2D has the
+ // notion of a single shared context with which all other contexts
+ // (on the same display device?) share textures and display lists;
+ // this is an approximation to that notion which will be refined
+ // later.
+ private static boolean initializedJ2DFBOShareContext;
+ private static GLContext j2dFBOShareContext;
+
+ // Accessors for new methods in sun.java2d.opengl.CGLSurfaceData
+ // class on OS X for enabling bridge
+ // public static long createOGLContextOnSurface(Graphics g, long ctx);
+ // public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx);
+ // public static void destroyOGLContext(long ctx);
+ private static Method createOGLContextOnSurfaceMethod;
+ private static Method makeOGLContextCurrentOnSurfaceMethod;
+ private static Method destroyOGLContextMethod;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ if (DEBUG && VERBOSE) {
+ System.err.println("Checking for Java2D/OpenGL support");
+ }
+ try {
+ isHeadless = true;
+ // Figure out whether the default graphics configuration is an
+ // OpenGL graphics configuration
+ GraphicsConfiguration cfg =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration();
+ // If we get here, we aren't running in headless mode
+ isHeadless = false;
+ String name = cfg.getClass().getName();
+ if (DEBUG && VERBOSE) {
+ System.err.println("Java2D support: default GraphicsConfiguration = " + name);
+ }
+ isOGLPipelineActive = (name.startsWith("sun.java2d.opengl"));
+
+ if (isOGLPipelineActive) {
+ try {
+ // Try to get methods we need to integrate
+ Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ invokeWithOGLContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLContextCurrent",
+ new Class[] {
+ Graphics.class,
+ Runnable.class
+ });
+ invokeWithOGLContextCurrentMethod.setAccessible(true);
+
+ isQueueFlusherThreadMethod = utils.getDeclaredMethod("isQueueFlusherThread",
+ new Class[] {});
+ isQueueFlusherThreadMethod.setAccessible(true);
+
+ getOGLViewportMethod = utils.getDeclaredMethod("getOGLViewport",
+ new Class[] {
+ Graphics.class,
+ Integer.TYPE,
+ Integer.TYPE
+ });
+ getOGLViewportMethod.setAccessible(true);
+
+ getOGLScissorBoxMethod = utils.getDeclaredMethod("getOGLScissorBox",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLScissorBoxMethod.setAccessible(true);
+
+ getOGLSurfaceIdentifierMethod = utils.getDeclaredMethod("getOGLSurfaceIdentifier",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceIdentifierMethod.setAccessible(true);
+
+ // Try to get additional methods required for proper FBO support
+ fbObjectSupportInitialized = true;
+ try {
+ invokeWithOGLSharedContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLSharedContextCurrent",
+ new Class[] {
+ GraphicsConfiguration.class,
+ Runnable.class
+ });
+ invokeWithOGLSharedContextCurrentMethod.setAccessible(true);
+
+ getOGLSurfaceTypeMethod = utils.getDeclaredMethod("getOGLSurfaceType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLSurfaceTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ fbObjectSupportInitialized = false;
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL FBO support");
+ }
+ }
+
+ // Try to get an additional method for FBO support in recent Mustang builds
+ try {
+ getOGLTextureTypeMethod = utils.getDeclaredMethod("getOGLTextureType",
+ new Class[] {
+ Graphics.class
+ });
+ getOGLTextureTypeMethod.setAccessible(true);
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("GL_ARB_texture_rectangle FBO support disabled");
+ }
+ }
+
+ // Try to set up APIs for enabling the bridge on OS X,
+ // where it isn't possible to create generalized
+ // external GLDrawables
+ Class cglSurfaceData = null;
+ try {
+ cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
+ }
+ }
+ if (cglSurfaceData != null) {
+ // FIXME: for now, assume that FBO support is not enabled on OS X
+ fbObjectSupportInitialized = false;
+
+ // We need to find these methods in order to make the bridge work on OS X
+ createOGLContextOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("createOGLContextOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ createOGLContextOnSurfaceMethod.setAccessible(true);
+
+ makeOGLContextCurrentOnSurfaceMethod = cglSurfaceData.getDeclaredMethod("makeOGLContextCurrentOnSurface",
+ new Class[] {
+ Graphics.class,
+ Long.TYPE
+ });
+ makeOGLContextCurrentOnSurfaceMethod.setAccessible(true);
+
+ destroyOGLContextMethod = cglSurfaceData.getDeclaredMethod("destroyOGLContext",
+ new Class[] {
+ Long.TYPE
+ });
+ destroyOGLContextMethod.setAccessible(true);
+ }
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ System.err.println("Disabling Java2D/JOGL integration");
+ }
+ isOGLPipelineActive = false;
+ }
+ }
+ } catch (HeadlessException e) {
+ // The AWT is running in headless mode, so the Java 2D / JOGL bridge is clearly disabled
+ }
+
+ if (DEBUG) {
+ System.err.println("JOGL/Java2D integration " + (isOGLPipelineActive ? "enabled" : "disabled"));
+ }
+ return null;
+ }
+ });
+ }
+
+ public static boolean isOGLPipelineActive() {
+ return isOGLPipelineActive;
+ }
+
+ public static boolean isFBOEnabled() {
+ return fbObjectSupportInitialized;
+ }
+
+ public static boolean isQueueFlusherThread() {
+ checkActive();
+
+ try {
+ return ((Boolean) isQueueFlusherThreadMethod.invoke(null, new Object[] {})).booleanValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Makes current the OpenGL context associated with the passed
+ Graphics object and runs the given Runnable on the Queue
+ Flushing Thread in one atomic action. */
+ public static void invokeWithOGLContextCurrent(Graphics g, Runnable r) throws GLException {
+ checkActive();
+
+ try {
+ // FIXME: this may need adjustment
+ // This seems to be needed in many applications which don't
+ // initialize an OpenGL context before this and which would
+ // otherwise cause initFBOShareContext to be called from the
+ // Queue Flusher Thread, which isn't allowed
+ initFBOShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice());
+
+ AWTUtil.lockToolkit();
+ try {
+ invokeWithOGLContextCurrentMethod.invoke(null, new Object[] {g, r});
+ } finally {
+ AWTUtil.unlockToolkit();
+ }
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Makes current the "shared" OpenGL context associated with the
+ given GraphicsConfiguration object, allowing JOGL to share
+ server-side OpenGL objects like textures and display lists with
+ this context when necessary. This is needed when Java2D's FBO
+ support is enabled, because in order to render into that FBO,
+ JOGL must share textures and display lists with it. Returns
+ false if the passed GraphicsConfiguration was not an OpenGL
+ GraphicsConfiguration. */
+ public static boolean invokeWithOGLSharedContextCurrent(GraphicsConfiguration g, Runnable r) throws GLException {
+ checkActive();
+
+ try {
+ AWTUtil.lockToolkit();
+ try {
+ return ((Boolean) invokeWithOGLSharedContextCurrentMethod.invoke(null, new Object[] {g, r})).booleanValue();
+ } finally {
+ AWTUtil.unlockToolkit();
+ }
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the OpenGL viewport associated with the given Graphics
+ object, assuming that the Graphics object is associated with a
+ component of the specified width and height. The user should
+ call glViewport() with the returned rectangle's bounds in order
+ to get correct rendering results. Should only be called from the
+ Queue Flusher Thread. */
+ public static Rectangle getOGLViewport(Graphics g,
+ int componentWidth,
+ int componentHeight) {
+ checkActive();
+
+ try {
+ return (Rectangle) getOGLViewportMethod.invoke(null, new Object[] {g,
+ new Integer(componentWidth),
+ new Integer(componentHeight)});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the OpenGL scissor region associated with the given
+ Graphics object, taking into account all clipping regions, etc.
+ To avoid destroying Java2D's previous rendering results, this
+ method should be called and the resulting rectangle's bounds
+ passed to a call to glScissor(). Should only be called from the
+ Queue Flusher Thread. */
+ public static Rectangle getOGLScissorBox(Graphics g) {
+ checkActive();
+
+ try {
+ return (Rectangle) getOGLScissorBoxMethod.invoke(null, new Object[] {g});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns an opaque "surface identifier" associated with the given
+ Graphics object. If this changes from invocation to invocation,
+ the underlying OpenGL drawable for the Graphics object has
+ changed and a new external GLDrawable and GLContext should be
+ created (and the old ones destroyed). Should only be called from
+ the Queue Flusher Thread.*/
+ public static Object getOGLSurfaceIdentifier(Graphics g) {
+ checkActive();
+
+ try {
+ return getOGLSurfaceIdentifierMethod.invoke(null, new Object[] {g});
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the underlying surface type for the given Graphics
+ object. This indicates, in particular, whether Java2D is
+ currently rendering into a pbuffer or FBO. */
+ public static int getOGLSurfaceType(Graphics g) {
+ checkActive();
+
+ try {
+ // FIXME: fallback path for pre-b73 (?) Mustang builds -- remove
+ // once fbobject support is in OGLUtilities
+ if (!fbObjectSupportInitialized) {
+ return 0;
+ }
+
+ return ((Integer) getOGLSurfaceTypeMethod.invoke(null, new Object[] { g })).intValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns the underlying texture target of the given Graphics
+ object assuming it is rendering to an FBO. Returns either
+ GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB. */
+ public static int getOGLTextureType(Graphics g) {
+ checkActive();
+
+ if (getOGLTextureTypeMethod == null) {
+ return GL.GL_TEXTURE_2D;
+ }
+
+ try {
+ return ((Integer) getOGLTextureTypeMethod.invoke(null, new Object[] { g })).intValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** Returns either the given GLContext or a substitute one with
+ which clients should share textures and display lists. Needed
+ when the Java2D/OpenGL pipeline is active and FBOs are being
+ used for rendering. FIXME: may need to alter the API in the
+ future to indicate which GraphicsDevice the source context is
+ associated with. */
+ public static GLContext filterShareContext(GLContext shareContext) {
+ if (isHeadless)
+ return shareContext;
+
+ // FIXME: this may need adjustment
+ initFBOShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice());
+ if (j2dFBOShareContext != null) {
+ return j2dFBOShareContext;
+ }
+ return shareContext;
+ }
+
+ /** Returns the GLContext associated with the Java2D "share
+ context", with which all contexts created by JOGL must share
+ textures and display lists when the FBO option is enabled for
+ the Java2D/OpenGL pipeline. */
+ public static GLContext getShareContext(GraphicsDevice device) {
+ initFBOShareContext(device);
+ // FIXME: for full generality probably need to have multiple of
+ // these, one per GraphicsConfiguration seen?
+ return j2dFBOShareContext;
+ }
+
+ //----------------------------------------------------------------------
+ // Mac OS X-specific methods
+ //
+
+ /** (Mac OS X-specific) Creates a new OpenGL context on the surface
+ associated with the given Graphics object, sharing textures and
+ display lists with the specified (CGLContextObj) share context. */
+ public static long createOGLContextOnSurface(Graphics g, long shareCtx) {
+ checkActive();
+
+ try {
+ return ((Long) createOGLContextOnSurfaceMethod.invoke(null, new Object[] { g, new Long(shareCtx) })).longValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** (Mac OS X-specific) Makes the given OpenGL context current on
+ the surface associated with the given Graphics object. */
+ public static boolean makeOGLContextCurrentOnSurface(Graphics g, long ctx) {
+ checkActive();
+
+ try {
+ return ((Boolean) makeOGLContextCurrentOnSurfaceMethod.invoke(null, new Object[] { g, new Long(ctx) })).booleanValue();
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ /** (Mac OS X-specific) Destroys the given OpenGL context. */
+ public static void destroyOGLContext(long ctx) {
+ checkActive();
+
+ try {
+ destroyOGLContextMethod.invoke(null, new Object[] { new Long(ctx) });
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (Exception e) {
+ throw (InternalError) new InternalError().initCause(e);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private static void checkActive() {
+ if (!isOGLPipelineActive()) {
+ throw new GLException("Java2D OpenGL pipeline not active (or necessary support not present)");
+ }
+ }
+
+ private static int getOGLUtilitiesIntField(final String name) {
+ Integer i = (Integer) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ Field f = utils.getField(name);
+ f.setAccessible(true);
+ return f.get(null);
+ } catch (Exception e) {
+ if (DEBUG && VERBOSE) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ });
+ if (i == null)
+ return 0;
+ if (DEBUG && VERBOSE) {
+ System.err.println("OGLUtilities." + name + " = " + i.intValue());
+ }
+ return i.intValue();
+ }
+
+ private static void initFBOShareContext(final GraphicsDevice device) {
+ // Note 1: this must not be done in the static initalizer due to
+ // deadlock problems.
+
+ // Note 2: the first execution of this method must not be from the
+ // Java2D Queue Flusher Thread.
+
+ if (isOGLPipelineActive() &&
+ isFBOEnabled() &&
+ !initializedJ2DFBOShareContext) {
+
+ // FIXME: this technique is probably not adequate in multi-head
+ // situations. Ideally we would keep track of a given share
+ // context on a per-GraphicsConfiguration basis or something
+ // similar rather than keeping one share context in a global
+ // variable.
+ initializedJ2DFBOShareContext = true;
+ if (DEBUG) {
+ System.err.println("Starting initialization of J2D FBO share context");
+ }
+ invokeWithOGLSharedContextCurrent(device.getDefaultConfiguration(), new Runnable() {
+ public void run() {
+ j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault()).createExternalGLContext();
+ }
+ });
+ if (DEBUG) {
+ System.err.println("Ending initialization of J2D FBO share context");
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java
new file mode 100644
index 000000000..07bc54b6a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/Java2DGLContext.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006 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.awt;
+
+import com.jogamp.opengl.impl.*;
+import java.awt.Graphics;
+
+/** Provides a construct by which the shared GLJPanel code can
+ * interact with a few methods in the Mac OS X-specific Java2D/JOGL
+ * bridge implementation.
+ */
+
+public interface Java2DGLContext {
+ public void setGraphics(Graphics g);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
new file mode 100755
index 000000000..42d4588b5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public abstract class EGLContext extends GLContextImpl {
+ private long eglContext;
+ private boolean eglQueryStringInitialized;
+ private boolean eglQueryStringAvailable;
+ private EGLExt eglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // EGL extension functions.
+ private EGLExtProcAddressTable eglExtProcAddressTable;
+
+ public EGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public EGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getEGLExt();
+ }
+
+ public EGLExt getEGLExt() {
+ if (eglExt == null) {
+ eglExt = new EGLExtImpl(this);
+ }
+ return eglExt;
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return eglExtProcAddressTable;
+ }
+
+ public final EGLExtProcAddressTable getEGLExtProcAddressTable() {
+ return eglExtProcAddressTable;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ return glExtensionName;
+ }
+
+ public long getContext() {
+ return eglContext;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
+ System.err.println("drawable not properly initialized");
+ return CONTEXT_NOT_CURRENT;
+ }
+ boolean created = false;
+ if (eglContext == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context 0x" +
+ Long.toHexString(eglContext) + " for " + getClass().getName());
+ }
+ created = true;
+ }
+ if (EGL.eglGetCurrentContext() != eglContext) {
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ ((EGLDrawable)drawable).getSurface(),
+ ((EGLDrawable)drawableRead).getSurface(),
+ eglContext)) {
+ throw new GLException("Error making context 0x" +
+ Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError());
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ EGL.EGL_NO_SURFACE,
+ EGL.EGL_NO_SURFACE,
+ EGL.EGL_NO_CONTEXT)) {
+ throw new GLException("Error freeing OpenGL context 0x" +
+ Long.toHexString(eglContext) + ": error code " + EGL.eglGetError());
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (eglContext != 0) {
+ if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), eglContext)) {
+ throw new GLException("Error destroying OpenGL context 0x" +
+ Long.toHexString(eglContext) + ": error code " + EGL.eglGetError());
+ }
+ eglContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void create() throws GLException {
+ long eglDisplay = ((EGLDrawable)drawable).getDisplay();
+ EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
+ GLProfile glProfile = drawable.getGLProfile();
+ _EGLConfig eglConfig = config.getNativeConfig();
+ long shareWith = EGL.EGL_NO_CONTEXT;
+
+ if (eglDisplay == 0) {
+ throw new GLException("Error: attempted to create an OpenGL context without a display connection");
+ }
+ if (eglConfig == null) {
+ throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
+ }
+
+ try {
+ // might be unavailable on EGL < 1.2
+ if(!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) {
+ throw new GLException("eglBindAPI to ES failed , error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ } catch (GLException glex) {
+ if (DEBUG) {
+ glex.printStackTrace();
+ }
+ }
+
+ EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this);
+ if (other != null) {
+ shareWith = other.getContext();
+ if (shareWith == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+
+ int[] contextAttrs = new int[] {
+ EGL.EGL_CONTEXT_CLIENT_VERSION, -1,
+ EGL.EGL_NONE
+ };
+ if (glProfile.usesNativeGLES2()) {
+ contextAttrs[1] = 2;
+ } else if (glProfile.usesNativeGLES1()) {
+ contextAttrs[1] = 1;
+ } else {
+ throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile);
+ }
+ eglContext = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0);
+ if (eglContext == 0) {
+ throw new GLException("Error creating OpenGL context: eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", "+glProfile+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ GLContextShareSet.contextCreated(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" +
+ Long.toHexString(eglContext) +
+ ",\n\twrite surface 0x" + Long.toHexString(((EGLDrawable)drawable).getSurface()) +
+ ",\n\tread surface 0x" + Long.toHexString(((EGLDrawable)drawableRead).getSurface())+
+ ",\n\t"+this+
+ ",\n\tsharing with 0x" + Long.toHexString(shareWith));
+ }
+ if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
+ ((EGLDrawable)drawable).getSurface(),
+ ((EGLDrawable)drawableRead).getSurface(),
+ eglContext)) {
+ throw new GLException("Error making context 0x" +
+ Long.toHexString(eglContext) + " current: error code " + EGL.eglGetError());
+ }
+ setGLFunctionAvailability(true);
+ }
+
+ public boolean isCreated() {
+ return (eglContext != 0);
+ }
+
+ protected void updateGLProcAddressTable() {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing EGL extension address table");
+ }
+ eglQueryStringInitialized = false;
+ eglQueryStringAvailable = false;
+
+ if (eglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ eglExtProcAddressTable = new EGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getEGLExtProcAddressTable());
+ super.updateGLProcAddressTable();
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (!eglQueryStringInitialized) {
+ eglQueryStringAvailable =
+ getDrawableImpl().getDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0;
+ eglQueryStringInitialized = true;
+ }
+ if (eglQueryStringAvailable) {
+ GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl();
+ factory.lockToolkit();
+ try {
+ String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(),
+ EGL.EGL_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("!!! EGL extensions: " + ret);
+ }
+ return ret;
+ } finally {
+ factory.unlockToolkit();
+ }
+ } else {
+ return "";
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if (EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval)) {
+ currentSwapInterval = interval ;
+ }
+ }
+
+ public abstract void bindPbufferToTexture();
+
+ public abstract void releasePbufferFromTexture();
+
+ //----------------------------------------------------------------------
+ // Currently unimplemented stuff
+ //
+
+ public void copy(GLContext source, int mask) throws GLException {
+ throw new GLException("Not yet implemented");
+ }
+
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java
new file mode 100755
index 000000000..e48c78301
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawable.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import com.jogamp.opengl.impl.GLDrawableImpl;
+import com.sun.nativewindow.impl.NWReflection;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import javax.media.opengl.*;
+
+public abstract class EGLDrawable extends GLDrawableImpl {
+ protected boolean ownEGLDisplay = false; // for destruction
+ protected boolean ownEGLSurface = false; // for destruction
+ private EGLGraphicsConfiguration eglConfig;
+ protected long eglDisplay;
+ protected long eglSurface;
+
+ protected EGLDrawable(EGLDrawableFactory factory,
+ NativeWindow component) throws GLException {
+ super(factory, component, false);
+ eglSurface=EGL.EGL_NO_SURFACE;
+ eglDisplay=0;
+ }
+
+ public long getDisplay() {
+ return eglDisplay;
+ }
+
+ public long getSurface() {
+ return eglSurface;
+ }
+
+ public EGLGraphicsConfiguration getGraphicsConfiguration() {
+ return eglConfig;
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilities)eglConfig.getChosenCapabilities();
+ }
+
+ public abstract GLContext createContext(GLContext shareWith);
+
+ protected abstract long createSurface(long eglDpy, _EGLConfig eglNativeCfg, long surfaceHandle);
+
+ private void recreateSurface() {
+ // create a new EGLSurface ..
+ if(EGL.EGL_NO_SURFACE!=eglSurface) {
+ EGL.eglDestroySurface(eglDisplay, eglSurface);
+ }
+
+ if(DEBUG) {
+ System.err.println("createSurface using eglDisplay 0x"+Long.toHexString(eglDisplay)+", "+eglConfig);
+ }
+
+ eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), component.getSurfaceHandle());
+ if (EGL.EGL_NO_SURFACE==eglSurface) {
+ throw new GLException("Creation of window surface failed: "+eglConfig+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+
+ if(DEBUG) {
+ System.err.println("setSurface using component: handle 0x"+Long.toHexString(component.getSurfaceHandle())+" -> 0x"+Long.toHexString(eglSurface));
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if (realized) {
+ if ( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) {
+ throw new GLException("Couldn't lock surface");
+ }
+ // lockSurface() also resolved the window/surface handles
+ try {
+ AbstractGraphicsConfiguration aConfig = component.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+ if(aDevice instanceof EGLGraphicsDevice) {
+ // just fetch the data .. trust but verify ..
+ eglDisplay = aDevice.getHandle();
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice);
+ }
+ if(aConfig instanceof EGLGraphicsConfiguration) {
+ eglConfig = (EGLGraphicsConfiguration) aConfig; // done ..
+ if (null == eglConfig) {
+ throw new GLException("Null EGLGraphicsConfiguration from "+aConfig);
+ }
+
+ int[] tmp = new int[1];
+ if ( 0 != component.getSurfaceHandle() &&
+ EGL.eglQuerySurface(eglDisplay, component.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) {
+ // component holds static EGLSurface
+ eglSurface = component.getSurfaceHandle();
+ if(DEBUG) {
+ System.err.println("setSurface re-using component's EGLSurface: handle 0x"+Long.toHexString(eglSurface));
+ }
+ } else {
+ // EGLSurface is ours ..
+ ownEGLSurface=true;
+
+ eglConfig.updateGraphicsConfiguration();
+
+ recreateSurface();
+ }
+ } else {
+ throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig);
+ }
+ } else {
+ // create a new EGL config ..
+ ownEGLDisplay=true;
+ // EGLSurface is ours ..
+ ownEGLSurface=true;
+
+ long nDisplay=0;
+ if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ nDisplay = component.getSurfaceHandle(); // don't even ask ..
+ } else {
+ nDisplay = aDevice.getHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
+ }
+ eglDisplay = EGL.eglGetDisplay(nDisplay);
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ if(DEBUG) {
+ System.err.println("eglDisplay("+Long.toHexString(nDisplay)+" <surfaceHandle>): failed, using EGL_DEFAULT_DISPLAY");
+ }
+ nDisplay = EGL.EGL_DEFAULT_DISPLAY;
+ eglDisplay = EGL.eglGetDisplay(nDisplay);
+ }
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Failed to created EGL display: nhandle 0x"+Long.toHexString(nDisplay)+", "+aDevice+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("eglDisplay("+Long.toHexString(nDisplay)+"): 0x"+Long.toHexString(eglDisplay));
+ }
+ if (!EGL.eglInitialize(eglDisplay, null, null)) {
+ throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay);
+ DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex());
+ GLCapabilities caps = (GLCapabilities) aConfig.getChosenCapabilities(); // yes, use the already choosen Capabilities (x11,win32,..)
+ eglConfig = (EGLGraphicsConfiguration) GraphicsConfigurationFactory.getFactory(e).chooseGraphicsConfiguration(caps, null, s);
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s);
+ } else if(DEBUG) {
+ System.err.println("Chosen eglConfig: "+eglConfig);
+ }
+ recreateSurface();
+ }
+ } finally {
+ unlockSurface();
+ }
+ } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) {
+ // Destroy the window surface
+ if (!EGL.eglDestroySurface(eglDisplay, eglSurface)) {
+ throw new GLException("Error destroying window surface (eglDestroySurface)");
+ }
+ eglSurface = EGL.EGL_NO_SURFACE;
+ if (ownEGLDisplay && EGL.EGL_NO_DISPLAY!=eglDisplay) {
+ EGL.eglTerminate(eglDisplay);
+ }
+ eglDisplay=EGL.EGL_NO_DISPLAY;
+ eglConfig=null;
+ }
+ }
+
+ public int getWidth() {
+ int[] tmp = new int[1];
+ if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
+ throw new GLException("Error querying surface width");
+ }
+ return tmp[0];
+ }
+
+ public int getHeight() {
+ int[] tmp = new int[1];
+ if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) {
+ throw new GLException("Error querying surface height");
+ }
+ return tmp[0];
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return EGLDynamicLookupHelper.getDynamicLookupHelper(getGLProfile());
+ }
+
+ public String toString() {
+ return getClass().getName()+"[realized "+getRealized()+
+ ",\n\tfactory "+getFactory()+
+ ",\n\twindow "+getNativeWindow()+
+ ",\n\teglSurface 0x"+Long.toHexString(eglSurface)+
+ ",\n\teglConfig "+eglConfig+
+ ",\n\trequested "+getRequestedGLCapabilities()+
+ ",\n\tchosen "+getChosenGLCapabilities()+"]";
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
new file mode 100755
index 000000000..f6c8b800e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+
+public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+
+ static {
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new EGLGraphicsConfigurationFactory();
+
+ // Check for other underlying stuff ..
+ if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ try {
+ NWReflection.createInstance("com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory");
+ } catch (Throwable t) {}
+ }
+ }
+
+ public EGLDrawableFactory() {
+ super();
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new EGLOnscreenDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ throw new GLException("Not yet implemented");
+ }
+
+ public boolean canCreateGLPbuffer() {
+ return true;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(NativeWindow target) {
+ return new EGLPbufferDrawable(this, target);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ NullWindow nw = new NullWindow(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(capabilities, chooser));
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ return new EGLExternalContext(absScreen);
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return false;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ throw new GLException("Not yet implemented");
+ }
+
+ public void loadGLULibrary() {
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java
new file mode 100755
index 000000000..21e28ad28
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDynamicLookupHelper.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+import java.security.*;
+
+/**
+ * Abstract implementation of the DynamicLookupHelper for EGL,
+ * which decouples it's dependencies to EGLDrawableFactory.
+ *
+ * Currently two implementations exist, one for ES1 and one for ES2.
+ */
+public abstract class EGLDynamicLookupHelper implements DynamicLookupHelper {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("EGL");
+ protected static final boolean DEBUG_LOOKUP;
+
+ private static final EGLDynamicLookupHelper eglES1DynamicLookupHelper;
+ private static final EGLDynamicLookupHelper eglES2DynamicLookupHelper;
+ private List/*<NativeLibrary>*/ glesLibraries;
+
+ static {
+ AccessControlContext localACC=AccessController.getContext();
+ DEBUG_LOOKUP = com.jogamp.opengl.impl.Debug.isPropertyDefined("jogl.debug.DynamicLookup", true, localACC);
+
+ EGLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new EGLES1DynamicLookupHelper();
+ } catch (Throwable t) {
+ if(DEBUG) {
+ t.printStackTrace();
+ }
+ }
+ eglES1DynamicLookupHelper = tmp;
+
+ tmp=null;
+ try {
+ tmp = new EGLES2DynamicLookupHelper();
+ } catch (Throwable t) {
+ if(DEBUG) {
+ t.printStackTrace();
+ }
+ }
+ eglES2DynamicLookupHelper = tmp;
+ }
+
+ public static EGLDynamicLookupHelper getDynamicLookupHelper(GLProfile glp) {
+ if (glp.usesNativeGLES2()) {
+ if(null==eglES2DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES2 not available");
+ }
+ return eglES2DynamicLookupHelper;
+ } else if (glp.usesNativeGLES1()) {
+ if(null==eglES1DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES1 not available");
+ }
+ return eglES1DynamicLookupHelper;
+ } else {
+ throw new GLException("Unsupported: "+glp);
+ }
+ }
+
+ public static EGLDynamicLookupHelper getDynamicLookupHelper(int esProfile) {
+ if (2==esProfile) {
+ if(null==eglES2DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES2 not available");
+ }
+ return eglES2DynamicLookupHelper;
+ } else if (1==esProfile) {
+ if(null==eglES1DynamicLookupHelper) {
+ throw new GLException("EGLDynamicLookupHelper for ES1 not available");
+ }
+ return eglES1DynamicLookupHelper;
+ } else {
+ throw new GLException("Unsupported: ES"+esProfile);
+ }
+ }
+
+ protected EGLDynamicLookupHelper() {
+ loadGLESLibrary(getESProfile());
+ EGL.resetProcAddressTable(this);
+ }
+
+ /** Must return the proper ES profile number, 1 for ES1 and 2 for ES2 */
+ protected abstract int getESProfile();
+
+ /** Must return at least one OpenGL ES library name */
+ protected abstract List/*<String>*/ getGLESLibNames();
+
+ /** May return OpenGL ES library name(s) */
+ protected List/*<String>*/ getEGLLibNames() {
+ List/*<String>*/ eglLibNames = new ArrayList();
+
+ // EGL
+ eglLibNames.add("EGL");
+ // for windows distributions using the 'unlike' lib prefix,
+ // where our tool does not add it.
+ eglLibNames.add("libEGL");
+
+ return eglLibNames;
+ }
+
+ private NativeLibrary loadFirstAvailable(List/*<String>*/ libNames, ClassLoader loader) {
+ for (Iterator iter = libNames.iterator(); iter.hasNext(); ) {
+ NativeLibrary lib = NativeLibrary.open((String) iter.next(), loader, false /*global*/);
+ if (lib != null) {
+ return lib;
+ }
+ }
+ return null;
+ }
+
+ private boolean loadEGLLibrary(ClassLoader loader, List/*<String>*/ eglLibNames) {
+ NativeLibrary lib = null;
+ if(null!=eglLibNames && eglLibNames.size()>0) {
+ // EGL libraries ..
+ lib = loadFirstAvailable(eglLibNames, loader);
+ if ( null != lib ) {
+ glesLibraries.add(lib);
+ }
+ }
+ return null!=lib;
+ }
+
+ private void loadGLESLibrary(int esProfile) {
+ List/*<String>*/ glesLibNames = getGLESLibNames();
+ List/*<String>*/ eglLibNames = getEGLLibNames();
+ boolean eglLoaded = false;
+
+ ClassLoader loader = getClass().getClassLoader();
+ NativeLibrary lib = null;
+
+ glesLibraries = new ArrayList();
+
+ // ES libraries ..
+ lib = loadFirstAvailable(glesLibNames, loader);
+ if ( null == lib ) {
+ /*** FIXME: Have to think about this ..
+ // try again with EGL loaded first ..
+ if ( !eglLoaded && loadEGLLibrary(loader, eglLibNames) ) {
+ eglLoaded = true ;
+ lib = loadFirstAvailable(glesLibNames, loader);
+ }
+ if ( null == lib ) {
+ throw new GLException("Unable to dynamically load OpenGL ES library for profile ES" + esProfile);
+ } */
+ throw new GLException("Unable to dynamically load OpenGL ES library for profile ES" + esProfile);
+ }
+ glesLibraries.add(lib);
+
+ if ( !eglLoaded && !loadEGLLibrary(loader, eglLibNames) ) {
+ throw new GLException("Unable to dynamically load EGL library for profile ES" + esProfile);
+ }
+
+ if (esProfile==2) {
+ NativeLibLoader.loadES2();
+ } else if (esProfile==1) {
+ NativeLibLoader.loadES1();
+ } else {
+ throw new GLException("Unsupported: ES"+esProfile);
+ }
+ }
+
+ private long dynamicLookupFunctionOnLibs(String glFuncName) {
+ String funcName=glFuncName;
+ long addr = dynamicLookupFunctionOnLibsImpl(funcName);
+ if( 0==addr && NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ // Hack: try some C++ decoration here for Imageon's emulation libraries ..
+ final int argAlignment=4; // 4 byte alignment of each argument
+ final int maxArguments=12; // experience ..
+ for(int arg=0; 0==addr && arg<=maxArguments; arg++) {
+ funcName = "_"+glFuncName+"@"+(arg*argAlignment);
+ addr = dynamicLookupFunctionOnLibsImpl(funcName);
+ }
+ }
+ if(DEBUG_LOOKUP) {
+ if(0!=addr) {
+ System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" 0x"+Long.toHexString(addr));
+ } else {
+ System.err.println("Lookup-Native: "+glFuncName+" / "+funcName+" ** FAILED ** ");
+ }
+ }
+ return addr;
+ }
+
+ private long dynamicLookupFunctionOnLibsImpl(String glFuncName) {
+ // Look up this function name in all known libraries
+ for (Iterator iter = glesLibraries.iterator(); iter.hasNext(); ) {
+ NativeLibrary lib = (NativeLibrary) iter.next();
+ long addr = lib.lookupFunction(glFuncName);
+ if (addr != 0) {
+ return addr;
+ }
+ }
+ return 0;
+ }
+
+ private long eglGetProcAddressHandle = 0;
+
+ public long dynamicLookupFunction(String glFuncName) {
+ if(null==glFuncName) {
+ return 0;
+ }
+
+ // bootstrap eglGetProcAddress
+ if(0==eglGetProcAddressHandle) {
+ eglGetProcAddressHandle = dynamicLookupFunctionOnLibs("eglGetProcAddress");
+ if(0==eglGetProcAddressHandle) {
+ GLException e = new GLException("Couldn't find eglGetProcAddress function entry");
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ throw e;
+ }
+ }
+
+ if(glFuncName.equals("eglGetProcAddress")) {
+ return eglGetProcAddressHandle;
+ }
+
+ long addr = EGL.eglGetProcAddress(eglGetProcAddressHandle, glFuncName);
+ if(DEBUG_LOOKUP) {
+ if(0!=addr) {
+ System.err.println("Lookup-EGL: <"+glFuncName+"> 0x"+Long.toHexString(addr));
+ }
+ }
+ if(0==addr) {
+ addr = dynamicLookupFunctionOnLibs(glFuncName);
+ }
+ return addr;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java
new file mode 100755
index 000000000..0dc9535ce
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES1DynamicLookupHelper.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+
+/**
+ * Implementation of the EGLDynamicLookupHelper for ES1.
+ */
+public class EGLES1DynamicLookupHelper extends EGLDynamicLookupHelper {
+
+ protected EGLES1DynamicLookupHelper() {
+ super();
+ }
+
+ protected int getESProfile() {
+ return 1;
+ }
+
+ protected List/*<String>*/ getGLESLibNames() {
+ List/*<String>*/ glesLibNames = new ArrayList();
+
+ glesLibNames.add("GLES_CM");
+ glesLibNames.add("GLES_CL");
+ glesLibNames.add("GLESv1_CM");
+ // for windows distributions using the 'unlike' lib prefix,
+ // where our tool does not add it.
+ glesLibNames.add("libGLES_CM");
+ glesLibNames.add("libGLES_CL");
+ glesLibNames.add("libGLESv1_CM");
+
+ return glesLibNames;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java
new file mode 100755
index 000000000..595ded538
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLES2DynamicLookupHelper.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+
+/**
+ * Implementation of the EGLDynamicLookupHelper for ES2.
+ */
+public class EGLES2DynamicLookupHelper extends EGLDynamicLookupHelper {
+
+ protected EGLES2DynamicLookupHelper() {
+ super();
+ }
+
+ protected int getESProfile() {
+ return 2;
+ }
+
+ protected List/*<String>*/ getGLESLibNames() {
+ List/*<String>*/ glesLibNames = new ArrayList();
+
+ glesLibNames.add("GLES20");
+ glesLibNames.add("GLESv2");
+ glesLibNames.add("GLESv2_CM");
+ // for windows distributions using the 'unlike' lib prefix
+ // where our tool does not add it.
+ glesLibNames.add("libGLES20");
+ glesLibNames.add("libGLESv2");
+ glesLibNames.add("libGLESv2_CM");
+
+ return glesLibNames;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java
new file mode 100755
index 000000000..de7fd2ba4
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLExternalContext.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import javax.media.nativewindow.*;
+
+public class EGLExternalContext extends EGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ public EGLExternalContext(AbstractGraphicsScreen screen) {
+ super(null, null);
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
new file mode 100644
index 000000000..33f9db140
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+
+public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public _EGLConfig getNativeConfig() {
+ return _config;
+ }
+
+ public int getNativeConfigID() {
+ return configID;
+ }
+
+ public EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen,
+ GLCapabilities capsChosen, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ _EGLConfig cfg, int cfgID) {
+ super(absScreen, capsChosen, capsRequested);
+ this.chooser = chooser;
+ _config = cfg;
+ configID = cfgID;
+ }
+
+ public static EGLGraphicsConfiguration create(GLCapabilities capsRequested, AbstractGraphicsScreen absScreen, int cfgID) {
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+ if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
+ throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
+ }
+ long dpy = absDevice.getHandle();
+ if (dpy == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display: "+absDevice);
+ }
+ GLProfile glp = capsRequested.getGLProfile();
+ _EGLConfig _cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID);
+ GLCapabilities caps = EGLConfig2Capabilities(glp, dpy, _cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer());
+ return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), _cfg, cfgID);
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ protected void updateGraphicsConfiguration() {
+ EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(getRequestedCapabilities(),
+ chooser,
+ getScreen());
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ _config = newConfig.getNativeConfig();
+ configID = newConfig.getNativeConfigID();
+ if(DEBUG) {
+ System.err.println("!!! updateGraphicsConfiguration: "+this);
+ }
+ }
+ }
+
+ public static _EGLConfig EGLConfigId2EGLConfig(GLProfile glp, long display, int configID) {
+ int[] attrs = new int[] {
+ EGL.EGL_CONFIG_ID, configID,
+ EGL.EGL_NONE
+ };
+ _EGLConfig[] configs = new _EGLConfig[1];
+ int[] numConfigs = new int[1];
+ if (!EGL.eglChooseConfig(display,
+ attrs, 0,
+ configs, 1,
+ numConfigs, 0)) {
+ return null;
+ }
+ if (numConfigs[0] == 0) {
+ return null;
+ }
+ return configs[0];
+ }
+
+ public static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ;
+ } else {
+ res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) || usePBuffer ;
+ }
+ if ( usePBuffer ) {
+ res = res && ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
+ }
+
+ return res;
+ }
+
+ public static GLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, _EGLConfig _config,
+ boolean relaxed, boolean onscreen, boolean usePBuffer) {
+ GLCapabilities caps = new GLCapabilities(glp);
+ int[] val = new int[1];
+
+ // Read the actual configuration into the choosen caps
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_RED_SIZE, val, 0)) {
+ caps.setRedBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_GREEN_SIZE, val, 0)) {
+ caps.setGreenBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_BLUE_SIZE, val, 0)) {
+ caps.setBlueBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_ALPHA_SIZE, val, 0)) {
+ caps.setAlphaBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_STENCIL_SIZE, val, 0)) {
+ caps.setStencilBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_DEPTH_SIZE, val, 0)) {
+ caps.setDepthBits(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_SAMPLES, val, 0)) {
+ caps.setSampleBuffers(val[0]>0?true:false);
+ caps.setNumSamples(val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_TRANSPARENT_TYPE, val, 0)) {
+ caps.setBackgroundOpaque(val[0] != EGL.EGL_TRANSPARENT_RGB);
+ }
+ if(!caps.isBackgroundOpaque()) {
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_TRANSPARENT_RED_VALUE, val, 0)) {
+ caps.setTransparentRedValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_TRANSPARENT_GREEN_VALUE, val, 0)) {
+ caps.setTransparentGreenValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_TRANSPARENT_BLUE_VALUE, val, 0)) {
+ caps.setTransparentBlueValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
+ }
+ /** Not defined in EGL
+ if(EGL.eglGetConfigAttrib(display, _config, EGL.EGL_TRANSPARENT_ALPHA_VALUE, val, 0)) {
+ 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 {
+ throw new GLException("EGL_SURFACE_TYPE does not match !!!");
+ }
+ } else {
+ if(relaxed) {
+ if(DEBUG) {
+ System.err.println("Could not determine EGL_SURFACE_TYPE !!!");
+ }
+ return null;
+ } else {
+ throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
+ }
+ }
+
+ return caps;
+ }
+
+ public static int[] GLCapabilities2AttribList(GLCapabilities caps) {
+ int[] attrs = new int[32];
+ int idx=0;
+
+ attrs[idx++] = EGL.EGL_SURFACE_TYPE;
+ attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+
+ attrs[idx++] = EGL.EGL_RED_SIZE;
+ attrs[idx++] = caps.getRedBits();
+
+ attrs[idx++] = EGL.EGL_GREEN_SIZE;
+ attrs[idx++] = caps.getGreenBits();
+
+ attrs[idx++] = EGL.EGL_BLUE_SIZE;
+ attrs[idx++] = caps.getBlueBits();
+
+ attrs[idx++] = EGL.EGL_ALPHA_SIZE;
+ attrs[idx++] = caps.getAlphaBits() > 0 ? caps.getAlphaBits() : EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_STENCIL_SIZE;
+ attrs[idx++] = caps.getStencilBits() > 0 ? caps.getStencilBits() : EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_DEPTH_SIZE;
+ attrs[idx++] = caps.getDepthBits();
+
+ attrs[idx++] = EGL.EGL_SAMPLES;
+ attrs[idx++] = caps.getSampleBuffers() ? caps.getNumSamples() : 1;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE;
+ attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE;
+
+ // 20
+
+ if(!caps.isBackgroundOpaque()) {
+ attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE;
+ attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE;
+ attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE;
+
+ attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE;
+ attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE;
+
+ /** Not define in EGL
+ attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE;
+ attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
+ }
+
+ // 26
+
+ attrs[idx++] = EGL.EGL_RENDERABLE_TYPE;
+ if(caps.getGLProfile().usesNativeGLES1()) {
+ attrs[idx++] = EGL.EGL_OPENGL_ES_BIT;
+ }
+ else if(caps.getGLProfile().usesNativeGLES2()) {
+ attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT;
+ } else {
+ attrs[idx++] = EGL.EGL_OPENGL_BIT;
+ }
+
+ // 28
+
+ attrs[idx++] = EGL.EGL_NONE;
+
+ return attrs;
+ }
+
+ public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
+ int[] attrs = new int[16];
+ int idx=0;
+
+ attrs[idx++] = EGL.EGL_WIDTH;
+ attrs[idx++] = width;
+
+ attrs[idx++] = EGL.EGL_HEIGHT;
+ attrs[idx++] = height;
+
+ attrs[idx++] = EGL.EGL_TEXTURE_FORMAT;
+ attrs[idx++] = texFormat;
+
+ attrs[idx++] = EGL.EGL_TEXTURE_TARGET;
+ attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D;
+
+ attrs[idx++] = EGL.EGL_NONE;
+
+ return attrs;
+ }
+
+ public String toString() {
+ return getClass().toString()+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+
+ ",\n\trequested " + getRequestedCapabilities()+
+ ",\n\tchosen " + getChosenCapabilities()+
+ "]";
+
+ }
+
+ private GLCapabilitiesChooser chooser;
+ private _EGLConfig _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
new file mode 100644
index 000000000..6546ecab7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.io.PrintStream;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import com.sun.nativewindow.impl.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on X11 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 EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL");
+
+ public EGLGraphicsConfigurationFactory() {
+ // become the selector for KD/EGL ..
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects");
+ }
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilities) capabilities,
+ (GLCapabilitiesChooser) chooser,
+ absScreen);
+ }
+
+ public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+ GLProfile glp = capabilities.getGLProfile();
+
+ if(null==absScreen) {
+ throw new GLException("Null AbstractGraphicsScreen");
+ }
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+
+ if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
+ throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
+ }
+ long eglDisplay = absDevice.getHandle();
+
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Invalid EGL display: "+absDevice);
+ }
+
+ GLCapabilities caps2 = (GLCapabilities) capabilities.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER
+ caps2.setDoubleBuffered(false);
+ }
+
+ EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, caps2, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+ if(DEBUG) {
+ System.err.println("eglChooseConfig failed with given capabilities "+caps2);
+ }
+
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+
+ _EGLConfig[] configs = new _EGLConfig[10];
+ int[] numConfigs = new int[1];
+
+ if(!EGL.eglGetConfigs(eglDisplay, configs, configs.length, numConfigs, 0)) {
+ throw new GLException("Graphics configuration fetch (eglGetConfigs) failed");
+ }
+ if (numConfigs[0] == 0) {
+ throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found");
+ }
+ GLCapabilities[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0],
+ caps2.isOnscreen(), caps2.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(caps2, 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], capabilities, 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
+ GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(8);
+ fixedCaps.setGreenBits(8);
+ fixedCaps.setBlueBits(8);
+ fixedCaps.setDepthBits(16);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (1): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+
+ //
+ // rgb565 - d16, s0
+ fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(5);
+ fixedCaps.setGreenBits(6);
+ fixedCaps.setBlueBits(5);
+ fixedCaps.setDepthBits(16);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (2): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+
+ //
+ // rgb565 - d16, s4
+ fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setRedBits(5);
+ fixedCaps.setGreenBits(6);
+ fixedCaps.setBlueBits(5);
+ fixedCaps.setDepthBits(16);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
+ if(DEBUG) {
+ System.err.println("trying fixed caps (3): "+fixedCaps);
+ }
+ res = eglChooseConfig(eglDisplay, fixedCaps, capabilities, chooser, absScreen);
+ if(null!=res) {
+ return res;
+ }
+ throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]");
+ }
+
+ protected static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
+ GLCapabilities capsChosen0, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GLProfile glp = capsChosen0.getGLProfile();
+ int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0);
+ _EGLConfig[] configs = new _EGLConfig[1];
+ int[] numConfigs = new int[1];
+ if (!EGL.eglChooseConfig(eglDisplay,
+ attrs, 0,
+ configs, configs.length,
+ numConfigs, 0)) {
+ throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0);
+ }
+ if (numConfigs[0] > 0) {
+ if(DEBUG) {
+ GLCapabilities[] 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[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()));
+ }
+ return null;
+ }
+ GLCapabilities capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs[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[0], val[0]);
+ }
+ if(DEBUG) {
+ System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", eglConfig ID 0x"+Integer.toHexString(val[0])+
+ ", for "+capsChosen0);
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+
+ ", "+capsChosen0);
+ }
+ }
+ return null;
+ }
+
+ protected static GLCapabilities[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, _EGLConfig[] configs, int num,
+ boolean onscreen, boolean usePBuffer) {
+ GLCapabilities[] caps = new GLCapabilities[num];
+ for(int i=0; i<num; i++) {
+ caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs[i],
+ true, onscreen, usePBuffer);
+ }
+ return caps;
+ }
+
+ protected static void printCaps(String prefix, GLCapabilities[] caps, PrintStream out) {
+ for(int i=0; i<caps.length; i++) {
+ out.println(prefix+"["+i+"] "+caps[i]);
+ }
+ }
+
+ protected static EGLGraphicsConfiguration createOffscreenGraphicsConfiguration(GLCapabilities caps, GLCapabilitiesChooser chooser) {
+ if(caps.isOnscreen()) {
+ throw new GLException("Error: Onscreen set: "+caps);
+ }
+ caps.setDoubleBuffered(false); // FIXME
+ long eglDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("eglDisplay(EGL_DEFAULT_DISPLAY): 0x"+Long.toHexString(eglDisplay));
+ }
+ if (!EGL.eglInitialize(eglDisplay, null, null)) {
+ throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay);
+ DefaultGraphicsScreen s = new DefaultGraphicsScreen(e, 0);
+ EGLGraphicsConfiguration eglConfig = chooseGraphicsConfigurationStatic(caps, chooser, s);
+ if (null == eglConfig) {
+ EGL.eglTerminate(eglDisplay);
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s);
+ } else if(DEBUG) {
+ System.err.println("Chosen eglConfig: "+eglConfig);
+ }
+ return eglConfig;
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java
new file mode 100755
index 000000000..b74991671
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenContext.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public class EGLOnscreenContext extends EGLContext {
+ public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ return super.makeCurrentImpl();
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java
new file mode 100644
index 000000000..d37a36fb0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLOnscreenDrawable.java
@@ -0,0 +1,82 @@
+/*
+ * 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.egl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class EGLOnscreenDrawable extends EGLDrawable {
+ protected EGLOnscreenDrawable(EGLDrawableFactory factory, NativeWindow component) throws GLException {
+ super(factory, component);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new EGLOnscreenContext(this, shareWith);
+ }
+
+ protected long createSurface(long eglDpy, _EGLConfig eglNativeCfg, long surfaceHandle) {
+ return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+ try {
+ if ( !isSurfaceLocked() ) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+
+ EGL.eglSwapBuffers(eglDisplay, eglSurface);
+
+ } finally {
+ if(didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java
new file mode 100755
index 000000000..5c634b9bd
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferContext.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import java.nio.*;
+import java.util.*;
+
+public class EGLPbufferContext extends EGLContext {
+ public EGLPbufferContext(EGLPbufferDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getFloatingPointMode() {
+ return 0; // FIXME ??
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Not yet implemented");
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java
new file mode 100644
index 000000000..a86045789
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLPbufferDrawable.java
@@ -0,0 +1,99 @@
+/*
+ * 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.egl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+import com.jogamp.opengl.impl.*;
+
+public class EGLPbufferDrawable extends EGLDrawable {
+ private int texFormat;
+ protected static final boolean useTexture = false; // No yet ..
+
+ protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeWindow target) {
+ super(factory, target);
+ ownEGLDisplay = true;
+
+ // get choosen ones ..
+ GLCapabilities caps = (GLCapabilities) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+
+ if(useTexture) {
+ this.texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ } else {
+ this.texFormat = EGL.EGL_NO_TEXTURE;
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ setRealized(true);
+
+ if (DEBUG) {
+ System.out.println("Created pbuffer: " + this);
+ }
+
+ }
+
+ protected long createSurface(long eglDpy, _EGLConfig eglNativeCfg, long surfaceHandle) {
+ NativeWindow nw = getNativeWindow();
+ int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
+ long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
+ if (EGL.EGL_NO_SURFACE==surf) {
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+nw.getWidth()+"x"+nw.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(surf);
+ return surf;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new EGLPbufferContext(this, shareWith);
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java
new file mode 100755
index 000000000..2eb3ca5df
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/ProjectDouble.java
@@ -0,0 +1,1041 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-13 22:20:29 -0700 (Fri, 13 Mar 2009) $ $Revision: 1867 $
+** $Header$
+*/
+
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT OWNER 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.
+ */
+
+/*
+ * 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.
+ */
+package com.jogamp.opengl.impl.gl2;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/**
+ * Project.java
+ * <p/>
+ * <p/>
+ * Created 11-jan-2004
+ *
+ * @author Erik Duijs
+ * @author Kenneth Russell
+ */
+public class ProjectDouble {
+ private static final double[] IDENTITY_MATRIX =
+ new double[] {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ // Note that we have cloned parts of the implementation in order to
+ // support incoming Buffers. The reason for this is to avoid loading
+ // non-direct buffer subclasses unnecessarily, because doing so can
+ // cause performance decreases on direct buffer operations, at least
+ // on the current HotSpot JVM. It would be nicer (and make the code
+ // simpler) to simply have the array-based entry points delegate to
+ // the versions taking Buffers by wrapping the arrays.
+
+ // Array-based implementation
+ private final double[] matrix = new double[16];
+
+ private final double[][] tempMatrix = new double[4][4];
+ private final double[] in = new double[4];
+ private final double[] out = new double[4];
+
+ private final double[] forward = new double[3];
+ private final double[] side = new double[3];
+ private final double[] up = new double[3];
+
+ // Buffer-based implementation
+ private DoubleBuffer locbuf;
+ private final DoubleBuffer matrixBuf;
+
+ private final DoubleBuffer tempMatrixBuf;
+ private final DoubleBuffer inBuf;
+ private final DoubleBuffer outBuf;
+
+ private final DoubleBuffer forwardBuf;
+ private final DoubleBuffer sideBuf;
+ private final DoubleBuffer upBuf;
+
+ public ProjectDouble() {
+ // Use direct buffers to avoid loading indirect buffer
+ // implementations for applications trying to avoid doing so.
+ // Slice up one big buffer because some NIO implementations
+ // allocate a huge amount of memory to back even the smallest of
+ // buffers.
+ DoubleBuffer locbuf = InternalBufferUtil.newDoubleBuffer(128);
+ int pos = 0;
+ int sz = 16;
+ matrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ tempMatrixBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 4;
+ inBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ outBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sz = 3;
+ forwardBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ sideBuf = slice(locbuf, pos, sz);
+ pos += sz;
+ upBuf = slice(locbuf, pos, sz);
+ }
+
+ public void destroy() {
+ if(locbuf!=null) {
+ locbuf.clear();
+ locbuf=null;
+ }
+ }
+
+ private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ private void __gluMakeIdentityd(DoubleBuffer m) {
+ int oldPos = m.position();
+ m.put(IDENTITY_MATRIX);
+ m.position(oldPos);
+ }
+
+ /**
+ * Make matrix an identity matrix
+ */
+ private void __gluMakeIdentityd(double[] m) {
+ for (int i = 0; i < 16; i++) {
+ m[i] = IDENTITY_MATRIX[i];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecd
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecd(double[] matrix, int matrix_offset, double[] in, double[] out) {
+ for (int i = 0; i < 4; i++) {
+ out[i] =
+ in[0] * matrix[0*4+i+matrix_offset] +
+ in[1] * matrix[1*4+i+matrix_offset] +
+ in[2] * matrix[2*4+i+matrix_offset] +
+ in[3] * matrix[3*4+i+matrix_offset];
+ }
+ }
+
+ /**
+ * Method __gluMultMatrixVecd
+ *
+ * @param matrix
+ * @param in
+ * @param out
+ */
+ private void __gluMultMatrixVecd(DoubleBuffer matrix, DoubleBuffer in, DoubleBuffer out) {
+ int inPos = in.position();
+ int outPos = out.position();
+ int matrixPos = matrix.position();
+ for (int i = 0; i < 4; i++) {
+ out.put(i + outPos,
+ in.get(0+inPos) * matrix.get(0*4+i+matrixPos) +
+ in.get(1+inPos) * matrix.get(1*4+i+matrixPos) +
+ in.get(2+inPos) * matrix.get(2*4+i+matrixPos) +
+ in.get(3+inPos) * matrix.get(3*4+i+matrixPos));
+ }
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ private boolean __gluInvertMatrixd(double[] src, double[] inverse) {
+ int i, j, k, swap;
+ double t;
+ double[][] temp = tempMatrix;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp[i][j] = src[i*4+j];
+ }
+ }
+ __gluMakeIdentityd(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp[i][k];
+ temp[i][k] = temp[swap][k];
+ temp[swap][k] = t;
+
+ t = inverse[i*4+k];
+ inverse[i*4+k] = inverse[swap*4+k];
+ inverse[swap*4+k] = t;
+ }
+ }
+
+ if (temp[i][i] == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp[i][i];
+ for (k = 0; k < 4; k++) {
+ temp[i][k] /= t;
+ inverse[i*4+k] /= t;
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp[j][i];
+ for (k = 0; k < 4; k++) {
+ temp[j][k] -= temp[i][k] * t;
+ inverse[j*4+k] -= inverse[i*4+k]*t;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param src
+ * @param inverse
+ *
+ * @return
+ */
+ private boolean __gluInvertMatrixd(DoubleBuffer src, DoubleBuffer inverse) {
+ int i, j, k, swap;
+ double t;
+
+ int srcPos = src.position();
+ int invPos = inverse.position();
+
+ DoubleBuffer temp = tempMatrixBuf;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ temp.put(i*4+j, src.get(i*4+j + srcPos));
+ }
+ }
+ __gluMakeIdentityd(inverse);
+
+ for (i = 0; i < 4; i++) {
+ //
+ // Look for largest element in column
+ //
+ swap = i;
+ for (j = i + 1; j < 4; j++) {
+ if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+ swap = j;
+ }
+ }
+
+ if (swap != i) {
+ //
+ // Swap rows.
+ //
+ for (k = 0; k < 4; k++) {
+ t = temp.get(i*4+k);
+ temp.put(i*4+k, temp.get(swap*4+k));
+ temp.put(swap*4+k, t);
+
+ t = inverse.get(i*4+k + invPos);
+ inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
+ inverse.put(swap*4+k + invPos, t);
+ }
+ }
+
+ if (temp.get(i*4+i) == 0) {
+ //
+ // No non-zero pivot. The matrix is singular, which shouldn't
+ // happen. This means the user gave us a bad matrix.
+ //
+ return false;
+ }
+
+ t = temp.get(i*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(i*4+k, temp.get(i*4+k) / t);
+ inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+ }
+ for (j = 0; j < 4; j++) {
+ if (j != i) {
+ t = temp.get(j*4+i);
+ for (k = 0; k < 4; k++) {
+ temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
+ inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void __gluMultMatricesd(double[] a, int a_offset, double[] b, int b_offset, double[] r) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r[i*4+j] =
+ a[i*4+0+a_offset]*b[0*4+j+b_offset] +
+ a[i*4+1+a_offset]*b[1*4+j+b_offset] +
+ a[i*4+2+a_offset]*b[2*4+j+b_offset] +
+ a[i*4+3+a_offset]*b[3*4+j+b_offset];
+ }
+ }
+ }
+
+
+ /**
+ * @param a
+ * @param b
+ * @param r
+ */
+ private void __gluMultMatricesd(DoubleBuffer a, DoubleBuffer b, DoubleBuffer r) {
+ int aPos = a.position();
+ int bPos = b.position();
+ int rPos = r.position();
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ r.put(i*4+j + rPos,
+ a.get(i*4+0+aPos)*b.get(0*4+j+bPos) +
+ a.get(i*4+1+aPos)*b.get(1*4+j+bPos) +
+ a.get(i*4+2+aPos)*b.get(2*4+j+bPos) +
+ a.get(i*4+3+aPos)*b.get(3*4+j+bPos));
+ }
+ }
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ private static void normalize(double[] v) {
+ double r;
+
+ r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+ if ( r == 0.0 )
+ return;
+
+ r = 1.0 / r;
+
+ v[0] *= r;
+ v[1] *= r;
+ v[2] *= r;
+
+ return;
+ }
+
+ /**
+ * Normalize vector
+ *
+ * @param v
+ */
+ private static void normalize(DoubleBuffer v) {
+ double r;
+
+ int vPos = v.position();
+
+ r = Math.sqrt(v.get(0+vPos) * v.get(0+vPos) +
+ v.get(1+vPos) * v.get(1+vPos) +
+ v.get(2+vPos) * v.get(2+vPos));
+ if ( r == 0.0 )
+ return;
+
+ r = 1.0 / r;
+
+ v.put(0+vPos, v.get(0+vPos) * r);
+ v.put(1+vPos, v.get(1+vPos) * r);
+ v.put(2+vPos, v.get(2+vPos) * r);
+
+ return;
+ }
+
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(double[] v1, double[] v2, double[] result) {
+ result[0] = v1[1] * v2[2] - v1[2] * v2[1];
+ result[1] = v1[2] * v2[0] - v1[0] * v2[2];
+ result[2] = v1[0] * v2[1] - v1[1] * v2[0];
+ }
+
+ /**
+ * Calculate cross-product
+ *
+ * @param v1
+ * @param v2
+ * @param result
+ */
+ private static void cross(DoubleBuffer v1, DoubleBuffer v2, DoubleBuffer result) {
+ int v1Pos = v1.position();
+ int v2Pos = v2.position();
+ int rPos = result.position();
+
+ result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos));
+ result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos));
+ result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos));
+ }
+
+ /**
+ * Method gluOrtho2D.
+ *
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ */
+ public void gluOrtho2D(GL2 gl, double left, double right, double bottom, double top) {
+ gl.glOrtho(left, right, bottom, top, -1, 1);
+ }
+
+ /**
+ * Method gluPerspective.
+ *
+ * @param fovy
+ * @param aspect
+ * @param zNear
+ * @param zFar
+ */
+ public void gluPerspective(GL2 gl, double fovy, double aspect, double zNear, double zFar) {
+ double sine, cotangent, deltaZ;
+ double radians = fovy / 2 * Math.PI / 180;
+
+ deltaZ = zFar - zNear;
+ sine = Math.sin(radians);
+
+ if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+ return;
+ }
+
+ cotangent = Math.cos(radians) / sine;
+
+ __gluMakeIdentityd(matrixBuf);
+
+ matrixBuf.put(0 * 4 + 0, cotangent / aspect);
+ matrixBuf.put(1 * 4 + 1, cotangent);
+ matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+ matrixBuf.put(2 * 4 + 3, -1);
+ matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+ matrixBuf.put(3 * 4 + 3, 0);
+
+ gl.glMultMatrixd(matrixBuf);
+ }
+
+ /**
+ * Method gluLookAt
+ *
+ * @param eyex
+ * @param eyey
+ * @param eyez
+ * @param centerx
+ * @param centery
+ * @param centerz
+ * @param upx
+ * @param upy
+ * @param upz
+ */
+ public void gluLookAt(GL2 gl,
+ double eyex,
+ double eyey,
+ double eyez,
+ double centerx,
+ double centery,
+ double centerz,
+ double upx,
+ double upy,
+ double upz) {
+ DoubleBuffer forward = this.forwardBuf;
+ DoubleBuffer side = this.sideBuf;
+ DoubleBuffer up = this.upBuf;
+
+ forward.put(0, centerx - eyex);
+ forward.put(1, centery - eyey);
+ forward.put(2, centerz - eyez);
+
+ up.put(0, upx);
+ up.put(1, upy);
+ up.put(2, upz);
+
+ normalize(forward);
+
+ /* Side = forward x up */
+ cross(forward, up, side);
+ normalize(side);
+
+ /* Recompute up as: up = side x forward */
+ cross(side, forward, up);
+
+ __gluMakeIdentityd(matrixBuf);
+ matrixBuf.put(0 * 4 + 0, side.get(0));
+ matrixBuf.put(1 * 4 + 0, side.get(1));
+ matrixBuf.put(2 * 4 + 0, side.get(2));
+
+ matrixBuf.put(0 * 4 + 1, up.get(0));
+ matrixBuf.put(1 * 4 + 1, up.get(1));
+ matrixBuf.put(2 * 4 + 1, up.get(2));
+
+ matrixBuf.put(0 * 4 + 2, -forward.get(0));
+ matrixBuf.put(1 * 4 + 2, -forward.get(1));
+ matrixBuf.put(2 * 4 + 2, -forward.get(2));
+
+ gl.glMultMatrixd(matrixBuf);
+ gl.glTranslated(-eyex, -eyey, -eyez);
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(double objx,
+ double objy,
+ double objz,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double[] win_pos,
+ int win_pos_offset ) {
+
+ double[] in = this.in;
+ double[] out = this.out;
+
+ in[0] = objx;
+ in[1] = objy;
+ in[2] = objz;
+ in[3] = 1.0;
+
+ __gluMultMatrixVecd(modelMatrix, modelMatrix_offset, in, out);
+ __gluMultMatrixVecd(projMatrix, projMatrix_offset, out, in);
+
+ if (in[3] == 0.0)
+ return false;
+
+ in[3] = (1.0 / in[3]) * 0.5;
+
+ // Map x, y and z to range 0-1
+ in[0] = in[0] * in[3] + 0.5f;
+ in[1] = in[1] * in[3] + 0.5f;
+ in[2] = in[2] * in[3] + 0.5f;
+
+ // Map x,y to viewport
+ win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+ win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+ win_pos[2+win_pos_offset] = in[2];
+
+ return true;
+ }
+
+ /**
+ * Method gluProject
+ *
+ * @param objx
+ * @param objy
+ * @param objz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param win_pos
+ *
+ * @return
+ */
+ public boolean gluProject(double objx,
+ double objy,
+ double objz,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ DoubleBuffer win_pos) {
+
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ in.put(0, objx);
+ in.put(1, objy);
+ in.put(2, objz);
+ in.put(3, 1.0);
+
+ __gluMultMatrixVecd(modelMatrix, in, out);
+ __gluMultMatrixVecd(projMatrix, out, in);
+
+ if (in.get(3) == 0.0)
+ return false;
+
+ in.put(3, (1.0 / in.get(3)) * 0.5);
+
+ // Map x, y and z to range 0-1
+ in.put(0, in.get(0) * in.get(3) + 0.5f);
+ in.put(1, in.get(1) * in.get(3) + 0.5f);
+ in.put(2, in.get(2) * in.get(3) + 0.5f);
+
+ // Map x,y to viewport
+ int vPos = viewport.position();
+ int wPos = win_pos.position();
+ win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
+ win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
+ win_pos.put(2+wPos, in.get(2));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(double winx,
+ double winy,
+ double winz,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double[] obj_pos,
+ int obj_pos_offset) {
+ double[] in = this.in;
+ double[] out = this.out;
+
+ __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!__gluInvertMatrixd(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = 1.0;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ out[3] = 1.0 / out[3];
+
+ obj_pos[0+obj_pos_offset] = out[0] * out[3];
+ obj_pos[1+obj_pos_offset] = out[1] * out[3];
+ obj_pos[2+obj_pos_offset] = out[2] * out[3];
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject(double winx,
+ double winy,
+ double winz,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ DoubleBuffer obj_pos) {
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+ if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, 1.0);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ int oPos = obj_pos.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecd(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0)
+ return false;
+
+ out.put(3, 1.0 / out.get(3));
+
+ obj_pos.put(0+oPos, out.get(0) * out.get(3));
+ obj_pos.put(1+oPos, out.get(1) * out.get(3));
+ obj_pos.put(2+oPos, out.get(2) * out.get(3));
+
+ return true;
+ }
+
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(double winx,
+ double winy,
+ double winz,
+ double clipw,
+ double[] modelMatrix,
+ int modelMatrix_offset,
+ double[] projMatrix,
+ int projMatrix_offset,
+ int[] viewport,
+ int viewport_offset,
+ double near,
+ double far,
+ double[] obj_pos,
+ int obj_pos_offset ) {
+ double[] in = this.in;
+ double[] out = this.out;
+
+ __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+ if (!__gluInvertMatrixd(matrix, matrix))
+ return false;
+
+ in[0] = winx;
+ in[1] = winy;
+ in[2] = winz;
+ in[3] = clipw;
+
+ // Map x and y from window coordinates
+ in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+ in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+ in[2] = (in[2] - near) / (far - near);
+
+ // Map to range -1 to 1
+ in[0] = in[0] * 2 - 1;
+ in[1] = in[1] * 2 - 1;
+ in[2] = in[2] * 2 - 1;
+
+ __gluMultMatrixVecd(matrix, 0, in, out);
+
+ if (out[3] == 0.0)
+ return false;
+
+ obj_pos[0+obj_pos_offset] = out[0];
+ obj_pos[1+obj_pos_offset] = out[1];
+ obj_pos[2+obj_pos_offset] = out[2];
+ obj_pos[3+obj_pos_offset] = out[3];
+ return true;
+ }
+
+ /**
+ * Method gluUnproject4
+ *
+ * @param winx
+ * @param winy
+ * @param winz
+ * @param clipw
+ * @param modelMatrix
+ * @param projMatrix
+ * @param viewport
+ * @param near
+ * @param far
+ * @param obj_pos
+ *
+ * @return
+ */
+ public boolean gluUnProject4(double winx,
+ double winy,
+ double winz,
+ double clipw,
+ DoubleBuffer modelMatrix,
+ DoubleBuffer projMatrix,
+ IntBuffer viewport,
+ double near,
+ double far,
+ DoubleBuffer obj_pos) {
+ DoubleBuffer in = this.inBuf;
+ DoubleBuffer out = this.outBuf;
+
+ __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+ if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+ return false;
+
+ in.put(0, winx);
+ in.put(1, winy);
+ in.put(2, winz);
+ in.put(3, clipw);
+
+ // Map x and y from window coordinates
+ int vPos = viewport.position();
+ in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+ in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+ in.put(2, (in.get(2) - near) / (far - near));
+
+ // Map to range -1 to 1
+ in.put(0, in.get(0) * 2 - 1);
+ in.put(1, in.get(1) * 2 - 1);
+ in.put(2, in.get(2) * 2 - 1);
+
+ __gluMultMatrixVecd(matrixBuf, in, out);
+
+ if (out.get(3) == 0.0)
+ return false;
+
+ int oPos = obj_pos.position();
+ obj_pos.put(0+oPos, out.get(0));
+ obj_pos.put(1+oPos, out.get(1));
+ obj_pos.put(2+oPos, out.get(2));
+ obj_pos.put(3+oPos, out.get(3));
+ return true;
+ }
+
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ */
+ public void gluPickMatrix(GL2 gl,
+ double x,
+ double y,
+ double deltaX,
+ double deltaY,
+ IntBuffer viewport) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ int vPos = viewport.position();
+ gl.glTranslated((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
+ (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
+ 0);
+ gl.glScaled(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0);
+ }
+
+ /**
+ * Method gluPickMatrix
+ *
+ * @param x
+ * @param y
+ * @param deltaX
+ * @param deltaY
+ * @param viewport
+ * @param viewport_offset
+ */
+ public void gluPickMatrix(GL2 gl,
+ double x,
+ double y,
+ double deltaX,
+ double deltaY,
+ int[] viewport,
+ int viewport_offset) {
+ if (deltaX <= 0 || deltaY <= 0) {
+ return;
+ }
+
+ /* Translate and scale the picked region to the entire window */
+ gl.glTranslated((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
+ (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
+ 0);
+ gl.glScaled(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java
new file mode 100644
index 000000000..a542dcf19
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/Util.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * * Neither the name of 'LWJGL' nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT OWNER 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.
+ */
+
+/*
+ * 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.
+ */
+
+package com.jogamp.opengl.impl.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.IntBuffer;
+import javax.media.opengl.*;
+
+/**
+ * Util.java
+ * <p/>
+ * <p/>
+ * Created 7-jan-2004
+ *
+ * @author Erik Duijs
+ */
+class Util {
+
+ /**
+ * temp int[] of one for getting an int from some GL functions
+ */
+ private int[] scratch = new int[1];
+
+ /**
+ * Return ceiling of integer division
+ *
+ * @param a
+ * @param b
+ *
+ * @return int
+ */
+ protected static int ceil(int a, int b) {
+ return (a % b == 0 ? a / b : a / b + 1);
+ }
+
+ /**
+ * Method compPerPix.
+ *
+ * @param format
+ *
+ * @return int
+ */
+ protected static int compPerPix(int format) {
+ /* Determine number of components per pixel */
+ switch ( format ) {
+ case GL2.GL_COLOR_INDEX:
+ case GL2.GL_STENCIL_INDEX:
+ case GL2.GL_DEPTH_COMPONENT:
+ case GL2.GL_RED:
+ case GL2.GL_GREEN:
+ case GL2.GL_BLUE:
+ case GL2.GL_ALPHA:
+ case GL2.GL_LUMINANCE:
+ return 1;
+ case GL2.GL_LUMINANCE_ALPHA:
+ return 2;
+ case GL2.GL_RGB:
+ case GL2.GL_BGR:
+ return 3;
+ case GL2.GL_RGBA:
+ case GL2.GL_BGRA:
+ return 4;
+ default :
+ return -1;
+ }
+ }
+
+ /**
+ * Method nearestPower.
+ * <p/>
+ * Compute the nearest power of 2 number. This algorithm is a little strange, but it works quite well.
+ *
+ * @param value
+ *
+ * @return int
+ */
+ protected static int nearestPower(int value) {
+ int i;
+
+ i = 1;
+
+ /* Error! */
+ if ( value == 0 )
+ return -1;
+
+ for ( ; ; ) {
+ if ( value == 1 ) {
+ return i;
+ } else if ( value == 3 ) {
+ return i << 2;
+ }
+ value >>= 1;
+ i <<= 1;
+ }
+ }
+
+ /**
+ * Method bytesPerPixel.
+ *
+ * @param format
+ * @param type
+ *
+ * @return int
+ */
+ protected static int bytesPerPixel(int format, int type) {
+ int n, m;
+
+ switch ( format ) {
+ case GL2.GL_COLOR_INDEX:
+ case GL2.GL_STENCIL_INDEX:
+ case GL2.GL_DEPTH_COMPONENT:
+ case GL2.GL_RED:
+ case GL2.GL_GREEN:
+ case GL2.GL_BLUE:
+ case GL2.GL_ALPHA:
+ case GL2.GL_LUMINANCE:
+ n = 1;
+ break;
+ case GL2.GL_LUMINANCE_ALPHA:
+ n = 2;
+ break;
+ case GL2.GL_RGB:
+ case GL2.GL_BGR:
+ n = 3;
+ break;
+ case GL2.GL_RGBA:
+ case GL2.GL_BGRA:
+ n = 4;
+ break;
+ default :
+ n = 0;
+ }
+
+ switch ( type ) {
+ case GL2.GL_UNSIGNED_BYTE:
+ m = 1;
+ break;
+ case GL2.GL_BYTE:
+ m = 1;
+ break;
+ case GL2.GL_BITMAP:
+ m = 1;
+ break;
+ case GL2.GL_UNSIGNED_SHORT:
+ m = 2;
+ break;
+ case GL2.GL_SHORT:
+ m = 2;
+ break;
+ case GL2.GL_UNSIGNED_INT:
+ m = 4;
+ break;
+ case GL2.GL_INT:
+ m = 4;
+ break;
+ case GL2.GL_FLOAT:
+ m = 4;
+ break;
+ default :
+ m = 0;
+ }
+
+ return n * m;
+ }
+
+ /**
+ * Convenience method for returning an int, rather than getting it out of a buffer yourself.
+ *
+ * @param what
+ *
+ * @return int
+ */
+ protected int glGetIntegerv(GL gl, int what) {
+ gl.glGetIntegerv(what, scratch, 0);
+ return scratch[0];
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java b/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java
new file mode 100755
index 000000000..3e3b6ae87
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/gl2/fixme/GLObjectTracker.java
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 2006 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.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+/**
+ * Tracks the creation of server-side OpenGL objects which can be
+ * shared between contexts. Ordinarily, when an OpenGL context is
+ * deleted and no other contexts are sharing server-side objects with
+ * it, all of the server-side objects are automatically deleted by the
+ * OpenGL implementation. It is not necessary for the end user to
+ * explicitly delete these objects. However, when the Java2D/OpenGL
+ * pipeline is active and frame buffer objects are being used for
+ * rendering, it is necessary for all OpenGL contexts created by JOGL
+ * to share server-side objects with the Java2D OpenGL context. This
+ * means that these objects "leak" into the namespace used by Java2D.
+ * In order to prevent memory leaks and to present the same
+ * programming model to the end user, it is necessary to track the
+ * creation and destruction of all of these server-side OpenGL objects
+ * and to explicitly release them when all of the JOGL-created
+ * contexts which can see them have been released. <P>
+ *
+ * The {@link #ref ref} and {@link #unref unref} methods should be
+ * used during the creation and destruction of OpenGL contexts by JOGL
+ * in order to update the liveness of the objects being tracked. The
+ * various other methods should be called by the OpenGL binding in the
+ * various named methods.
+ */
+
+public class GLObjectTracker {
+ private static final boolean DEBUG = Debug.debug("GLObjectTracker");
+
+ //----------------------------------------------------------------------
+ // Adders
+ //
+
+ // glGenBuffers
+ public synchronized void addBuffers(int n, IntBuffer ids) {
+ add(getList(BUFFERS), n, ids);
+ }
+
+ // glGenBuffers
+ public synchronized void addBuffers(int n, int[] ids, int ids_offset) {
+ add(getList(BUFFERS), n, ids, ids_offset);
+ }
+
+ // glGenBuffersARB
+ public synchronized void addBuffersARB(int n, IntBuffer ids) {
+ add(getList(BUFFERS_ARB), n, ids);
+ }
+
+ // glGenBuffersARB
+ public synchronized void addBuffersARB(int n, int[] ids, int ids_offset) {
+ add(getList(BUFFERS_ARB), n, ids, ids_offset);
+ }
+
+ // glGenFencesAPPLE
+ public synchronized void addFencesAPPLE(int n, IntBuffer ids) {
+ add(getList(FENCES_APPLE), n, ids);
+ }
+
+ // glGenFencesAPPLE
+ public synchronized void addFencesAPPLE(int n, int[] ids, int ids_offset) {
+ add(getList(FENCES_APPLE), n, ids, ids_offset);
+ }
+
+ // glGenFencesNV
+ public synchronized void addFencesNV(int n, IntBuffer ids) {
+ add(getList(FENCES_NV), n, ids);
+ }
+
+ // glGenFencesNV
+ public synchronized void addFencesNV(int n, int[] ids, int ids_offset) {
+ add(getList(FENCES_NV), n, ids, ids_offset);
+ }
+
+ // glGenFragmentShadersATI
+ public synchronized void addFragmentShadersATI(int start, int n) {
+ add(getList(FRAGMENT_SHADERS_ATI), start, n);
+ }
+
+ // glGenFramebuffersEXT
+ public synchronized void addFramebuffersEXT(int n, IntBuffer ids) {
+ add(getList(FRAMEBUFFERS_EXT), n, ids);
+ }
+
+ // glGenFramebuffersEXT
+ public synchronized void addFramebuffersEXT(int n, int[] ids, int ids_offset) {
+ add(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glGenLists
+ public synchronized void addLists(int start, int n) {
+ add(getList(LISTS), start, n);
+ }
+
+ // glGenOcclusionQueriesNV
+ public synchronized void addOcclusionQueriesNV(int n, IntBuffer ids) {
+ add(getList(OCCLUSION_QUERIES_NV), n, ids);
+ }
+
+ // glGenOcclusionQueriesNV
+ public synchronized void addOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+ add(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+ }
+
+ // glCreateProgram
+ public synchronized void addProgramObject(int obj) {
+ add(getList(PROGRAM_OBJECTS), obj, 1);
+ }
+
+ // glCreateProgramObjectARB
+ public synchronized void addProgramObjectARB(int obj) {
+ add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glGenProgramsARB
+ public synchronized void addProgramsARB(int n, IntBuffer ids) {
+ add(getList(PROGRAMS_ARB), n, ids);
+ }
+
+ // glGenProgramsARB
+ public synchronized void addProgramsARB(int n, int[] ids, int ids_offset) {
+ add(getList(PROGRAMS_ARB), n, ids, ids_offset);
+ }
+
+ // glGenProgramsNV
+ public synchronized void addProgramsNV(int n, IntBuffer ids) {
+ add(getList(PROGRAMS_NV), n, ids);
+ }
+
+ // glGenProgramsNV
+ public synchronized void addProgramsNV(int n, int[] ids, int ids_offset) {
+ add(getList(PROGRAMS_NV), n, ids, ids_offset);
+ }
+
+ // glGenQueries
+ public synchronized void addQueries(int n, IntBuffer ids) {
+ add(getList(QUERIES), n, ids);
+ }
+
+ // glGenQueries
+ public synchronized void addQueries(int n, int[] ids, int ids_offset) {
+ add(getList(QUERIES), n, ids, ids_offset);
+ }
+
+ // glGenQueriesARB
+ public synchronized void addQueriesARB(int n, IntBuffer ids) {
+ add(getList(QUERIES_ARB), n, ids);
+ }
+
+ // glGenQueriesARB
+ public synchronized void addQueriesARB(int n, int[] ids, int ids_offset) {
+ add(getList(QUERIES_ARB), n, ids, ids_offset);
+ }
+
+ // glGenRenderbuffersEXT
+ public synchronized void addRenderbuffersEXT(int n, IntBuffer ids) {
+ add(getList(RENDERBUFFERS_EXT), n, ids);
+ }
+
+ // glGenRenderbuffersEXT
+ public synchronized void addRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+ add(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glCreateShader
+ public synchronized void addShaderObject(int obj) {
+ add(getList(SHADER_OBJECTS), obj, 1);
+ }
+
+ // glCreateShaderObjectARB
+ public synchronized void addShaderObjectARB(int obj) {
+ add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glGenTextures
+ public synchronized void addTextures(int n, IntBuffer ids) {
+ add(getList(TEXTURES), n, ids);
+ }
+
+ // glGenTextures
+ public synchronized void addTextures(int n, int[] ids, int ids_offset) {
+ add(getList(TEXTURES), n, ids, ids_offset);
+ }
+
+ // glGenVertexArraysAPPLE
+ public synchronized void addVertexArraysAPPLE(int n, IntBuffer ids) {
+ add(getList(VERTEX_ARRAYS_APPLE), n, ids);
+ }
+
+ // glGenVertexArraysAPPLE
+ public synchronized void addVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+ add(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+ }
+
+ // glGenVertexShadersEXT
+ public synchronized void addVertexShadersEXT(int start, int n) {
+ add(getList(VERTEX_SHADERS_EXT), start, n);
+ }
+
+ //----------------------------------------------------------------------
+ // Removers
+ //
+
+ // glDeleteBuffers
+ public synchronized void removeBuffers(int n, IntBuffer ids) {
+ remove(getList(BUFFERS), n, ids);
+ }
+
+ // glDeleteBuffers
+ public synchronized void removeBuffers(int n, int[] ids, int ids_offset) {
+ remove(getList(BUFFERS), n, ids, ids_offset);
+ }
+
+ // glDeleteBuffersARB
+ public synchronized void removeBuffersARB(int n, IntBuffer ids) {
+ remove(getList(BUFFERS_ARB), n, ids);
+ }
+
+ // glDeleteBuffersARB
+ public synchronized void removeBuffersARB(int n, int[] ids, int ids_offset) {
+ remove(getList(BUFFERS_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteFencesAPPLE
+ public synchronized void removeFencesAPPLE(int n, IntBuffer ids) {
+ remove(getList(FENCES_APPLE), n, ids);
+ }
+
+ // glDeleteFencesAPPLE
+ public synchronized void removeFencesAPPLE(int n, int[] ids, int ids_offset) {
+ remove(getList(FENCES_APPLE), n, ids, ids_offset);
+ }
+
+ // glDeleteFencesNV
+ public synchronized void removeFencesNV(int n, IntBuffer ids) {
+ remove(getList(FENCES_NV), n, ids);
+ }
+
+ // glDeleteFencesNV
+ public synchronized void removeFencesNV(int n, int[] ids, int ids_offset) {
+ remove(getList(FENCES_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteFragmentShaderATI
+ public synchronized void removeFragmentShaderATI(int obj) {
+ remove(getList(FRAGMENT_SHADERS_ATI), obj, 1);
+ }
+
+ // glDeleteFramebuffersEXT
+ public synchronized void removeFramebuffersEXT(int n, IntBuffer ids) {
+ remove(getList(FRAMEBUFFERS_EXT), n, ids);
+ }
+
+ // glDeleteFramebuffersEXT
+ public synchronized void removeFramebuffersEXT(int n, int[] ids, int ids_offset) {
+ remove(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glDeleteLists
+ public synchronized void removeLists(int start, int n) {
+ remove(getList(LISTS), start, n);
+ }
+
+ // glDeleteOcclusionQueriesNV
+ public synchronized void removeOcclusionQueriesNV(int n, IntBuffer ids) {
+ remove(getList(OCCLUSION_QUERIES_NV), n, ids);
+ }
+
+ // glDeleteOcclusionQueriesNV
+ public synchronized void removeOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+ remove(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteProgram
+ public synchronized void removeProgramObject(int obj) {
+ remove(getList(PROGRAM_OBJECTS), obj, 1);
+ }
+
+ // glDeleteObjectARB
+ public synchronized void removeProgramOrShaderObjectARB(int obj) {
+ remove(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+ }
+
+ // glDeleteProgramsARB
+ public synchronized void removeProgramsARB(int n, IntBuffer ids) {
+ remove(getList(PROGRAMS_ARB), n, ids);
+ }
+
+ // glDeleteProgramsARB
+ public synchronized void removeProgramsARB(int n, int[] ids, int ids_offset) {
+ remove(getList(PROGRAMS_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteProgramsNV
+ public synchronized void removeProgramsNV(int n, IntBuffer ids) {
+ remove(getList(PROGRAMS_NV), n, ids);
+ }
+
+ // glDeleteProgramsNV
+ public synchronized void removeProgramsNV(int n, int[] ids, int ids_offset) {
+ remove(getList(PROGRAMS_NV), n, ids, ids_offset);
+ }
+
+ // glDeleteQueries
+ public synchronized void removeQueries(int n, IntBuffer ids) {
+ remove(getList(QUERIES), n, ids);
+ }
+
+ // glDeleteQueries
+ public synchronized void removeQueries(int n, int[] ids, int ids_offset) {
+ remove(getList(QUERIES), n, ids, ids_offset);
+ }
+
+ // glDeleteQueriesARB
+ public synchronized void removeQueriesARB(int n, IntBuffer ids) {
+ remove(getList(QUERIES_ARB), n, ids);
+ }
+
+ // glDeleteQueriesARB
+ public synchronized void removeQueriesARB(int n, int[] ids, int ids_offset) {
+ remove(getList(QUERIES_ARB), n, ids, ids_offset);
+ }
+
+ // glDeleteRenderbuffersEXT
+ public synchronized void removeRenderbuffersEXT(int n, IntBuffer ids) {
+ remove(getList(RENDERBUFFERS_EXT), n, ids);
+ }
+
+ // glDeleteRenderbuffersEXT
+ public synchronized void removeRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+ remove(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+ }
+
+ // glDeleteShader
+ public synchronized void removeShaderObject(int obj) {
+ remove(getList(SHADER_OBJECTS), obj, 1);
+ }
+
+ // glDeleteTextures
+ public synchronized void removeTextures(int n, IntBuffer ids) {
+ remove(getList(TEXTURES), n, ids);
+ }
+
+ // glDeleteTextures
+ public synchronized void removeTextures(int n, int[] ids, int ids_offset) {
+ remove(getList(TEXTURES), n, ids, ids_offset);
+ }
+
+ // glDeleteVertexArraysAPPLE
+ public synchronized void removeVertexArraysAPPLE(int n, IntBuffer ids) {
+ remove(getList(VERTEX_ARRAYS_APPLE), n, ids);
+ }
+
+ // glDeleteVertexArraysAPPLE
+ public synchronized void removeVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+ remove(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+ }
+
+ // glDeleteVertexShaderEXT
+ public synchronized void removeVertexShaderEXT(int obj) {
+ remove(getList(VERTEX_SHADERS_EXT), obj, 1);
+ }
+
+ //----------------------------------------------------------------------
+ // Reference count maintenance and manual deletion
+ //
+
+ public synchronized void transferAll(GLObjectTracker other) {
+ for (int i = 0; i < lists.length; i++) {
+ getList(i).addAll(other.lists[i]);
+ if (other.lists[i] != null) {
+ other.lists[i].clear();
+ }
+ }
+ dirty = true;
+ }
+
+ public synchronized void ref() {
+ ++refCount;
+ }
+
+ public void unref(GLObjectTracker deletedObjectPool) {
+ boolean tryDelete = false;
+ synchronized (this) {
+ if (--refCount == 0) {
+ tryDelete = true;
+ }
+ }
+ if (tryDelete) {
+ // See whether we should try to do the work now or whether we
+ // have to postpone
+ GLContext cur = GLContext.getCurrent();
+ if ((cur != null) &&
+ (cur instanceof GLContextImpl)) {
+ GLContextImpl curImpl = (GLContextImpl) cur;
+ if (deletedObjectPool != null &&
+ deletedObjectPool == curImpl.getDeletedObjectTracker()) {
+ // Should be safe to delete these objects now
+ try {
+ delete((GL2)curImpl.getGL());
+ return;
+ } catch (GLException e) {
+ // Shouldn't happen, but if it does, transfer all objects
+ // to the deleted object pool hoping we can later clean
+ // them up
+ deletedObjectPool.transferAll(this);
+ throw(e);
+ }
+ }
+ }
+ // If we get here, we couldn't attempt to delete the objects
+ // right now; instead try to transfer them to the
+ // deletedObjectPool for later cleanup (FIXME: should consider
+ // throwing an exception if deletedObjectPool is null, since
+ // that shouldn't happen)
+ if (DEBUG) {
+ String s = null;
+ if (cur == null) {
+ s = "current context was null";
+ } else if (!(cur instanceof GLContextImpl)) {
+ s = "current context was not a GLContextImpl";
+ } else if (deletedObjectPool == null) {
+ s = "no current deletedObjectPool";
+ } else if (deletedObjectPool != ((GLContextImpl) cur).getDeletedObjectTracker()) {
+ s = "deletedObjectTracker didn't match";
+ if (((GLContextImpl) cur).getDeletedObjectTracker() == null) {
+ s += " (other was null)";
+ }
+ } else {
+ s = "unknown reason";
+ }
+ System.err.println("Deferred destruction of server-side OpenGL objects into " + deletedObjectPool + ": " + s);
+ }
+
+ if (deletedObjectPool != null) {
+ deletedObjectPool.transferAll(this);
+ }
+ }
+ }
+
+ public void clean(GL2 gl) {
+ if (dirty) {
+ try {
+ delete(gl);
+ dirty = false;
+ } catch (GLException e) {
+ // FIXME: not sure what to do here; probably a bad idea to be
+ // throwing exceptions during an otherwise-successful makeCurrent
+ }
+ }
+ }
+
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // Kinds of sharable server-side OpenGL objects this class tracks
+ private static final int BUFFERS = 0;
+ private static final int BUFFERS_ARB = 1;
+ private static final int FENCES_APPLE = 2;
+ private static final int FENCES_NV = 3;
+ private static final int FRAGMENT_SHADERS_ATI = 4;
+ private static final int FRAMEBUFFERS_EXT = 5;
+ private static final int LISTS = 6;
+ private static final int OCCLUSION_QUERIES_NV = 7;
+ private static final int PROGRAM_AND_SHADER_OBJECTS_ARB = 8;
+ private static final int PROGRAM_OBJECTS = 9;
+ private static final int PROGRAMS_ARB = 10;
+ private static final int PROGRAMS_NV = 11;
+ private static final int QUERIES = 12;
+ private static final int QUERIES_ARB = 13;
+ private static final int RENDERBUFFERS_EXT = 14;
+ private static final int SHADER_OBJECTS = 15;
+ private static final int TEXTURES = 16;
+ private static final int VERTEX_ARRAYS_APPLE = 17;
+ private static final int VERTEX_SHADERS_EXT = 18;
+ private static final int NUM_OBJECT_TYPES = 19;
+
+ static abstract class Deleter {
+ public abstract void delete(GL2 gl, int obj);
+ }
+
+ static class ObjectList {
+ private static final int MIN_CAPACITY = 4;
+
+ private int size;
+ private int capacity;
+ private int[] data;
+ private Deleter deleter;
+ private String name;
+
+ public ObjectList(Deleter deleter) {
+ this.deleter = deleter;
+ clear();
+ }
+
+ public void add(int obj) {
+ if (size == capacity) {
+ int newCapacity = 2 * capacity;
+ int[] newData = new int[newCapacity];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ capacity = newCapacity;
+ }
+
+ data[size++] = obj;
+ }
+
+ public void addAll(ObjectList other) {
+ if (other == null) {
+ return;
+ }
+ for (int i = 0; i < other.size; i++) {
+ add(other.data[i]);
+ }
+ }
+
+ public boolean remove(int value) {
+ for (int i = 0; i < size; i++) {
+ if (data[i] == value) {
+ if (i < size - 1) {
+ System.arraycopy(data, i+1, data, i, size - i - 1);
+ }
+ --size;
+ if ((size < capacity / 4) &&
+ (capacity > MIN_CAPACITY)) {
+ int newCapacity = capacity / 4;
+ if (newCapacity < MIN_CAPACITY) {
+ newCapacity = MIN_CAPACITY;
+ }
+ int[] newData = new int[newCapacity];
+ System.arraycopy(data, 0, newData, 0, size);
+ data = newData;
+ capacity = newCapacity;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setName(String name) {
+ if (DEBUG) {
+ this.name = name;
+ }
+ }
+
+ public void delete(GL2 gl) {
+ // Just in case we start throwing exceptions during deletion,
+ // make sure we make progress rather than going into an infinite
+ // loop
+ while (size > 0) {
+ int obj = data[size - 1];
+ --size;
+ if (DEBUG) {
+ System.err.println("Deleting server-side OpenGL object " + obj +
+ ((name != null) ? (" (" + name + ")") : ""));
+ }
+ deleter.delete(gl, obj);
+ }
+ }
+
+ public void clear() {
+ size = 0;
+ capacity = MIN_CAPACITY;
+ data = new int[capacity];
+ }
+ }
+
+ private ObjectList[] lists = new ObjectList[NUM_OBJECT_TYPES];
+ private int refCount;
+ private boolean dirty;
+
+ private void add(ObjectList list, int n, IntBuffer ids) {
+ int pos = ids.position();
+ for (int i = 0; i < n; i++) {
+ list.add(ids.get(pos + i));
+ }
+ }
+
+ private void add(ObjectList list, int n, int[] ids, int ids_offset) {
+ for (int i = 0; i < n; i++) {
+ list.add(ids[i + ids_offset]);
+ }
+ }
+
+ private void add(ObjectList list, int start, int n) {
+ for (int i = 0; i < n; i++) {
+ list.add(start + i);
+ }
+ }
+
+ private void remove(ObjectList list, int n, IntBuffer ids) {
+ int pos = ids.position();
+ for (int i = 0; i < n; i++) {
+ list.remove(ids.get(pos + i));
+ }
+ }
+
+ private void remove(ObjectList list, int n, int[] ids, int ids_offset) {
+ for (int i = 0; i < n; i++) {
+ list.remove(ids[i + ids_offset]);
+ }
+ }
+
+ private void remove(ObjectList list, int start, int n) {
+ for (int i = 0; i < n; i++) {
+ list.remove(start + i);
+ }
+ }
+
+ private ObjectList getList(int which) {
+ ObjectList list = lists[which];
+ if (list == null) {
+ Deleter deleter = null;
+ String name = null;
+ // Figure out which deleter we need
+ switch (which) {
+ case BUFFERS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteBuffers(1, new int[] { obj }, 0);
+ }
+ };
+ name = "buffer";
+ break;
+ case BUFFERS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteBuffersARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB buffer";
+ break;
+ case FENCES_APPLE:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFencesAPPLE(1, new int[] { obj }, 0);
+ }
+ };
+ name = "APPLE fence";
+ break;
+ case FENCES_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFencesNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV fence";
+ break;
+ case FRAGMENT_SHADERS_ATI:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFragmentShaderATI(obj);
+ }
+ };
+ name = "ATI fragment shader";
+ break;
+ case FRAMEBUFFERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteFramebuffersEXT(1, new int[] { obj }, 0);
+ }
+ };
+ name = "EXT framebuffer";
+ break;
+ case LISTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteLists(obj, 1);
+ }
+ };
+ name = "display list";
+ break;
+ case OCCLUSION_QUERIES_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteOcclusionQueriesNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV occlusion query";
+ break;
+ case PROGRAM_AND_SHADER_OBJECTS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteObjectARB(obj);
+ }
+ };
+ name = "ARB program or shader object";
+ break;
+ case PROGRAM_OBJECTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgram(obj);
+ }
+ };
+ name = "program object";
+ break;
+ case PROGRAMS_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgramsARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB program object";
+ break;
+ case PROGRAMS_NV:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteProgramsNV(1, new int[] { obj }, 0);
+ }
+ };
+ name = "NV program";
+ break;
+ case QUERIES:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteQueries(1, new int[] { obj }, 0);
+ }
+ };
+ name = "query";
+ break;
+ case QUERIES_ARB:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteQueriesARB(1, new int[] { obj }, 0);
+ }
+ };
+ name = "ARB query";
+ break;
+ case RENDERBUFFERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteRenderbuffersEXT(1, new int[] { obj }, 0);
+ }
+ };
+ name = "EXT renderbuffer";
+ break;
+ case SHADER_OBJECTS:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteShader(obj);
+ }
+ };
+ name = "shader object";
+ break;
+ case TEXTURES:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteTextures(1, new int[] { obj }, 0);
+ }
+ };
+ name = "texture";
+ break;
+ case VERTEX_ARRAYS_APPLE:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteVertexArraysAPPLE(1, new int[] { obj }, 0);
+ }
+ };
+ name = "APPLE vertex array";
+ break;
+ case VERTEX_SHADERS_EXT:
+ deleter = new Deleter() {
+ public void delete(GL2 gl, int obj) {
+ gl.glDeleteVertexShaderEXT(obj);
+ }
+ };
+ name = "EXT vertex shader";
+ break;
+ default:
+ throw new InternalError("Unexpected OpenGL object type " + which);
+ }
+
+ list = new ObjectList(deleter);
+ list.setName(name);
+ lists[which] = list;
+ }
+ return list;
+ }
+
+ private void delete(GL2 gl) {
+ for (int i = 0; i < lists.length; i++) {
+ ObjectList list = lists[i];
+ if (list != null) {
+ list.delete(gl);
+ lists[i] = null;
+ }
+ }
+ }
+}
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
new file mode 100644
index 000000000..bf4023c1c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
@@ -0,0 +1,342 @@
+/*
+ * 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.macosx.cgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public abstract class MacOSXCGLContext extends GLContextImpl
+{
+ protected long nsContext; // NSOpenGLContext
+ protected long cglContext; // CGLContextObj
+ private CGLExt cglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // CGL extension functions.
+ private CGLExtProcAddressTable cglExtProcAddressTable;
+
+ public MacOSXCGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public MacOSXCGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getCGLExt();
+ }
+
+ public CGLExt getCGLExt() {
+ if (cglExt == null) {
+ cglExt = new CGLExtImpl(this);
+ }
+ return cglExt;
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getCGLExtProcAddressTable();
+ }
+
+ public final CGLExtProcAddressTable getCGLExtProcAddressTable() {
+ return cglExtProcAddressTable;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName)
+ {
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName)
+ {
+ return glExtensionName;
+ }
+
+ protected abstract boolean create();
+
+ /**
+ * Creates and initializes an appropriate OpenGl nsContext. Should only be
+ * called by {@link makeCurrentImpl()}.
+ */
+ protected boolean create(boolean pbuffer, boolean floatingPoint) {
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getNSContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilitiesRequested = (GLCapabilities)config.getRequestedCapabilities();
+ GLProfile glProfile = capabilitiesRequested.getGLProfile();
+ if(glProfile.isGL3()) {
+ throw new GLException("GL3 profile currently not supported on MacOSX, due to the lack of a OpenGL 3.1 implementation");
+ }
+ // HACK .. bring in OnScreen/PBuffer selection to the DrawableFactory !!
+ GLCapabilities capabilities = (GLCapabilities) capabilitiesRequested.clone();
+ capabilities.setPBuffer(pbuffer);
+ capabilities.setPbufferFloatingPointBuffers(floatingPoint);
+
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(capabilities);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
+ }
+ config.setChosenPixelFormat(pixelFormat);
+ try {
+ int[] viewNotReady = new int[1];
+ // Try to allocate a context with this
+ nsContext = CGL.createContext(share,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ pixelFormat,
+ viewNotReady, 0);
+ if (nsContext == 0) {
+ if (viewNotReady[0] == 1) {
+ if (DEBUG) {
+ System.err.println("!!! View not ready for " + getClass().getName());
+ }
+ // View not ready at the window system level -- this is OK
+ return false;
+ }
+ throw new GLException("Error creating NSOpenGLContext with requested pixel format");
+ }
+
+ if (!pbuffer && !capabilities.isBackgroundOpaque()) {
+ // Set the context opacity
+ CGL.setContextOpacity(nsContext, 0);
+ }
+
+ GLCapabilities caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(glProfile, pixelFormat);
+ config.setChosenCapabilities(caps);
+ } finally {
+ CGL.deletePixelFormat(pixelFormat);
+ }
+ if (!CGL.makeCurrentContext(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ setGLFunctionAvailability(true);
+ GLContextShareSet.contextCreated(this);
+ return true;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (0 == cglContext && drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ if (DEBUG) {
+ System.err.println("drawable not properly initialized");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+ boolean created = false;
+ if ( 0 == cglContext && 0 == nsContext) {
+ if (!create()) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if ( 0 != cglContext ) {
+ if (CGL.kCGLNoError != CGL.CGLSetCurrentContext(cglContext)) {
+ throw new GLException("Error making cglContext current");
+ }
+ } else {
+ if (!CGL.makeCurrentContext(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if ( 0 != cglContext ) {
+ CGL.CGLReleaseContext(cglContext);
+ } else {
+ if (!CGL.clearCurrentContext(nsContext)) {
+ throw new GLException("Error freeing OpenGL nsContext");
+ }
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ boolean hadContext = isCreated();
+ if ( 0 != cglContext ) {
+ if (CGL.kCGLNoError != CGL.CGLDestroyContext(cglContext)) {
+ throw new GLException("Unable to delete OpenGL cglContext");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL cglContext " + cglContext);
+ }
+ cglContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ } else if ( 0 != nsContext ) {
+ if (!CGL.deleteContext(nsContext)) {
+ throw new GLException("Unable to delete OpenGL nsContext");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL nsContext " + nsContext);
+ }
+ nsContext = 0;
+ }
+ if(hadContext) {
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public boolean isCreated() {
+ return 0 != cglContext || 0 != nsContext ;
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getCGLContext();
+ long src = 0;
+ if( 0 != dst ) {
+ src = ((MacOSXCGLContext) source).getCGLContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL cglContext has not been created ; Destination has a cglContext.");
+ }
+ CGL.CGLCopyContext(src, dst, mask);
+ } else {
+ dst = getNSContext();
+ src = ((MacOSXCGLContext) source).getNSContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL nsContext has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL nsContext has not been created");
+ }
+ CGL.copyContext(dst, src, mask);
+ }
+ }
+
+ protected void updateGLProcAddressTable() {
+ if (DEBUG) {
+ System.err.println("!!! Initializing CGL extension address table");
+ }
+ if (cglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ cglExtProcAddressTable = new CGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getCGLExtProcAddressTable());
+ super.updateGLProcAddressTable();
+ }
+
+ public String getPlatformExtensionsString()
+ {
+ return "";
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if ( 0 != cglContext ) {
+ int[] lval = new int[] { (int) interval } ;
+ CGL.CGLSetParameter(cglContext, CGL.kCGLCPSwapInterval, lval, 0);
+ } else if ( 0 != nsContext ) {
+ CGL.setSwapInterval(nsContext, interval);
+ } else {
+ throw new GLException("OpenGL context not current");
+ }
+ currentSwapInterval = interval ;
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ // FIXME: apparently the Apple extension doesn't require a custom memory allocator
+ throw new GLException("Not yet implemented");
+ }
+
+ public boolean isFunctionAvailable(String glFunctionName)
+ {
+ return super.isFunctionAvailable(glFunctionName);
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return true;
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ // Support for "mode switching" as described in MacOSXCGLDrawable
+ public abstract void setOpenGLMode(int mode);
+ public abstract int getOpenGLMode();
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getCGLContext() {
+ return cglContext;
+ }
+ public long getNSContext() {
+ return nsContext;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java
new file mode 100644
index 000000000..2b91eb5d3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawable.java
@@ -0,0 +1,109 @@
+/*
+ * 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.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
+ // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs
+ // to represent the contexts for e.g. the Java2D back buffer. When
+ // the Java2D/JOGL bridge is active, this means that if we want to
+ // be able to share textures and display lists with the Java2D
+ // contexts, we need to use the CGL APIs rather than the NSOpenGL
+ // APIs on the JOGL side. For example, if we create a pbuffer using
+ // the NSOpenGL APIs and want to share textures and display lists
+ // between it and the Java2D back buffer, there is no way to do so,
+ // because the Java2D context is actually a CGLContextObj and the
+ // NSOpenGLContext's initWithFormat:shareContext: only accepts an
+ // NSOpenGLContext as its second argument. Of course there is no way
+ // to wrap an NSOpenGLContext around an arbitrary CGLContextObj.
+ //
+ // The situation we care most about is allowing a GLPbuffer to share
+ // textures, etc. with a GLJPanel when the Java2D/JOGL bridge is
+ // active; several of the demos rely on this functionality. We aim
+ // to get there by allowing a GLPBuffer to switch its implementation
+ // between using an NSOpenGLPixelBuffer and a CGLPBufferObj. In
+ // order to track whether this has been done we need to have the
+ // notion of a "mode" of both the MacOSXCGLDrawable and the
+ // MacOSXGLContext. Initially the mode is "unspecified", meaning it
+ // leans toward the default (NSOpenGL). If sharing is requested
+ // between either a GLJPanel and a GLPbuffer or a GLCanvas and a
+ // GLPbuffer, the GLPbuffer will be switched into the appropriate
+ // mode: CGL mode for a GLJPanel and NSOpenGL mode for a GLCanvas.
+ // To avoid thrashing we support exactly one such switch during the
+ // lifetime of a given GLPbuffer. This is not a fully general
+ // solution (for example, you can't share textures among a
+ // GLPbuffer, a GLJPanel and a GLCanvas simultaneously) but should
+ // be enough to get things off the ground.
+ public static final int NSOPENGL_MODE = 1;
+ public static final int CGL_MODE = 2;
+
+ public MacOSXCGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ if( NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface() ) {
+ throw new GLException("Couldn't lock surface");
+ }
+ try {
+ // don't remove this block .. locking the surface is essential to update surface data
+ } finally {
+ unlockSurface();
+ }
+ }
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (MacOSXCGLDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ // Support for "mode switching" as per above
+ public abstract void setOpenGLMode(int mode);
+ public abstract int getOpenGLMode();
+}
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
new file mode 100644
index 000000000..c08599964
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -0,0 +1,161 @@
+/*
+ * 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.macosx.cgl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.nio.*;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.*;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+ public MacOSXCGLDrawableFactory() {
+ super();
+
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new MacOSXCGLGraphicsConfigurationFactory();
+
+ try {
+ NWReflection.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (Throwable t) { }
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new MacOSXOnscreenCGLDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ return new MacOSXOffscreenCGLDrawable(this, target);
+ }
+
+ public boolean canCreateGLPbuffer() {
+ return true;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ /**
+ * FIXME: Think about this ..
+ * should not be necessary ? ..
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ returnList.add(new MacOSXPbufferCGLDrawable(factory, target));
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ */
+ return new MacOSXPbufferCGLDrawable(this, target);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault();
+ NullWindow nw = new NullWindow(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen, true));
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ return MacOSXExternalCGLContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return false;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public void loadGLULibrary() {
+ // Nothing to do; already loaded by native code; not much point in
+ // making it lazier on this platform
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ return CGL.getProcAddress(glFuncName);
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("not supported in non AWT enviroment");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ /** Returns the length of the computed gamma ramp for this OS and
+ hardware. Returns 0 if gamma changes are not supported. */
+ protected int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ return CGL.setGammaRamp(ramp.length,
+ ramp, 0,
+ ramp, 0,
+ ramp, 0);
+ }
+
+ protected Buffer getGammaRamp() {
+ return null;
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ CGL.resetGammaRamp();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
new file mode 100644
index 000000000..889d1c333
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2008 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.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+
+public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+ long pixelformat;
+
+ public MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested,
+ long pixelformat) {
+ super(screen, capsChosen, capsRequested);
+ this.pixelformat=pixelformat;
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ protected void setChosenPixelFormat(long pixelformat) {
+ this.pixelformat=pixelformat;
+ }
+
+ protected void setChosenCapabilities(GLCapabilities caps) {
+ super.setChosenCapabilities(caps);
+ }
+
+ protected static final int[] cglInternalAttributeToken = new int[] {
+ CGL.kCGLPFAColorFloat,
+ CGL.NSOpenGLPFAPixelBuffer,
+ CGL.NSOpenGLPFADoubleBuffer,
+ CGL.NSOpenGLPFAStereo,
+ CGL.NSOpenGLPFAColorSize,
+ CGL.NSOpenGLPFAAlphaSize,
+ CGL.NSOpenGLPFADepthSize,
+ CGL.NSOpenGLPFAAccumSize,
+ CGL.NSOpenGLPFAStencilSize,
+ CGL.NSOpenGLPFASampleBuffers,
+ CGL.NSOpenGLPFASamples };
+
+ protected static int[] GLCapabilities2AttribList(GLCapabilities caps) {
+ int[] ivalues = new int[cglInternalAttributeToken.length];
+
+ for (int idx = 0; idx < cglInternalAttributeToken.length; idx++) {
+ int attr = cglInternalAttributeToken[idx];
+ switch (attr) {
+ case CGL.kCGLPFAColorFloat:
+ ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFAPixelBuffer:
+ ivalues[idx] = caps.isPBuffer() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFADoubleBuffer:
+ ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0);
+ break;
+
+ case CGL.NSOpenGLPFAStereo:
+ ivalues[idx] = (caps.getStereo() ? 1 : 0);
+ break;
+
+ case CGL.NSOpenGLPFAColorSize:
+ ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits());
+ break;
+
+ case CGL.NSOpenGLPFAAlphaSize:
+ ivalues[idx] = caps.getAlphaBits();
+ break;
+
+ case CGL.NSOpenGLPFADepthSize:
+ ivalues[idx] = caps.getDepthBits();
+ break;
+
+ case CGL.NSOpenGLPFAAccumSize:
+ ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits());
+ break;
+
+ case CGL.NSOpenGLPFAStencilSize:
+ ivalues[idx] = caps.getStencilBits();
+ break;
+
+ case CGL.NSOpenGLPFASampleBuffers:
+ ivalues[idx] = caps.getSampleBuffers() ? 1 : 0;
+ break;
+
+ case CGL.NSOpenGLPFASamples:
+ ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return ivalues;
+ }
+
+ protected static long GLCapabilities2NSPixelFormat(GLCapabilities caps) {
+ int[] ivalues = GLCapabilities2AttribList(caps);
+ return CGL.createPixelFormat(cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ }
+
+ protected static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ return PixelFormat2GLCapabilities(glp, pixelFormat, true);
+ }
+
+ protected static GLCapabilities CGLPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ return PixelFormat2GLCapabilities(glp, pixelFormat, false);
+ }
+
+ private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
+ int[] ivalues = new int[cglInternalAttributeToken.length];
+
+ // On this platform the pixel format is associated with the
+ // context and not the drawable. However it's a reasonable
+ // approximation to just store the chosen pixel format up in the
+ // NativeWindow's AbstractGraphicsConfiguration,
+ // since the public API doesn't provide for a different GLCapabilities per context.
+ // Note: These restrictions of the platform's API might be considered as a bug anyways.
+
+ // Figure out what attributes we really got
+ GLCapabilities caps = new GLCapabilities(glp);
+ if(nsUsage) {
+ CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ } else {
+ CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0);
+ }
+ for (int i = 0; i < cglInternalAttributeToken.length; i++) {
+ int attr = cglInternalAttributeToken[i];
+ switch (attr) {
+ case CGL.kCGLPFAColorFloat:
+ caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAPixelBuffer:
+ caps.setPBuffer(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFADoubleBuffer:
+ caps.setDoubleBuffered(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAStereo:
+ caps.setStereo(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFAColorSize:
+ {
+ int bitSize = ivalues[i];
+ if (bitSize == 32)
+ bitSize = 24;
+ bitSize /= 3;
+ caps.setRedBits(bitSize);
+ caps.setGreenBits(bitSize);
+ caps.setBlueBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAAlphaSize:
+ caps.setAlphaBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFADepthSize:
+ caps.setDepthBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFAAccumSize:
+ {
+ int bitSize = ivalues[i] / 4;
+ caps.setAccumRedBits(bitSize);
+ caps.setAccumGreenBits(bitSize);
+ caps.setAccumBlueBits(bitSize);
+ caps.setAccumAlphaBits(bitSize);
+ }
+ break;
+
+ case CGL.NSOpenGLPFAStencilSize:
+ caps.setStencilBits(ivalues[i]);
+ break;
+
+ case CGL.NSOpenGLPFASampleBuffers:
+ caps.setSampleBuffers(ivalues[i] != 0);
+ break;
+
+ case CGL.NSOpenGLPFASamples:
+ caps.setNumSamples(ivalues[i]);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return caps;
+ }
+}
+
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
new file mode 100644
index 000000000..ab53e49e9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import com.sun.nativewindow.impl.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on OSX 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 MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public MacOSXCGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.macosx.MacOSXGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false);
+ }
+
+ protected static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+
+ return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilities)capabilities, (GLCapabilities)capabilities, 0);
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java
new file mode 100644
index 000000000..239eedd43
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2005 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.macosx.cgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+import javax.media.nativewindow.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class MacOSXExternalCGLContext extends MacOSXCGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private MacOSXExternalCGLContext(Drawable drawable, long cglContext, long nsContext) {
+ super(drawable, null);
+ drawable.setExternalCGLContext(this);
+ this.cglContext = cglContext;
+ this.nsContext = nsContext;
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static MacOSXExternalCGLContext create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long pixelFormat = 0;
+ long currentDrawable = 0;
+ long cglContext = 0;
+ long nsContext = CGL.getCurrentContext(); // Check: MacOSX 10.3 ..
+ if( 0 != nsContext ) {
+ currentDrawable = CGL.getNSView(nsContext);
+ long ctx = CGL.getCGLContext(nsContext);
+ if (ctx == 0) {
+ throw new GLException("Error: NULL cglContext of nsContext 0x" +Long.toHexString(nsContext));
+ }
+ pixelFormat = CGL.CGLGetPixelFormat(ctx);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create nsContext 0x"+Long.toHexString(nsContext)+
+ ", cglContext 0x"+Long.toHexString(ctx)+
+ ", pixelFormat 0x"+Long.toHexString(pixelFormat));
+ }
+ } else {
+ cglContext = CGL.CGLGetCurrentContext();
+ if (cglContext == 0) {
+ throw new GLException("Error: current cglContext null, no nsContext");
+ }
+ pixelFormat = CGL.CGLGetPixelFormat(cglContext);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create cglContext 0x"+Long.toHexString(cglContext)+
+ ", pixelFormat 0x"+Long.toHexString(pixelFormat));
+ }
+ }
+
+ if (0 == pixelFormat) {
+ throw new GLException("Error: current pixelformat of current cglContext 0x"+Long.toHexString(cglContext)+" is null");
+ }
+ GLCapabilities caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat);
+ if(DEBUG) {
+ System.err.println("MacOSXExternalCGLContext Create "+caps);
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(currentDrawable);
+ return new MacOSXExternalCGLContext(new Drawable(factory, nw), cglContext, nsContext);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ protected boolean create() {
+ return true;
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ protected void swapBuffers() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities caps = (GLCapabilities)config.getChosenCapabilities();
+ if(caps.isOnscreen()) {
+ if (CGL.kCGLNoError != CGL.CGLFlushDrawable(cglContext)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for external GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.CGL_MODE;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends MacOSXCGLDrawable {
+ MacOSXExternalCGLContext extCtx;
+
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ void setExternalCGLContext(MacOSXExternalCGLContext externalContext) {
+ extCtx = externalContext;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+
+ protected void swapBuffersImpl() {
+ if (extCtx != null) {
+ extCtx.swapBuffers();
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for external GLContext's drawables");
+ }
+
+ public int getOpenGLMode() {
+ return CGL_MODE;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java
new file mode 100644
index 000000000..8b8bb46fa
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.macosx.cgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOffscreenCGLContext extends MacOSXPbufferCGLContext
+{
+ public MacOSXOffscreenCGLContext(MacOSXPbufferCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ GL gl = getGL();
+ return gl.isGL2()?GL2.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ return true;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
new file mode 100644
index 000000000..adaa48f34
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
@@ -0,0 +1,56 @@
+/*
+ * 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.macosx.cgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable {
+
+ public MacOSXOffscreenCGLDrawable(GLDrawableFactory factory,
+ NativeWindow target) {
+ super(factory, target);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new MacOSXOffscreenCGLContext(this, shareWith);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java
new file mode 100644
index 000000000..4c64864fa
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -0,0 +1,130 @@
+/*
+ * 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.macosx.cgl;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
+ protected MacOSXOnscreenCGLDrawable drawable;
+
+ public MacOSXOnscreenCGLContext(MacOSXOnscreenCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ int ret = super.makeCurrentImpl();
+ if ((ret == CONTEXT_CURRENT) ||
+ (ret == CONTEXT_CURRENT_NEW)) {
+ // Assume the canvas might have been resized or moved and tell the OpenGL
+ // context to update itself. This used to be done only upon receiving a
+ // reshape event but that doesn't appear to be sufficient. An experiment
+ // was also done to add a HierarchyBoundsListener to the GLCanvas and
+ // do this updating only upon reshape of this component or reshape or movement
+ // of an ancestor, but this also wasn't sufficient and left garbage on the
+ // screen in some situations.
+ CGL.updateContext(nsContext);
+ } else {
+ if (!isOptimizable()) {
+ // This can happen if the window currently is zero-sized, for example.
+ // Make sure we don't leave the surface locked in this case.
+ drawable.unlockSurface();
+ lockRes = NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ }
+ return ret;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY)) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected void swapBuffers() {
+ if (!CGL.flushBuffer(nsContext)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+
+ protected void update() throws GLException {
+ if (nsContext == 0) {
+ throw new GLException("Context not created");
+ }
+ CGL.updateContext(nsContext);
+ }
+
+ protected boolean create() {
+ return create(false, false);
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.NSOPENGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for on-screen GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.NSOPENGL_MODE;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
new file mode 100644
index 000000000..6ee023867
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -0,0 +1,100 @@
+/*
+ * 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.macosx.cgl;
+
+import java.lang.ref.WeakReference;
+import java.security.*;
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
+ private List/*<WeakReference<GLContext>>*/ createdContexts =
+ new ArrayList();
+
+ protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ MacOSXOnscreenCGLContext context =
+ new MacOSXOnscreenCGLContext(this, shareWith);
+ // NOTE: we need to keep track of the created contexts in order to
+ // implement swapBuffers() because of how Mac OS X implements its
+ // OpenGL window interface
+ synchronized (this) {
+ List newContexts = new ArrayList();
+ newContexts.addAll(createdContexts);
+ newContexts.add(new WeakReference(context));
+ createdContexts = newContexts;
+ }
+ return context;
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ protected void swapBuffersImpl() {
+ for (Iterator iter = createdContexts.iterator(); iter.hasNext(); ) {
+ WeakReference ref = (WeakReference) iter.next();
+ MacOSXOnscreenCGLContext ctx = (MacOSXOnscreenCGLContext) ref.get();
+ // FIXME: clear out unreachable contexts
+ if (ctx != null) {
+ ctx.swapBuffers();
+ }
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != NSOPENGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for on-screen GLDrawables");
+ }
+
+ public int getOpenGLMode() {
+ return NSOPENGL_MODE;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java
new file mode 100644
index 000000000..131375338
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -0,0 +1,359 @@
+package com.jogamp.opengl.impl.macosx.cgl;
+
+import java.security.*;
+import java.util.*;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
+ protected MacOSXPbufferCGLDrawable drawable;
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ private static boolean isTigerOrLater;
+
+ static {
+ String osVersion = Debug.getProperty("os.version", false, AccessController.getContext());
+ StringTokenizer tok = new StringTokenizer(osVersion, ". ");
+ int major = Integer.parseInt(tok.nextToken());
+ int minor = Integer.parseInt(tok.nextToken());
+ isTigerOrLater = ((major > 10) || (minor > 3));
+ }
+
+ public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ initOpenGLImpl();
+ }
+
+ public void bindPbufferToTexture() {
+ GL gl = getGL();
+ gl.glBindTexture(textureTarget, texture);
+ // FIXME: not clear whether this is really necessary, but since
+ // the API docs seem to imply it is and since it doesn't seem to
+ // impact performance, leaving it in
+ CGL.setContextTextureImageToPBuffer(nsContext, drawable.getPbuffer(), GL.GL_FRONT);
+ }
+
+ public void releasePbufferFromTexture() {
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getPbuffer() == 0) {
+ if (DEBUG) {
+ System.err.println("Pbuffer not instantiated yet for " + this);
+ }
+ // pbuffer not instantiated yet
+ return CONTEXT_NOT_CURRENT;
+ }
+
+ if (getOpenGLMode() != drawable.getOpenGLMode()) {
+ setOpenGLMode(drawable.getOpenGLMode());
+ }
+
+ boolean created = false;
+ if (nsContext == 0) {
+ if (!create()) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created OpenGL context " + toHexString(nsContext) + " for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!impl.makeCurrent(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+
+ // Initialize render-to-texture support if requested
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ GL gl = getGL();
+ boolean rect = gl.isGL2() && capabilities.getPbufferRenderToTextureRectangle();
+ if (rect) {
+ if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) {
+ System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ }
+ textureTarget = (rect ? GL2.GL_TEXTURE_RECTANGLE : GL.GL_TEXTURE_2D);
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!impl.release(nsContext)) {
+ throw new GLException("Error releasing OpenGL nsContext");
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (nsContext != 0) {
+ if (!impl.destroy(nsContext)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + nsContext);
+ }
+ nsContext = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ if (nsContext == 0) {
+ throw new GLException("OpenGL context not current");
+ }
+ impl.setSwapInterval(nsContext, interval);
+ currentSwapInterval = impl.getSwapInterval() ;
+ }
+
+ public int getFloatingPointMode() {
+ return GLPbuffer.APPLE_FLOAT;
+ }
+
+ protected boolean create() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers() &&
+ !isTigerOrLater) {
+ throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later");
+ }
+ // Change our OpenGL mode to match that of any share context before we create ourselves
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ if (other != null) {
+ setOpenGLMode(other.getOpenGLMode());
+ }
+ // Will throw exception upon error
+ nsContext = impl.create();
+
+ if (!impl.makeCurrent(nsContext)) {
+ throw new GLException("Error making nsContext current");
+ }
+ setGLFunctionAvailability(true);
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+ // OpenGL "mode switching" functionality
+ //
+ private boolean haveSetOpenGLMode = false;
+ // FIXME: should consider switching the default mode based on
+ // whether the Java2D/JOGL bridge is active -- need to ask ourselves
+ // whether it's more likely that we will share with a GLCanvas or a
+ // GLJPanel when the bridge is turned on
+ private int openGLMode = MacOSXCGLDrawable.NSOPENGL_MODE;
+ // Implementation object (either NSOpenGL-based or CGL-based)
+ protected Impl impl;
+
+ public void setOpenGLMode(int mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
+ }
+ destroyImpl();
+ drawable.setOpenGLMode(mode);
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ if (DEBUG) {
+ System.err.println("Switching PBuffer context mode to " +
+ ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE"));
+ }
+ initOpenGLImpl();
+ }
+
+ public int getOpenGLMode() {
+ return openGLMode;
+ }
+
+ private void initOpenGLImpl() {
+ switch (openGLMode) {
+ case MacOSXCGLDrawable.NSOPENGL_MODE:
+ impl = new NSOpenGLImpl();
+ break;
+ case MacOSXCGLDrawable.CGL_MODE:
+ impl = new CGLImpl();
+ break;
+ default:
+ throw new InternalError("Illegal implementation mode " + openGLMode);
+ }
+ }
+
+ // Abstract interface for implementation of this context (either
+ // NSOpenGL-based or CGL-based)
+ interface Impl {
+ public long create();
+ public boolean destroy(long ctx);
+ public boolean makeCurrent(long ctx);
+ public boolean release(long ctx);
+ public void setSwapInterval(long ctx, int interval);
+ public int getSwapInterval();
+ }
+
+ // NSOpenGLContext-based implementation
+ class NSOpenGLImpl implements Impl {
+ public long create() {
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers() &&
+ !isTigerOrLater) {
+ throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later");
+ }
+ if (!MacOSXPbufferCGLContext.this.create(true, capabilities.getPbufferFloatingPointBuffers())) {
+ throw new GLException("Error creating context for pbuffer");
+ }
+ // Must now associate the pbuffer with our newly-created context
+ CGL.setContextPBuffer(nsContext, drawable.getPbuffer());
+ return nsContext;
+ }
+
+ public boolean destroy(long ctx) {
+ return CGL.deleteContext(ctx);
+ }
+
+ public boolean makeCurrent(long ctx) {
+ return CGL.makeCurrentContext(ctx);
+ }
+
+ public boolean release(long ctx) {
+ return CGL.clearCurrentContext(ctx);
+ }
+
+ private int currentSwapInterval = 0 ;
+
+ public void setSwapInterval(long ctx, int interval) {
+ CGL.setSwapInterval(ctx, interval);
+ currentSwapInterval = interval ;
+ }
+ public int getSwapInterval() {
+ return currentSwapInterval;
+ }
+ }
+
+ class CGLImpl implements Impl {
+ public long create() {
+ // Find and configure share context
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(MacOSXPbufferCGLContext.this);
+ long share = 0;
+ if (other != null) {
+ // Reconfigure pbuffer-based GLContexts
+ if (other instanceof MacOSXPbufferCGLContext) {
+ MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other;
+ ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE);
+ } else {
+ if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) {
+ throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs");
+ }
+ }
+ share = other.getNSContext();
+ // Note we don't check for a 0 return value, since switching
+ // the context's mode causes it to be destroyed and not
+ // re-initialized until the next makeCurrent
+ }
+
+ // Set up pixel format attributes
+ // FIXME: shall go into MacOSXCGLGraphicsConfiguration
+ int[] attrs = new int[256];
+ int i = 0;
+ attrs[i++] = CGL.kCGLPFAPBuffer;
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ if (capabilities.getPbufferFloatingPointBuffers())
+ attrs[i++] = CGL.kCGLPFAColorFloat;
+ if (capabilities.getDoubleBuffered())
+ attrs[i++] = CGL.kCGLPFADoubleBuffer;
+ if (capabilities.getStereo())
+ attrs[i++] = CGL.kCGLPFAStereo;
+ attrs[i++] = CGL.kCGLPFAColorSize;
+ attrs[i++] = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits());
+ attrs[i++] = CGL.kCGLPFAAlphaSize;
+ attrs[i++] = capabilities.getAlphaBits();
+ attrs[i++] = CGL.kCGLPFADepthSize;
+ attrs[i++] = capabilities.getDepthBits();
+ // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m
+ attrs[i++] = CGL.kCGLPFAStencilSize;
+ attrs[i++] = capabilities.getStencilBits();
+ attrs[i++] = CGL.kCGLPFAAccumSize;
+ attrs[i++] = (capabilities.getAccumRedBits() +
+ capabilities.getAccumGreenBits() +
+ capabilities.getAccumBlueBits() +
+ capabilities.getAccumAlphaBits());
+ if (capabilities.getSampleBuffers()) {
+ attrs[i++] = CGL.kCGLPFASampleBuffers;
+ attrs[i++] = 1;
+ attrs[i++] = CGL.kCGLPFASamples;
+ attrs[i++] = capabilities.getNumSamples();
+ }
+
+ // Use attribute array to select pixel format
+ long[] fmt = new long[1];
+ long[] numScreens = new long[1];
+ int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, 0, numScreens, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while choosing pixel format");
+ }
+
+ // Create new context
+ long[] ctx = new long[1];
+ if (DEBUG) {
+ System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ }
+ res = CGL.CGLCreateContext(fmt[0], share, ctx, 0);
+ CGL.CGLDestroyPixelFormat(fmt[0]);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while creating context");
+ }
+ // Attach newly-created context to the pbuffer
+ res = CGL.CGLSetPBuffer(ctx[0], drawable.getPbuffer(), 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ }
+ return ctx[0];
+ }
+
+ public boolean destroy(long ctx) {
+ return (CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError);
+ }
+
+ public boolean makeCurrent(long ctx) {
+ return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError;
+ }
+
+ public boolean release(long ctx) {
+ return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError);
+ }
+
+ public void setSwapInterval(long ctx, int interval) {
+ // For now not supported (not really relevant for off-screen contexts anyway)
+ }
+ public int getSwapInterval() {
+ return 0;
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java
new file mode 100644
index 000000000..eb6de929d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -0,0 +1,250 @@
+/*
+ * 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.macosx.cgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
+ private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable");
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ // NSOpenGLPbuffer (for normal mode)
+ // CGLPbufferObj (for CGL_MODE situation, i.e., when Java2D/JOGL bridge is active)
+ // Note that we can not store this in the NativeWindow because the
+ // semantic is that contains an NSView
+ protected long pBuffer;
+
+ public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ initOpenGLImpl();
+ createPbuffer();
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ createPbuffer();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new MacOSXPbufferCGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ if (this.pBuffer != 0) {
+ NativeWindow nw = getNativeWindow();
+ impl.destroy(pBuffer);
+ this.pBuffer = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ if (DEBUG) {
+ System.err.println("Destroyed pbuffer: " + pBuffer);
+ }
+ }
+ }
+
+ public long getPbuffer() {
+ return pBuffer;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+ private void createPbuffer() {
+ NativeWindow nw = getNativeWindow();
+ DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+ GLProfile glProfile = capabilities.getGLProfile();
+ int renderTarget;
+ if (glProfile.isGL2() && capabilities.getPbufferRenderToTextureRectangle()) {
+ renderTarget = GL2.GL_TEXTURE_RECTANGLE;
+ } else {
+ int w = getNextPowerOf2(getWidth());
+ int h = getNextPowerOf2(getHeight());
+ ((SurfaceChangeable)nw).setSize(w, h);
+ renderTarget = GL.GL_TEXTURE_2D;
+ }
+
+ int internalFormat = GL.GL_RGBA;
+ if (capabilities.getPbufferFloatingPointBuffers()) {
+ // FIXME: want to check availability of GL_APPLE_float_pixels
+ // extension, but need valid OpenGL context in order to do so --
+ // in worst case would need to create dummy window / GLCanvas
+ // (undesirable) -- could maybe also do this with pbuffers
+ /*
+ if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) {
+ throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
+ }
+ */
+ if(glProfile.isGL2()) {
+ switch (capabilities.getRedBits()) {
+ case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break;
+ case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break;
+ default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)");
+ }
+ } else {
+ internalFormat = GL.GL_RGBA;
+ }
+ }
+
+ pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight());
+ if (pBuffer == 0) {
+ throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
+ }
+
+ ((SurfaceChangeable)nw).setSurfaceHandle(pBuffer);
+
+ }
+
+ private int getNextPowerOf2(int number) {
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
+
+ //---------------------------------------------------------------------------
+ // OpenGL "mode switching" functionality
+ //
+ private boolean haveSetOpenGLMode = false;
+ // FIXME: should consider switching the default mode based on
+ // whether the Java2D/JOGL bridge is active -- need to ask ourselves
+ // whether it's more likely that we will share with a GLCanvas or a
+ // GLJPanel when the bridge is turned on
+ private int openGLMode = NSOPENGL_MODE;
+ // Implementation object (either NSOpenGL-based or CGL-based)
+ protected Impl impl;
+
+ public void setOpenGLMode(int mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
+ }
+ destroy();
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ if (DEBUG) {
+ System.err.println("Switching PBuffer drawable mode to " +
+ ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE"));
+ }
+ initOpenGLImpl();
+ createPbuffer();
+ }
+
+ public int getOpenGLMode() {
+ return openGLMode;
+ }
+
+ private void initOpenGLImpl() {
+ switch (openGLMode) {
+ case NSOPENGL_MODE:
+ impl = new NSOpenGLImpl();
+ break;
+ case CGL_MODE:
+ impl = new CGLImpl();
+ break;
+ default:
+ throw new InternalError("Illegal implementation mode " + openGLMode);
+ }
+ }
+
+ // Abstract interface for implementation of this drawable (either
+ // NSOpenGL-based or CGL-based)
+ interface Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height);
+ public void destroy(long pbuffer);
+ }
+
+ // NSOpenGLPixelBuffer implementation
+ class NSOpenGLImpl implements Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height) {
+ return CGL.createPBuffer(renderTarget, internalFormat, width, height);
+ }
+
+ public void destroy(long pbuffer) {
+ CGL.destroyPBuffer(pbuffer);
+ }
+ }
+
+ // CGL implementation
+ class CGLImpl implements Impl {
+ public long create(int renderTarget, int internalFormat, int width, int height) {
+ long[] pbuffer = new long[1];
+ int res = CGL.CGLCreatePBuffer(width, height, renderTarget, internalFormat, 0, pbuffer, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error creating CGL-based pbuffer: error code " + res);
+ }
+ return pbuffer[0];
+ }
+
+ public void destroy(long pbuffer) {
+ int res = CGL.CGLDestroyPBuffer(pbuffer);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error destroying CGL-based pbuffer: error code " + res);
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
new file mode 100644
index 000000000..cc973c56a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLDrawableFactory.java
@@ -0,0 +1,64 @@
+/*
+ * 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.macosx.cgl.awt;
+
+import java.lang.reflect.InvocationTargetException;
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.awt.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+public class MacOSXAWTCGLDrawableFactory extends MacOSXCGLDrawableFactory {
+
+ public MacOSXAWTCGLDrawableFactory() {
+ super();
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return true;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ return new MacOSXJava2DCGLContext(shareWith);
+ }
+}
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
new file mode 100644
index 000000000..97d5e8d68
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.macosx.cgl.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+import com.sun.nativewindow.impl.jawt.*;
+import com.sun.nativewindow.impl.jawt.macosx.*;
+
+public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public MacOSXAWTCGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("MacOSXAWTCGLGraphicsConfigurationFactory: got "+absScreen);
+ }
+
+ long displayHandle = 0;
+
+ MacOSXGraphicsDevice macDevice = new MacOSXGraphicsDevice();
+ DefaultGraphicsScreen macScreen = new DefaultGraphicsScreen(macDevice, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("MacOSXAWTCGLGraphicsConfigurationFactory: made "+macScreen);
+ }
+
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ MacOSXCGLGraphicsConfiguration macConfig = (MacOSXCGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(macDevice).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ macScreen);
+
+ if (macConfig == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+macScreen);
+ }
+
+ // FIXME: we have nothing to match .. so choose the default
+ return new AWTGraphicsConfiguration(awtScreen, macConfig.getChosenCapabilities(), macConfig.getRequestedCapabilities(), gc, macConfig);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
new file mode 100644
index 000000000..9010d4461
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2006 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.macosx.cgl.awt;
+
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+import java.awt.Graphics;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.awt.*;
+import com.jogamp.opengl.impl.macosx.cgl.*;
+
+/** MacOSXCGLContext implementation supporting the Java2D/JOGL bridge
+ * on Mac OS X. The external GLDrawable mechanism does not work on Mac
+ * OS X due to how drawables and contexts are operated upon on this
+ * platform, so it is necessary to supply an alternative means to
+ * create, make current, and destroy contexts on the Java2D "drawable"
+ * on the Mac platform.
+ */
+
+public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGLContext {
+ private Graphics graphics;
+
+ // FIXME: ignoring context sharing for the time being; will need to
+ // rethink this in particular if using FBOs to implement the
+ // Java2D/OpenGL pipeline on Mac OS X
+
+ public MacOSXJava2DCGLContext(GLContext shareWith) {
+ super(null, shareWith);
+ }
+
+ public void setGraphics(Graphics g) {
+ this.graphics = g;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ boolean created = false;
+ if (nsContext == 0) {
+ if (!create()) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (DEBUG) {
+ System.err.println("!!! Created GL nsContext for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!Java2D.makeOGLContextCurrentOnSurface(graphics, nsContext)) {
+ throw new GLException("Error making context current");
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected boolean create() {
+ // Find and configure share context
+ MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ // Reconfigure pbuffer-based GLContexts
+ if (other instanceof MacOSXPbufferCGLContext) {
+ MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other;
+ ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE);
+ } else {
+ if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) {
+ throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs");
+ }
+ }
+ share = other.getNSContext();
+ // Note we don't check for a 0 return value, since switching
+ // the context's mode causes it to be destroyed and not
+ // re-initialized until the next makeCurrent
+ }
+
+ if (DEBUG) {
+ System.err.println("!!! Share context is " + toHexString(share) + " for " + getClass().getName());
+ }
+
+ long ctx = Java2D.createOGLContextOnSurface(graphics, share);
+ if (ctx == 0) {
+ return false;
+ }
+ // FIXME: think about GLContext sharing
+ nsContext = ctx;
+ return true;
+ }
+
+ protected void releaseImpl() throws GLException {
+ // FIXME: would need another primitive in the Java2D class in
+ // order to implement this; hopefully should not matter for
+ // correctness
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (nsContext != 0) {
+ Java2D.destroyOGLContext(nsContext);
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + nsContext);
+ }
+ nsContext = 0;
+ // FIXME
+ // GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public void setOpenGLMode(int mode) {
+ if (mode != MacOSXCGLDrawable.CGL_MODE)
+ throw new GLException("OpenGL mode switching not supported for Java2D GLContexts");
+ }
+
+ public int getOpenGLMode() {
+ return MacOSXCGLDrawable.CGL_MODE;
+ }
+}
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
new file mode 100644
index 000000000..89a25fe9a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -0,0 +1,101 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
+ private long hwnd, hdc;
+
+ public WindowsDummyWGLDrawable(GLDrawableFactory factory) {
+ super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(null, true, true)), true);
+ // All entries to CreateDummyWindow must synchronize on one object
+ // to avoid accidentally registering the dummy window class twice
+ synchronized (WindowsDummyWGLDrawable.class) {
+ hwnd = WGL.CreateDummyWindow(0, 0, 1, 1);
+ }
+ hdc = WGL.GetDC(hwnd);
+ NullWindow nw = (NullWindow) getNativeWindow();
+ nw.setSurfaceHandle(hdc);
+ // Choose a (hopefully hardware-accelerated) OpenGL pixel format for this device context
+ GLCapabilities caps = new GLCapabilities(null);
+ caps.setDepthBits(16);
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps);
+ int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if ((pixelFormat == 0) ||
+ (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) {
+ destroy();
+ }
+ }
+
+ public void setSize(int width, int height) {
+ }
+
+ public int getWidth() {
+ return 1;
+ }
+
+ public int getHeight() {
+ return 1;
+ }
+
+ 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);
+ }
+
+ public void destroy() {
+ if (hdc != 0) {
+ WGL.ReleaseDC(hwnd, hdc);
+ hdc = 0;
+ }
+ if (hwnd != 0) {
+ WGL.ShowWindow(hwnd, WGL.SW_HIDE);
+ WGL.DestroyWindow(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
new file mode 100755
index 000000000..25691ab91
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
@@ -0,0 +1,146 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class WindowsExternalWGLContext extends WindowsWGLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private WindowsExternalWGLContext(Drawable drawable, long hglrc, WindowsWGLGraphicsConfiguration cfg) {
+ super(drawable, null);
+ this.context = hglrc;
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this);
+ }
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false);
+ cfg.updateCapabilitiesByWGL(this);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static WindowsExternalWGLContext create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ long hglrc = WGL.wglGetCurrentContext();
+ if (hglrc == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a context current");
+ }
+ int pfdID = WGL.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat");
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(hdc);
+
+ return new WindowsExternalWGLContext(new Drawable(factory, nw), hglrc, cfg);
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends WindowsWGLDrawable {
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+ }
+}
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
new file mode 100755
index 000000000..f5b89842d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -0,0 +1,90 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
+
+ private WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, true);
+ }
+
+ protected static WindowsExternalWGLDrawable create(GLDrawableFactory factory, GLProfile glp) {
+ long hdc = WGL.wglGetCurrentDC();
+ if (0==hdc) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ int pfdID = WGL.GetPixelFormat(hdc);
+ if (pfdID == 0) {
+ throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat");
+ }
+
+ AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault();
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(hdc);
+
+ cfg.updateGraphicsConfiguration(factory, nw);
+
+ return new WindowsExternalWGLDrawable(factory, nw);
+ }
+
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsWGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
new file mode 100644
index 000000000..25d93b50e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOffscreenWGLContext extends WindowsWGLContext {
+ public WindowsOffscreenWGLContext(WindowsOffscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ return GL.GL_UNSIGNED_BYTE;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ // On Windows these contexts are always single-buffered
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // We can take care of this in the DIB creation (see below)
+ return false;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
new file mode 100644
index 000000000..88bfb3b1c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java
@@ -0,0 +1,139 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable {
+ private long origbitmap;
+ private long hbitmap;
+
+ public WindowsOffscreenWGLDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+ create();
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ create();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOffscreenWGLContext(this, shareWith);
+ }
+
+ private void create() {
+ NativeWindow nw = getNativeWindow();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getRequestedCapabilities();
+ int width = getWidth();
+ int height = getHeight();
+ BITMAPINFO info = BITMAPINFO.create();
+ BITMAPINFOHEADER header = info.getBmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits() +
+ capabilities.getAlphaBits());
+ header.setBiSize(header.size());
+ header.setBiWidth(width);
+ // NOTE: negating the height causes the DIB to be in top-down row
+ // order rather than bottom-up; ends up being correct during pixel
+ // readback
+ header.setBiHeight(-1 * height);
+ header.setBiPlanes((short) 1);
+ header.setBiBitCount((short) bitsPerPixel);
+ header.setBiXPelsPerMeter(0);
+ header.setBiYPelsPerMeter(0);
+ header.setBiClrUsed(0);
+ header.setBiClrImportant(0);
+ header.setBiCompression(WGL.BI_RGB);
+ header.setBiSizeImage(width * height * bitsPerPixel / 8);
+
+ long hdc = WGL.CreateCompatibleDC(0);
+ if (hdc == 0) {
+ System.out.println("LastError: " + WGL.GetLastError());
+ throw new GLException("Error creating device context for offscreen OpenGL context");
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(hdc);
+
+ hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0);
+ if (hbitmap == 0) {
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error creating offscreen bitmap of width " + width +
+ ", height " + height);
+ }
+ if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
+ WGL.DeleteObject(hbitmap);
+ hbitmap = 0;
+ WGL.DeleteDC(hdc);
+ hdc = 0;
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ config.updateGraphicsConfiguration(getFactory(), nw);
+ }
+
+ public void destroy() {
+ NativeWindow nw = getNativeWindow();
+ if (nw.getSurfaceHandle() != 0) {
+ // Must destroy bitmap and device context
+ WGL.SelectObject(nw.getSurfaceHandle(), origbitmap);
+ WGL.DeleteObject(hbitmap);
+ WGL.DeleteDC(nw.getSurfaceHandle());
+ origbitmap = 0;
+ hbitmap = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
new file mode 100644
index 000000000..aeb13110e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLContext.java
@@ -0,0 +1,88 @@
+/*
+ * 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.windows.wgl;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLContext extends WindowsWGLContext {
+ protected WindowsOnscreenWGLDrawable drawable;
+
+ public WindowsOnscreenWGLContext(WindowsOnscreenWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ int ret = super.makeCurrentImpl();
+ return ret;
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
new file mode 100644
index 000000000..401b8c3c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java
@@ -0,0 +1,63 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable {
+ protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsOnscreenWGLContext(this, shareWith);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
new file mode 100644
index 000000000..b0524bcd9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLContext.java
@@ -0,0 +1,155 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsPbufferWGLContext extends WindowsWGLContext {
+ private static final boolean DEBUG = Debug.debug("WindowsPbufferWGLContext");
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private WindowsPbufferWGLDrawable drawable;
+ private boolean rtt; // render-to-texture?
+ private boolean hasRTT; // render-to-texture extension available?
+ private boolean rect; // render-to-texture-rectangle?
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ public WindowsPbufferWGLContext(WindowsPbufferWGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public void bindPbufferToTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ GL gl = getGL();
+ WGLExt wglExt = getWGLExt();
+ gl.glBindTexture(textureTarget, texture);
+ if (rtt && hasRTT) {
+ if (!wglExt.wglBindTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError());
+ }
+ }
+ // FIXME: comment is wrong now
+ // Note that if the render-to-texture extension is not supported,
+ // we perform a glCopyTexImage2D in swapBuffers().
+ }
+
+ public void releasePbufferFromTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ if (rtt && hasRTT) {
+ WGLExt wglExt = getWGLExt();
+ if (!wglExt.wglReleaseTexImageARB(drawable.getPbuffer(), WGLExt.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
+ }
+ }
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ int res = super.makeCurrentImpl();
+ if (DEBUG && VERBOSE) {
+ System.err.println("WindowsPbufferWGLContext: super.makeCurrentImpl() = " + res);
+ }
+ if (res == CONTEXT_CURRENT_NEW) {
+ GLCapabilities capabilities = drawable.getChosenGLCapabilities();
+
+ // Initialize render-to-texture support if requested
+ GL gl = getGL();
+ rtt = capabilities.getPbufferRenderToTexture();
+ rect = gl.isGL2() && capabilities.getPbufferRenderToTextureRectangle();
+
+ if (rtt) {
+ if (DEBUG) {
+ System.err.println("Initializing render-to-texture support");
+ }
+
+ if (!gl.isExtensionAvailable("WGL_ARB_render_texture")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: WGL_ARB_render_texture extension not " +
+ "supported; implementing render_to_texture support using slow texture readback");
+ } else {
+ hasRTT = true;
+
+ if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ if (rect) {
+ if (DEBUG) {
+ System.err.println(" Using render-to-texture-rectangle");
+ }
+ textureTarget = GL2.GL_TEXTURE_RECTANGLE_ARB;
+ } else {
+ if (DEBUG) {
+ System.err.println(" Using vanilla render-to-texture");
+ }
+ textureTarget = GL.GL_TEXTURE_2D;
+ }
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp, 0);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+ }
+ }
+ }
+ return res;
+ }
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
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
new file mode 100644
index 000000000..c7034e93b
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -0,0 +1,330 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+
+public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
+ private long cachedParentHdc;
+ private WGLExt cachedWGLExt; // cached WGLExt instance from parent GLCanvas,
+ // needed to destroy pbuffer
+ private long buffer; // pbuffer handle
+
+ private int floatMode;
+
+ public WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeWindow target,
+ WindowsWGLDrawable dummyDrawable,
+ WGLExt wglExt) {
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ createPbuffer(dummyDrawable.getNativeWindow().getSurfaceHandle(), wglExt);
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ throw new GLException("Recreation via setRealized not supported.");
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new WindowsPbufferWGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ NativeWindow nw = getNativeWindow();
+ if(0!=buffer) {
+ WGLExt wglExt = cachedWGLExt;
+ if (nw.getSurfaceHandle() != 0) {
+ // Must release DC and pbuffer
+ // NOTE that since the context is not current, glGetError() can
+ // not be called here, so we skip the use of any composable
+ // pipelines (see WindowsOnscreenWGLContext.makeCurrentImpl)
+ if (wglExt.wglReleasePbufferDCARB(buffer, nw.getSurfaceHandle()) == 0) {
+ throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError());
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ }
+ if (!wglExt.wglDestroyPbufferARB(buffer)) {
+ throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError());
+ }
+ buffer = 0;
+ }
+ }
+
+ public long getPbuffer() {
+ return buffer;
+ }
+
+ public int getFloatingPointMode() {
+ return floatMode;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+
+ private void createPbuffer(long parentHdc, WGLExt wglExt) {
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int[] floatModeTmp = new int[1];
+ int niattribs = 0;
+ int width, height;
+
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities)config.getRequestedCapabilities();
+ GLProfile glProfile = capabilities.getGLProfile();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
+ System.out.println("Pbuffer caps: " + capabilities);
+ }
+
+ if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes,
+ wglExt,
+ true,
+ floatModeTmp)){
+ throw new GLException("Pbuffer-related extensions not supported");
+ }
+
+ floatMode = floatModeTmp[0];
+ boolean rtt = capabilities.getPbufferRenderToTexture();
+ boolean rect = capabilities.getPbufferRenderToTextureRectangle();
+ boolean useFloat = capabilities.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+
+ if (useFloat) {
+ ati = (floatMode == GLPbuffer.ATI_FLOAT);
+ }
+
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!wglExt.wglChoosePixelFormatARB(parentHdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ boolean haveMultisample = wglExt.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();
+ }
+ }
+
+ 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;
+ }
+
+ 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_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ 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());
+ }
+
+ // Get the device context.
+ long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDC() failed");
+ }
+
+ NativeWindow nw = getNativeWindow();
+ // Set up instance variables
+ buffer = tmpBuffer;
+ ((SurfaceChangeable)nw).setSurfaceHandle(tmpHdc);
+ cachedWGLExt = wglExt;
+ cachedParentHdc = parentHdc;
+
+ // 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)) {
+ GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, true, false, true);
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ if (WGL.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);
+ }
+ }
+ if(newCaps.isOnscreen()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps);
+ }
+ config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true);
+ } else {
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) {
+ throw new GLException("Unable to describe pixel format " + pformats[whichFormat]);
+ }
+ GLCapabilities 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);
+ }
+ }
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
+ width = tmp[0];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
+ height = tmp[0];
+ ((SurfaceChangeable)nw).setSize(width, height);
+ }
+
+ private static String wglGetLastError() {
+ return WindowsWGLDrawableFactory.wglGetLastError();
+ }
+}
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
new file mode 100644
index 000000000..08c77539c
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
@@ -0,0 +1,439 @@
+/*
+ * 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.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public class WindowsWGLContext extends GLContextImpl {
+ protected long hglrc;
+ private boolean wglGetExtensionsStringEXTInitialized;
+ private boolean wglGetExtensionsStringEXTAvailable;
+ private boolean wglMakeContextCurrentInitialized;
+ private boolean wglMakeContextCurrentARBAvailable;
+ private boolean wglMakeContextCurrentEXTAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
+ private WGLExt wglExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // WGL extension functions.
+ private WGLExtProcAddressTable wglExtProcAddressTable;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
+
+ extensionNameMap = new HashMap();
+ extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
+ extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+ }
+
+ // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
+ public WindowsWGLContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public WindowsWGLContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getWGLExt();
+ }
+
+ public WGLExt getWGLExt() {
+ if (wglExt == null) {
+ wglExt = new WGLExtImpl(this);
+ }
+ return wglExt;
+ }
+
+ public boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long hglrc) {
+ WGLExt wglExt = getWGLExt();
+ if (!wglMakeContextCurrentInitialized) {
+ wglMakeContextCurrentARBAvailable = isFunctionAvailable("wglMakeContextCurrentARB");
+ wglMakeContextCurrentEXTAvailable = isFunctionAvailable("wglMakeContextCurrentEXT");
+ wglMakeContextCurrentInitialized = true;
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.wglMakeContextCurrent: ARB "+wglMakeContextCurrentARBAvailable+", EXT "+wglMakeContextCurrentEXTAvailable);
+ }
+ }
+ if(wglMakeContextCurrentARBAvailable) {
+ return wglExt.wglMakeContextCurrentARB(hDrawDC, hReadDC, hglrc);
+ } else if(wglMakeContextCurrentEXTAvailable) {
+ return wglExt.wglMakeContextCurrentEXT(hDrawDC, hReadDC, hglrc);
+ }
+ return WGL.wglMakeCurrent(hDrawDC, hglrc);
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getWGLExtProcAddressTable();
+ }
+
+ public final WGLExtProcAddressTable getWGLExtProcAddressTable() {
+ return wglExtProcAddressTable;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ String lookup = (String) extensionNameMap.get(glExtensionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glExtensionName;
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link #makeCurrentImpl()}.
+ */
+ protected void create() {
+ GLCapabilities glCaps = drawable.getChosenGLCapabilities();
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.create got "+glCaps);
+ }
+
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ throw new GLException("Internal error: attempted to create OpenGL context without an associated drawable");
+ }
+ // Windows can set up sharing of display lists after creation time
+ WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
+ long hglrc2 = 0;
+ if (other != null) {
+ hglrc2 = other.getHGLRC();
+ if (hglrc2 == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+
+ // To use WGL_ARB_create_context, we have to make a temp context current,
+ // so we are able to use GetProcAddress
+ long temp_hglrc = WGL.wglCreateContext(drawable.getNativeWindow().getSurfaceHandle());
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created temp OpenGL context " + toHexString(temp_hglrc) + " for " + this + ", device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + ", not yet sharing");
+ }
+ if (temp_hglrc == 0) {
+ throw new GLException("Unable to create temp OpenGL context for device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle()));
+ } else {
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), temp_hglrc)) {
+ throw new GLException("Error making temp context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ setGLFunctionAvailability(true);
+
+ if( !isFunctionAvailable("wglCreateContextAttribsARB") ||
+ !isExtensionAvailable("WGL_ARB_create_context") ) {
+ if(glCaps.getGLProfile().isGL3()) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (no WGL_ARB_create_context)");
+ }
+
+ // continue with temp context for GL < 3.0
+ hglrc = temp_hglrc;
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.create done (old ctx < 3.0 - no WGL_ARB_create_context) 0x"+Long.toHexString(hglrc));
+ }
+ } else {
+ WGLExt wglExt = getWGLExt();
+
+ // preset with default values
+ int attribs[] = {
+ /* 0 */ WGLExt.WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+ /* 2 */ WGLExt.WGL_CONTEXT_MINOR_VERSION_ARB, 0,
+ /* 4 */ WGLExt.WGL_CONTEXT_FLAGS_ARB, 0 /* WGLExt.WGL_CONTEXT_DEBUG_BIT_ARB */,
+ /* 6 */ 0, 0,
+ /* 8 */ 0
+ };
+
+ if(glCaps.getGLProfile().isGL3()) {
+ // Try >= 3.2 core first !
+ // In contrast to GLX no verify with a None drawable binding (default framebuffer) is necessary,
+ // if no 3.2 is available creation fails already!
+ attribs[0+1] = 3;
+ attribs[2+1] = 2;
+ if(glCaps.getGLProfile().isGL3bc()) {
+ attribs[6+0] = WGLExt.WGL_CONTEXT_PROFILE_MASK_ARB;
+ attribs[6+1] = WGLExt.WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ }
+ /**
+ * don't stricten requirements any further, even compatible would be fine
+ *
+ } else {
+ attribs[6+0] = WGLExt.WGL_CONTEXT_PROFILE_MASK_ARB;
+ attribs[6+1] = WGLExt.WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ */
+ hglrc = wglExt.wglCreateContextAttribsARB(drawable.getNativeWindow().getSurfaceHandle(), hglrc2, attribs, 0);
+ if(0==hglrc) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContext couldn't create >= 3.2 core context - fallback");
+ }
+ // Try >= 3.1 forward compatible - last resort for GL3 !
+ attribs[0+1] = 3;
+ attribs[2+1] = 1;
+ if(!glCaps.getGLProfile().isGL3bc()) {
+ attribs[4+1] |= WGLExt.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ attribs[6+0] = 0;
+ attribs[6+1] = 0;
+ } else if(DEBUG) {
+ System.err.println("WindowsWGLContext.createContext >= 3.2 available 0x"+Long.toHexString(hglrc));
+ }
+ }
+ if(0==hglrc) {
+ // 3.1 or 3.0 ..
+ hglrc = wglExt.wglCreateContextAttribsARB(drawable.getNativeWindow().getSurfaceHandle(), hglrc2, attribs, 0);
+ if(DEBUG) {
+ if(0==hglrc) {
+ System.err.println("WindowsWGLContext.createContext couldn't create >= 3.0 context - fallback");
+ } else {
+ System.err.println("WindowsWGLContext.createContext >= 3.0 available 0x"+Long.toHexString(hglrc));
+ }
+ }
+ }
+
+ if(0==hglrc) {
+ if(glCaps.getGLProfile().isGL3()) {
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (have WGL_ARB_create_context)");
+ }
+
+ // continue with temp context for GL < 3.0
+ hglrc = temp_hglrc;
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ throw new GLException("Error making old context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ updateGLProcAddressTable();
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.create done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(hglrc));
+ }
+ } else {
+ hglrc2 = 0; // mark as shared ..
+ WGL.wglMakeCurrent(0, 0);
+ WGL.wglDeleteContext(temp_hglrc);
+
+ if (!WGL.wglMakeCurrent(drawable.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ throw new GLException("Error making new context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ updateGLProcAddressTable();
+ if(DEBUG) {
+ System.err.println("WindowsWGLContext.create done (new ctx >= 3.0) 0x"+Long.toHexString(hglrc));
+ }
+ }
+ }
+ }
+ if(0!=hglrc2) {
+ if (!WGL.wglShareLists(hglrc2, hglrc)) {
+ throw new GLException("wglShareLists(" + toHexString(hglrc2) +
+ ", " + toHexString(hglrc) + ") failed: error code 0x" +
+ Integer.toHexString(WGL.GetLastError()));
+ }
+ }
+ GLContextShareSet.contextCreated(this);
+ WGL.wglMakeCurrent(0, 0); // release immediatly to gain from ARB/EXT wglMakeContextCurrent(draw, read, ctx)!
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created OpenGL context " + toHexString(hglrc) + " for " + this + ", device context " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + ", sharing with " + toHexString(hglrc2));
+ }
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ if (DEBUG) {
+ System.err.println("drawable not properly initialized");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+ boolean created = false;
+ if (hglrc == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (WGL.wglGetCurrentContext() != hglrc) {
+ if (!wglMakeContextCurrent(drawable.getNativeWindow().getSurfaceHandle(), drawableRead.getNativeWindow().getSurfaceHandle(), hglrc)) {
+ throw new GLException("Error making context current: 0x" + Integer.toHexString(WGL.GetLastError()));
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
+ ", hglrc " + toHexString(hglrc) + ") succeeded");
+ }
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+
+ WindowsWGLGraphicsConfiguration config =
+ (WindowsWGLGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateCapabilitiesByWGL(this);
+
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!wglMakeContextCurrent(0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context: 0x" + Integer.toHexString(WGL.GetLastError()));
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ if (DEBUG) {
+ Exception e = new Exception(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(hglrc));
+ e.printStackTrace();
+ }
+ if (hglrc != 0) {
+ if (!WGL.wglDeleteContext(hglrc)) {
+ throw new GLException("Unable to delete OpenGL context");
+ }
+ hglrc = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ }
+
+ public boolean isCreated() {
+ return (hglrc != 0);
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getHGLRC();
+ long src = ((WindowsWGLContext) source).getHGLRC();
+ if (src == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+ if (!WGL.wglCopyContext(src, dst, mask)) {
+ throw new GLException("wglCopyContext failed");
+ }
+ }
+
+ protected void updateGLProcAddressTable() {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this);
+ }
+ wglGetExtensionsStringEXTInitialized=false;
+ wglGetExtensionsStringEXTAvailable=false;
+ wglMakeContextCurrentInitialized=false;
+ wglMakeContextCurrentARBAvailable=false;
+ wglMakeContextCurrentEXTAvailable=false;
+
+ if (wglExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ wglExtProcAddressTable = new WGLExtProcAddressTable();
+ }
+ resetProcAddressTable(getWGLExtProcAddressTable());
+ super.updateGLProcAddressTable();
+ }
+
+ public String getPlatformExtensionsString() {
+ if (!wglGetExtensionsStringEXTInitialized) {
+ wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0);
+ wglGetExtensionsStringEXTInitialized = true;
+ }
+ if (wglGetExtensionsStringEXTAvailable) {
+ return getWGLExt().wglGetExtensionsStringEXT();
+ } else {
+ return "";
+ }
+ }
+
+ protected void setSwapIntervalImpl(int interval) {
+ WGLExt wglExt = getWGLExt();
+ if (wglExt.isExtensionAvailable("WGL_EXT_swap_control")) {
+ if ( wglExt.wglSwapIntervalEXT(interval) ) {
+ currentSwapInterval = interval ;
+ }
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getWGLExt().wglAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getHGLRC() {
+ return hglrc;
+ }
+}
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
new file mode 100644
index 000000000..c76766b2e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
@@ -0,0 +1,129 @@
+/*
+ * 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.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+public abstract class WindowsWGLDrawable extends GLDrawableImpl {
+ private static final int MAX_SET_PIXEL_FORMAT_FAIL_COUNT = 5;
+ private static final boolean PROFILING = Debug.debug("WindowsWGLDrawable.profiling");
+ private static final int PROFILING_TICKS = 200;
+ private int profilingLockSurfaceTicks;
+ private long profilingLockSurfaceTime;
+ private int profilingUnlockSurfaceTicks;
+ private long profilingUnlockSurfaceTime;
+ private int profilingSwapBuffersTicks;
+ private long profilingSwapBuffersTime;
+
+
+ public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ protected void setRealizedImpl() {
+ if(!realized) {
+ return; // nothing todo ..
+ }
+
+ if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) {
+ throw new GLException("WindowsWGLDrawable.setRealized(true): lockSurface - surface not ready");
+ }
+ try {
+ NativeWindow nativeWindow = getNativeWindow();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration(getFactory(), nativeWindow);
+ if (DEBUG) {
+ System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config);
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+
+ try {
+ if ( !isSurfaceLocked() ) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock = true;
+ }
+
+ long startTime = 0;
+ if (PROFILING) {
+ startTime = System.currentTimeMillis();
+ }
+
+ if (!WGL.SwapBuffers(getNativeWindow().getSurfaceHandle()) && (WGL.GetLastError() != 0)) {
+ throw new GLException("Error swapping buffers");
+ }
+
+ if (PROFILING) {
+ long endTime = System.currentTimeMillis();
+ profilingSwapBuffersTime += (endTime - startTime);
+ int ticks = PROFILING_TICKS;
+ if (++profilingSwapBuffersTicks == ticks) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)");
+ profilingSwapBuffersTime = 0;
+ profilingSwapBuffersTicks = 0;
+ }
+ }
+ } finally {
+ if (didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (WindowsWGLDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+}
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
new file mode 100644
index 000000000..38b9bac51
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -0,0 +1,279 @@
+/*
+ * 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.windows.wgl;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NWReflection;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+import com.sun.nativewindow.impl.NullWindow;
+
+public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+ private static final boolean VERBOSE = Debug.verbose();
+
+ // Handle to GLU32.dll
+ // FIXME: this should go away once we delete support for the C GLU library
+ private long hglu32;
+
+ // Handle to core OpenGL32.dll
+ private long hopengl32;
+
+ public WindowsWGLDrawableFactory() {
+ super();
+
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new WindowsWGLGraphicsConfigurationFactory();
+ try {
+ NWReflection.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (Throwable t) { }
+
+ loadOpenGL32Library();
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new WindowsOnscreenWGLDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ return new WindowsOffscreenWGLDrawable(this, target);
+ }
+
+ private boolean pbufferSupportInitialized = false;
+ private boolean canCreateGLPbuffer = false;
+ public boolean canCreateGLPbuffer() {
+ if (!pbufferSupportInitialized) {
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ WindowsDummyWGLDrawable dummyDrawable = new WindowsDummyWGLDrawable(factory);
+ GLContext dummyContext = dummyDrawable.createContext(null);
+ if (dummyContext != null) {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ dummyContext.makeCurrent();
+ GL dummyGL = dummyContext.getGL();
+ canCreateGLPbuffer = dummyGL.isExtensionAvailable("GL_ARB_pbuffer");
+ pbufferSupportInitialized = true;
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ }
+ if (DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.canCreateGLPbuffer() = " + canCreateGLPbuffer);
+ }
+ return canCreateGLPbuffer;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ WindowsDummyWGLDrawable dummyDrawable = new WindowsDummyWGLDrawable(factory);
+ WindowsWGLContext dummyContext = (WindowsWGLContext) dummyDrawable.createContext(null);
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
+ lastContext.release();
+ }
+ dummyContext.makeCurrent();
+ WGLExt dummyWGLExt = dummyContext.getWGLExt();
+ try {
+ GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(factory, target,
+ dummyDrawable,
+ dummyWGLExt);
+ returnList.add(pbufferDrawable);
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ } finally {
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ }
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault();
+ NullWindow nw = new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capabilities, chooser, screen) );
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ return WindowsExternalWGLContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return true;
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ return WindowsExternalWGLDrawable.create(this, null);
+ }
+
+ public void loadOpenGL32Library() {
+ if (hopengl32 == 0) {
+ hopengl32 = WGL.LoadLibraryA("OpenGL32");
+ if (DEBUG) {
+ if (hopengl32 == 0) {
+ System.err.println("WindowsWGLDrawableFactory: Could not load OpenGL32.dll - maybe an embedded device");
+ }
+ }
+ }
+ }
+
+ public void loadGLULibrary() {
+ if (hglu32 == 0) {
+ hglu32 = WGL.LoadLibraryA("GLU32");
+ if (hglu32 == 0) {
+ throw new GLException("Error loading GLU32.DLL");
+ }
+ }
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ long res = WGL.wglGetProcAddress(glFuncName);
+ if (res == 0) {
+ // It may happen that a driver doesn't return the OpenGL32 core function pointer
+ // with wglGetProcAddress (e.g. NVidia GL 3.1) - hence we have to look harder.
+ if (hopengl32 != 0) {
+ res = WGL.GetProcAddress(hopengl32, glFuncName);
+ }
+ }
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ if (hglu32 != 0) {
+ res = WGL.GetProcAddress(hglu32, glFuncName);
+ }
+ }
+ return res;
+ }
+
+ static String wglGetLastError() {
+ long err = WGL.GetLastError();
+ String detail = null;
+ switch ((int) err) {
+ case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ protected int getGammaRampLength() {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ short[] rampData = new short[3 * GAMMA_RAMP_LENGTH];
+ for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) {
+ short scaledValue = (short) (ramp[i] * 65535);
+ rampData[i] = scaledValue;
+ rampData[i + GAMMA_RAMP_LENGTH] = scaledValue;
+ rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue;
+ }
+
+ long screenDC = WGL.GetDC(0);
+ boolean res = WGL.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData));
+ WGL.ReleaseDC(0, screenDC);
+ return res;
+ }
+
+ protected Buffer getGammaRamp() {
+ ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]);
+ long screenDC = WGL.GetDC(0);
+ boolean res = WGL.GetDeviceGammaRamp(screenDC, rampData);
+ WGL.ReleaseDC(0, screenDC);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ // getGammaRamp failed earlier
+ return;
+ }
+ long screenDC = WGL.GetDC(0);
+ WGL.SetDeviceGammaRamp(screenDC, originalGammaRamp);
+ WGL.ReleaseDC(0, screenDC);
+ }
+}
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
new file mode 100644
index 000000000..bb59434b7
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+
+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");
+
+ 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;
+
+ public WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested,
+ PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, GLCapabilitiesChooser chooser) {
+ super(screen, capsChosen, capsRequested);
+ this.chooser=chooser;
+ this.pixelfmt = pixelfmt;
+ this.pixelfmtID = pixelfmtID;
+ }
+
+ public static WindowsWGLGraphicsConfiguration create(long hdc, int pfdID,
+ GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer)
+ {
+ if(pfdID<=0) {
+ throw new GLException("Invalid pixelformat id "+pfdID);
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault();
+ }
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
+ if (WGL.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ throw new GLException("Unable to describe pixel format " + pfdID);
+ }
+
+ GLCapabilities caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer);
+ if(null==caps) {
+ throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID);
+ }
+ WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser());
+ cfg.setCapsPFD(caps, pfd, pfdID, false);
+
+ return cfg;
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ /** Update config - before having a valid context */
+ protected void updateGraphicsConfiguration(GLDrawableFactory factory, NativeWindow nativeWindow) {
+ WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, nativeWindow);
+ }
+
+ /** Update config - after having a valid and current context */
+ protected void updateCapabilitiesByWGL(GLContextImpl context) {
+ if(choosenByWGLPixelFormat) return; // already done ..
+
+ GLCapabilities capabilities = (GLCapabilities) getRequestedCapabilities();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+ GLProfile glp = capabilities.getGLProfile();
+
+ WGLExt wglExt = (WGLExt) context.getPlatformGLExtensions();
+ GLDrawable drawable = context.getGLDrawable();
+ NativeWindow nativeWindow = drawable.getNativeWindow();
+ long hdc = nativeWindow.getSurfaceHandle();
+
+ GLCapabilities[] caps = HDC2GLCapabilities(wglExt, hdc, getPixelFormatID(), glp, true, onscreen, usePBuffer);
+ if(null!=caps && null!=caps[0]) {
+ setCapsPFD(caps[0], getPixelFormat(), getPixelFormatID(), true);
+ }
+ }
+
+ protected void setCapsPFD(GLCapabilities caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) {
+ this.pixelfmt = pfd;
+ this.pixelfmtID = pfdID;
+ setChosenCapabilities(caps);
+ this.isChosen=true;
+ this.choosenByWGLPixelFormat=choosenByWGLPixelFormat;
+ if (DEBUG) {
+ System.err.println("*** setCapsPFD: WGL-Choosen "+choosenByWGLPixelFormat+", pfdID "+pfdID+", "+caps);
+ }
+ }
+
+ public boolean getCapabilitiesChosen() {
+ return isChosen;
+ }
+
+ public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; }
+ public int getPixelFormatID() { return pixelfmtID; }
+ public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; }
+
+ private static int haveWGLChoosePixelFormatARB = -1;
+ private static int haveWGLARBMultisample = -1;
+
+ public static GLCapabilities[] HDC2GLCapabilities(WGLExt wglExt, long hdc, int pfdIDOnly,
+ GLProfile glp, boolean relaxed, boolean onscreen, boolean usePBuffer) {
+
+ if(haveWGLChoosePixelFormatARB<0) {
+ haveWGLChoosePixelFormatARB = wglExt.isExtensionAvailable("WGL_ARB_pixel_format")?1:0;
+ }
+ if(haveWGLARBMultisample<0) {
+ haveWGLARBMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample")?1:0;
+ }
+ if (0==haveWGLChoosePixelFormatARB) {
+ return null;
+ }
+
+ // 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)
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ int niattribs = 0;
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ int[] iresults = new int [2*MAX_ATTRIBS];
+
+ 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("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats);
+ }
+
+ if(pfdIDOnly>0 && pfdIDOnly>numFormats) {
+ throw new GLException("Invalid pixelformat ID " + pfdIDOnly + " (should be between 1 and " + numFormats + ")");
+ }
+
+ // Should we be filtering out the pixel formats which aren't
+ // applicable, as we are doing here?
+ // We don't have enough information in the GLCapabilities to
+ // represent those that aren't...
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_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_PIXEL_TYPE_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_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;
+ if (1==haveWGLARBMultisample) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ }
+
+ if(pfdIDOnly>0) {
+ availableCaps = new GLCapabilities[1];
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfdIDOnly, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + pfdIDOnly + " of device context");
+ }
+ availableCaps[0] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults,
+ relaxed, onscreen, usePBuffer);
+ } else {
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context");
+ }
+ availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults,
+ relaxed, onscreen, usePBuffer);
+ }
+ }
+ } else {
+ long lastErr = WGL.GetLastError();
+ // Intel Extreme graphics fails with a zero error code
+ if (lastErr != 0) {
+ throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError());
+ }
+ }
+ return availableCaps;
+ }
+
+ public static boolean GLCapabilities2AttribList(GLCapabilities caps,
+ int[] iattributes,
+ WGLExt wglExt,
+ boolean pbuffer,
+ int[] floatMode) throws GLException {
+ if (!wglExt.isExtensionAvailable("WGL_ARB_pixel_format")) {
+ return false;
+ }
+
+ int niattribs = 0;
+
+ iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ 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++] = GL.GL_TRUE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
+ if (caps.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
+ if (caps.getStereo()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = caps.getDepthBits();
+ iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAlphaBits();
+ iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
+ iattributes[niattribs++] = caps.getStencilBits();
+ if (caps.getAccumRedBits() > 0 ||
+ caps.getAccumGreenBits() > 0 ||
+ caps.getAccumBlueBits() > 0 ||
+ caps.getAccumAlphaBits() > 0) {
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits() +
+ caps.getAccumAlphaBits());
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumRedBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumGreenBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumBlueBits();
+ iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = caps.getAccumAlphaBits();
+ }
+
+ if (wglExt.isExtensionAvailable("WGL_ARB_multisample")) {
+ if (caps.getSampleBuffers()) {
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
+ iattributes[niattribs++] = caps.getNumSamples();
+ }
+ }
+
+ boolean rtt = caps.getPbufferRenderToTexture();
+ boolean rect = caps.getPbufferRenderToTextureRectangle();
+ boolean useFloat = caps.getPbufferFloatingPointBuffers();
+ boolean ati = false;
+ if (pbuffer) {
+ // Check some invariants and set up some state
+ if (rect && !rtt) {
+ throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
+ }
+
+ if (rect) {
+ if (!wglExt.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
+ }
+ }
+
+ if (useFloat) {
+ if (!wglExt.isExtensionAvailable("WGL_ATI_pixel_format_float") &&
+ !wglExt.isExtensionAvailable("WGL_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers not supported by this hardware");
+ }
+
+ // Prefer NVidia extension over ATI
+ if (wglExt.isExtensionAvailable("WGL_NV_float_buffer")) {
+ ati = false;
+ floatMode[0] = GLPbuffer.NV_FLOAT;
+ } else {
+ ati = true;
+ floatMode[0] = GLPbuffer.ATI_FLOAT;
+ }
+ if (DEBUG) {
+ System.err.println("Using " + (ati ? "ATI" : "NVidia") + " floating-point extension");
+ }
+ }
+
+ // See whether we need to change the pixel type to support ATI's
+ // floating-point pbuffers
+ if (useFloat && ati) {
+ if (rtt) {
+ throw new GLException("Render-to-floating-point-texture not supported on ATI hardware");
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_FLOAT_ARB;
+ }
+ } else {
+ if (!rtt) {
+ // Currently we don't support non-truecolor visuals in the
+ // GLCapabilities, so we don't offer the option of making
+ // color-index pbuffers.
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ }
+
+ if (useFloat && !ati) {
+ iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (rtt) {
+ if (useFloat) {
+ assert(!ati);
+ if (!rect) {
+ throw new GLException("Render-to-floating-point-texture only supported on NVidia hardware with render-to-texture-rectangle");
+ }
+ iattributes[niattribs++] = WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = rect ? WGLExt.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGLExt.WGL_BIND_TO_TEXTURE_RGB_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+ }
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TYPE_RGBA_ARB;
+ }
+ iattributes[niattribs++] = 0;
+
+ 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 ;
+
+ public static int WGLConfig2DrawableTypeBits(int[] iattribs,
+ int niattribs,
+ 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;
+ break;
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT;
+ break;
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT;
+ break;
+ }
+ }
+ return val;
+ }
+
+ public static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & WINDOW_BIT) ) ;
+ } else {
+ res = ( 0 != (val & BITMAP_BIT) ) || usePBuffer ;
+ }
+ if ( usePBuffer ) {
+ res = res && ( 0 != (val & PBUFFER_BIT) ) ;
+ }
+
+ return res;
+ }
+ public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs,
+ int niattribs,
+ int[] iresults,
+ boolean relaxed, 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(relaxed) {
+ res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) );
+ res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) );
+ } else {
+ throw new GLException("WGL DrawableType does not match !!!");
+ }
+
+ 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:
+ res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case WGLExt.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE) {
+ return null;
+ }
+ break;
+
+ case WGLExt.WGL_DEPTH_BITS_ARB:
+ res.setDepthBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_STENCIL_BITS_ARB:
+ res.setStencilBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_DOUBLE_BUFFER_ARB:
+ res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_STEREO_ARB:
+ res.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) {
+ res.setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ 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]);
+ }
+ }
+ return res;
+ }
+
+ // PIXELFORMAT
+
+ public static GLCapabilities PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) {
+ if ((pfd.getDwFlags() & WGL.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() & WGL.PFD_DOUBLEBUFFER) != 0);
+ res.setStereo ((pfd.getDwFlags() & WGL.PFD_STEREO) != 0);
+ res.setHardwareAccelerated( ((pfd.getDwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
+ ((pfd.getDwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0) );
+ res.setOnscreen ( onscreen && ((pfd.getDwFlags() & WGL.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;
+ }
+
+ public static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilities caps) {
+ 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 = (WGL.PFD_SUPPORT_OPENGL |
+ WGL.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= WGL.PFD_DOUBLEBUFFER;
+ }
+ if (caps.isOnscreen()) {
+ pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
+ }
+ if (caps.getStereo()) {
+ pfdFlags |= WGL.PFD_STEREO;
+ }
+ pfd.setDwFlags(pfdFlags);
+ pfd.setIPixelType((byte) WGL.PFD_TYPE_RGBA);
+ pfd.setCColorBits((byte) colorDepth);
+ pfd.setCRedBits ((byte) caps.getRedBits());
+ pfd.setCGreenBits((byte) caps.getGreenBits());
+ pfd.setCBlueBits ((byte) caps.getBlueBits());
+ pfd.setCAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.setCAccumBits ((byte) accumDepth);
+ pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.setCDepthBits((byte) caps.getDepthBits());
+ pfd.setCStencilBits((byte) caps.getStencilBits());
+ pfd.setILayerType((byte) WGL.PFD_MAIN_PLANE);
+
+ /* FIXME: Missing:
+ caps.getSampleBuffers()
+ caps.getNumSamples ()
+ }
+ caps.getBackgroundOpaque()
+ try {
+ caps.getPbufferFloatingPointBuffers()
+ } catch (Exception e) {}
+ */
+ return pfd;
+ }
+
+ public static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.setNSize((short) pfd.size());
+ pfd.setNVersion((short) 1);
+ return pfd;
+ }
+
+ public String toString() {
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", wglChoosen "+choosenByWGLPixelFormat+
+ ",\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
new file mode 100644
index 000000000..06590a913
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import com.sun.nativewindow.impl.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+
+/** 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 {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public WindowsWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GLCapabilities caps = (GLCapabilities)capabilities;
+ return chooseGraphicsConfigurationStatic(caps, chooser, absScreen);
+ }
+
+ protected static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) {
+ GLCapabilities caps = new GLCapabilities(null);
+ caps.setDoubleBuffered(onscreen); // FIXME
+ caps.setOnscreen (onscreen);
+ caps.setPBuffer (usePBuffer);
+
+ GLCapabilities caps2 = (GLCapabilities) caps.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER
+ caps2.setDoubleBuffered(false);
+ }
+
+ if(null==absScreen) {
+ absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ }
+ return new WindowsWGLGraphicsConfiguration(absScreen, caps2, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps2), -1, null);
+ }
+
+ protected static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities caps,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if(null==absScreen) {
+ absScreen = DefaultGraphicsScreen.createScreenDevice(0);
+ }
+ GLCapabilities caps2 = (GLCapabilities) caps.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER
+ caps2.setDoubleBuffered(false);
+ }
+ return new WindowsWGLGraphicsConfiguration(absScreen, caps2, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps2), -1,
+ (GLCapabilitiesChooser)chooser);
+ }
+
+ protected static void updateGraphicsConfiguration(CapabilitiesChooser chooser,
+ GLDrawableFactory factory, NativeWindow nativeWindow) {
+ if (nativeWindow == null) {
+ throw new IllegalArgumentException("NativeWindow is null");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ boolean choosenBywGLPixelFormat = false;
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ GLCapabilities capabilities = (GLCapabilities) config.getRequestedCapabilities();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+ GLProfile glProfile = capabilities.getGLProfile();
+ long hdc = nativeWindow.getSurfaceHandle();
+
+ if (DEBUG) {
+ Exception ex = new Exception("WindowsWGLGraphicsConfigurationFactory got HDC "+toHexString(hdc));
+ ex.printStackTrace();
+ System.err.println("WindowsWGLGraphicsConfigurationFactory got NW "+nativeWindow);
+ }
+
+ PIXELFORMATDESCRIPTOR pfd = null;
+ int pixelFormat = -1; // 1-based pixel format
+ boolean pixelFormatSet = false;
+ GLCapabilities chosenCaps = null;
+
+ if (onscreen) {
+ if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) {
+ // 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("!!!! NOTE: pixel format already chosen for HDC: " + toHexString(hdc)+
+ ", pixelformat "+pixelFormat);
+ }
+ pixelFormatSet = true;
+ }
+
+ GLCapabilities[] availableCaps = null;
+ int numFormats = 0;
+ pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ // Produce a recommended pixel format selection for the GLCapabilitiesChooser.
+ // Use wglChoosePixelFormatARB if user requested multisampling and if we have it available
+ WindowsWGLDrawable dummyDrawable = null;
+ GLContextImpl dummyContext = null;
+ WGLExt dummyWGLExt = null;
+ if (capabilities.getSampleBuffers()) {
+ dummyDrawable = new WindowsDummyWGLDrawable(factory);
+ dummyContext = (GLContextImpl) dummyDrawable.createContext(null);
+ if (dummyContext != null) {
+ dummyContext.makeCurrent();
+ dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions();
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": Not using WGL_ARB_pixel_format, because multisampling not requested");
+ }
+ int recommendedPixelFormat = pixelFormat; // 1-based pixel format
+ boolean haveWGLChoosePixelFormatARB = false;
+ boolean gotAvailableCaps = false;
+ if (dummyWGLExt != null) {
+ try {
+ haveWGLChoosePixelFormatARB = dummyWGLExt.isExtensionAvailable("WGL_ARB_pixel_format");
+ if (haveWGLChoosePixelFormatARB) {
+ if(pixelFormat<=0) {
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+
+ if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes,
+ dummyWGLExt,
+ false,
+ null)) {
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if (dummyWGLExt.wglChoosePixelFormatARB(hdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ numFormatsTmp, 0)) {
+ numFormats = numFormatsTmp[0];
+ if (recommendedPixelFormat<=0 && numFormats > 0) {
+ recommendedPixelFormat = pformats[0];
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat);
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() );
+ Thread.dumpStack();
+ }
+ }
+ if (DEBUG) {
+ if (recommendedPixelFormat <= 0) {
+ System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format: "+WGL.GetLastError());
+ if (capabilities.getSampleBuffers()) {
+ System.err.print(" for multisampled GLCapabilities");
+ }
+ System.err.println();
+ }
+ }
+ }
+ }
+
+ availableCaps = WindowsWGLGraphicsConfiguration.HDC2GLCapabilities(dummyWGLExt, hdc, -1, glProfile, pixelFormatSet, onscreen, usePBuffer);
+ gotAvailableCaps = null!=availableCaps ;
+ choosenBywGLPixelFormat = gotAvailableCaps ;
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": wglChoosePixelFormatARB not available");
+ }
+ } finally {
+ dummyContext.release();
+ dummyContext.destroy();
+ dummyDrawable.destroy();
+ }
+ }
+
+ if (!gotAvailableCaps) {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Using ChoosePixelFormat ... (LastError: "+WGL.GetLastError()+")");
+ }
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities);
+ recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": ChoosePixelFormat(HDC "+toHexString(hdc)+") = " + recommendedPixelFormat + " (LastError: "+WGL.GetLastError()+")");
+ System.err.println(getThreadName() + ": Used " + capabilities);
+ }
+
+ numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("Unable to enumerate pixel formats of window " +
+ toHexString(hdc) + " for GLCapabilitiesChooser (LastError: "+WGL.GetLastError()+")");
+ }
+ availableCaps = new GLCapabilities[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
+ throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ }
+ availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer);
+ }
+ }
+
+ // NOTE: officially, should make a copy of all of these
+ // GLCapabilities to avoid mutation by the end user during the
+ // chooseCapabilities call, but for the time being, assume they
+ // won't be changed
+
+ if(pixelFormat<=0) {
+ if(null!=chooser) {
+ // Supply information to chooser
+ try {
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat) + 1;
+ } catch (NativeWindowException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ pixelFormat = -1;
+ }
+ } else {
+ pixelFormat = recommendedPixelFormat;
+ }
+ if (pixelFormat <= 0) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration .. unable to choose config, using first");
+ }
+ pixelFormat = 1; // default ..
+ } else if ( pixelFormat > numFormats ) {
+ throw new GLException("Invalid result " + pixelFormat +
+ " from GLCapabilitiesChooser (should be between 1 and " +
+ numFormats + ")");
+ }
+ }
+ chosenCaps = availableCaps[pixelFormat-1];
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):");
+ System.err.println(chosenCaps);
+ }
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ throw new GLException("Error re-describing the chosen pixel format: " + WGL.GetLastError());
+ }
+ } else {
+ // For now, use ChoosePixelFormat for offscreen surfaces until
+ // we figure out how to properly choose an offscreen-
+ // compatible pixel format
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities);
+ pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ }
+ if(!pixelFormatSet) {
+ if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
+ long lastError = WGL.GetLastError();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() +
+ ", current DC = " + WGL.wglGetCurrentDC());
+ System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc));
+ }
+ throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError);
+ }
+ pixelFormatSet=true;
+ }
+ // Reuse the previously-constructed GLCapabilities because it
+ // turns out that using DescribePixelFormat on some pixel formats
+ // (which, for example, support full-scene antialiasing) for some
+ // reason return that they are not OpenGL-capable
+ if (chosenCaps != null) {
+ capabilities = chosenCaps;
+ } else {
+ capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer);
+ }
+ config.setCapsPFD(capabilities, pfd, pixelFormat, choosenBywGLPixelFormat);
+ }
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+ public 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
new file mode 100644
index 000000000..4458fb1ac
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.windows.wgl.*;
+import com.sun.nativewindow.impl.jawt.*;
+import com.sun.nativewindow.impl.jawt.windows.*;
+
+public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+
+ public WindowsAWTWGLGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen);
+ }
+ GraphicsConfiguration gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ long displayHandle = 0;
+
+ WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice();
+ DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: made "+winScreen);
+ }
+
+ WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(winDevice).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ winScreen);
+
+ if (winConfig == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+winScreen);
+ }
+
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig);
+ }
+
+ // FIXME: we have nothing to match .. so choose the default
+ return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(), gc, winConfig);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
new file mode 100644
index 000000000..cbd98014a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.impl.*;
+import javax.media.nativewindow.NativeWindowFactory;
+import com.sun.nativewindow.impl.x11.*;
+
+public class GLXUtil {
+ public static boolean isMultisampleAvailable(long display) {
+ try {
+ X11Lib.XLockDisplay(display);
+ String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS);
+ if (exts != null) {
+ return (exts.indexOf("GLX_ARB_multisample") >= 0);
+ }
+ return false;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ /** Workaround for apparent issue with ATI's proprietary drivers
+ where direct contexts still send GLX tokens for GL calls */
+ public static boolean isVendorATI(long display) {
+ try {
+ X11Lib.XLockDisplay(display);
+ String vendor = GLX.glXGetClientString(display, GLX.GLX_VENDOR);
+ return vendor != null && vendor.startsWith("ATI") ;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java
new file mode 100755
index 000000000..b94dac1da
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java
@@ -0,0 +1,154 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+import com.sun.nativewindow.impl.x11.*;
+
+public class X11ExternalGLXContext extends X11GLXContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+ private GLContext lastContext;
+
+ private X11ExternalGLXContext(Drawable drawable, long context) {
+ super(drawable, null);
+ this.context = context;
+ GLContextShareSet.contextCreated(this);
+ setGLFunctionAvailability(false);
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
+ }
+
+ protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long context = GLX.glXGetCurrentContext();
+ if (context == 0) {
+ throw new GLException("Error: current context null");
+ }
+ long display = GLX.glXGetCurrentDisplay();
+ if (display == 0) {
+ throw new GLException("Error: current display null");
+ }
+ long drawable = GLX.glXGetCurrentDrawable();
+ if (drawable == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
+ }
+ int[] val = new int[1];
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
+ X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(drawable);
+ return new X11ExternalGLXContext(new Drawable(factory, nw), context);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ protected void create() {
+ }
+
+ public int makeCurrent() throws GLException {
+ // Save last context if necessary to allow external GLContexts to
+ // talk to other GLContexts created by this library
+ GLContext cur = getCurrent();
+ if (cur != null && cur != this) {
+ lastContext = cur;
+ setCurrent(null);
+ }
+ return super.makeCurrent();
+ }
+
+ public void release() throws GLException {
+ super.release();
+ setCurrent(lastContext);
+ lastContext = null;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+
+ // Need to provide the display connection to extension querying APIs
+ static class Drawable extends X11GLXDrawable {
+ Drawable(GLDrawableFactory factory, NativeWindow comp) {
+ super(factory, comp, true);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void setSize(int width, int height) {
+ throw new GLException("Should not call this");
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java
new file mode 100755
index 000000000..261b1b370
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java
@@ -0,0 +1,134 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.NullWindow;
+import com.sun.nativewindow.impl.x11.*;
+
+import com.jogamp.gluegen.runtime.PointerBuffer;
+
+public class X11ExternalGLXDrawable extends X11GLXDrawable {
+ private int fbConfigID;
+ private int renderType;
+
+ private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component, int renderType) {
+ super(factory, component, true);
+
+ this.renderType = renderType;
+
+ // Need GLXFBConfig ID in order to properly create new contexts
+ // on this drawable
+ X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) component.getGraphicsConfiguration();
+ fbConfigID = cfg.getFBConfigID();
+ }
+
+ protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) {
+ ((GLDrawableFactoryImpl)factory).lockToolkit();
+ try {
+ long context = GLX.glXGetCurrentContext();
+ if (context == 0) {
+ throw new GLException("Error: current context null");
+ }
+ long display = GLX.glXGetCurrentDisplay();
+ if (display == 0) {
+ throw new GLException("Error: current display null");
+ }
+ long drawable = GLX.glXGetCurrentDrawable();
+ if (drawable == 0) {
+ throw new GLException("Error: attempted to make an external GLDrawable without a drawable current");
+ }
+ int[] val = new int[1];
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
+ X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
+
+ int w, h;
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
+ w=val[0];
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
+ h=val[0];
+
+ GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0);
+ if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) {
+ if (DEBUG) {
+ System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")");
+ }
+ }
+ NullWindow nw = new NullWindow(cfg);
+ nw.setSurfaceHandle(drawable);
+ nw.setSize(w, h);
+ return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE);
+ } finally {
+ ((GLDrawableFactoryImpl)factory).unlockToolkit();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new Context(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ return getNativeWindow().getWidth();
+ }
+
+ public int getHeight() {
+ return getNativeWindow().getHeight();
+ }
+
+ class Context extends X11GLXContext {
+ Context(X11GLXDrawable drawable, GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ protected void create() {
+ createContext(true);
+ }
+ }
+}
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
new file mode 100644
index 000000000..629bcb0b9
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -0,0 +1,555 @@
+/*
+ * 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.x11.glx;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+import com.sun.nativewindow.impl.x11.*;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+
+public abstract class X11GLXContext extends GLContextImpl {
+ protected long context;
+ private boolean glXQueryExtensionsStringInitialized;
+ private boolean glXQueryExtensionsStringAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private GLXExt glXExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // GLX extension functions.
+ private GLXExtProcAddressTable glXExtProcAddressTable;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
+ }
+
+ public X11GLXContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead,
+ GLContext shareWith) {
+ super(drawable, drawableRead, shareWith);
+ }
+
+ public X11GLXContext(GLDrawableImpl drawable,
+ GLContext shareWith) {
+ this(drawable, null, shareWith);
+ }
+
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getGLXExtProcAddressTable();
+ }
+
+ public final GLXExtProcAddressTable getGLXExtProcAddressTable() {
+ return glXExtProcAddressTable;
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getGLXExt();
+ }
+
+ public GLXExt getGLXExt() {
+ if (glXExt == null) {
+ glXExt = new GLXExtImpl(this);
+ }
+ return glXExt;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ return glExtensionName;
+ }
+
+ /** Helper routine which usually just turns around and calls
+ * createContext (except for pbuffers, which use a different context
+ * creation mechanism). Should only be called by {@link
+ * makeCurrentImpl()}.
+ */
+ protected abstract void create();
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link create()}.
+ * Note: The direct parameter may be overwritten by the direct state of a shared context.
+ */
+ protected void createContext(boolean direct) {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext got "+config);
+ }
+ long display = config.getScreen().getDevice().getHandle();
+
+ X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ direct = GLX.glXIsDirect(display, share);
+ }
+
+ GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
+ isVendorATI = GLXUtil.isVendorATI(display);
+
+ if(config.getFBConfigID()<0) {
+ // not able to use FBConfig
+ if(glCaps.getGLProfile().isGL3()) {
+ throw new GLException("Unable to create OpenGL >= 3.1 context");
+ }
+ context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct);
+ if (context == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ if (!GLX.glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ throw new GLException("Error making temp context (old2) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ }
+ setGLFunctionAvailability(true);
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext done (old2 ctx) 0x"+Long.toHexString(context));
+ }
+
+ } else {
+
+ // To use GLX_ARB_create_context, we have to make a temp context current,
+ // so we are able to use GetProcAddress
+ long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct);
+ if (temp_context == 0) {
+ throw new GLException("Unable to create temp OpenGL context");
+ } else {
+ if (!GLX.glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ temp_context)) {
+ throw new GLException("Error making temp context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ }
+ setGLFunctionAvailability(true);
+
+ if( !isFunctionAvailable("glXCreateContextAttribsARB") ||
+ !isExtensionAvailable("GLX_ARB_create_context") ) {
+ if(glCaps.getGLProfile().isGL3()) {
+ GLX.glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (no GLX_ARB_create_context)");
+ }
+
+ // continue with temp context for GL < 3.0
+ context = temp_context;
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no GLX_ARB_create_context) 0x"+Long.toHexString(context));
+ }
+ } else {
+ GLXExt glXExt = getGLXExt();
+
+ // preset with default values
+ int attribs[] = {
+ /* 0 */ GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ /* 2 */ GLX.GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+ /* 4 */ GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE,
+ /* 6 */ GLX.GLX_CONTEXT_FLAGS_ARB, 0 /* GLX.GLX_CONTEXT_DEBUG_BIT_ARB */,
+ /* 8 */ 0, 0,
+ /* 10 */ 0
+ };
+
+ if(glCaps.getGLProfile().isGL3()) {
+ // Try >= 3.2 core first
+ // and verify with a None drawable binding (default framebuffer)
+ attribs[0+1] = 3;
+ attribs[2+1] = 2;
+ if(glCaps.getGLProfile().isGL3bc()) {
+ attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB;
+ attribs[8+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ }
+ /**
+ * don't stricten requirements any further, even compatible would be fine
+ *
+ } else {
+ attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB;
+ attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ }
+ */
+
+ context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
+ if(0!=context) {
+ if (!GLX.glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext couldn't make >= 3.2 core context current - fallback");
+ }
+ GLX.glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, context);
+ context = 0;
+ } else if(DEBUG) {
+ System.err.println("X11GLXContext.createContext >= 3.2 available 0x"+Long.toHexString(context));
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext couldn't create >= 3.2 core context - fallback");
+ }
+ }
+ if(0==context) {
+ // Try >= 3.1 forward compatible - last resort for GL3 !
+ attribs[0+1] = 3;
+ attribs[2+1] = 1;
+ if(!glCaps.getGLProfile().isGL3bc()) {
+ attribs[6+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ attribs[8+0] = 0;
+ attribs[8+1] = 0;
+ }
+ }
+ if(0==context) {
+ // 3.1 or 3.0 ..
+ context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
+ if(0!=context) {
+ if (!GLX.glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext couldn't make >= 3.0 core context current - fallback");
+ }
+ GLX.glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, context);
+ context = 0;
+ } else if(DEBUG) {
+ System.err.println("X11GLXContext.createContext >= 3.0 available 0x"+Long.toHexString(context));
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext couldn't create >= 3.0 core context - fallback");
+ }
+ }
+ }
+
+ if(0==context) {
+ if(glCaps.getGLProfile().isGL3()) {
+ GLX.glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("Unable to create OpenGL >= 3.1 context (have GLX_ARB_create_context)");
+ }
+
+ // continue with temp context for GL < 3.0
+ context = temp_context;
+ if (!GLX.glXMakeContextCurrent(display,
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ GLX.glXMakeContextCurrent(display, 0, 0, 0);
+ GLX.glXDestroyContext(display, temp_context);
+ throw new GLException("Error making context (old) current: display 0x"+Long.toHexString(display)+", context 0x"+Long.toHexString(context)+", drawable "+drawable);
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext done (old ctx < 3.0 - no 3.0) 0x"+Long.toHexString(context));
+ }
+ } else {
+ GLX.glXDestroyContext(display, temp_context);
+
+ // need to update the GL func table ..
+ updateGLProcAddressTable();
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContext done (new ctx >= 3.0) 0x"+Long.toHexString(context));
+ }
+ }
+ }
+ }
+ }
+ GLContextShareSet.contextCreated(this);
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected int makeCurrentImpl() throws GLException {
+ int lockRes = drawable.lockSurface();
+ boolean exceptionOccurred = false;
+ try {
+ if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ return makeCurrentImplAfterLock();
+ } catch (RuntimeException e) {
+ exceptionOccurred = true;
+ throw e;
+ } finally {
+ if (exceptionOccurred ||
+ (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ protected void releaseImpl() throws GLException {
+ try {
+ releaseImplAfterLock();
+ } finally {
+ if (!isOptimizable() && drawable.isSurfaceLocked()) {
+ drawable.unlockSurface();
+ }
+ }
+ }
+
+ protected int makeCurrentImplAfterLock() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (drawable.getNativeWindow().getSurfaceHandle() == 0) {
+ if (DEBUG) {
+ System.err.println("drawable not properly initialized");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (GLX.glXGetCurrentContext() != context) {
+
+ if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(),
+ drawable.getNativeWindow().getSurfaceHandle(),
+ drawableRead.getNativeWindow().getSurfaceHandle(),
+ context)) {
+ throw new GLException("Error making context current");
+ }
+ if (DEBUG && (VERBOSE || created)) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " +
+ toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) +
+ ", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
+ }
+
+ if (created) {
+ setGLFunctionAvailability(false);
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void releaseImplAfterLock() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), 0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ if (context != 0) {
+ if (DEBUG) {
+ System.err.println("glXDestroyContext(0x" +
+ Long.toHexString(drawable.getNativeWindow().getDisplayHandle()) +
+ ", 0x" +
+ Long.toHexString(context) + ")");
+ }
+ GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context);
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + context);
+ }
+ context = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public boolean isCreated() {
+ return (context != 0);
+ }
+
+ public void copy(GLContext source, int mask) throws GLException {
+ long dst = getContext();
+ long src = ((X11GLXContext) source).getContext();
+ if (src == 0) {
+ throw new GLException("Source OpenGL context has not been created");
+ }
+ if (dst == 0) {
+ throw new GLException("Destination OpenGL context has not been created");
+ }
+ if (drawable.getNativeWindow().getDisplayHandle() == 0) {
+ throw new GLException("Connection to X display not yet set up");
+ }
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ GLX.glXCopyContext(drawable.getNativeWindow().getDisplayHandle(), src, dst, mask);
+ // Should check for X errors and raise GLException
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ protected void updateGLProcAddressTable() {
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing GLX extension address table");
+ }
+ glXQueryExtensionsStringInitialized = false;
+ glXQueryExtensionsStringAvailable = false;
+
+ if (glXExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ glXExtProcAddressTable = new GLXExtProcAddressTable();
+ }
+ resetProcAddressTable(getGLXExtProcAddressTable());
+ super.updateGLProcAddressTable();
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (!glXQueryExtensionsStringInitialized) {
+ glXQueryExtensionsStringAvailable =
+ getDrawableImpl().getDynamicLookupHelper().dynamicLookupFunction("glXQueryExtensionsString") != 0;
+ glXQueryExtensionsStringInitialized = true;
+ }
+ if (glXQueryExtensionsStringAvailable) {
+ GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl();
+ factory.lockToolkit();
+ try {
+ String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(),
+ drawable.getNativeWindow().getScreenIndex());
+ if (DEBUG) {
+ System.err.println("!!! GLX extensions: " + ret);
+ }
+ return ret;
+ } finally {
+ factory.unlockToolkit();
+ }
+ } else {
+ return "";
+ }
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return getGLDrawable().getFactory().canCreateGLPbuffer();
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
+
+ private int hasSwapIntervalSGI = 0;
+
+ protected void setSwapIntervalImpl(int interval) {
+ getDrawableImpl().getFactoryImpl().lockToolkit();
+ try {
+ GLXExt glXExt = getGLXExt();
+ if(0==hasSwapIntervalSGI) {
+ try {
+ hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1;
+ } catch (Throwable t) { hasSwapIntervalSGI=1; }
+ }
+ if (hasSwapIntervalSGI>0) {
+ try {
+ if( 0 == glXExt.glXSwapIntervalSGI(interval) ) {
+ currentSwapInterval = interval;
+ }
+ } catch (Throwable t) { hasSwapIntervalSGI=-1; }
+ }
+ } finally {
+ getDrawableImpl().getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getGLXExt().glXAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean isOptimizable() {
+ return (super.isOptimizable() && !isVendorATI);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public long getContext() {
+ return context;
+ }
+
+ private boolean isVendorATI = false;
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java
new file mode 100644
index 000000000..fe030af00
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java
@@ -0,0 +1,100 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.x11.*;
+import com.jogamp.gluegen.runtime.DynamicLookupHelper;
+
+public abstract class X11GLXDrawable extends GLDrawableImpl {
+ protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) {
+ super(factory, comp, realized);
+ }
+
+ public DynamicLookupHelper getDynamicLookupHelper() {
+ return (X11GLXDrawableFactory) getFactoryImpl() ;
+ }
+
+ protected void setRealizedImpl() {
+ if(!realized) {
+ return; // nothing to do
+ }
+
+ if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) {
+ throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready");
+ }
+ try {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration();
+
+ if (DEBUG) {
+ System.err.println("!!! X11GLXDrawable.setRealized(true): "+config);
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected void swapBuffersImpl() {
+ boolean didLock = false;
+ try {
+ if ( !isSurfaceLocked() ) {
+ // Usually the surface shall be locked within [makeCurrent .. swap .. release]
+ if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+ didLock=true;
+ }
+
+ GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle());
+
+ } finally {
+ if(didLock) {
+ unlockSurface();
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------
+ // Internals only below this point
+ //
+}
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
new file mode 100644
index 000000000..089a516ee
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import java.nio.*;
+import java.security.*;
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.gluegen.runtime.*;
+import com.jogamp.gluegen.runtime.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+import com.sun.nativewindow.impl.NullWindow;
+import com.sun.nativewindow.impl.NWReflection;
+import com.sun.nativewindow.impl.x11.*;
+
+public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper {
+ public X11GLXDrawableFactory() {
+ super();
+ // Must initialize GLX support eagerly in case a pbuffer is the
+ // first thing instantiated
+ GLProcAddressHelper.resetProcAddressTable(GLX.getGLXProcAddressTable(), this);
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ new X11GLXGraphicsConfigurationFactory();
+ try {
+ NWReflection.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory",
+ new Object[] {});
+ } catch (Throwable t) { }
+ }
+
+ public GLDrawableImpl createOnscreenDrawable(NativeWindow target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new X11OnscreenGLXDrawable(this, target);
+ }
+
+ protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) {
+ return new X11OffscreenGLXDrawable(this, target);
+ }
+
+ private boolean pbufferSupportInitialized = false;
+ private boolean canCreateGLPbuffer = false;
+ public boolean canCreateGLPbuffer() {
+ if (!pbufferSupportInitialized) {
+ long display = X11Util.getThreadLocalDefaultDisplay();
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ int screen = 0; // FIXME: provide way to specify this?
+
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+ if (DEBUG) {
+ System.err.println("!!! GLX version: major " + major[0] +
+ ", minor " + minor[0]);
+ }
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
+ if (str != null && str.startsWith("1.") &&
+ (str.charAt(2) >= '3')) {
+ canCreateGLPbuffer = true;
+ }
+ } else {
+ canCreateGLPbuffer = ((major[0] > 1) || (minor[0] > 2));
+ }
+
+ pbufferSupportInitialized = true;
+ }
+ return canCreateGLPbuffer;
+ }
+
+ protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) {
+ /**
+ * FIXME: Think about this ..
+ * should not be necessary ? ..
+ final List returnList = new ArrayList();
+ final GLDrawableFactory factory = this;
+ Runnable r = new Runnable() {
+ public void run() {
+ returnList.add(new X11PbufferGLXDrawable(factory, target));
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLDrawableImpl) returnList.get(0);
+ */
+ return new X11PbufferGLXDrawable(this, target);
+ }
+
+
+ protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) {
+ AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault();
+ NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, screen));
+ nw.setSize(width, height);
+ return nw;
+ }
+
+ public GLContext createExternalGLContext() {
+ return X11ExternalGLXContext.create(this, null);
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return canCreateGLPbuffer();
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ return X11ExternalGLXDrawable.create(this, null);
+ }
+
+ public void loadGLULibrary() {
+ X11Lib.dlopen("/usr/lib/libGLU.so");
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ long res = 0;
+ res = GLX.glXGetProcAddressARB(glFuncName);
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ res = X11Lib.dlsym(glFuncName);
+ }
+ return res;
+ }
+
+ public boolean canCreateContextOnJava2DSurface() {
+ return false;
+ }
+
+ public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
+ throws GLException {
+ throw new GLException("Unimplemented on this platform");
+ }
+
+ //----------------------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private boolean gotGammaRampLength;
+ private int gammaRampLength;
+ protected synchronized int getGammaRampLength() {
+ if (gotGammaRampLength) {
+ return gammaRampLength;
+ }
+
+ long display = X11Util.getThreadLocalDefaultDisplay();
+ try {
+ X11Lib.XLockDisplay(display);
+ int[] size = new int[1];
+ boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
+ X11Lib.DefaultScreen(display),
+ size, 0);
+ if (!res) {
+ return 0;
+ }
+ gotGammaRampLength = true;
+ gammaRampLength = size[0];
+ return gammaRampLength;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected boolean setGammaRamp(float[] ramp) {
+ int len = ramp.length;
+ short[] rampData = new short[len];
+ for (int i = 0; i < len; i++) {
+ rampData[i] = (short) (ramp[i] * 65535);
+ }
+
+ long display = X11Util.getThreadLocalDefaultDisplay();
+ try {
+ X11Lib.XLockDisplay(display);
+ boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ rampData.length,
+ rampData, 0,
+ rampData, 0,
+ rampData, 0);
+ return res;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected Buffer getGammaRamp() {
+ int size = getGammaRampLength();
+ ShortBuffer rampData = ShortBuffer.wrap(new short[3 * size]);
+ rampData.position(0);
+ rampData.limit(size);
+ ShortBuffer redRampData = rampData.slice();
+ rampData.position(size);
+ rampData.limit(2 * size);
+ ShortBuffer greenRampData = rampData.slice();
+ rampData.position(2 * size);
+ rampData.limit(3 * size);
+ ShortBuffer blueRampData = rampData.slice();
+ long display = X11Util.getThreadLocalDefaultDisplay();
+ try {
+ X11Lib.XLockDisplay(display);
+ boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ size,
+ redRampData,
+ greenRampData,
+ blueRampData);
+ if (!res) {
+ return null;
+ }
+ return rampData;
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+
+ protected void resetGammaRamp(Buffer originalGammaRamp) {
+ if (originalGammaRamp == null)
+ return; // getGammaRamp failed originally
+ ShortBuffer rampData = (ShortBuffer) originalGammaRamp;
+ int capacity = rampData.capacity();
+ if ((capacity % 3) != 0) {
+ throw new IllegalArgumentException("Must not be the original gamma ramp");
+ }
+ int size = capacity / 3;
+ rampData.position(0);
+ rampData.limit(size);
+ ShortBuffer redRampData = rampData.slice();
+ rampData.position(size);
+ rampData.limit(2 * size);
+ ShortBuffer greenRampData = rampData.slice();
+ rampData.position(2 * size);
+ rampData.limit(3 * size);
+ ShortBuffer blueRampData = rampData.slice();
+ long display = X11Util.getThreadLocalDefaultDisplay();
+ try {
+ X11Lib.XLockDisplay(display);
+ X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
+ size,
+ redRampData,
+ greenRampData,
+ blueRampData);
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ }
+ }
+}
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
new file mode 100644
index 000000000..498605594
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import java.util.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.gluegen.runtime.NativeLibrary;
+import com.jogamp.gluegen.runtime.PointerBuffer;
+import com.sun.nativewindow.impl.x11.*;
+
+public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public static final int MAX_ATTRIBS = 128;
+ private long fbConfig;
+ private int fbConfigID;
+ private GLCapabilitiesChooser chooser;
+
+ public X11GLXGraphicsConfiguration(X11GraphicsScreen screen,
+ GLCapabilities capsChosen, GLCapabilities capsRequested, GLCapabilitiesChooser chooser,
+ XVisualInfo info, long fbcfg, int fbcfgID) {
+ super(screen, capsChosen, capsRequested, info);
+ this.chooser=chooser;
+ fbConfig = fbcfg;
+ fbConfigID = fbcfgID;
+ }
+
+ public static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
+ long display = x11Screen.getDevice().getHandle();
+ if(0==display) {
+ throw new GLException("Display null of "+x11Screen);
+ }
+ int screen = x11Screen.getIndex();
+ long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+ if(0==fbcfg) {
+ throw new GLException("FBConfig null of 0x"+Integer.toHexString(fbcfgID));
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault();
+ }
+ GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ if(null==caps) {
+ throw new GLException("GLCapabilities null of 0x"+Long.toHexString(fbcfg));
+ }
+ XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
+ if(null==xvi) {
+ throw new GLException("XVisualInfo null of 0x"+Long.toHexString(fbcfg));
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID);
+ }
+
+ public Object clone() {
+ return super.clone();
+ }
+
+ public long getFBConfig() { return fbConfig; }
+ public int getFBConfigID() { return fbConfigID; }
+
+ protected void updateGraphicsConfiguration() {
+ X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(getRequestedCapabilities(),
+ chooser,
+ getScreen());
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setXVisualInfo(newConfig.getXVisualInfo());
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ fbConfig = newConfig.getFBConfig();
+ fbConfigID = newConfig.getFBConfigID();
+ if(DEBUG) {
+ System.err.println("!!! updateGraphicsConfiguration: "+this);
+ }
+ }
+ }
+
+ public static int[] GLCapabilities2AttribList(GLCapabilities caps,
+ boolean forFBAttr,
+ boolean isMultisampleAvailable,
+ long display,
+ int screen)
+ {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int[] res = new int[MAX_ATTRIBS];
+ int idx = 0;
+
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_DRAWABLE_TYPE;
+ res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ;
+ }
+
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_RENDER_TYPE;
+ res[idx++] = GLX.GLX_RGBA_BIT;
+ } else {
+ res[idx++] = GLX.GLX_RGBA;
+ }
+
+ // FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ?
+ if (forFBAttr) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE;
+ res[idx++] = GLX.GLX_STEREO;
+ res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE;
+ res[idx++] = GLX.GLX_TRANSPARENT_TYPE;
+ res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB;
+ if(!caps.isBackgroundOpaque()) {
+ res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE;
+ res[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE;
+ res[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE;
+ res[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE;
+ res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE;
+ res[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE;
+ }
+ } else {
+ if (caps.getDoubleBuffered()) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ }
+ if (caps.getStereo()) {
+ res[idx++] = GLX.GLX_STEREO;
+ }
+ }
+
+ res[idx++] = GLX.GLX_RED_SIZE;
+ res[idx++] = caps.getRedBits();
+ res[idx++] = GLX.GLX_GREEN_SIZE;
+ res[idx++] = caps.getGreenBits();
+ res[idx++] = GLX.GLX_BLUE_SIZE;
+ res[idx++] = caps.getBlueBits();
+ res[idx++] = GLX.GLX_ALPHA_SIZE;
+ res[idx++] = caps.getAlphaBits();
+ res[idx++] = GLX.GLX_DEPTH_SIZE;
+ res[idx++] = caps.getDepthBits();
+ if (caps.getStencilBits() > 0) {
+ res[idx++] = GLX.GLX_STENCIL_SIZE;
+ res[idx++] = caps.getStencilBits();
+ }
+ if (caps.getAccumRedBits() > 0 ||
+ caps.getAccumGreenBits() > 0 ||
+ caps.getAccumBlueBits() > 0 ||
+ caps.getAccumAlphaBits() > 0) {
+ res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
+ res[idx++] = caps.getAccumRedBits();
+ res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ res[idx++] = caps.getAccumGreenBits();
+ res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ res[idx++] = caps.getAccumBlueBits();
+ res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE;
+ res[idx++] = caps.getAccumAlphaBits();
+ }
+ if (isMultisampleAvailable && caps.getSampleBuffers()) {
+ res[idx++] = GLX.GLX_SAMPLE_BUFFERS;
+ res[idx++] = GL.GL_TRUE;
+ res[idx++] = GLX.GLX_SAMPLES;
+ res[idx++] = caps.getNumSamples();
+ }
+ if (caps.isPBuffer()) {
+ if (caps.getPbufferFloatingPointBuffers()) {
+ String glXExtensions = GLX.glXQueryExtensionsString(display, screen);
+ if (glXExtensions == null ||
+ glXExtensions.indexOf("GLX_NV_float_buffer") < 0) {
+ throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware: "+glXExtensions);
+ }
+ res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV;
+ res[idx++] = GL.GL_TRUE;
+ }
+ }
+ res[idx++] = 0;
+ return res;
+ }
+
+ // FBConfig
+
+ public static boolean GLXFBConfigValid(long display, long fbcfg) {
+ int[] tmp = new int[1];
+ if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
+ boolean res;
+
+ if ( onscreen ) {
+ res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ;
+ } else {
+ res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) || usePBuffer ;
+ }
+ if ( usePBuffer ) {
+ res = res && ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ;
+ }
+
+ return res;
+ }
+
+ public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
+ boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) {
+ int[] tmp = new int[1];
+ int val;
+ val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0);
+ if (val != GLX.GLX_RGBA_BIT) {
+ throw new GLException("Visual does not support RGBA");
+ }
+ 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 {
+ throw new GLException("GLX_DRAWABLE_TYPE does not match !!!");
+ }
+ 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);
+ res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ if (isMultisampleEnabled) {
+ 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);
+ if(!res.isBackgroundOpaque()) {
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_RED_VALUE, tmp, 0);
+ res.setTransparentRedValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_GREEN_VALUE, tmp, 0);
+ res.setTransparentGreenValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_BLUE_VALUE, tmp, 0);
+ res.setTransparentBlueValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+
+ glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_ALPHA_VALUE, tmp, 0);
+ res.setTransparentAlphaValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]);
+ }
+ try {
+ res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
+ } catch (Exception e) {}
+ return res;
+ }
+
+ private static String glXGetFBConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset);
+ if (res != 0) {
+ throw new GLException("glXGetFBConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res));
+ }
+ return tmp[tmp_offset];
+ }
+
+ public static int glXFBConfig2FBConfigID(long display, long cfg) {
+ int[] tmpID = new int[1];
+ return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0);
+ }
+
+ public static long glXFBConfigID2FBConfig(long display, int screen, int id) {
+ int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 };
+ int[] count = { -1 };
+ PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ return 0;
+ }
+ return fbcfgsL.get(0);
+ }
+
+ // Visual Info
+
+ public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) {
+ XVisualInfo res = null;
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try{
+ int[] count = new int[1];
+ XVisualInfo template = XVisualInfo.create();
+ template.setVisualid(visualID);
+ XVisualInfo[] infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask, template, count, 0);
+ if (infos == null || infos.length == 0) {
+ return null;
+ }
+ res = XVisualInfo.create(infos[0]);
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ if (DEBUG) {
+ System.err.println("!!! Fetched XVisualInfo for visual ID 0x" + Long.toHexString(visualID));
+ System.err.println("!!! Resulting XVisualInfo: visualid = 0x" + Long.toHexString(res.getVisualid()));
+ }
+ return res;
+ }
+
+ public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) {
+ int[] tmp = new int[1];
+ int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
+ if (val == 0) {
+ throw new GLException("Visual does not support OpenGL");
+ }
+ val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
+ if (val == 0) {
+ throw new GLException("Visual does not support RGBA");
+ }
+ GLCapabilities res = new GLCapabilities(glp);
+ res.setOnscreen (onscreen);
+ res.setPBuffer (usePBuffer);
+ 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
+ // glXCreateContext, not by the XVisualInfo. Optimistically claim
+ // that all GLCapabilities have the capability to be hardware
+ // accelerated.
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ if (isMultisampleEnabled) {
+ res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
+ res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
+ }
+ return res;
+ }
+
+ private static String glXGetConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
+ if (res != 0) {
+ throw new GLException("glXGetConfig(0x"+Long.toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res));
+ }
+ return tmp[tmp_offset];
+ }
+
+ public String toString() {
+ return "X11GLXGraphicsConfiguration["+getScreen()+", visualID 0x" + Long.toHexString(getVisualID()) + ", fbConfigID 0x" + Long.toHexString(fbConfigID) +
+ ",\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
new file mode 100644
index 000000000..1ddac9013
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.sun.nativewindow.impl.NativeWindowFactoryImpl;
+import com.sun.nativewindow.impl.x11.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+
+import com.jogamp.gluegen.runtime.PointerBuffer;
+
+/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
+ are used on X11 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 X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public X11GLXGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen);
+ }
+
+ protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ if (!(absScreen instanceof X11GraphicsScreen)) {
+ throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here");
+ }
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen;
+
+ GLProfile glProfile = GLProfile.getDefault();
+ GLCapabilities caps=null;
+ XVisualInfo xvis=null;
+ long fbcfg = 0;
+ int fbid = -1;
+
+ // Utilizing FBConfig
+ //
+ GLCapabilities capsFB = null;
+ long display = x11Screen.getDevice().getHandle();
+ try {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
+ long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex());
+ xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID);
+ caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable);
+
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, display, screen);
+ int[] count = { -1 };
+ PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ throw new Exception("Could not fetch FBConfig for "+caps);
+ }
+ fbcfg = fbcfgsL.get(0);
+ capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable);
+
+ fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg);
+
+ xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg);
+ if (xvis==null) {
+ throw new GLException("Error: Choosen FBConfig has no visual");
+ }
+ } catch (Throwable t) {
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid);
+ }
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ if (!(absScreen instanceof X11GraphicsScreen)) {
+ throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here");
+ }
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen;
+
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if (capabilities == null) {
+ capabilities = new GLCapabilities(null);
+ }
+
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = ((GLCapabilities)capabilities).isPBuffer();
+
+ GLCapabilities caps2 = (GLCapabilities) capabilities.clone();
+ if(!caps2.isOnscreen()) {
+ // OFFSCREEN !DOUBLE_BUFFER
+ caps2.setDoubleBuffered(false);
+ }
+
+ X11GLXGraphicsConfiguration res;
+ res = chooseGraphicsConfigurationFBConfig((GLCapabilities) caps2,
+ (GLCapabilitiesChooser) chooser,
+ x11Screen);
+ if(null==res) {
+ if(usePBuffer) {
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig");
+ }
+ res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2,
+ (GLCapabilitiesChooser) chooser,
+ x11Screen);
+ }
+ if(null==res) {
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration");
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res);
+ }
+ return res;
+ }
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ X11GraphicsScreen x11Screen) {
+ int recommendedIndex = -1;
+ GLCapabilities[] caps = null;
+ PointerBuffer fbcfgsL = null;
+ int chosen=-1;
+ int retFBID=-1;
+ XVisualInfo retXVisualInfo = null;
+ GLProfile glProfile = capabilities.getGLProfile();
+ boolean onscreen = capabilities.isOnscreen();
+ boolean usePBuffer = capabilities.isPBuffer();
+
+ // Utilizing FBConfig
+ //
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+ try {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen);
+ int[] count = { -1 };
+
+ fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<1) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]);
+ }
+ return null;
+ }
+ if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: 0x"+Long.toHexString(fbcfgsL.get(0)));
+ }
+ return null;
+ }
+ recommendedIndex = 0; // 1st match is always recommended ..
+ caps = new GLCapabilities[fbcfgsL.limit()];
+ for (int i = 0; i < fbcfgsL.limit(); i++) {
+ caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
+ false, onscreen, usePBuffer, isMultisampleAvailable);
+ }
+
+ if(null==chooser) {
+ chosen = recommendedIndex;
+ } else {
+ try {
+ chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
+ } catch (NativeWindowException e) {
+ if(DEBUG) {
+ e.printStackTrace();
+ }
+ chosen = -1;
+ }
+ }
+ if (chosen < 0) {
+ // keep on going ..
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig 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) + ")");
+ }
+
+ retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen));
+
+ retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen));
+ if (retXVisualInfo==null) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]);
+ }
+ if(caps[chosen].isOnscreen()) {
+ // Onscreen drawables shall have a XVisual ..
+ return null;
+ }
+ }
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+
+ return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID);
+ }
+
+ protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ X11GraphicsScreen x11Screen) {
+ if (chooser == null) {
+ 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 = capabilities.getGLProfile();
+ boolean onscreen = capabilities.isOnscreen();
+ GLCapabilities[] caps = null;
+ int recommendedIndex = -1;
+ XVisualInfo retXVisualInfo = null;
+ int chosen=-1;
+
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+ try {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ X11Lib.XLockDisplay(display);
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen);
+ XVisualInfo[] infos = null;
+
+ XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0);
+ if (DEBUG) {
+ System.err.print("!!! glXChooseVisual recommended ");
+ if (recommendedVis == null) {
+ System.err.println("null visual");
+ } else {
+ System.err.println("visual id 0x" + Long.toHexString(recommendedVis.getVisualid()));
+ }
+ }
+ int[] count = new int[1];
+ XVisualInfo template = XVisualInfo.create();
+ template.setScreen(screen);
+ infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0);
+ if (infos == null || infos.length<1) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ caps = new GLCapabilities[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 chosen by glXChooseVisual
+ if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
+ recommendedIndex = i;
+ }
+ }
+ try {
+ chosen = chooser.chooseCapabilities(capabilities, 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");
+ }
+ retXVisualInfo = XVisualInfo.create(infos[chosen]);
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1);
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java
new file mode 100644
index 000000000..306a711bd
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java
@@ -0,0 +1,77 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OffscreenGLXContext extends X11GLXContext {
+ private X11OffscreenGLXDrawable drawable;
+
+ public X11OffscreenGLXContext(X11OffscreenGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ GL gl = getGL();
+ return gl.isGL2()?GL2.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ GLCapabilities caps = (GLCapabilities)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if (caps.getDoubleBuffered()) {
+ return GL.GL_BACK;
+ }
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // There doesn't seem to be a way to do this in the construction
+ // of the Pixmap or GLXPixmap
+ return true;
+ }
+
+ protected void create() {
+ createContext(false);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
new file mode 100644
index 000000000..7d866a200
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java
@@ -0,0 +1,150 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.x11.*;
+
+public class X11OffscreenGLXDrawable extends X11GLXDrawable {
+ private long pixmap;
+
+ protected X11OffscreenGLXDrawable(GLDrawableFactory factory, NativeWindow target) {
+ super(factory, target, true);
+ create();
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ create();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OffscreenGLXContext(this, shareWith);
+ }
+
+ private void create() {
+ NativeWindow nw = getNativeWindow();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ XVisualInfo vis = config.getXVisualInfo();
+ int bitsPerPixel = vis.getDepth();
+ AbstractGraphicsScreen aScreen = config.getScreen();
+ AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ long dpy = aDevice.getHandle();
+ int screen = aScreen.getIndex();
+
+ getFactoryImpl().lockToolkit();
+ try {
+ X11Lib.XLockDisplay(dpy);
+ pixmap = X11Lib.XCreatePixmap(dpy, (int) X11Lib.RootWindow(dpy, screen),
+ component.getWidth(), component.getHeight(), bitsPerPixel);
+ if (pixmap == 0) {
+ throw new GLException("XCreatePixmap failed");
+ }
+ long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap);
+ if (drawable == 0) {
+ X11Lib.XFreePixmap(dpy, pixmap);
+ pixmap = 0;
+ throw new GLException("glXCreateGLXPixmap failed");
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(drawable);
+ if (DEBUG) {
+ System.err.println("Created pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(dpy));
+ }
+ } finally {
+ X11Lib.XUnlockDisplay(dpy);
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public void destroy() {
+ if (pixmap == 0) return;
+
+ NativeWindow nw = getNativeWindow();
+ long display = nw.getDisplayHandle();
+ try {
+ getFactoryImpl().lockToolkit();
+ X11Lib.XLockDisplay(display);
+
+ long drawable = nw.getSurfaceHandle();
+ if (DEBUG) {
+ System.err.println("Destroying pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+
+ // Must destroy pixmap and GLXPixmap
+
+ if (DEBUG) {
+ long cur = GLX.glXGetCurrentContext();
+ if (cur != 0) {
+ System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction");
+ }
+ }
+
+ // FIXME: workaround for crashes on NVidia hardware when
+ // destroying pixmap (no context is current at the point of the
+ // crash, at least from the point of view of
+ // glXGetCurrentContext)
+ GLX.glXMakeCurrent(display, 0, 0);
+
+ GLX.glXDestroyGLXPixmap(display, drawable);
+ X11Lib.XFreePixmap(display, pixmap);
+ drawable = 0;
+ pixmap = 0;
+ display = 0;
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ } finally {
+ X11Lib.XUnlockDisplay(display);
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java
new file mode 100644
index 000000000..c89a5efd5
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java
@@ -0,0 +1,68 @@
+/*
+ * 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.x11.glx;
+
+import java.util.*;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OnscreenGLXContext extends X11GLXContext {
+ // This indicates whether the context we have created is indirect
+ // and therefore requires the toolkit to be locked around all GL
+ // calls rather than just all GLX calls
+ protected boolean isIndirect;
+
+ public X11OnscreenGLXContext(X11OnscreenGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ }
+
+ public boolean isOptimizable() {
+ return super.isOptimizable() && !isIndirect;
+ }
+
+ protected void create() {
+ createContext(true);
+ isIndirect = !GLX.glXIsDirect(drawable.getNativeWindow().getDisplayHandle(), context);
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java
new file mode 100644
index 000000000..43468b858
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java
@@ -0,0 +1,64 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.nativewindow.*;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11OnscreenGLXDrawable extends X11GLXDrawable {
+ protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeWindow component) {
+ super(factory, component, false);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OnscreenGLXContext(this, shareWith);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java
new file mode 100644
index 000000000..e0993abc3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java
@@ -0,0 +1,100 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.*;
+
+public class X11PbufferGLXContext extends X11GLXContext {
+ private X11PbufferGLXDrawable drawable;
+
+ public X11PbufferGLXContext(X11PbufferGLXDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public void bindPbufferToTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ protected void create() {
+ if (DEBUG) {
+ System.err.println("Creating context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
+ }
+
+ // Create a gl context for the p-buffer.
+ X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)
+ getGLDrawable().getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+
+ context = GLX.glXCreateNewContext(drawable.getNativeWindow().getDisplayHandle(),
+ config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, true);
+ if (context == 0) {
+ throw new GLException("pbuffer creation error: glXCreateNewContext() failed");
+ }
+ GLContextShareSet.contextCreated(this);
+
+ if (DEBUG) {
+ System.err.println("Created context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java
new file mode 100644
index 000000000..3e012225e
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java
@@ -0,0 +1,157 @@
+/*
+ * 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.x11.glx;
+
+import javax.media.opengl.*;
+import javax.media.nativewindow.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+import com.sun.nativewindow.impl.x11.*;
+
+public class X11PbufferGLXDrawable extends X11GLXDrawable {
+ protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeWindow target) {
+ /* GLCapabilities caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height */
+ super(factory, target, true);
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration());
+ }
+
+ createPbuffer();
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
+ }
+
+ protected void setRealizedImpl() {
+ if(realized) {
+ createPbuffer();
+ } else {
+ destroy();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11PbufferGLXContext(this, shareWith);
+ }
+
+ public void destroy() {
+ getFactoryImpl().lockToolkit();
+ try {
+ NativeWindow nw = getNativeWindow();
+ if (nw.getSurfaceHandle() != 0) {
+ GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle());
+ }
+ ((SurfaceChangeable)nw).setSurfaceHandle(0);
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ private void createPbuffer() {
+ getFactoryImpl().lockToolkit();
+ try {
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsScreen aScreen = config.getScreen();
+ AbstractGraphicsDevice aDevice = aScreen.getDevice();
+ long display = aDevice.getHandle();
+ int screen = aScreen.getIndex();
+
+ if (display==0) {
+ throw new GLException("Null display");
+ }
+
+ NativeWindow nw = getNativeWindow();
+
+ GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities();
+
+ if (capabilities.getPbufferRenderToTexture()) {
+ throw new GLException("Render-to-texture pbuffers not supported yet on X11");
+ }
+
+ if (capabilities.getPbufferRenderToTextureRectangle()) {
+ throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
+ }
+
+ // Create the p-buffer.
+ int niattribs = 0;
+ int[] iattributes = new int[5];
+
+ iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = nw.getWidth();
+ iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = nw.getHeight();
+ iattributes[niattribs++] = 0;
+
+ long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
+ if (pbuffer == 0) {
+ // FIXME: query X error code for detail error message
+ throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
+ }
+
+ // Set up instance variables
+ ((SurfaceChangeable)nw).setSurfaceHandle(pbuffer);
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_WIDTH, tmp, 0);
+ int width = tmp[0];
+ GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
+ int height = tmp[0];
+ ((SurfaceChangeable)nw).setSize(width, height);
+ } finally {
+ getFactoryImpl().unlockToolkit();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ // Floating-point pbuffers currently require NVidia hardware on X11
+ return GLPbuffer.NV_FLOAT;
+ }
+
+ protected void swapBuffersImpl() {
+ if(DEBUG) {
+ System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ }
+ }
+}
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
new file mode 100644
index 000000000..3b2c8f541
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+package com.jogamp.opengl.impl.x11.glx.awt;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.opengl.*;
+import javax.media.opengl.awt.*;
+
+import com.jogamp.opengl.impl.*;
+import com.sun.nativewindow.impl.jawt.*;
+import com.sun.nativewindow.impl.jawt.x11.*;
+import com.sun.nativewindow.impl.x11.*;
+import com.jogamp.opengl.impl.x11.*;
+import com.jogamp.opengl.impl.x11.glx.*;
+
+public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+
+ public X11AWTGLXGraphicsConfigurationFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ }
+
+ public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ CapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen) {
+ GraphicsDevice device = null;
+ if (absScreen != null &&
+ !(absScreen instanceof AWTGraphicsScreen)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
+ }
+
+ if(null==absScreen) {
+ absScreen = AWTGraphicsScreen.createScreenDevice(-1);
+ }
+ AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
+ device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
+ if (capabilities != null &&
+ !(capabilities instanceof GLCapabilities)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects");
+ }
+
+ if (chooser != null &&
+ !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen);
+ }
+
+ GraphicsConfiguration gc;
+ X11GraphicsConfiguration x11Config;
+
+ // Need the lock here, since it could be an AWT owned display connection
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
+ if(0==displayHandle) {
+ displayHandle = X11Util.getThreadLocalDefaultDisplay();
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
+ }
+ } else {
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
+ }
+ }
+ ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle);
+ X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle);
+
+ X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen);
+ }
+
+ gc = device.getDefaultConfiguration();
+ AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc);
+ if(DEBUG) {
+ System.err.println("AWT Colormodel compatible: "+capabilities);
+ }
+
+ x11Config = (X11GraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ x11Screen);
+ if (x11Config == null) {
+ throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+
+ long visualID = x11Config.getVisualID();
+ // Now figure out which GraphicsConfiguration corresponds to this
+ // visual by matching the visual ID
+ GraphicsConfiguration[] configs = device.getConfigurations();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration config = configs[i];
+ if (config != null) {
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) {
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ config, x11Config);
+ }
+ }
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ }
+ // Either we weren't able to reflectively introspect on the
+ // X11GraphicsConfig or something went wrong in the steps above;
+ // Let's take the default configuration as used on Windows and MacOSX then ..
+ if(DEBUG) {
+ System.err.println("!!! Using default configuration");
+ }
+ return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config);
+ }
+}