diff options
author | Sven Gothel <[email protected]> | 2010-11-14 09:04:45 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-14 09:04:45 +0100 |
commit | 83d3a3f2ea8dc328e621b3abbe671f46379c7e65 (patch) | |
tree | b7fafe2ef1610a6be0723316ae5bf5938b9f222d /src/jogl/classes/javax/media/opengl/GLContext.java | |
parent | c3bfb82614e9fa0f8ea7169cd412a6f0c71973e0 (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/media/opengl/GLContext.java')
-rw-r--r-- | src/jogl/classes/javax/media/opengl/GLContext.java | 347 |
1 files changed, 220 insertions, 127 deletions
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(); + } } |