diff options
Diffstat (limited to 'src/jogl/classes')
6 files changed, 281 insertions, 103 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index bf6ee31df..ecfa230d2 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -46,13 +46,13 @@ import java.util.HashSet; import javax.media.nativewindow.AbstractGraphicsDevice; +import jogamp.opengl.Debug; +import jogamp.opengl.GLContextImpl; + import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.common.util.locks.LockFactory; import com.jogamp.common.util.locks.RecursiveLock; -import jogamp.opengl.Debug; -import jogamp.opengl.GLContextImpl; - /** 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 @@ -70,9 +70,9 @@ public abstract class GLContext { public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true); /** Reflects property jogl.debug.DebugGL. If true, the debug pipeline is enabled at context creation. */ - public final static boolean DEBUG_GL = Debug.isPropertyDefined("jogl.debug.DebugGL", true); + public static final boolean DEBUG_GL = Debug.isPropertyDefined("jogl.debug.DebugGL", true); /** Reflects property jogl.debug.TraceGL. If true, the trace pipeline is enabled at context creation. */ - public final static boolean TRACE_GL = Debug.isPropertyDefined("jogl.debug.TraceGL", true); + public static final boolean TRACE_GL = Debug.isPropertyDefined("jogl.debug.TraceGL", true); /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */ public static final int CONTEXT_NOT_CURRENT = 0; @@ -81,32 +81,49 @@ 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. Cache key value. */ + /** <code>ARB_create_context</code> related: created via ARB_create_context. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_IS_ARB_CREATED = 1 << 0; - /** <code>ARB_create_context</code> related: compatibility profile. Cache key value. */ + /** <code>ARB_create_context</code> related: desktop compatibility profile. Cache key value. See {@link #isGLCompatibilityProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_PROFILE_COMPAT = 1 << 1; - /** <code>ARB_create_context</code> related: core profile. Cache key value. */ + /** <code>ARB_create_context</code> related: desktop core profile. Cache key value. See {@link #isGLCoreProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_PROFILE_CORE = 1 << 2; - /** <code>ARB_create_context</code> related: ES profile. Cache key value. */ + /** <code>ARB_create_context</code> related: ES profile. Cache key value. See {@link #isGLES()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_PROFILE_ES = 1 << 3; - /** <code>ARB_create_context</code> related: flag forward compatible. Cache key value. */ + /** <code>ARB_create_context</code> related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_OPTION_FORWARD = 1 << 4; - /** <code>ARB_create_context</code> related: flag debug. Not a cache key. */ + /** <code>ARB_create_context</code> related: flag debug. Not a cache key. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ public static final int CTX_OPTION_DEBUG = 1 << 5; - /** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. */ + /** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ protected static final int CTX_IMPL_ES2_COMPAT = 1 << 8; - /** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. */ - protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 15; + /** Context supports FBO, details see {@link #hasFBO()}. + * Not a cache key. + * @see #hasFBO() + * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile) + */ + protected static final int CTX_IMPL_FBO = 1 << 9; - private static ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>(); + /** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. See {@link #isHardwareRasterizer()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ + protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 15; - private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>(); - private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap(); + protected static final String GL_ARB_ES2_compatibility = "GL_ARB_ES2_compatibility"; + protected static final String GL_ARB_framebuffer_object = "GL_ARB_framebuffer_object"; + protected static final String GL_EXT_framebuffer_object = "GL_EXT_framebuffer_object"; + protected static final String GL_EXT_framebuffer_blit = "GL_EXT_framebuffer_blit"; + protected static final String GL_EXT_framebuffer_multisample = "GL_EXT_framebuffer_multisample"; + protected static final String GL_EXT_packed_depth_stencil = "GL_EXT_packed_depth_stencil"; + protected static final String GL_ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two"; + protected static final String GL_EXT_texture_format_BGRA8888 = "GL_EXT_texture_format_BGRA8888"; + protected static final String GL_IMG_texture_format_BGRA8888 = "GL_IMG_texture_format_BGRA8888"; + + private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>(); + + private final HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>(); + private final IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap(); // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock. - protected RecursiveLock lock = LockFactory.createRecursiveLock(); + protected final RecursiveLock lock = LockFactory.createRecursiveLock(); /** The underlying native OpenGL context */ protected long contextHandle; @@ -137,36 +154,74 @@ public abstract class GLContext { } /** - * Returns the GLDrawable to which this context may be used to - * draw. + * Sets the read/write drawable for framebuffer operations. + * <p> + * If the context was current on this thread, it is being released before switching the drawable + * and made current afterwards. However the user shall take extra care that not other thread + * attempts to make this context current. Otherwise a race condition may happen. + * </p> + * <p> + * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary + * switching the drawable of an already established GLContext, i.e. which is already made current once. + * FIXME: Validate functionality! + * </p> + * @param readWrite the read/write drawable for framebuffer operations. + * @param setWriteOnly if <code>true</code> and if the current read-drawable differs + * from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}), + * only change the write-drawable. Otherwise set both drawables. + * @return the replaced read/write drawable + * + * @throws GLException in case <code>null</code> is being passed or + * this context is made current on another thread. + * + * @see #isGLReadDrawableAvailable() + * @see #getGLReadDrawable() + * @see #setGLReadDrawable() + * @see #getGLDrawable() + */ + public abstract GLDrawable setGLDrawable(GLDrawable readWrite, boolean setWriteOnly); + + /** + * Returns the write-drawable this context uses for framebuffer operations. */ public abstract GLDrawable getGLDrawable(); /** - * Return availability of GL read drawable. - * @return true if a GL read drawable is supported with your driver, otherwise false. + * Query whether using a distinguished read-drawable is supported. + * @return true if using a read-drawable is supported with your driver/OS, otherwise false. */ public abstract boolean isGLReadDrawableAvailable(); /** - * Set the read GLDrawable for read framebuffer operations.<br> + * Set the read-Drawable for read framebuffer operations.<br> * The caller should query if this feature is supported via {@link #isGLReadDrawableAvailable()}. + * <p> + * If the context was current on this thread, it is being released before switching the drawable + * and made current afterwards. However the user shall take extra care that not other thread + * attempts to make this context current. Otherwise a race condition may happen. + * </p> * - * @param read the read GLDrawable for read framebuffer operations. - * If null is passed, the default write drawable will be set. + * @param read the read-drawable for read framebuffer operations. + * If null is passed, the default write drawable will be set. + * @return the replaced read-drawable * - * @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. + * @throws GLException in case a read drawable is not supported or + * this context is made current on another thread. * * @see #isGLReadDrawableAvailable() * @see #getGLReadDrawable() */ - public abstract void setGLReadDrawable(GLDrawable read); + public abstract GLDrawable setGLReadDrawable(GLDrawable read); /** - * Returns the read GLDrawable this context uses for read framebuffer operations. + * Returns the read-Drawable this context uses for read framebuffer operations. + * <p> + * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)}, + * it equals to the write-drawable (default). + * </p> * @see #isGLReadDrawableAvailable() * @see #setGLReadDrawable(javax.media.opengl.GLDrawable) + * @see #getGLDrawable() */ public abstract GLDrawable getGLReadDrawable(); @@ -190,7 +245,7 @@ public abstract class GLContext { * </p> * <p> * This method is blocking, i.e. waits until another thread has - * released the context. + * released the context. * </p> * <p> * The drawable's surface is being locked at entry @@ -547,6 +602,28 @@ public abstract class GLContext { return 0 != ( ctxOptions & CTX_IMPL_ES2_COMPAT ) ; } + /** + * @return true if impl. is a hardware rasterizer, otherwise false. + * @see GLProfile#isHardwareRasterizer() + */ + public final boolean isHardwareRasterizer() { + return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ; + } + + /** Returns whether the context supports FBO, hence is either GL-ES >= 2.0, >= core GL 3.0 or implements the extensions + * <code>GL_ARB_ES2_compatibility</code>, <code>ARB_framebuffer_object</code> or all of + * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>, + * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>. + * @see #CTX_IMPL_FBO + */ + public final boolean hasFBO() { + return 0 != ( ctxOptions & CTX_IMPL_FBO ) ; + } + + /** + * @return true if context supports GLSL + * @see GLProfile#hasGLSL() + */ public final boolean hasGLSL() { return isGL2ES2() ; } @@ -555,60 +632,70 @@ public abstract class GLContext { public boolean isNPOTTextureAvailable() { return isGL3() || isGLES2Compatible() || isExtensionAvailable(GL_ARB_texture_non_power_of_two); } - private static final String GL_ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two"; public boolean isTextureFormatBGRA8888Available() { return isGL2GL3() || - isExtensionAvailable("GL_EXT_texture_format_BGRA8888") || - isExtensionAvailable("GL_IMG_texture_format_BGRA8888") ; + isExtensionAvailable(GL_EXT_texture_format_BGRA8888) || + isExtensionAvailable(GL_IMG_texture_format_BGRA8888) ; } + /** @see GLProfile#isGL4bc() */ public final boolean isGL4bc() { return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED) && 0 != (ctxOptions & CTX_PROFILE_COMPAT); } + /** @see GLProfile#isGL4() */ public final boolean isGL4() { return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED) && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)); } + /** @see GLProfile#isGL3bc() */ public final boolean isGL3bc() { return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 ) && 0 != (ctxOptions & CTX_IS_ARB_CREATED) && 0 != (ctxOptions & CTX_PROFILE_COMPAT); } + /** @see GLProfile#isGL3() */ 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)); } - + + /** @see GLProfile#isGL2() */ public final boolean isGL2() { return ctxMajorVersion>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT); } + /** @see GLProfile#isGL2GL3() */ public final boolean isGL2GL3() { return isGL2() || isGL3(); } + /** @see GLProfile#isGLES1() */ public final boolean isGLES1() { return ctxMajorVersion==1 && 0 != ( ctxOptions & CTX_PROFILE_ES ) ; } + /** @see GLProfile#isGLES2() */ public final boolean isGLES2() { return ctxMajorVersion==2 && 0 != ( ctxOptions & CTX_PROFILE_ES ) ; } + /** @see GLProfile#isGLES() */ public final boolean isGLES() { return 0 != ( CTX_PROFILE_ES & ctxOptions ) ; } + /** @see GLProfile#isGL2ES1() */ public final boolean isGL2ES1() { return isGL2() || isGLES1() ; } + /** @see GLProfile#isGL2ES2() */ public final boolean isGL2ES2() { return isGL2GL3() || isGLES2() ; } @@ -846,8 +933,11 @@ public abstract class GLContext { */ private static /*final*/ HashSet<String> deviceVersionsAvailableSet = new HashSet<String>(); - protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) { - return device.getUniqueID() + "-" + toHexString(composeBits(major, profile, 0)); + /** clears the device/context mappings as well as the GL/GLX proc address tables. */ + protected static void shutdown() { + deviceVersionAvailable.clear(); + deviceVersionsAvailableSet.clear(); + GLContextImpl.shutdownImpl(); // well .. } protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) { @@ -869,11 +959,8 @@ public abstract class GLContext { } } - /** clears the device/context mappings as well as the GL/GLX proc address tables. */ - protected static void shutdown() { - deviceVersionAvailable.clear(); - deviceVersionsAvailableSet.clear(); - GLContextImpl.shutdownImpl(); // well .. + protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) { + return device.getUniqueID() + "-" + toHexString(composeBits(major, profile, 0)); } /** @@ -967,18 +1054,71 @@ public abstract class GLContext { } /** + * Returns the GLProfile's major version number and it's context property (CTP) for availability mapping request. + */ + protected static final void getRequestMajorAndCompat(final GLProfile glp, int[/*2*/] reqMajorCTP) { + final GLProfile glpImpl = glp.getImpl(); + if(glpImpl.isGL4()) { + reqMajorCTP[0]=4; + } else if (glpImpl.isGL3()) { + reqMajorCTP[0]=3; + } else /* if (glpImpl.isGL2()) */ { + reqMajorCTP[0]=2; + } + if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc + reqMajorCTP[1]=CTX_PROFILE_COMPAT; + } else { + reqMajorCTP[1]=CTX_PROFILE_CORE; + } + } + + /** + * @param device the device the context profile is being requested for + * @param GLProfile the GLProfile the context profile is being requested for + * @return the GLProfile's context property (CTP) if available, otherwise <code>0</code> + */ + protected static final int getAvailableContextProperties(final AbstractGraphicsDevice device, final GLProfile glp) { + final int[] reqMajorCTP = new int[] { 0, 0 }; + getRequestMajorAndCompat(glp, reqMajorCTP); + + int _major[] = { 0 }; + int _minor[] = { 0 }; + int _ctp[] = { 0 }; + if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], + _major, _minor, _ctp)) { + return _ctp[0]; + } + return 0; // n/a + } + + /** + * @param device the device the profile is being requested * @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} - * @return the highest GLProfile string regarding the version and profile bits. - * @throws GLException if version and context profile bits could not be mapped to a GLProfile + * @return the highest GLProfile regarding availability, version and profile bits. */ - public static String getAvailableGLProfile(AbstractGraphicsDevice device, int reqMajor, int reqProfile) + protected static GLProfile getAvailableGLProfile(AbstractGraphicsDevice device, int reqMajor, int reqProfile) throws GLException { int major[] = { 0 }; int minor[] = { 0 }; int ctp[] = { 0 }; if(GLContext.getAvailableGLVersion(device, reqMajor, reqProfile, major, minor, ctp)) { - return GLContext.getGLProfile(major[0], minor[0], ctp[0]); + return GLProfile.get(GLContext.getGLProfile(major[0], minor[0], ctp[0])); + } + return null; + } + + /** + * @param device the device the profile is being requested + * @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} + */ + protected 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; } @@ -990,7 +1130,7 @@ public abstract class GLContext { * @param isHardware return value of one boolean, whether the profile is a hardware rasterizer or not * @return true if the requested GL version is available regardless of a software or hardware rasterizer, otherwise false. */ - public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int reqMajor, int reqProfile, boolean isHardware[]) { + protected static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int reqMajor, int reqProfile, boolean isHardware[]) { Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile); if(null==valI) { return false; @@ -1027,21 +1167,7 @@ public abstract class GLContext { return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware); } - /** - * @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) { + protected static String getGLVersion(int major, int minor, int ctp, String gl_version) { boolean needColon = false; StringBuilder sb = new StringBuilder(); sb.append(major); @@ -1055,6 +1181,7 @@ public abstract class GLContext { needColon = appendString(sb, "arb", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp )); needColon = appendString(sb, "debug", needColon, 0 != ( CTX_OPTION_DEBUG & ctp )); needColon = appendString(sb, "ES2 compatible", needColon, 0 != ( CTX_IMPL_ES2_COMPAT & ctp )); + needColon = appendString(sb, "FBO", needColon, 0 != ( CTX_IMPL_FBO & ctp )); if( 0 != ( CTX_IMPL_ACCEL_SOFT & ctp ) ) { needColon = appendString(sb, "software", needColon, true); } else { diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java index 1093685d6..d6480e7aa 100644 --- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java @@ -492,6 +492,23 @@ public abstract class GLDrawableFactory { GLContext shareWith) throws GLException; + /** + * Returns true if it is possible to create an <i>framebuffer object</i> (FBO). + * <p> + * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. + * </p> + * <p> + * FBO support is queried as described in {@link GLContext#hasFBO()}. + * </p> + * + * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device. + * @param glp {@link GLProfile} to check for FBO capabilities + * @see GLContext#hasFBO() + */ + public final boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp) { + return 0 != ( GLContext.CTX_IMPL_FBO & GLContext.getAvailableContextProperties(device, glp) ); + } + //---------------------------------------------------------------------- // Methods for interacting with third-party OpenGL libraries diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java index ed457b0ea..cc4f6c517 100644 --- a/src/jogl/classes/javax/media/opengl/GLProfile.java +++ b/src/jogl/classes/javax/media/opengl/GLProfile.java @@ -113,9 +113,7 @@ public class GLProfile { * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program, * otherwise <code>false</code>. * - * @deprecated This method shall not need to be called for other reasons than having a defined initialization sequence. - * To ensure homogeneous behavior with application not calling this method, you shall pass <code>firstUIActionOnProcess=false</code>. - * This method is subject to be removed in future versions of JOGL. + * @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL. */ public static void initSingleton(final boolean firstUIActionOnProcess) { initLock.lock(); @@ -1003,6 +1001,11 @@ public class GLProfile { public final boolean isGLES2() { return GLES2 == profile; } + + /** Indicates whether this profile is capable of GLES. <p>Includes [ GLES1, GLES2 ].</p> */ + public final boolean isGLES() { + return GLES2 == profile || GLES1 == profile; + } /** Indicates whether this profile is capable of GL2ES1. <p>Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].</p> */ public final boolean isGL2ES1() { diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 4ef8b9750..7362a2bd8 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -161,18 +161,22 @@ public abstract class GLContextImpl extends GLContext { } @Override - public final void setGLReadDrawable(GLDrawable read) { - if(null!=read && drawable!=read && !isGLReadDrawableAvailable()) { - throw new GLException("GL Read Drawable not available"); + public final GLDrawable setGLReadDrawable(GLDrawable read) { + if(!isGLReadDrawableAvailable()) { + throw new GLException("Setting read drawable feature not available"); } final boolean lockHeld = lock.isOwner(Thread.currentThread()); if(lockHeld) { release(); + } else if(lock.isLockedByOtherThread()) { // still could glitch .. + throw new GLException("GLContext current by other thread ("+lock.getOwner()+"), operation not allowed."); } + final GLDrawable old = drawableRead; drawableRead = ( null != read ) ? (GLDrawableImpl) read : drawable; if(lockHeld) { makeCurrent(); } + return old; } @Override @@ -181,6 +185,28 @@ public abstract class GLContextImpl extends GLContext { } @Override + public final GLDrawable setGLDrawable(GLDrawable readWrite, boolean setWriteOnly) { + if(null==readWrite) { + throw new GLException("Null read/write drawable not allowed"); + } + final boolean lockHeld = lock.isOwner(Thread.currentThread()); + if(lockHeld) { + release(); + } else if(lock.isLockedByOtherThread()) { // still could glitch .. + throw new GLException("GLContext current by other thread ("+lock.getOwner()+"), operation not allowed."); + } + if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable + drawableRead = (GLDrawableImpl) readWrite; + } + final GLDrawable old = drawable; + drawable = ( null != readWrite ) ? (GLDrawableImpl) readWrite : null; + if(lockHeld) { + makeCurrent(); + } + return old; + } + + @Override public final GLDrawable getGLDrawable() { return drawable; } @@ -630,13 +656,10 @@ public abstract class GLContextImpl extends GLContext { * @see #createContextARBImpl * @see #destroyContextARBImpl */ - protected final long createContextARB(long share, boolean direct) + protected final long createContextARB(final long share, final boolean direct) { - AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); - AbstractGraphicsDevice device = config.getScreen().getDevice(); - GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - GLProfile glp = glCaps.getGLProfile(); - GLProfile glpImpl = glp.getImpl(); + final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration(); + final AbstractGraphicsDevice device = config.getScreen().getDevice(); if (DEBUG) { System.err.println(getThreadName() + ": createContextARB: mappedVersionsAvailableSet("+device.getConnection()+"): "+ @@ -650,22 +673,15 @@ public abstract class GLContextImpl extends GLContext { } } - int reqMajor; - if(glpImpl.isGL4()) { - reqMajor=4; - } else if (glpImpl.isGL3()) { - reqMajor=3; - } else /* if (glpImpl.isGL2()) */ { - reqMajor=2; - } - - boolean compat = glpImpl.isGL2(); // incl GL3bc and GL4bc + final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final int[] reqMajorCTP = new int[] { 0, 0 }; + getRequestMajorAndCompat(glCaps.getGLProfile(), reqMajorCTP); + int _major[] = { 0 }; int _minor[] = { 0 }; int _ctp[] = { 0 }; long _ctx = 0; - - if( GLContext.getAvailableGLVersion(device, reqMajor, compat?CTX_PROFILE_COMPAT:CTX_PROFILE_CORE, + if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], _major, _minor, _ctp)) { _ctp[0] |= additionalCtxCreationFlags; _ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]); @@ -675,7 +691,7 @@ public abstract class GLContextImpl extends GLContext { } return _ctx; } - + private final boolean mapGLVersions(AbstractGraphicsDevice device) { synchronized (GLContext.deviceVersionAvailable) { boolean success = false; @@ -698,10 +714,11 @@ public abstract class GLContextImpl extends GLContext { private final boolean createContextARBMapVersionsAvailable(int reqMajor, boolean compat) { long _context; int reqProfile = compat ? CTX_PROFILE_COMPAT : CTX_PROFILE_CORE ; - int ctp = CTX_IS_ARB_CREATED | CTX_PROFILE_CORE; // default + int ctp = CTX_IS_ARB_CREATED; if(compat) { - ctp &= ~CTX_PROFILE_CORE ; - ctp |= CTX_PROFILE_COMPAT ; + ctp |= CTX_PROFILE_COMPAT ; + } else { + ctp |= CTX_PROFILE_CORE ; } // To ensure GL profile compatibility within the JOGL application @@ -1070,10 +1087,15 @@ public abstract class GLContextImpl extends GLContext { } } } - if( isExtensionAvailable("GL_ARB_ES2_compatibility") ) { + + if( 0 != ( CTX_PROFILE_ES & ctxProfileBits ) && ctxMajorVersion >= 2 || + isExtensionAvailable(GL_ARB_ES2_compatibility) ) { ctxProfileBits |= CTX_IMPL_ES2_COMPAT; + ctxProfileBits |= CTX_IMPL_FBO; + } else if( hasFBOImpl(ctxMajorVersion, ctxProfileBits, extensionAvailability) ) { + ctxProfileBits |= CTX_IMPL_FBO; } - + // // Set GL Version (complete w/ version string) // @@ -1081,7 +1103,24 @@ public abstract class GLContextImpl extends GLContext { setDefaultSwapInterval(); } - + + protected static final boolean hasFBOImpl(int ctxMajorVersion, int ctxProfileBits, ExtensionAvailabilityCache extCache) { + return ( ctxMajorVersion >= 3 ) || // any >= 3.0 GL ctx + + ( 0 != (ctxProfileBits & CTX_PROFILE_ES) && ctxMajorVersion >= 2 ) || // ES >= 2.0 + + ( null != extCache && + + ( extCache.isExtensionAvailable(GL_ARB_ES2_compatibility) ) || // ES 2.0 compatible + + ( extCache.isExtensionAvailable(GL_ARB_framebuffer_object) ) || // ARB_framebuffer_object + + ( extCache.isExtensionAvailable(GL_EXT_framebuffer_object) && // EXT_framebuffer_object* + extCache.isExtensionAvailable(GL_EXT_framebuffer_multisample) && + extCache.isExtensionAvailable(GL_EXT_framebuffer_blit) && + extCache.isExtensionAvailable(GL_EXT_packed_depth_stencil) ) ); + } + protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) { if(!isCurrentContextHardwareRasterizer()) { ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT; @@ -1212,7 +1251,7 @@ public abstract class GLContextImpl extends GLContext { protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctxProfileBits) { // remove non-key values - ctxProfileBits &= ~( GLContext.CTX_OPTION_DEBUG | GLContext.CTX_IMPL_ES2_COMPAT ) ; + ctxProfileBits &= ~( GLContext.CTX_OPTION_DEBUG | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) ; return device.getUniqueID() + "-" + toHexString(composeBits(major, minor, ctxProfileBits)); } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java index 06cd550b4..65a4c3ece 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java @@ -224,15 +224,7 @@ public abstract class EGLContext extends GLContextImpl { throw new GLException("Error making context 0x" + Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError()); } - int ctp = CTX_PROFILE_ES; - int major; - if(glProfile.usesNativeGLES2()) { - ctp |= CTX_IMPL_ES2_COMPAT; - major = 2; - } else { - major = 1; - } - setGLFunctionAvailability(true, major, 0, ctp); + setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES); return true; } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java index 0a451e5eb..585638d21 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java @@ -45,7 +45,7 @@ public class EGLExternalContext extends EGLContext { public EGLExternalContext(AbstractGraphicsScreen screen) { super(null, null); GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES); + setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_ES); getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } |