diff options
Diffstat (limited to 'src/jogl/classes/javax/media/opengl/GLContext.java')
-rw-r--r-- | src/jogl/classes/javax/media/opengl/GLContext.java | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java new file mode 100644 index 000000000..b859dee00 --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -0,0 +1,780 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package javax.media.opengl; + +import java.util.HashMap; +import java.util.HashSet; +import javax.media.nativewindow.AbstractGraphicsDevice; +import jogamp.opengl.Debug; + +/** Abstraction for an OpenGL rendering context. In order to perform + OpenGL rendering, a context must be "made current" on the current + thread. OpenGL rendering semantics specify that only one context + may be current on the current thread at any given time, and also + that a given context may be current on only one thread at any + given time. Because components can be added to and removed from + the component hierarchy at any time, it is possible that the + underlying OpenGL context may need to be destroyed and recreated + multiple times over the lifetime of a given component. This + 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}. */ + public static final int CONTEXT_CURRENT = 1; + /** 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; + + /** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL software implementation */ + protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 0; + /** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL hardware implementation */ + protected static final int CTX_IMPL_ACCEL_HARD = 1 << 1; + + private static ThreadLocal currentContext = new ThreadLocal(); + + private HashMap/*<int, Object>*/ attachedObjects = new HashMap(); + + /** 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. + */ + public abstract GLDrawable getGLDrawable(); + + /** + * Return availability of GL read drawable. + * @return true if a GL read drawable is supported with your driver, otherwise false. + */ + public abstract boolean isGLReadDrawableAvailable(); + + /** + * Set the read GLDrawable for read framebuffer operations.<br> + * The caller should query if this feature is supported via {@link #isGLReadDrawableAvailable()}. + * + * @param read the read GLDrawable for read framebuffer operations. + * If null is passed, the default write drawable will be set. + * + * @throws GLException in case a read drawable is not supported + * and the given drawable is not null and not equal to the internal write drawable. + * + * @see #isGLReadDrawableAvailable() + * @see #getGLReadDrawable() + */ + public abstract void setGLReadDrawable(GLDrawable read); + + /** + * Returns the read GLDrawable this context uses for read framebuffer operations. + * @see #isGLReadDrawableAvailable() + * @see #setGLReadDrawable(javax.media.opengl.GLDrawable) + */ + public abstract GLDrawable getGLReadDrawable(); + + /** + * Makes this GLContext current on the calling thread. + * + * There are two return values that indicate success and one that + * indicates failure. A return value of CONTEXT_CURRENT_NEW + * indicates that that context has been made current, and that + * this is the first time this context has been made current, or + * that the state of the underlying context or drawable may have + * changed since the last time this context was made current. In + * this case, the application may wish to initialize the state. A + * return value of CONTEXT_CURRENT indicates that the context has + * been made currrent, with its previous state restored. + * + * If the context could not be made current (for example, because + * the underlying drawable has not ben realized on the display) , + * a value of CONTEXT_NOT_CURRENT is returned. + * + * If the context is in use by another thread at the time of the + * call, then if isSynchronized() is true the call will + * block. If isSynchronized() is false, an exception will be + * thrown and the context will remain current on the other thread. + * + * @return CONTEXT_CURRENT if the context was successfully made current + * @return CONTEXT_CURRENT_NEW if the context was successfully made + * current, but need to be initialized. + * + * @return CONTEXT_NOT_CURRENT if the context could not be made current. + * + * @throws GLException if synchronization is disabled and the + * context is current on another thread, or because the context + * could not be created or made current due to non-recoverable, + * window system-specific errors. + */ + public abstract int makeCurrent() throws GLException; + + /** + * Releases control of this GLContext from the current thread. + * + * @throws GLException if the context had not previously been made + * current on the current thread + */ + public abstract void release() throws GLException; + + /** + * Copies selected groups of OpenGL state variables from the + * supplied source context into this one. The <code>mask</code> + * parameter indicates which groups of state variables are to be + * copied. <code>mask</code> contains the bitwise OR of the same + * symbolic names that are passed to the GL command {@link + * GL#glPushAttrib glPushAttrib}. The single symbolic constant + * {@link GL2#GL_ALL_ATTRIB_BITS GL_ALL_ATTRIB_BITS} can be used to + * copy the maximum possible portion of rendering state. <P> + * + * Not all values for GL state can be copied. For example, pixel + * pack and unpack state, render mode state, and select and feedback + * state are not copied. The state that can be copied is exactly the + * state that is manipulated by the GL command {@link + * GL2#glPushAttrib glPushAttrib}. <P> + * + * On most platforms, this context may not be current to any thread, + * including the calling thread, when this method is called. Some + * platforms have additional requirements such as whether this + * context or the source context must occasionally be made current + * in order for the results of the copy to be seen; these + * requirements are beyond the scope of this specification. + * + * @param source the source OpenGL context from which to copy state + * @param mask a mask of symbolic names indicating which groups of state to copy + + * @throws GLException if an OpenGL-related error occurred + */ + public abstract void copy(GLContext source, int mask) throws GLException; + + /** + * Returns the GL object bound to this thread current context. + * If no context is current, throw an GLException + * + * @return the current context's GL object on this thread + * @throws GLException if no context is current + */ + public static GL getCurrentGL() throws GLException { + GLContext glc = getCurrent(); + if(null==glc) { + throw new GLException("No OpenGL context current on this thread"); + } + return glc.getGL(); + } + + /** + * Returns this thread current context. + * If no context is current, returns null. + * + * @return the context current on this thread, or null if no context + * is current. + */ + public static GLContext getCurrent() { + return (GLContext) currentContext.get(); + } + + /** + * @return true if this GLContext is current on this thread + */ + public final boolean isCurrent() { + return getCurrent() == this ; + } + + /** + * Sets the thread-local variable returned by {@link #getCurrent} + * and has no other side-effects. For use by third parties adding + * new GLContext implementations; not for use by end users. + */ + protected static void setCurrent(GLContext cur) { + currentContext.set(cur); + } + + /** + * Destroys this OpenGL context and frees its associated + * resources. The context should have been released before this + * method is called. + */ + public abstract void destroy(); + + /** + * Returns true if 'makeCurrent' will exhibit synchronized behavior. + */ + public abstract boolean isSynchronized(); + + /** + * Determines whether 'makeCurrent' will exhibit synchronized behavior. + */ + public abstract void setSynchronized(boolean isSynchronized); + + /** + * 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(); + + /** + * Sets the GL pipeline object for this GLContext. + * + * @return the set GL pipeline or null if not successful + */ + public abstract GL setGL(GL gl); + + /** + * Returns the native GL context handle + */ + public final long getHandle() { return contextHandle; } + + /** + * Indicates whether the underlying OpenGL context has been created. + */ + public final boolean isCreated() { + return 0 != contextHandle; + } + + /** + * Returns the attached user object for the given name to this GLContext. + */ + public final Object getAttachedObject(int name) { + return attachedObjects.get(new Integer(name)); + } + + /** + * Returns the attached user object for the given name to this GLContext. + */ + public final Object getAttachedObject(String name) { + return attachedObjects.get(name); + } + + /** + * Sets the attached user object for the given name to this GLContext. + * Returns the previously set object or null. + */ + public final Object putAttachedObject(int name, Object obj) { + return attachedObjects.put(new Integer(name), obj); + } + + /** + * Sets the attached user object for the given name to this GLContext. + * Returns the previously set object or null. + */ + public final Object putAttachedObject(String name, Object obj) { + return attachedObjects.put(name, obj); + } + + /** + * Classname, GL, GLDrawable + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()); + sb.append(" ["); + this.append(sb); + sb.append("] "); + return sb.toString(); + } + + public final StringBuffer append(StringBuffer sb) { + sb.append("OpenGL "); + sb.append(getGLVersionMajor()); + sb.append("."); + sb.append(getGLVersionMinor()); + sb.append(", options 0x"); + sb.append(Integer.toHexString(ctxOptions)); + sb.append(", "); + sb.append(getGLVersion()); + sb.append(", handle "); + sb.append(toHexString(contextHandle)); + sb.append(", "); + sb.append(getGL()); + if(getGLDrawable()!=getGLReadDrawable()) { + sb.append(",\n\tRead Drawable : "); + sb.append(getGLReadDrawable()); + sb.append(",\n\tWrite Drawable: "); + sb.append(getGLDrawable()); + } else { + sb.append(",\n\tDrawable: "); + sb.append(getGLDrawable()); + } + return sb; + } + + /** Returns a non-null (but possibly empty) string containing the + space-separated list of available platform-dependent (e.g., WGL, + GLX) extensions. Can only be called while this context is + current. */ + public abstract String getPlatformExtensionsString(); + + /** Returns a non-null (but possibly empty) string containing the + space-separated list of available extensions. + Can only be called while this context is current. + This is equivalent to + {@link javax.media.opengl.GL#glGetString(int) glGetString}({@link javax.media.opengl.GL#GL_EXTENSIONS GL_EXTENSIONS}) + */ + public abstract String getGLExtensionsString(); + + public final int getGLVersionMajor() { return ctxMajorVersion; } + public final int getGLVersionMinor() { return ctxMinorVersion; } + public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); } + public final boolean isGLCoreProfile() { return ( 0 != ( CTX_PROFILE_CORE & ctxOptions ) ); } + public final boolean isGLEmbeddedProfile() { return ( 0 != ( CTX_PROFILE_ES & ctxOptions ) ); } + public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); } + public final boolean isCreatedWithARBMethod() { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); } + + /** + * Returns a valid OpenGL version string, ie<br> + * <pre> + * major.minor ([option]?[options,]*) - gl-version + * </pre><br> + * + * <ul> + * <li> options + * <ul> + * <li> <code>old</code> refers to the non ARB_create_context created context</li> + * <li> <code>new</code> refers to the ARB_create_context created context</li> + * <li> <code>compatible profile</code></li> + * <li> <code>core profile</code></li> + * <li> <code>forward compatible</code></li> + * <li> <code>any</code> refers to the non forward compatible context</li> + * <li> <code>ES</code> refers to the GLES context variant</li> + * </ul></li> + * <li> <i>gl-version</i> the GL_VERSION string</li> + * </ul> + * + * e.g.: + * <table border="0"> + * <tr> <td></td> <td></td> </tr> + * <tr> + * <td>row 2, cell 1</td> + * <td>row 2, cell 2</td> + * </tr> + * </table> + * + * <table border="0"> + * <tr><td></td> <td>ES2</td> <td><code>2.0 (ES, any, new) - 2.0 ES Profile</code></td></tr> + * <tr><td>ATI</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.2.9704 Compatibility Profile Context</code></td></tr> + * <tr><td>ATI</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> + * <tr><td>ATI</td><td>GL3bc</td><td><code>3.3 (compatibility profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> + * <tr><td>NV</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.0.0 NVIDIA 195.36.07.03</code></td></tr> + * <tr><td>NV</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> + * <tr><td>NV</td><td>GL3bc</td> <td><code>3.3 (compatibility profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> + * </table> + */ + public final String getGLVersion() { + return ctxVersionString; + } + + public final boolean isGL4bc() { + return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED) + && 0 != (ctxOptions & CTX_PROFILE_COMPAT); + } + + public final boolean isGL4() { + return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED) + && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)); + } + + public final boolean isGL3bc() { + 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 || ctxMajorVersion==3 && ctxMinorVersion>=1 ) + && 0 != (ctxOptions & CTX_IS_ARB_CREATED) + && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)); + } + + public final boolean isGL2() { + return ctxMajorVersion>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT); + } + + public final boolean isGL2GL3() { + return isGL2() || isGL3(); + } + + public final boolean isGLES1() { + return ctxMajorVersion==1 && 0!=(ctxOptions & CTX_PROFILE_ES); + } + + public final boolean isGLES2() { + return ctxMajorVersion==2 && 0!=(ctxOptions & CTX_PROFILE_ES); + } + + public final boolean isGLES() { + return isGLEmbeddedProfile(); + } + + public final boolean isGL2ES1() { + return isGL2() || isGLES1() ; + } + + public final boolean isGL2ES2() { + return isGL2GL3() || isGLES2() ; + } + + public final boolean hasGLSL() { + return isGL2ES2() ; + } + + public static final int GL_VERSIONS[][] = { + /* 0.*/ { -1 }, + /* 1.*/ { 0, 1, 2, 3, 4, 5 }, + /* 2.*/ { 0, 1 }, + /* 3.*/ { 0, 1, 2, 3 }, + /* 4.*/ { 0, 1 } }; + + public static final int getMaxMajor() { + return GL_VERSIONS.length-1; + } + + public static final int getMaxMinor(int major) { + if(1>major || major>=GL_VERSIONS.length) return -1; + return GL_VERSIONS[major].length-1; + } + + public static final boolean isValidGLVersion(int major, int minor) { + if(1>major || major>=GL_VERSIONS.length) return false; + if(0>minor || minor>=GL_VERSIONS[major].length) return false; + return true; + } + + public static final boolean decrementGLVersion(int major[], int minor[]) { + if(null==major || major.length<1 ||null==minor || minor.length<1) { + throw new GLException("invalid array arguments"); + } + int m = major[0]; + int n = minor[0]; + if(!isValidGLVersion(m, n)) return false; + + // decrement .. + n -= 1; + if(n < 0) { + m -= 1; + n = GL_VERSIONS[m].length-1; + } + if(!isValidGLVersion(m, n)) return false; + major[0]=m; + minor[0]=n; + + 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 + // + + /** + * @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 getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) { + return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0)); + } + + protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) { + synchronized ( deviceVersionsAvailableSet ) { + return deviceVersionsAvailableSet.contains(device.getUniqueID()); + } + } + + protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) { + synchronized ( deviceVersionsAvailableSet ) { + String devKey = device.getUniqueID(); + 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 jogamp.opengl.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 + */ + 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 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; + } + + /** + * @param reqMajor Key Value either 1, 2, 3 or 4 + * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} + * @param major if not null, returns the used major version + * @param minor if not null, returns the used minor version + * @param ctp if not null, returns the used context profile + */ + 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); + } + if(null!=minor) { + minor[0] = getComposed8bit(val, 2); + } + if(null!=ctp) { + ctp[0] = getComposed8bit(val, 3); + } + return true; + } + + /** + * @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 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 String getGLVersion(int major, int minor, int ctp, String gl_version) { + boolean needColon = false; + StringBuffer sb = new StringBuffer(); + sb.append(major); + sb.append("."); + sb.append(minor); + sb.append(" ("); + needColon = appendString(sb, "ES", needColon, 0 != ( CTX_PROFILE_ES & ctp )); + needColon = appendString(sb, "compatibility profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp )); + needColon = appendString(sb, "core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp )); + needColon = appendString(sb, "forward compatible", needColon, 0 != ( CTX_OPTION_FORWARD & ctp )); + needColon = appendString(sb, "any", needColon, 0 != ( CTX_OPTION_ANY & ctp )); + needColon = appendString(sb, "new", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp )); + needColon = appendString(sb, "old", needColon, 0 == ( CTX_IS_ARB_CREATED & ctp )); + sb.append(")"); + if(null!=gl_version) { + sb.append(" - "); + sb.append(gl_version); + } + return sb.toString(); + } + + protected static String toString(int val, boolean hex) { + if(hex) { + return "0x" + Integer.toHexString(val); + } + return String.valueOf(val); + } + + protected static String toHexString(int hex) { + return "0x" + Integer.toHexString(hex); + } + + protected static String toHexString(long hex) { + return "0x" + Long.toHexString(hex); + } + + private static boolean appendString(StringBuffer sb, String string, boolean needColon, boolean condition) { + if(condition) { + if(needColon) { + sb.append(", "); + } + sb.append(string); + needColon=true; + } + return needColon; + } + + protected static String getThreadName() { + return Thread.currentThread().getName(); + } + +} + |