summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-11-14 09:04:45 +0100
committerSven Gothel <[email protected]>2010-11-14 09:04:45 +0100
commit83d3a3f2ea8dc328e621b3abbe671f46379c7e65 (patch)
treeb7fafe2ef1610a6be0723316ae5bf5938b9f222d /src/jogl/classes/javax
parentc3bfb82614e9fa0f8ea7169cd412a6f0c71973e0 (diff)
JOGL: Complete eager and lazy mapping of GLProfiles in respect to multiple device.
AbstractGraphicsDevice's 'connection' and 'type' attribute is used as a unique key to map GLProfiles and GLContext's major/profile -> major/minor/profile mapping. Eager initialiaztion as well as lazy is supported to maintain a simple API. This is currently tested on X11, where one app display NEWT/GL window and content on the local and remote device. See TestRemoteWindow01NEWT.java and TestRemoteGLWindows01NEWT.java
Diffstat (limited to 'src/jogl/classes/javax')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilities.java2
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java347
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java52
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java646
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java12
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java2
6 files changed, 740 insertions, 321 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 4368add3f..d48b95c79 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -81,7 +81,7 @@ public class GLCapabilities extends Capabilities implements Cloneable {
* @param glp GLProfile, or null for the default GLProfile
*/
public GLCapabilities(GLProfile glp) {
- glProfile = (null!=glp)?glp:GLProfile.getDefault();
+ glProfile = (null!=glp)?glp:GLProfile.getDefault(GLProfile.getDefaultDevice());
}
public Object clone() {
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 2f63d5c8e..34ac8e93b 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -40,9 +40,10 @@
package javax.media.opengl;
+import com.jogamp.opengl.impl.Debug;
import java.util.HashMap;
-import com.jogamp.common.util.IntIntHashMap;
-import com.jogamp.common.util.IntObjectHashMap;
+import java.util.HashSet;
+import javax.media.nativewindow.AbstractGraphicsDevice;
/** Abstraction for an OpenGL rendering context. In order to perform
OpenGL rendering, a context must be "made current" on the current
@@ -56,8 +57,9 @@ import com.jogamp.common.util.IntObjectHashMap;
process is handled by the implementation, and the GLContext
abstraction provides a stable object which clients can use to
refer to a given context. */
-
public abstract class GLContext {
+ protected static final boolean DEBUG0 = Debug.debug("GLContext");
+
/** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */
public static final int CONTEXT_NOT_CURRENT = 0;
/** Indicates that the context was made current during the last call to {@link #makeCurrent makeCurrent}. */
@@ -65,6 +67,21 @@ public abstract class GLContext {
/** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}. */
public static final int CONTEXT_CURRENT_NEW = 2;
+ /** <code>ARB_create_context</code> related: created via ARB_create_context */
+ protected static final int CTX_IS_ARB_CREATED = 1 << 0;
+ /** <code>ARB_create_context</code> related: compatibility profile */
+ protected static final int CTX_PROFILE_COMPAT = 1 << 1;
+ /** <code>ARB_create_context</code> related: core profile */
+ protected static final int CTX_PROFILE_CORE = 1 << 2;
+ /** <code>ARB_create_context</code> related: ES profile */
+ protected static final int CTX_PROFILE_ES = 1 << 3;
+ /** <code>ARB_create_context</code> related: flag forward compatible */
+ protected static final int CTX_OPTION_FORWARD = 1 << 4;
+ /** <code>ARB_create_context</code> related: not flag forward compatible */
+ protected static final int CTX_OPTION_ANY = 1 << 5;
+ /** <code>ARB_create_context</code> related: flag debug */
+ protected static final int CTX_OPTION_DEBUG = 1 << 6;
+
private static ThreadLocal currentContext = new ThreadLocal();
private HashMap/*<int, Object>*/ attachedObjects = new HashMap();
@@ -72,6 +89,26 @@ public abstract class GLContext {
/** The underlying native OpenGL context */
protected long contextHandle;
+ protected GLContext() {
+ resetStates();
+ }
+
+ protected int ctxMajorVersion;
+ protected int ctxMinorVersion;
+ protected int ctxOptions;
+ protected String ctxVersionString;
+
+ protected void resetStates() {
+ ctxMajorVersion=-1;
+ ctxMinorVersion=-1;
+ ctxOptions=0;
+ ctxVersionString=null;
+ if(null!=attachedObjects) {
+ attachedObjects.clear();
+ }
+ contextHandle=0;
+ }
+
/**
* Returns the GLDrawable to which this context may be used to
* draw.
@@ -225,6 +262,8 @@ public abstract class GLContext {
/**
* Returns the GL pipeline object for this GLContext.
+ *
+ * @return the aggregated GL instance, or null if this context was not yet made current.
*/
public abstract GL getGL();
@@ -371,41 +410,26 @@ public abstract class GLContext {
return ctxVersionString;
}
- protected int ctxMajorVersion=-1;
- protected int ctxMinorVersion=-1;
- protected int ctxOptions=0;
- protected String ctxVersionString=null;
-
- /** <code>ARB_create_context</code> related: created via ARB_create_context */
- protected static final int CTX_IS_ARB_CREATED = 1 << 0;
- /** <code>ARB_create_context</code> related: compatibility profile */
- protected static final int CTX_PROFILE_COMPAT = 1 << 1;
- /** <code>ARB_create_context</code> related: core profile */
- protected static final int CTX_PROFILE_CORE = 1 << 2;
- /** <code>ARB_create_context</code> related: ES profile */
- protected static final int CTX_PROFILE_ES = 1 << 3;
- /** <code>ARB_create_context</code> related: flag forward compatible */
- protected static final int CTX_OPTION_FORWARD = 1 << 4;
- /** <code>ARB_create_context</code> related: not flag forward compatible */
- protected static final int CTX_OPTION_ANY = 1 << 5;
- /** <code>ARB_create_context</code> related: flag debug */
- protected static final int CTX_OPTION_DEBUG = 1 << 6;
-
-
public final boolean isGL4bc() {
- return ctxMajorVersion>=4 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
}
public final boolean isGL4() {
- return ctxMajorVersion>=4 && 0!=(ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
public final boolean isGL3bc() {
- return ctxMajorVersion>=3 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
}
public final boolean isGL3() {
- return ctxMajorVersion>=3 && 0!=(ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
}
public final boolean isGL2() {
@@ -483,18 +507,122 @@ public abstract class GLContext {
return true;
}
+ protected static int compose8bit(int one, int two, int three, int four) {
+ return ( ( one & 0x000000FF ) << 24 ) |
+ ( ( two & 0x000000FF ) << 16 ) |
+ ( ( three & 0x000000FF ) << 8 ) |
+ ( ( four & 0x000000FF ) ) ;
+ }
+
+ protected static int getComposed8bit(int bits32, int which ) {
+ switch (which) {
+ case 1: return ( bits32 & 0xFF000000 ) >> 24 ;
+ case 2: return ( bits32 & 0x00FF0000 ) >> 16 ;
+ case 3: return ( bits32 & 0x0000FF00 ) >> 8 ;
+ case 4: return ( bits32 & 0xFF0000FF ) ;
+ }
+ throw new GLException("argument which out of range: "+which);
+ }
+
+ protected static String composed8BitToString(int bits32, boolean hex1, boolean hex2, boolean hex3, boolean hex4) {
+ int a = getComposed8bit(bits32, 1);
+ int b = getComposed8bit(bits32, 2);
+ int c = getComposed8bit(bits32, 3);
+ int d = getComposed8bit(bits32, 4);
+ return "["+toString(a, hex1)+", "+toString(b, hex2)+", "+toString(c, hex3)+", "+toString(d, hex4)+"]";
+ }
+
+ private static void validateProfileBits(int bits, String argName) {
+ int num = 0;
+ if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
+ if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
+ if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; }
+ if(1!=num) {
+ throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num);
+ }
+ }
+
+ //
+ // version mapping
+ //
+
/**
- * @param major Key Value either 1, 2, 3 or 4
+ * @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
+ */
+ protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+
+ /**
+ * @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
+ */
+ private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+
+ protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ return getUniqueDeviceString(device) + "-" + toHexString(compose8bit(major, minor, ctp, 0));
+ }
+
+ protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
+ return getUniqueDeviceString(device) + "-" + toHexString(compose8bit(major, profile, 0, 0));
+ }
+
+ protected static String getUniqueDeviceString(AbstractGraphicsDevice device) {
+ return device.getType() + "_" + device.getConnection() ;
+ }
+
+ protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ return deviceVersionsAvailableSet.contains(getUniqueDeviceString(device));
+ }
+ }
+
+ protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ String devKey = getUniqueDeviceString(device);
+ if ( deviceVersionsAvailableSet.contains(devKey) ) {
+ throw new InternalError("Already set: "+devKey);
+ }
+ deviceVersionsAvailableSet.add(devKey);
+ if (DEBUG0) {
+ String msg = getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet "+devKey;
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ // System.err.println(msg);
+ }
+ }
+ }
+
+ /**
+ * Called by {@link com.jogamp.opengl.impl.GLContextImpl#createContextARBMapVersionsAvailable} not intended to be used by
+ * implementations. However, if {@link #createContextARB} is not being used within
+ * {@link javax.media.opengl.GLDrawableFactory#getOrCreateSharedContext(javax.media.nativewindow.AbstractGraphicsDevice)},
+ * GLProfile has to map the available versions.
+ *
+ * @param reqMajor Key Value either 1, 2, 3 or 4
* @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @return the old mapped value
+ *
+ * @see #createContextARBMapVersionsAvailable
*/
- public static final String getGLVersionAvailable(int major, int profile) {
- int _major[] = { 0 };
- int _minor[] = { 0 };
- int _ctp[] = { 0 };
- if(getGLVersionAvailable(major, profile, _major, _minor, _ctp)) {
- return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ protected static Integer mapAvailableGLVersion(AbstractGraphicsDevice device,
+ int reqMajor, int profile, int resMajor, int resMinor, int resCtp)
+ {
+ validateProfileBits(profile, "profile");
+ validateProfileBits(resCtp, "resCtp");
+
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.put( key, val );
}
- return null;
+ return val;
+ }
+
+ protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int profile) {
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val;
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.get( key );
+ }
+ return val;
}
/**
@@ -504,15 +632,16 @@ public abstract class GLContext {
* @param minor if not null, returns the used minor version
* @param ctp if not null, returns the used context profile
*/
- public static final boolean getGLVersionAvailable(int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
- int key = compose8bit(reqMajor, reqProfile, 0, 0);
- int val;
- synchronized(mappedVersionsAvailableLock) {
- val = mappedVersionsAvailable.get( key );
- }
- if(val<=0) {
+ protected static boolean getAvailableGLVersion(AbstractGraphicsDevice device,
+ int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
+
+ Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
return false;
}
+
+ int val = valI.intValue();
+
if(null!=major) {
major[0] = getComposed8bit(val, 1);
}
@@ -529,14 +658,51 @@ public abstract class GLContext {
* @param major Key Value either 1, 2, 3 or 4
* @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
*/
- public static final boolean isGLVersionAvailable(int major, int profile) {
- return getGLVersionAvailable(major, profile, null, null, null);
+ public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int major, int profile) {
+ return null != getAvailableGLVersion(device, major, profile);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
+ }
+
+ /**
+ * @param major Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ */
+ public static String getAvailableGLVersionAsString(AbstractGraphicsDevice device, int major, int profile) {
+ int _major[] = { 0 };
+ int _minor[] = { 0 };
+ int _ctp[] = { 0 };
+ if(getAvailableGLVersion(device, major, profile, _major, _minor, _ctp)) {
+ return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ }
+ return null;
}
- public static final boolean isGL4bcAvailable() { return isGLVersionAvailable(4, CTX_PROFILE_COMPAT); }
- public static final boolean isGL4Available() { return isGLVersionAvailable(4, CTX_PROFILE_CORE); }
- public static final boolean isGL3bcAvailable() { return isGLVersionAvailable(3, CTX_PROFILE_COMPAT); }
- public static final boolean isGL3Available() { return isGLVersionAvailable(3, CTX_PROFILE_CORE); }
- public static final boolean isGL2Available() { return isGLVersionAvailable(2, CTX_PROFILE_COMPAT); }
public static String getGLVersion(int major, int minor, int ctp, String gl_version) {
boolean needColon = false;
@@ -560,83 +726,6 @@ public abstract class GLContext {
return sb.toString();
}
- protected static final Object mappedVersionsAvailableLock;
- protected static final IntIntHashMap mappedVersionsAvailable;
- protected static volatile boolean mappedVersionsAvailableSet;
-
- protected static final Object mappedProcAddressLock;
- protected static final IntObjectHashMap mappedGLProcAddress;
- protected static final IntObjectHashMap mappedGLXProcAddress;
-
- static {
- mappedVersionsAvailableLock = new Object();
- mappedVersionsAvailableSet = false;
- mappedVersionsAvailable = new IntIntHashMap();
- mappedVersionsAvailable.setKeyNotFoundValue(-1);
- mappedProcAddressLock = new Object();
- mappedGLProcAddress = new IntObjectHashMap();
- mappedGLProcAddress.setKeyNotFoundValue(null);
- mappedGLXProcAddress = new IntObjectHashMap();
- mappedGLXProcAddress.setKeyNotFoundValue(null);
- }
-
- private static void validateProfileBits(int bits, String argName) {
- int num = 0;
- if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; }
- if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; }
- if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; }
- if(1!=num) {
- throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num);
- }
- }
-
- /**
- * Called by {@link GLContextImpl#createContextARBMapVersionsAvailable} not intendet to be used by
- * implementations. However, if {@link #createContextARB} is not being used within the
- * {@link GLDrawableImpl} constructor, GLProfile has to map the available versions.
- *
- * @param reqMajor Key Value either 1, 2, 3 or 4
- * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
-
- * @see #createContextARBMapVersionsAvailable
- */
- protected static void mapVersionAvailable(int reqMajor, int profile, int resMajor, int resMinor, int resCtp)
- {
- validateProfileBits(profile, "profile");
- validateProfileBits(resCtp, "resCtp");
-
- int key = compose8bit(reqMajor, profile, 0, 0);
- int val = compose8bit(resMajor, resMinor, resCtp, 0);
- synchronized(mappedVersionsAvailableLock) {
- mappedVersionsAvailable.put( key, val );
- }
- }
-
- protected static int compose8bit(int one, int two, int three, int four) {
- return ( ( one & 0x000000FF ) << 24 ) |
- ( ( two & 0x000000FF ) << 16 ) |
- ( ( three & 0x000000FF ) << 8 ) |
- ( ( four & 0x000000FF ) ) ;
- }
-
- protected static int getComposed8bit(int bits32, int which ) {
- switch (which) {
- case 1: return ( bits32 & 0xFF000000 ) >> 24 ;
- case 2: return ( bits32 & 0x00FF0000 ) >> 16 ;
- case 3: return ( bits32 & 0x0000FF00 ) >> 8 ;
- case 4: return ( bits32 & 0xFF0000FF ) ;
- }
- throw new GLException("argument which out of range: "+which);
- }
-
- protected static String composed8BitToString(int bits32, boolean hex1, boolean hex2, boolean hex3, boolean hex4) {
- int a = getComposed8bit(bits32, 1);
- int b = getComposed8bit(bits32, 2);
- int c = getComposed8bit(bits32, 3);
- int d = getComposed8bit(bits32, 4);
- return "["+toString(a, hex1)+", "+toString(b, hex2)+", "+toString(c, hex3)+", "+toString(d, hex4)+"]";
- }
-
protected static String toString(int val, boolean hex) {
if(hex) {
return "0x" + Integer.toHexString(val);
@@ -662,6 +751,10 @@ public abstract class GLContext {
}
return needColon;
}
+
+ protected static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index d1bdcdda1..f6dce1c9c 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -47,6 +47,7 @@ import com.jogamp.common.util.ReflectionUtil;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.HashSet;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -150,6 +151,8 @@ public abstract class GLDrawableFactory {
eglFactory = tmp;
}
+ private AbstractGraphicsDevice defaultSharedDevice = null;
+
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
glDrawableFactories.add(this);
@@ -168,6 +171,55 @@ public abstract class GLDrawableFactory {
protected abstract void shutdownInstance();
+ /**
+ * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection()}. for this factory<br>
+ * The implementation must return a non <code>null</code> default device, which must not be opened, ie. it's native handle may be <code>null</code>.
+ * @return the default shared device for this factory, eg. :0.0 on X11 desktop.
+ */
+ public abstract AbstractGraphicsDevice getDefaultDevice();
+
+ /**
+ * @return true if the device is compatible with this factory, ie. if it can be used for creation. Otherwise false.
+ */
+ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device);
+
+ /**
+ * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * or if a new shared context could be created and mapped. Otherwise return false.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device if <code>null</code>, the platform default device is being used
+ */
+ public final boolean getIsSharedContextAvailable(AbstractGraphicsDevice device) {
+ return null != getOrCreateSharedContext(device);
+ }
+
+ /**
+ * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device if <code>null</code>, the platform default device is being used
+ */
+ protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
+ if(null==device) {
+ device = getDefaultDevice();
+ if(null==device) {
+ throw new InternalError("no default device");
+ }
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device);
+ }
+ } else if( !getIsDeviceCompatible(device) ) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device);
+ }
+ return null;
+ }
+ return getOrCreateSharedContextImpl(device);
+ }
+ protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
+
/**
* Returns the sole GLDrawableFactory instance.
*
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index c5f5a8511..4111eb5a2 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -40,7 +40,6 @@ package javax.media.opengl;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.jvm.JVMUtil;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.common.util.VersionUtil;
import com.jogamp.nativewindow.NativeWindowVersion;
import com.jogamp.opengl.impl.Debug;
import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
@@ -50,6 +49,7 @@ import com.jogamp.opengl.JoglVersion;
import java.util.HashMap;
import java.util.Iterator;
import java.security.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.fixedfunc.GLPointerFunc;
import javax.media.nativewindow.NativeWindowFactory;
@@ -104,18 +104,22 @@ public class GLProfile {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
registerFactoryShutdownHook();
- initProfiles(firstUIActionOnProcess);
+ initProfilesForDefaultDevices(firstUIActionOnProcess);
return null;
}
});
-
- if(null==defaultGLProfile) {
- throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+glAvailabilityToString());
- }
}
}
/**
+ * Trigger eager initialization of GLProfiles for the given device,
+ * in case it isn't done yet.
+ */
+ public static void initProfiles(AbstractGraphicsDevice device) {
+ getProfileMap(device);
+ }
+
+ /**
* Manual shutdown method, may be called after your last JOGL use
* within the running JVM.<br>
* This method is called via the JVM shutdown hook.<br>
@@ -132,87 +136,169 @@ public class GLProfile {
// Query platform available OpenGL implementation
//
- public static final boolean isGL4bcAvailable() { return null != mappedProfiles.get(GL4bc); }
- public static final boolean isGL4Available() { return null != mappedProfiles.get(GL4); }
- public static final boolean isGL3bcAvailable() { return null != mappedProfiles.get(GL3bc); }
- public static final boolean isGL3Available() { return null != mappedProfiles.get(GL3); }
- public static final boolean isGL2Available() { return null != mappedProfiles.get(GL2); }
- public static final boolean isGLES2Available() { return null != mappedProfiles.get(GLES2); }
- public static final boolean isGLES1Available() { return null != mappedProfiles.get(GLES1); }
- public static final boolean isGL2ES1Available() { return null != mappedProfiles.get(GL2ES1); }
- public static final boolean isGL2ES2Available() { return null != mappedProfiles.get(GL2ES2); }
-
- public static final String glAvailabilityToString() {
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4bc);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3bc);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES2);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES1);
+ }
+
+ public static boolean isGL2ES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES1);
+ }
+
+ public static boolean isGL2ES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4bcAvailable() {
+ return isGL4bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4Available() {
+ return isGL4Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3bcAvailable() {
+ return isGL3bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3Available() {
+ return isGL3Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2Available() {
+ return isGL2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES2Available() {
+ return isGLES2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES1Available() {
+ return isGLES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES1Available() {
+ return isGL2ES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES2Available() {
+ return isGL2ES2Available(null);
+ }
+
+ public static String glAvailabilityToString(AbstractGraphicsDevice device) {
boolean avail;
StringBuffer sb = new StringBuffer();
+ validateInitialization();
+
+ if(null==device) {
+ device = defaultDevice;
+ }
+
sb.append("GLAvailability[Native[GL4bc ");
- avail=isGL4bcAvailable();
+ avail=isGL4bcAvailable(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 4, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL4 ");
- avail=isGL4Available();
+ avail=isGL4Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 4, GLContext.CTX_PROFILE_CORE);
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL3bc ");
- avail=isGL3bcAvailable();
+ avail=isGL3bcAvailable(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 3, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL3 ");
- avail=isGL3Available();
+ avail=isGL3Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 3, GLContext.CTX_PROFILE_CORE);
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL2 ");
- avail=isGL2Available();
+ avail=isGL2Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 2, GLContext.CTX_PROFILE_COMPAT);
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL2ES1 ");
- sb.append(isGL2ES1Available());
+ sb.append(isGL2ES1Available(device));
sb.append(", GLES1 ");
- avail=isGLES1Available();
+ avail=isGLES1Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 1, GLContext.CTX_PROFILE_ES);
+ glAvailabilityToString(device, sb, 1, GLContext.CTX_PROFILE_ES);
}
sb.append(", GL2ES2 ");
- sb.append(isGL2ES2Available());
+ sb.append(isGL2ES2Available(device));
sb.append(", GLES2 ");
- avail=isGLES2Available();
+ avail=isGLES2Available(device);
sb.append(avail);
if(avail) {
- glAvailabilityToString(sb, 2, GLContext.CTX_PROFILE_ES);
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_ES);
}
sb.append("], Profiles[");
- for(Iterator i=mappedProfiles.values().iterator(); i.hasNext(); ) {
+ for(Iterator i=getProfileMap(device).values().iterator(); i.hasNext(); ) {
sb.append(((GLProfile)i.next()).toString());
sb.append(", ");
}
sb.append(", default ");
- sb.append(defaultGLProfile);
+ sb.append(getDefault(device));
sb.append("]]");
return sb.toString();
}
+ /** Uses the default device */
+ public static String glAvailabilityToString() {
+ return glAvailabilityToString(null);
+ }
+
//
// Public (user-visible) profiles
//
@@ -249,6 +335,9 @@ public class GLProfile {
/** The intersection of the desktop GL3 and GL2 profile */
public static final String GL2GL3 = "GL2GL3";
+ /** The default profile, used for the device default profile map */
+ private static final String GL_DEFAULT = "GL_DEFAULT";
+
/**
* All GL Profiles in the order of default detection.
* Desktop compatibility profiles (the one with fixed function pipeline) comes first.
@@ -337,12 +426,14 @@ public class GLProfile {
* It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
* @see #GL_PROFILE_LIST_ALL
*/
- public static final GLProfile getDefault() {
- validateInitialization();
- if(null==defaultGLProfile) {
- throw new GLException("No default profile available"); // should never be reached
- }
- return defaultGLProfile;
+ public static GLProfile getDefault(AbstractGraphicsDevice device) {
+ GLProfile glp = get(device, GL_DEFAULT);
+ return glp;
+ }
+
+ /** Uses the default device */
+ public static GLProfile getDefault() {
+ return getDefault(defaultDevice);
}
/**
@@ -352,7 +443,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
*/
- public static final GLProfile getMaxFixedFunc()
+ public static GLProfile getMaxFixedFunc(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxFixedFunc()
throws GLException
{
return get(GL_PROFILE_LIST_MAX_FIXEDFUNC);
@@ -365,7 +463,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_MAX_PROGSHADER
*/
- public static final GLProfile getMaxProgrammable()
+ public static GLProfile getMaxProgrammable(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxProgrammable()
throws GLException
{
return get(GL_PROFILE_LIST_MAX_PROGSHADER);
@@ -378,7 +483,14 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_GL2ES1
*/
- public static final GLProfile getGL2ES1()
+ public static GLProfile getGL2ES1(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES1);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES1()
throws GLException
{
return get(GL_PROFILE_LIST_GL2ES1);
@@ -391,29 +503,40 @@ public class GLProfile {
* @throws GLException if no implementation for the given profile is found.
* @see #GL_PROFILE_LIST_GL2ES2
*/
- public static final GLProfile getGL2ES2()
+ public static GLProfile getGL2ES2(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES2()
throws GLException
{
return get(GL_PROFILE_LIST_GL2ES2);
}
/** Returns a GLProfile object.
- * Verfifies the given profile and chooses an apropriate implementation.
+ * verifies the given profile and chooses an appropriate implementation.
* A generic value of <code>null</code> or <code>GL</code> will result in
* the default profile.
*
* @throws GLException if no implementation for the given profile is found.
*/
- public static final GLProfile get(String profile)
+ public static GLProfile get(AbstractGraphicsDevice device, String profile)
throws GLException
{
- validateInitialization();
- if(null==profile || profile.equals("GL")) return getDefault();
- GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
- if(null==glProfile) {
- throw new GLException("No implementation for profile "+profile+" available");
+ if(null==profile || profile.equals("GL")) {
+ profile = GL_DEFAULT;
}
- return glProfile;
+ return (GLProfile) getProfileMap(device).get(profile);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String profile)
+ throws GLException
+ {
+ return get(defaultDevice, profile);
}
/**
@@ -422,36 +545,43 @@ public class GLProfile {
*
* @throws GLException if no implementation for the given profile is found.
*/
- public static final GLProfile get(String[] profiles)
+ public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
throws GLException
{
- validateInitialization();
+ HashMap map = getProfileMap(device);
for(int i=0; i<profiles.length; i++) {
String profile = profiles[i];
- GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
+ GLProfile glProfile = (GLProfile) map.get(profile);
if(null!=glProfile) {
return glProfile;
}
}
- throw new GLException("Profiles "+array2String(profiles)+" not available");
+ throw new GLException("Profiles "+array2String(profiles)+" not available on device "+device);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String[] profiles)
+ throws GLException
+ {
+ return get(defaultDevice, profiles);
}
/** Indicates whether the native OpenGL ES1 profile is in use.
* This requires an EGL interface.
*/
- public static final boolean usesNativeGLES1(String profileImpl) {
+ public static boolean usesNativeGLES1(String profileImpl) {
return GLES1.equals(profileImpl);
}
/** Indicates whether the native OpenGL ES2 profile is in use.
- * This requires an EGL interface.
+ * This requires an EGL or ES2 compatible interface.
*/
- public static final boolean usesNativeGLES2(String profileImpl) {
+ public static boolean usesNativeGLES2(String profileImpl) {
return GLES2.equals(profileImpl);
}
/** Indicates whether either of the native OpenGL ES profiles are in use. */
- public static final boolean usesNativeGLES(String profileImpl) {
+ public static boolean usesNativeGLES(String profileImpl) {
return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
}
@@ -922,20 +1052,16 @@ public class GLProfile {
private static /*final*/ boolean isAWTAvailable;
+ private static /*final*/ boolean hasDesktopGL;
private static /*final*/ boolean hasGL234Impl;
- private static /*final*/ boolean hasGL4bcImpl;
- private static /*final*/ boolean hasGL4Impl;
- private static /*final*/ boolean hasGL3bcImpl;
- private static /*final*/ boolean hasGL3Impl;
- private static /*final*/ boolean hasGL2Impl;
private static /*final*/ boolean hasGLES2Impl;
private static /*final*/ boolean hasGLES1Impl;
- /** The JVM/process wide default GL profile **/
- private static /*final*/ GLProfile defaultGLProfile;
-
- /** All GLProfiles */
- private static /*final*/ HashMap/*<String, GLProfile>*/ mappedProfiles;
+ private static /*final*/ GLDrawableFactoryImpl eglFactory;
+ private static /*final*/ GLDrawableFactoryImpl desktopFactory;
+ private static /*final*/ AbstractGraphicsDevice defaultDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultDesktopDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultEGLDevice;
static boolean initialized = false;
@@ -947,7 +1073,11 @@ public class GLProfile {
* Tries the profiles implementation and native libraries.
* Throws an GLException if no profile could be found at all.
*/
- private static void initProfiles(boolean firstUIActionOnProcess) {
+ private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
+
+ if(DEBUG) {
+ System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess);
+ }
NativeWindowFactory.initSingleton(firstUIActionOnProcess);
@@ -957,17 +1087,7 @@ public class GLProfile {
ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas", classloader) ; // JOGL
hasGL234Impl = ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.gl4.GL4bcImpl", classloader);
- hasGL4bcImpl = hasGL234Impl;
- hasGL4Impl = hasGL234Impl;
- hasGL3bcImpl = hasGL234Impl;
- hasGL3Impl = hasGL234Impl;
- hasGL2Impl = hasGL234Impl;
- mappedProfiles = computeProfileMap();
-
- boolean hasDesktopGL = false;
- boolean hasNativeOSFactory = false;
- Throwable t;
-
+
//
// Iteration of desktop GL availability detection
// utilizing the detected GL version in the shared context.
@@ -975,14 +1095,12 @@ public class GLProfile {
// - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
// which will register at GLContext ..
//
-
- t=null;
+ Throwable t=null;
// if successfull it has a shared dummy drawable and context created
try {
- GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
- hasNativeOSFactory = null != factory;
- if(hasNativeOSFactory) {
- DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) factory.getGLDynamicLookupHelper(0);
+ desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
+ if(null != desktopFactory) {
+ DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(0);
if(null!=glLookupHelper) {
hasDesktopGL = glLookupHelper.hasGLBinding();
}
@@ -998,43 +1116,29 @@ public class GLProfile {
if(null!=t) {
t.printStackTrace();
}
- if(!hasNativeOSFactory) {
- System.err.println("Info: GLProfile.init - Native platform GLDrawable factory not available");
+ if(null == desktopFactory) {
+ System.err.println("Info: GLProfile.init - Desktop GLDrawable factory not available");
}
}
- if(hasDesktopGL && !GLContext.mappedVersionsAvailableSet) {
- // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
- // so we have to add the usual suspect
- GLContext.mapVersionAvailable(2, GLContext.CTX_PROFILE_COMPAT, 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
- }
-
- if(!hasNativeOSFactory) {
+ if(null == desktopFactory) {
hasDesktopGL = false;
hasGL234Impl = false;
- hasGL4bcImpl = false;
- hasGL4Impl = false;
- hasGL3bcImpl = false;
- hasGL3Impl = false;
- hasGL2Impl = false;
} else {
- hasGL4bcImpl = hasGL4bcImpl && GLContext.isGL4bcAvailable();
- hasGL4Impl = hasGL4Impl && GLContext.isGL4Available();
- hasGL3bcImpl = hasGL3bcImpl && GLContext.isGL3bcAvailable();
- hasGL3Impl = hasGL3Impl && GLContext.isGL3Available();
- hasGL2Impl = hasGL2Impl && GLContext.isGL2Available();
+ defaultDesktopDevice = desktopFactory.getDefaultDevice();
+ defaultDevice = defaultDesktopDevice;
}
if ( ReflectionUtil.isClassAvailable("com.jogamp.opengl.impl.egl.EGLDrawableFactory", classloader) ) {
t=null;
try {
- GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
- if(null != factory) {
- GLDynamicLookupHelper eglLookupHelper = factory.getGLDynamicLookupHelper(2);
+ eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
+ if(null != eglFactory) {
+ GLDynamicLookupHelper eglLookupHelper = eglFactory.getGLDynamicLookupHelper(2);
if(null!=eglLookupHelper) {
hasGLES2Impl = eglLookupHelper.isLibComplete();
}
- eglLookupHelper = factory.getGLDynamicLookupHelper(1);
+ eglLookupHelper = eglFactory.getGLDynamicLookupHelper(1);
if(null!=eglLookupHelper) {
hasGLES1Impl = eglLookupHelper.isLibComplete();
}
@@ -1048,30 +1152,151 @@ public class GLProfile {
} catch (RuntimeException re) {
t=re;
}
- if(DEBUG && null!=t) {
- t.printStackTrace();
+ if(DEBUG) {
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ if(null == eglFactory) {
+ System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
+ }
}
}
- if(hasGLES2Impl) {
- GLContext.mapVersionAvailable(2, GLContext.CTX_PROFILE_ES, 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+
+ if(null == eglFactory) {
+ hasGLES2Impl = false;
+ hasGLES1Impl = false;
+ } else {
+ defaultEGLDevice = eglFactory.getDefaultDevice();
+ if (null==defaultDevice) {
+ defaultDevice = defaultEGLDevice;
+ }
+ }
+
+ boolean addedAnyProfile = initProfilesForDevice(defaultDesktopDevice);
+ addedAnyProfile = addedAnyProfile || initProfilesForDevice(defaultEGLDevice);
+
+ if(DEBUG) {
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.print(JoglVersion.getInstance());
+
+ System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
+ System.err.println("GLProfile.init has desktopFactory "+(null!=desktopFactory));
+ System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL);
+ System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
+ System.err.println("GLProfile.init has eglFactory "+(null!=eglFactory));
+ System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
+ System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.init defaultDesktopDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultEGLDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultDevice "+defaultDevice);
+ }
+
+ if(!addedAnyProfile) {
+ throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+ glAvailabilityToString());
}
- if(hasGLES1Impl) {
- GLContext.mapVersionAvailable(1, GLContext.CTX_PROFILE_ES, 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+
+ /**
+ * @param device the device for which profiles shall be initialized
+ * @return true if any profile for the device exists, otherwise false
+ */
+ private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ boolean isSet = GLContext.getAvailableGLVersionsSet(device);
+
+ if(DEBUG) {
+ String msg = "Info: GLProfile.initProfilesForDevice: "+device.getConnection()+", isSet "+isSet;
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ // System.err.println(msg);
+ }
+ if(isSet) {
+ return null != GLProfile.getDefault(device);
+ }
+
+ boolean addedAnyProfile = false;
+
+ if( hasDesktopGL && desktopFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all Desktop and EGL profiles ..
+ computeProfileMap(device, true /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean desktopSharedCtxAvail = desktopFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": desktop Shared Ctx "+desktopSharedCtxAvail);
+ }
+ if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_COMPAT,
+ 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
+ }
+ computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ addedAnyProfile = null != GLProfile.getDefault(device);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLProfile: DesktopFactory - Device is not available: "+device.getConnection());
+ }
}
- mappedProfiles = computeProfileMap();
+ if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all EGL profiles ..
+ computeProfileMap(device, false /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean eglSharedCtxAvail = eglFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": egl Shared Ctx "+eglSharedCtxAvail);
+ }
+ if(hasGLES2Impl && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_ES,
+ 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ if(hasGLES1Impl && null == GLContext.getAvailableGLVersion(device, 1, GLContext.CTX_PROFILE_ES)) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 1, GLContext.CTX_PROFILE_ES,
+ 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ addedAnyProfile = addedAnyProfile || null != GLProfile.getDefault(device);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLProfile: EGLFactory - Device is not available: "+device.getConnection());
+ }
+ }
+ if(!GLContext.getAvailableGLVersionsSet(device)) {
+ GLContext.setAvailableGLVersionsSet(device);
+ }
if (DEBUG) {
- System.err.println(GlueGenVersion.getInstance().getInfo(null));
- System.err.println(NativeWindowVersion.getInstance().getInfo(null));
- System.err.print(JoglVersion.getInstance().getInfo(null));
- System.err.println("GLProfile.init firstUIActionOnProcess "+firstUIActionOnProcess);
- System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
- System.err.println("GLProfile.init hasNativeOSFactory "+hasNativeOSFactory);
- System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL);
- System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
- System.err.println("GLProfile.init "+glAvailabilityToString());
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": added profile(s): "+addedAnyProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
}
+
+ return addedAnyProfile;
+ }
+
+ public static AbstractGraphicsDevice getDefaultDevice() {
+ validateInitialization();
+ return defaultDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultDesktopDevice() {
+ validateInitialization();
+ return defaultDesktopDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultEGLDevice() {
+ validateInitialization();
+ return defaultEGLDevice;
}
private static synchronized void registerFactoryShutdownHook() {
@@ -1102,7 +1327,7 @@ public class GLProfile {
}
}
- private static final String array2String(String[] list) {
+ private static String array2String(String[] list) {
StringBuffer msg = new StringBuffer();
msg.append("[");
for (int i = 0; i < list.length; i++) {
@@ -1114,8 +1339,8 @@ public class GLProfile {
return msg.toString();
}
- private static final void glAvailabilityToString(StringBuffer sb, int major, int profile) {
- String str = GLContext.getGLVersionAvailable(major, profile);
+ private static void glAvailabilityToString(AbstractGraphicsDevice device, StringBuffer sb, int major, int profile) {
+ String str = GLContext.getAvailableGLVersionAsString(device, major, profile);
if(null==str) {
throw new GLException("Internal Error");
}
@@ -1124,103 +1349,152 @@ public class GLProfile {
sb.append("]");
}
- private static HashMap computeProfileMap() {
- defaultGLProfile=null;
- HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length);
+ private static void computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) {
+ if (DEBUG) {
+ System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", eglCtxUndef "+eglCtxUndef);
+ }
+ GLProfile defaultGLProfile = null;
+ HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length + 1 /* default */);
for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
String profile = GL_PROFILE_LIST_ALL[i];
- String profileImpl = computeProfileImpl(profile);
+ String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, eglCtxUndef);
if(null!=profileImpl) {
GLProfile glProfile = new GLProfile(profile, profileImpl);
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile);
+ System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
}
if(null==defaultGLProfile) {
defaultGLProfile=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init default "+glProfile);
+ System.err.println("GLProfile.init map default "+glProfile+" on device "+device.getConnection());
}
}
} else {
if (DEBUG) {
- System.err.println("GLProfile.init map *** no mapping for "+profile);
+ System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getConnection());
}
}
}
- return _mappedProfiles;
- }
-
- private static final String getGLImplBaseClassName(String profileImpl) {
- if ( GL4bc.equals(profileImpl) ||
- GL4.equals(profileImpl) ||
- GL3bc.equals(profileImpl) ||
- GL3.equals(profileImpl) ||
- GL2.equals(profileImpl) ) {
- return "com.jogamp.opengl.impl.gl4.GL4bc";
- } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es1.GLES1";
- } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
- return "com.jogamp.opengl.impl.es2.GLES2";
- } else {
- throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ if(null!=defaultGLProfile) {
+ _mappedProfiles.put(GL_DEFAULT, defaultGLProfile);
}
+ setProfileMap(device, _mappedProfiles);
}
/**
* Returns the profile implementation
*/
- private static String computeProfileImpl(String profile) {
+ private static String computeProfileImpl(AbstractGraphicsDevice device, String profile, boolean desktopCtxUndef, boolean eglCtxUndef) {
if (GL2ES1.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3bcImpl) {
- return GL3bc;
- } else if(hasGL4bcImpl) {
- return GL4bc;
- } else if(hasGLES1Impl) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ }
+ }
+ if(hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
return GLES1;
}
} else if (GL2ES2.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3Impl) {
- return GL3;
- } else if(hasGL4Impl) {
- return GL4;
- } else if(hasGLES2Impl) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
+ }
+ if(hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
return GLES2;
}
} else if(GL2GL3.equals(profile)) {
- if(hasGL2Impl) {
- return GL2;
- } else if(hasGL3bcImpl) {
- return GL3bc;
- } else if(hasGL4bcImpl) {
- return GL4bc;
- } else if(hasGL3Impl) {
- return GL3;
- } else if(hasGL4Impl) {
- return GL4;
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
}
- } else if(GL4bc.equals(profile) && hasGL4bcImpl) {
+ } else if(GL4bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device))) {
return GL4bc;
- } else if(GL4.equals(profile) && hasGL4Impl) {
+ } else if(GL4.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device))) {
return GL4;
- } else if(GL3bc.equals(profile) && hasGL3bcImpl) {
+ } else if(GL3bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device))) {
return GL3bc;
- } else if(GL3.equals(profile) && hasGL3Impl) {
+ } else if(GL3.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device))) {
return GL3;
- } else if(GL2.equals(profile) && hasGL2Impl) {
+ } else if(GL2.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device))) {
return GL2;
- } else if(GLES2.equals(profile) && hasGLES2Impl) {
+ } else if(GLES2.equals(profile) && hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
return GLES2;
- } else if(GLES1.equals(profile) && hasGLES1Impl) {
+ } else if(GLES1.equals(profile) && hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
return GLES1;
}
return null;
}
+ private static String getGLImplBaseClassName(String profileImpl) {
+ if ( GL4bc.equals(profileImpl) ||
+ GL4.equals(profileImpl) ||
+ GL3bc.equals(profileImpl) ||
+ GL3.equals(profileImpl) ||
+ GL2.equals(profileImpl) ) {
+ return "com.jogamp.opengl.impl.gl4.GL4bc";
+ } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es1.GLES1";
+ } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
+ return "com.jogamp.opengl.impl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ }
+ }
+
+ private static /*final*/ HashMap/*<device_connection, HashMap<GL-String, GLProfile>*/ deviceConn2ProfileMap = new HashMap();
+
+ /**
+ * This implementation support lazy initialization, while avoiding recursion/deadlocks.<br>
+ * If no mapping 'device -> GLProfiles-Map' exists yet, it triggers<br>
+ * - create empty mapping device -> GLProfiles-Map <br>
+ * - initialization<br<
+ *
+ * @param device the key 'device -> GLProfiles-Map'
+ * @return the GLProfile HashMap
+ */
+ private static HashMap getProfileMap(AbstractGraphicsDevice device) {
+ validateInitialization();
+ if(null==device) {
+ device = defaultDevice;
+ }
+ String deviceKey = GLContext.getUniqueDeviceString(device);
+ HashMap map = (HashMap) deviceConn2ProfileMap.get(deviceKey);
+ if(null==map) {
+ map = new HashMap();
+ synchronized ( deviceConn2ProfileMap ) {
+ deviceConn2ProfileMap.put(deviceKey, map);
+ }
+ initProfilesForDevice(device);
+ }
+ return map;
+ }
+
+ private static void setProfileMap(AbstractGraphicsDevice device, HashMap/*<GL-String, GLProfile>*/mappedProfiles) {
+ validateInitialization();
+ synchronized ( deviceConn2ProfileMap ) {
+ deviceConn2ProfileMap.put(GLContext.getUniqueDeviceString(device), mappedProfiles);
+ }
+ }
+
private GLProfile(String profile, String profileImpl) {
this.profile = profile;
this.profileImpl = profileImpl;
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 9db718bfb..c0f2736fb 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -83,7 +83,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
static {
DEBUG = Debug.debug("GLCanvas");
- defaultGLProfile = GLProfile.getDefault();
+ defaultGLProfile = GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
}
private GLProfile glProfile;
@@ -795,11 +795,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
* A most simple JOGL AWT test entry
*/
public static void main(String args[]) {
- System.err.println(GlueGenVersion.getInstance().getInfo(null));
- System.err.println(NativeWindowVersion.getInstance().getInfo(null));
- System.err.print(JoglVersion.getInstance().getInfo(null));
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.print(JoglVersion.getInstance());
- GLCapabilities caps = new GLCapabilities( GLProfile.getDefault() );
+ GLCapabilities caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
Frame frame = new Frame("JOGL AWT Test");
GLCanvas glCanvas = new GLCanvas(caps);
@@ -809,7 +809,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
glCanvas.addGLEventListener(new GLEventListener() {
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
- System.err.println(JoglVersion.getInstance().getGLInfo(gl, null));
+ System.err.println(JoglVersion.getInstance().toString(gl));
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index b9bbf71c2..955e51e69 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -1275,7 +1275,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
public GLProfile getGLProfile() {
// FIXME: should do better than this; is it possible to using only platform-independent code?
- return GLProfile.getDefault();
+ return GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
}
public void handleReshape() {