();
+ 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.
+ *
+ * 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.
+ *
+ *
+ * Disclaimer : 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!
+ *
+ * @param readWrite the read/write drawable for framebuffer operations.
+ * @param setWriteOnly if true
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 null
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.
+ * Set the read-Drawable for read framebuffer operations.
* The caller should query if this feature is supported via {@link #isGLReadDrawableAvailable()}.
+ *
+ * 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.
+ *
*
- * @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.
+ *
+ * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)},
+ * it equals to the write-drawable (default).
+ *
* @see #isGLReadDrawableAvailable()
* @see #setGLReadDrawable(javax.media.opengl.GLDrawable)
+ * @see #getGLDrawable()
*/
public abstract GLDrawable getGLReadDrawable();
@@ -190,7 +245,7 @@ public abstract class GLContext {
*
*
* This method is blocking, i.e. waits until another thread has
- * released the context.
+ * released the context.
*
*
* 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
+ * GL_ARB_ES2_compatibility
, ARB_framebuffer_object
or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ * @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 deviceVersionsAvailableSet = new HashSet();
- 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 0
+ */
+ 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 framebuffer object (FBO).
+ *
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+ *
+ *
+ * FBO support is queried as described in {@link GLContext#hasFBO()}.
+ *
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
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 true
if called before the first UI action of the running program,
* otherwise false
.
*
- * @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 firstUIActionOnProcess=false
.
- * 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. Includes [ GLES1, GLES2 ].
*/
+ public final boolean isGLES() {
+ return GLES2 == profile || GLES1 == profile;
+ }
/** Indicates whether this profile is capable of GL2ES1. Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].
*/
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
@@ -180,6 +184,28 @@ public abstract class GLContextImpl extends GLContext {
return drawableRead;
}
+ @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
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 96baab3ae..5cc0d765c 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -531,7 +531,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
return;
}
- window.lockWindow(); // sync: context/drawable could been recreated/destroyed while animating
+ window.lockWindow(); // sync: context/drawable could have been recreated/destroyed while animating
try {
if( null == context && 0 s) {
+ s++;
+ System.err.println(s+" - switch - START "+ ( t1 - t0 ));
+ animator.pause();
+
+ if(0 == s%2) {
+ glad1.addGLEventListener(0, glad2.removeGLEventListener(0));
+ GLContext ctx1 = glad1.setContext(glad2.getContext());
+ glad2.setContext(ctx1);
+ } else {
+ glad2.addGLEventListener(0, glad1.removeGLEventListener(0));
+ GLContext ctx2 = glad2.setContext(glad1.getContext());
+ glad1.setContext(ctx2);
+ }
+
+ System.err.println(s+" - switch - END "+ ( t1 - t0 ));
+
+ animator.resume();
+ }
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ animator.stop();
+ glad1.destroy();
+ glad2.destroy();
+ }
+
+ @Test(timeout=30000)
+ public void testSwitch2GLWindowOneDemo() throws InterruptedException {
+ GearsES2 gears = new GearsES2(1);
+ final QuitAdapter quitAdapter = new QuitAdapter();
+
+ GLWindow glWindow1 = GLWindow.create(caps);
+ glWindow1.setTitle("win1");
+ glWindow1.setSize(width, height);
+ glWindow1.setPosition(64, 64);
+ glWindow1.addGLEventListener(0, gears);
+ glWindow1.addWindowListener(quitAdapter);
+
+ GLWindow glWindow2 = GLWindow.create(caps);
+ glWindow2.setTitle("win2");
+ glWindow2.setSize(width+100, height+100);
+ glWindow2.setPosition(2*64+width, 64);
+ glWindow2.addWindowListener(quitAdapter);
+
+ Animator animator = new Animator();
+ animator.add(glWindow1);
+ animator.add(glWindow2);
+ animator.start();
+
+ glWindow1.setVisible(true);
+ glWindow2.setVisible(true);
+
+ int s = 0;
+ long t0 = System.currentTimeMillis();
+ long t1 = t0;
+
+ while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration ) {
+ if( ( t1 - t0 ) / period > s) {
+ s++;
+ System.err.println(s+" - switch - START "+ ( t1 - t0 ));
+ animator.pause();
+
+ if(0 == s%2) {
+ glWindow1.addGLEventListener(0, glWindow2.removeGLEventListener(0));
+ GLContext ctx1 = glWindow1.setContext(glWindow2.getContext());
+ glWindow2.setContext(ctx1);
+ } else {
+ glWindow2.addGLEventListener(0, glWindow1.removeGLEventListener(0));
+ GLContext ctx2 = glWindow2.setContext(glWindow1.getContext());
+ glWindow1.setContext(ctx2);
+ }
+
+ System.err.println(s+" - switch - END "+ ( t1 - t0 ));
+
+ animator.resume();
+ }
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ animator.stop();
+ glWindow1.destroy();
+ glWindow2.destroy();
+
+ }
+
+ @Test(timeout=30000)
+ public void testSwitch2GLWindowEachWithOwnDemo() throws InterruptedException {
+ GearsES2 gears = new GearsES2(1);
+ RedSquareES2 rsquare = new RedSquareES2(1);
+ final QuitAdapter quitAdapter = new QuitAdapter();
+
+ GLWindow glWindow1 = GLWindow.create(caps);
+ glWindow1.setTitle("win1");
+ glWindow1.setSize(width, height);
+ glWindow1.setPosition(64, 64);
+ glWindow1.addGLEventListener(0, gears);
+ glWindow1.addWindowListener(quitAdapter);
+
+ GLWindow glWindow2 = GLWindow.create(caps);
+ glWindow2.setTitle("win2");
+ glWindow2.setSize(width+100, height+100);
+ glWindow2.setPosition(2*64+width, 64);
+ glWindow2.addGLEventListener(0, rsquare);
+ glWindow2.addWindowListener(quitAdapter);
+
+ Animator animator = new Animator();
+ animator.add(glWindow1);
+ animator.add(glWindow2);
+ animator.start();
+
+ glWindow1.setVisible(true);
+ glWindow2.setVisible(true);
+
+ int s = 0;
+ long t0 = System.currentTimeMillis();
+ long t1 = t0;
+
+ while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration ) {
+ if( ( t1 - t0 ) / period > s) {
+ s++;
+ System.err.println(s+" - switch - START "+ ( t1 - t0 ));
+ animator.pause();
+
+ GLEventListener demo1 = glWindow1.removeGLEventListener(0);
+ GLEventListener demo2 = glWindow2.removeGLEventListener(0);
+
+ GLContext ctx1 = glWindow1.setContext(glWindow2.getContext());
+ glWindow1.addGLEventListener(0, demo2);
+
+ glWindow2.setContext(ctx1);
+ glWindow2.addGLEventListener(0, demo1);
+
+ System.err.println(s+" - switch - END "+ ( t1 - t0 ));
+
+ animator.resume();
+ }
+ Thread.sleep(100);
+ t1 = System.currentTimeMillis();
+ }
+
+ animator.stop();
+ glWindow1.destroy();
+ glWindow2.destroy();
+
+ }
+
+ // default timing for 2 switches
+ static long duration = 2200; // ms
+ static long period = 1000; // ms
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i XAWT related).
+ * Or ensure old/new parent is visible, see below.
+ *
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
+ System.err.println("Demos: 1 - X Container 1");
+ container1.remove(newtCanvasAWT);
+ jFrame1.validate();
+ System.err.println("Demos: 1 - X Container 2");
+ jPanel2.remove(newtCanvasAWT);
+ jFrame2.validate();
+ } }); */
+ /*
+ * Invisible X11 windows may also case BadMatch (-> XAWT related)
+ */
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ System.err.println("Demos: 2 - !visible");
jFrame1.setVisible(false);
+ System.err.println("Demos: 3 - !visible");
jFrame2.setVisible(false);
} });
Assert.assertEquals(true, glWindow1.isNativeValid());
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
+ System.err.println("Demos: 4 - X frame");
jFrame1.dispose();
+ System.err.println("Demos: 5 - X frame");
jFrame2.dispose();
} });
Assert.assertEquals(true, glWindow1.isNativeValid());
+ System.err.println("Demos: 6 - X GLWindow");
glWindow1.destroy();
Assert.assertEquals(false, glWindow1.isNativeValid());
+
+ System.err.println("Demos: 7 - X DisturbanceThread");
+ disturbanceAction.stopAndWaitUntilDone();
}
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
@@ -393,8 +424,10 @@ public class TestParenting01cSwingAWT extends UITestCase {
waitReparent = atoi(args[++i]);
}
}
- System.out.println("durationPerTest "+durationPerTest);
- System.out.println("waitReparent "+waitReparent);
+ System.err.println("durationPerTest "+durationPerTest);
+ System.err.println("waitReparent "+waitReparent);
+ org.junit.runner.JUnitCore.main(TestParenting01cSwingAWT.class.getName());
+ /**
String tstname = TestParenting01cSwingAWT.class.getName();
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
tstname,
@@ -406,7 +439,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
"logfailedtests=true",
"logtestlistenerevents=true",
"formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
- "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } );
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
}
}
--
cgit v1.2.3
From e85e3ec2a73ac35aaf911f0b1e34b234be1622da Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 6 Jul 2012 01:20:48 +0200
Subject: Enhance Bootsrapping of JOGL around 37% - 40% (1st start in new JVM)
- GLProfile and GLContext*
GLProfile: Enhance bootsrapping performance of loading GL*Impl class
- Offthread classloading of all GL*Impl via reflection at startup
reduces startup time here around 12% (800ms down to 700ms).
GLContext*: Enhance bootsrapping performance of querying available GL profiles
- Add PROFILE_ALIASING mode, defaults to true - can be disabled w/ property 'jogl.debug.GLContext.NoProfileAliasing'
- PROFILE_ALIASING:
If true (default), bootstrapping the available GL profiles
will use the highest compatible GL context for each profile,
hence skipping querying lower profiles if a compatible higher one is found.
Linux x86_64 - Nvidia: 28%, 700ms down to 500ms
Linux x86_64 - AMD : 40%, 1500ms down to 900ms
- GL*Impl:
- make fields final: glProfile, _context, buffer*Tracker and glStateTracker
- allow null _context/glProfile in initialization (bootstrapping)
- JoglVersion.getDefaultOpenGLInfo(..)
- add arg: 'boolean withCapabilitiesInfo', allowing to suppres the list of caps
---
.../config/jogl/gl-impl-CustomJavaCode-common.java | 4 +-
make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java | 18 ++--
make/config/jogl/gl-impl-CustomJavaCode-gles1.java | 18 ++--
make/config/jogl/gl-impl-CustomJavaCode-gles2.java | 18 ++--
make/scripts/tests.sh | 5 +-
.../classes/com/jogamp/opengl/JoglVersion.java | 16 ++--
.../classes/com/jogamp/opengl/swt/GLCanvas.java | 2 +-
src/jogl/classes/javax/media/opengl/GLContext.java | 71 +++++++++++++--
src/jogl/classes/javax/media/opengl/GLProfile.java | 81 +++++++++--------
.../classes/javax/media/opengl/awt/GLCanvas.java | 2 +-
src/jogl/classes/jogamp/opengl/GLContextImpl.java | 100 +++++++++++++++++----
.../jogamp/opengl/x11/glx/X11GLXContext.java | 10 +--
.../classes/com/jogamp/newt/opengl/GLWindow.java | 2 +-
.../classes/jogamp/newt/driver/android/MD.java | 2 +-
.../test/junit/jogl/acore/TestGLProfile01NEWT.java | 2 +-
.../junit/jogl/acore/TestShutdownCompleteNEWT.java | 19 ++--
16 files changed, 261 insertions(+), 109 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index 2c3227ee5..d552bc6e4 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -1,7 +1,7 @@
public GLProfile getGLProfile() {
return this.glProfile;
}
- private GLProfile glProfile;
+ private final GLProfile glProfile;
public int glGetBoundBuffer(int target) {
return bufferStateTracker.getBoundBufferObject(target, this);
@@ -46,7 +46,7 @@
return _context;
}
- private GLContextImpl _context;
+ private final GLContextImpl _context;
/**
* @see javax.media.opengl.GLContext#setSwapInterval(int)
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
index dc4f898e6..95aa7cc2c 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gl4bc.java
@@ -17,9 +17,15 @@ public void setObjectTracker(GLObjectTracker tracker) {
public GL4bcImpl(GLProfile glp, GLContextImpl context) {
this._context = context;
- this.bufferSizeTracker = context.getBufferSizeTracker();
- this.bufferStateTracker = context.getBufferStateTracker();
- this.glStateTracker = context.getGLStateTracker();
+ if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
+ this.bufferStateTracker = context.getBufferStateTracker();
+ this.glStateTracker = context.getGLStateTracker();
+ } else {
+ this.bufferSizeTracker = null;
+ this.bufferStateTracker = null;
+ this.glStateTracker = null;
+ }
this.glProfile = glp;
}
@@ -35,9 +41,9 @@ public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2,
// Helpers for ensuring the correct amount of texture data
//
-private GLBufferSizeTracker bufferSizeTracker;
-private GLBufferStateTracker bufferStateTracker;
-private GLStateTracker glStateTracker;
+private final GLBufferSizeTracker bufferSizeTracker;
+private final GLBufferStateTracker bufferStateTracker;
+private final GLStateTracker glStateTracker;
private boolean bufferObjectExtensionsInitialized = false;
private boolean haveARBPixelBufferObject;
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
index 9b0d98fe9..dff33cf81 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles1.java
@@ -1,8 +1,14 @@
public GLES1Impl(GLProfile glp, GLContextImpl context) {
this._context = context;
- this.bufferSizeTracker = context.getBufferSizeTracker();
- this.bufferStateTracker = context.getBufferStateTracker();
- this.glStateTracker = context.getGLStateTracker();
+ if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
+ this.bufferStateTracker = context.getBufferStateTracker();
+ this.glStateTracker = context.getGLStateTracker();
+ } else {
+ this.bufferSizeTracker = null;
+ this.bufferStateTracker = null;
+ this.glStateTracker = null;
+ }
this.glProfile = glp;
}
@@ -106,9 +112,9 @@ public final GL2GL3 getGL2GL3() throws GLException {
// Helpers for ensuring the correct amount of texture data
//
-private GLBufferSizeTracker bufferSizeTracker;
-private GLBufferStateTracker bufferStateTracker;
-private GLStateTracker glStateTracker;
+private final GLBufferSizeTracker bufferSizeTracker;
+private final GLBufferStateTracker bufferStateTracker;
+private final GLStateTracker glStateTracker;
private boolean bufferObjectExtensionsInitialized = false;
private boolean haveOESFramebufferObject;
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
index ea6544d29..a4976f5ea 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-gles2.java
@@ -4,9 +4,15 @@ private boolean inBeginEndPair;
public GLES2Impl(GLProfile glp, GLContextImpl context) {
this._context = context;
- this.bufferSizeTracker = context.getBufferSizeTracker();
- this.bufferStateTracker = context.getBufferStateTracker();
- this.glStateTracker = context.getGLStateTracker();
+ if(null != context) {
+ this.bufferSizeTracker = context.getBufferSizeTracker();
+ this.bufferStateTracker = context.getBufferStateTracker();
+ this.glStateTracker = context.getGLStateTracker();
+ } else {
+ this.bufferSizeTracker = null;
+ this.bufferStateTracker = null;
+ this.glStateTracker = null;
+ }
this.glProfile = glp;
}
@@ -110,9 +116,9 @@ public final GL2GL3 getGL2GL3() throws GLException {
// Helpers for ensuring the correct amount of texture data
//
-private GLBufferSizeTracker bufferSizeTracker;
-private GLBufferStateTracker bufferStateTracker;
-private GLStateTracker glStateTracker;
+private final GLBufferSizeTracker bufferSizeTracker;
+private final GLBufferStateTracker bufferStateTracker;
+private final GLStateTracker glStateTracker;
private boolean bufferObjectExtensionsInitialized = false;
private boolean haveOESFramebufferObject;
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 852dd6f25..10890c786 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -53,6 +53,7 @@ function jrun() {
swton=$1
shift
+ #D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
#D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
@@ -214,7 +215,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
@@ -226,7 +227,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextVBOES2NEWT2 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index c8e5d212b..75785fd86 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -93,22 +93,24 @@ public class JoglVersion extends JogampVersion {
return sb;
}
- public static StringBuilder getDefaultOpenGLInfo(StringBuilder sb) {
+ public static StringBuilder getDefaultOpenGLInfo(StringBuilder sb, boolean withCapabilitiesInfo) {
if(null==sb) {
sb = new StringBuilder();
}
final AbstractGraphicsDevice device = GLProfile.getDefaultDevice();
- sb.append("Default Profiles ").append(Platform.getNewline());
+ sb.append("Default Profiles on device ").append(device).append(Platform.getNewline());
if(null!=device) {
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
} else {
sb.append("none");
}
- sb.append(Platform.getNewline()).append(Platform.getNewline());
- sb.append("Desktop Capabilities: ").append(Platform.getNewline());
- getAvailableCapabilitiesInfo(GLDrawableFactory.getDesktopFactory(), device, sb);
- sb.append("EGL Capabilities: ").append(Platform.getNewline());
- getAvailableCapabilitiesInfo(GLDrawableFactory.getEGLFactory(), device, sb);
+ if(withCapabilitiesInfo) {
+ sb.append(Platform.getNewline()).append(Platform.getNewline());
+ sb.append("Desktop Capabilities: ").append(Platform.getNewline());
+ getAvailableCapabilitiesInfo(GLDrawableFactory.getDesktopFactory(), device, sb);
+ sb.append("EGL Capabilities: ").append(Platform.getNewline());
+ getAvailableCapabilitiesInfo(GLDrawableFactory.getEGLFactory(), device, sb);
+ }
return sb;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 62b496891..571f5c5b2 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -570,7 +570,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
final Display display = new Display();
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index ecfa230d2..351f90027 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -43,12 +43,15 @@ package javax.media.opengl;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
import javax.media.nativewindow.AbstractGraphicsDevice;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
@@ -66,6 +69,32 @@ import com.jogamp.common.util.locks.RecursiveLock;
abstraction provides a stable object which clients can use to
refer to a given context. */
public abstract class GLContext {
+ /**
+ * If true
(default), bootstrapping the available GL profiles
+ * will use the highest compatible GL context for each profile,
+ * hence skipping querying lower profiles if a compatible higher one is found:
+ *
+ * 4.2-core -> 4.2-core, 3.3-core
+ * 4.2-comp -> 4.2-comp, 3.3-comp, 2
+ *
+ * Otherwise the dedicated GL context would be queried and used:
+ *
+ * 4.2-core -> 4.2-core
+ * 3.3-core -> 3.3-core
+ * 4.2-comp -> 4.2-comp
+ * 3.3-comp -> 3.3-comp
+ * 3.0-comp -> 2
+ *
+ * Using aliasing speeds up initialization about:
+ *
+ *
+ * Integrates default read/write framebuffers via {@link GLContext#getDefaultReadFramebuffer()} and {@link GLContext#getDefaultReadFramebuffer()},
+ * which is being hooked at {@link GL#glBindFramebuffer(int, int)} when the default (zero
) framebuffer is selected.
+ *
+ *
+ * FIXME: Implement support for {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} .
+ */
+public class FBObject {
+ protected static final boolean DEBUG = Debug.debug("FBObject");
+
+ /**
+ * Returns true
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * ARB_ES2_compatibility
, ARB_framebuffer_object
, EXT_framebuffer_object
or OES_framebuffer_object
.
+ *
+ *
+ * Basic FBO support may only include one color attachment and no multisampling,
+ * as well as limited internal formats for renderbuffer.
+ *
+ * @see GLContext#hasFBO()
+ */
+ public static final boolean supportsBasicFBO(GL gl) {
+ return gl.getContext().hasFBO();
+ }
+
+ /**
+ * Returns true
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ *
+ * Full FBO support includes multiple color attachments and multisampling.
+ *
+ */
+ public static final boolean supportsFullFBO(GL gl) {
+ return gl.isGL3() || // GL >= 3.0
+
+ gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
+
+ ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
+ gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+ gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+ gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ) ;
+ }
+
+ public static final int getMaxSamples(GL gl) {
+ if( supportsFullFBO(gl) ) {
+ int[] val = new int[] { 0 } ;
+ gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+ return val[0];
+ } else {
+ return 0;
+ }
+ }
+
+ /** Common super class of all attachments */
+ public static abstract class Attachment {
+ public enum Type {
+ NONE, DEPTH, STENCIL, DEPTH_STENCIL, COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE;
+
+ /**
+ * Returns {@link #COLOR}, {@link #DEPTH}, {@link #STENCIL} or {@link #DEPTH_STENCIL}
+ * @throws IllegalArgumentException if format
cannot be handled.
+ */
+ public static Type determine(int format) throws IllegalArgumentException {
+ switch(format) {
+ case GL.GL_RGBA4:
+ case GL.GL_RGB5_A1:
+ case GL.GL_RGB565:
+ case GL.GL_RGB8:
+ case GL.GL_RGBA8:
+ return Type.COLOR;
+ case GL.GL_DEPTH_COMPONENT16:
+ case GL.GL_DEPTH_COMPONENT24:
+ case GL.GL_DEPTH_COMPONENT32:
+ return Type.DEPTH;
+ case GL.GL_STENCIL_INDEX1:
+ case GL.GL_STENCIL_INDEX4:
+ case GL.GL_STENCIL_INDEX8:
+ return Type.STENCIL;
+ case GL.GL_DEPTH24_STENCIL8:
+ return Type.DEPTH_STENCIL;
+ default:
+ throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ }
+ }
+ };
+
+ /** immutable type [{@link #COLOR}, {@link #DEPTH}, {@link #STENCIL}, {@link #COLOR_TEXTURE}, {@link #DEPTH_TEXTURE}, {@link #STENCIL_TEXTURE} ] */
+ public final Type type;
+
+ /** immutable the internal format */
+ public final int format;
+
+ private int width, height;
+
+ private int name;
+
+ /** true
if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
+ protected boolean resourceOwner;
+
+ private int initCounter;
+
+ protected Attachment(Type type, int iFormat, int width, int height, int name) {
+ this.type = type;
+ this.format = iFormat;
+ this.width = width;
+ this.height = height;
+ this.name = name;
+ this.resourceOwner = false;
+ this.initCounter = 0;
+ }
+
+ /** width of attachment */
+ public final int getWidth() { return width; }
+ /** height of attachment */
+ public final int getHeight() { return height; }
+ /* pp */ final void setSize(int w, int h) { width = w; height = h; }
+
+ /** buffer name [1..max], maybe a texture or renderbuffer name, depending on type. */
+ public final int getName() { return name; }
+ /* pp */ final void setName(int n) { name = n; }
+
+ public final int getInitCounter() { return initCounter; }
+
+ /**
+ * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is zero
.
+ * Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public void initialize(GL gl) throws GLException {
+ initCounter++;
+ /*
+ super.initialize(gl);
+ if(1 == getInitCounter() && 0 == getName() ) {
+ do init ..
+ freeResources = true; // if all OK
+ }
+ */
+ }
+
+ /**
+ * Releases the attachment buffer if initialized, i.e. name is zero
.
+ * Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.
+ * @throws GLException if buffer release fails.
+ */
+ public void free(GL gl) throws GLException {
+ /*
+ if(1 == getInitCounter() && freeResources && .. ) {
+ do free ..
+ }
+ super.free(gl);
+ */
+ initCounter--;
+ if(0 == initCounter) {
+ resourceOwner = false;
+ name = 0;
+ }
+ if(DEBUG) {
+ System.err.println("Attachment.free: "+this);
+ }
+ }
+
+ /**
+ *
+ * Comparison by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if( this == o ) return true;
+ if( ! ( o instanceof Attachment ) ) return false;
+ final Attachment a = (Attachment)o;
+ return type == a.type &&
+ format == a.format ||
+ width == a.width ||
+ height== a.height ||
+ name == a.name ;
+ }
+
+ /**
+ *
+ * Hashed by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + type.ordinal();
+ hash = ((hash << 5) - hash) + format;
+ hash = ((hash << 5) - hash) + width;
+ hash = ((hash << 5) - hash) + height;
+ hash = ((hash << 5) - hash) + name;
+ return hash;
+ }
+
+ int objectHashCode() { return super.hashCode(); }
+
+ public String toString() {
+ return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
+ ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+
+ ", resOwner "+resourceOwner+", initCount "+initCounter+"]";
+ }
+
+ public static Type getType(int attachmentPoint, int maxColorAttachments) {
+ if( GL.GL_COLOR_ATTACHMENT0 <= attachmentPoint && attachmentPoint < GL.GL_COLOR_ATTACHMENT0+maxColorAttachments ) {
+ return Type.COLOR;
+ }
+ switch(attachmentPoint) {
+ case GL.GL_DEPTH_ATTACHMENT:
+ return Type.DEPTH;
+ case GL.GL_STENCIL_ATTACHMENT:
+ return Type.STENCIL;
+ default:
+ throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint));
+ }
+ }
+ }
+
+ /** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
+ public static class RenderAttachment extends Attachment {
+ private int samples;
+
+ /**
+ * @param type allowed types are {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
+ * @param iFormat
+ * @param samples
+ * @param width
+ * @param height
+ * @param name
+ */
+ public RenderAttachment(Type type, int iFormat, int samples, int width, int height, int name) {
+ super(validateType(type), iFormat, width, height, name);
+ this.samples = samples;
+ }
+
+ /** number of samples, or zero for no multisampling */
+ public final int getSamples() { return samples; }
+ /* pp */ final void setSamples(int s) { samples = s; }
+
+ private static Type validateType(Type type) {
+ switch(type) {
+ case DEPTH:
+ case STENCIL:
+ case COLOR:
+ return type;
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
+ }
+ }
+
+ /**
+ *
+ * Comparison by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object o) {
+ if( this == o ) return true;
+ if( ! ( o instanceof RenderAttachment ) ) return false;
+ return super.equals(o) &&
+ samples == ((RenderAttachment)o).samples;
+ }
+
+ /**
+ *
+ * Hashed by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = super.hashCode();
+ hash = ((hash << 5) - hash) + samples;
+ return hash;
+ }
+
+ @Override
+ public void initialize(GL gl) throws GLException {
+ super.initialize(gl);
+ if( 1 == getInitCounter() && 0 == getName() ) {
+ final int[] name = new int[] { -1 };
+ gl.glGenRenderbuffers(1, name, 0);
+ if( 0 == name[0] ) {
+ throw new GLException("null renderbuffer, "+this);
+ }
+ setName(name[0]);
+
+ gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
+ if( samples > 0 ) {
+ ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());
+ } else {
+ gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
+ }
+ int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR != glerr) {
+ gl.glDeleteRenderbuffers(1, name, 0);
+ setName(0);
+ throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ }
+ resourceOwner = true;
+ if(DEBUG) {
+ System.err.println("Attachment.init: "+this);
+ }
+ }
+ }
+
+ @Override
+ public void free(GL gl) {
+ if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
+ final int[] name = new int[] { getName() };
+ gl.glDeleteRenderbuffers(1, name, 0);
+ }
+ super.free(gl);
+ }
+
+ public String toString() {
+ return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
+ ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+
+ ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]";
+ }
+ }
+
+ /**
+ * Marker interface, denotes a color buffer attachment.
+ * Always an instance of {@link Attachment}.
+ * Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
+ */
+ public static interface Colorbuffer {
+ }
+
+ /** Color render buffer attachment */
+ public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
+ public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
+ super(Type.COLOR, iFormat, samples, width, height, name);
+ }
+ }
+
+ /** Texture attachment */
+ public static class TextureAttachment extends Attachment implements Colorbuffer {
+ /** details of the texture setup */
+ public final int dataFormat, dataType, magFilter, minFilter, wrapS, wrapT;
+
+ /**
+ * @param type allowed types are [ {@link Type#COLOR_TEXTURE}, {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} ]
+ * @param iFormat
+ * @param width
+ * @param height
+ * @param dataFormat
+ * @param dataType
+ * @param magFilter
+ * @param minFilter
+ * @param wrapS
+ * @param wrapT
+ * @param name
+ */
+ public TextureAttachment(Type type, int iFormat, int width, int height, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT, int name) {
+ super(validateType(type), iFormat, width, height, name);
+ this.dataFormat = dataFormat;
+ this.dataType = dataType;
+ this.magFilter = magFilter;
+ this.minFilter = minFilter;
+ this.wrapS = wrapS;
+ this.wrapT = wrapT;
+ }
+
+ private static Type validateType(Type type) {
+ switch(type) {
+ case COLOR_TEXTURE:
+ case DEPTH_TEXTURE:
+ case STENCIL_TEXTURE:
+ return type;
+ default:
+ throw new IllegalArgumentException("Invalid type: "+type);
+ }
+ }
+
+ /**
+ * Initializes the texture and set it's parameter, if uninitialized, i.e. name is zero
.
+ * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
+ */
+ @Override
+ public void initialize(GL gl) throws GLException {
+ super.initialize(gl);
+ if( 1 == getInitCounter() && 0 == getName() ) {
+ final int[] name = new int[] { -1 };
+ gl.glGenTextures(1, name, 0);
+ if(0 == name[0]) {
+ throw new GLException("null texture, "+this);
+ }
+ setName(name[0]);
+
+ gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+ if( 0 < magFilter ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
+ }
+ if( 0 < minFilter ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter);
+ }
+ if( 0 < wrapS ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
+ }
+ if( 0 < wrapT ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
+ }
+ int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR != glerr) {
+ gl.glDeleteTextures(1, name, 0);
+ setName(0);
+ throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ }
+ resourceOwner = true;
+ }
+ if(DEBUG) {
+ System.err.println("Attachment.init: "+this);
+ }
+ }
+
+ @Override
+ public void free(GL gl) {
+ if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
+ final int[] name = new int[] { getName() };
+ gl.glDeleteTextures(1, name, 0);
+ }
+ super.free(gl);
+ }
+ }
+
+ private boolean initialized;
+ private boolean basicFBOSupport;
+ private boolean fullFBOSupport;
+ private boolean rgba8Avail;
+ private boolean depth24Avail;
+ private boolean depth32Avail;
+ private boolean stencil01Avail;
+ private boolean stencil04Avail;
+ private boolean stencil08Avail;
+ private boolean stencil16Avail;
+ private boolean packedDepthStencilAvail;
+ private int maxColorAttachments, maxSamples, maxTextureSize, maxRenderbufferSize;
+
+ private int width, height, samples;
+ private int vStatus;
+ private int fbName;
+ private boolean bound;
+
+ private int colorAttachmentCount;
+ private Colorbuffer[] colorAttachmentPoints; // colorbuffer attachment points
+ private RenderAttachment depth, stencil; // depth and stencil maybe equal in case of packed-depth-stencil
+
+ private final FBObject samplesSink; // MSAA sink
+ private TextureAttachment samplesSinkTexture;
+ private boolean samplesSinkDirty;
+
+ //
+ // ColorAttachment helper ..
+ //
+
+ private final void validateColorAttachmentPointRange(int point) {
+ if(maxColorAttachments != colorAttachmentPoints.length) {
+ throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
+ }
+ if(0 > point || point >= maxColorAttachments) {
+ throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+ }
+ }
+
+ private final void validateAddColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ if( null != colorAttachmentPoints[point] ) {
+ throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]);
+ }
+ }
+
+ private final void addColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ final Colorbuffer c = colorAttachmentPoints[point];
+ if( null != c && c != ca ) {
+ throw new IllegalArgumentException("Add failed: requested to add "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+ }
+ colorAttachmentPoints[point] = ca;
+ colorAttachmentCount++;
+ }
+
+ private final void removeColorAttachment(int point, Colorbuffer ca) {
+ validateColorAttachmentPointRange(point);
+ final Colorbuffer c = colorAttachmentPoints[point];
+ if( null != c && c != ca ) {
+ throw new IllegalArgumentException("Remove failed: requested to removed "+ca+" at "+point+", but slot is holding "+c+"; "+this);
+ }
+ colorAttachmentPoints[point] = null;
+ colorAttachmentCount--;
+ }
+
+ /**
+ * Return the {@link Colorbuffer} attachment at attachmentPoint
if it is attached to this FBO, otherwise null.
+ *
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachTexture2D(GL, int, boolean, int, int, int, int)
+ * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
+ */
+ public final Colorbuffer getColorbuffer(int attachmentPoint) {
+ validateColorAttachmentPointRange(attachmentPoint);
+ return colorAttachmentPoints[attachmentPoint];
+ }
+
+ /**
+ * Finds the passed {@link Colorbuffer} within the valid range of attachment points
+ * using reference comparison only.
+ *
+ * Note: Slow. Implementation uses a logN array search to save resources, i.e. not using a HashMap.
+ *
+ * @param ca the {@link Colorbuffer} to look for.
+ * @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1]
+ */
+ public final int getColorbufferAttachmentPoint(Colorbuffer ca) {
+ for(int i=0; ireference only.
+ *
+ *
+ * Note: Slow. Uses {@link #getColorbufferAttachmentPoint(Colorbuffer)} to determine it's attachment point
+ * to be used for {@link #getColorbuffer(int)}
+ *
+ *
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachColorbuffer(GL, boolean)
+ * @see #attachTexture2D(GL, int, boolean, int, int, int, int)
+ * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
+ */
+ public final Colorbuffer getColorbuffer(Colorbuffer ca) {
+ final int p = getColorbufferAttachmentPoint(ca);
+ return p>=0 ? getColorbuffer(p) : null;
+ }
+
+ /**
+ * Creates an uninitialized FBObject instance.
+ *
+ * Call {@link #init(GL, int, int, int)} .. etc to use it.
+ *
+ */
+ public FBObject() {
+ this(false);
+ }
+ /* pp */ FBObject(boolean isSampleSink) {
+ this.initialized = false;
+
+ // TBD @ init
+ this.basicFBOSupport = false;
+ this.fullFBOSupport = false;
+ this.rgba8Avail = false;
+ this.depth24Avail = false;
+ this.depth32Avail = false;
+ this.stencil01Avail = false;
+ this.stencil04Avail = false;
+ this.stencil08Avail = false;
+ this.stencil16Avail = false;
+ this.packedDepthStencilAvail = false;
+ this.maxColorAttachments=-1;
+ this.maxSamples=-1;
+ this.maxTextureSize = 0;
+ this.maxRenderbufferSize = 0;
+
+ this.width = 0;
+ this.height = 0;
+ this.samples = 0;
+ this.vStatus = -1;
+ this.fbName = 0;
+ this.bound = false;
+
+ this.colorAttachmentPoints = null; // at init ..
+ this.colorAttachmentCount = 0;
+ this.depth = null;
+ this.stencil = null;
+
+ this.samplesSink = isSampleSink ? null : new FBObject(true);
+ this.samplesSinkTexture = null;
+ this.samplesSinkDirty = true;
+ }
+
+ private void init(GL gl, int width, int height, int samples) throws GLException {
+ if(initialized) {
+ throw new GLException("FBO already initialized");
+ }
+ fullFBOSupport = supportsFullFBO(gl);
+
+ if( !fullFBOSupport && !supportsBasicFBO(gl) ) {
+ throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
+ }
+
+ basicFBOSupport = true;
+
+ rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
+ depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
+ depth32Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth32);
+ stencil01Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil1);
+ stencil04Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil4);
+ stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8);
+ stencil16Avail = fullFBOSupport;
+
+ packedDepthStencilAvail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil);
+
+ final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments);
+
+ int val[] = new int[1];
+
+ int glerr = gl.glGetError();
+ if(DEBUG && GL.GL_NO_ERROR != glerr) {
+ System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr));
+ }
+
+ int realMaxColorAttachments = 1;
+ maxColorAttachments = 1;
+ if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) {
+ try {
+ gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
+ glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
+ } else if(DEBUG) {
+ System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ } catch (GLException gle) {}
+ }
+ maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
+
+ colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
+ colorAttachmentCount = 0;
+
+ maxSamples = 0;
+ if(fullFBOSupport) {
+ gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+ glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ maxSamples = val[0];
+ } else if(DEBUG) {
+ System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ }
+ gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
+ maxTextureSize = val[0];
+ gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
+ this.maxRenderbufferSize = val[0];
+
+ glerr = gl.glGetError();
+ if(DEBUG && GL.GL_NO_ERROR != glerr) {
+ System.err.println("FBObject.init-preexisting.1 GL Error 0x"+Integer.toHexString(glerr));
+ }
+
+ this.width = width;
+ this.height = height;
+ this.samples = samples <= maxSamples ? samples : maxSamples;
+
+ if(DEBUG) {
+ System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples");
+ System.err.println("basicFBOSupport: "+basicFBOSupport);
+ System.err.println("fullFBOSupport: "+fullFBOSupport);
+ System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments);
+ System.err.println("maxSamples: "+maxSamples);
+ System.err.println("maxTextureSize: "+maxTextureSize);
+ System.err.println("maxRenderbufferSize: "+maxRenderbufferSize);
+ System.err.println("rgba8: "+rgba8Avail);
+ System.err.println("depth24: "+depth24Avail);
+ System.err.println("depth32: "+depth32Avail);
+ System.err.println("stencil01: "+stencil01Avail);
+ System.err.println("stencil04: "+stencil04Avail);
+ System.err.println("stencil08: "+stencil08Avail);
+ System.err.println("stencil16: "+stencil16Avail);
+ System.err.println("packedDepthStencil: "+packedDepthStencilAvail);
+ System.err.println("NV_fbo_color_attachments: "+NV_fbo_color_attachments);
+ System.err.println(gl.getContext().getGLVersion());
+ System.err.println(JoglVersion.getGLStrings(gl, null).toString());
+ System.err.println(gl.getContext());
+ }
+
+ checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
+
+ if(width > 2 + maxTextureSize || height> 2 + maxTextureSize ||
+ width > maxRenderbufferSize || height> maxRenderbufferSize ) {
+ throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
+ }
+
+ if(null != samplesSink) {
+ // init sampling sink
+ samplesSink.reset(gl, width, height);
+ resetMSAATexture2DSink(gl);
+ }
+
+ // generate fbo ..
+ gl.glGenFramebuffers(1, val, 0);
+ fbName = val[0];
+ if(0 == fbName) {
+ throw new GLException("null framebuffer");
+ }
+
+ // bind fbo ..
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbName);
+ checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error
+ if(!gl.glIsFramebuffer(fbName)) {
+ checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
+ }
+ bound = true;
+ initialized = true;
+
+ updateStatus(gl);
+ if(DEBUG) {
+ System.err.println("FBObject.init(): "+this);
+ }
+ }
+
+ /**
+ * Initializes or resets this FBO's instance.
+ *
+ * In case the new parameters are compatible with the current ones
+ * no action will be performed. Otherwise all attachments will be recreated
+ * to match the new given parameters.
+ *
+ *
+ * Currently incompatibility and hence recreation is given if
+ * the size or sample count doesn't match for subsequent calls.
+ *
+ *
+ * Leaves the FBO bound state untouched
+ *
+ * @param gl the current GL context
+ * @param newWidth
+ * @param newHeight
+ * @throws GLException in case of an error
+ */
+ public final void reset(GL gl, int newWidth, int newHeight) {
+ reset(gl, newWidth, newHeight, 0);
+ }
+
+ /**
+ * Initializes or resets this FBO's instance.
+ *
+ * In case the new parameters are compatible with the current ones
+ * no action will be performed. Otherwise all attachments will be recreated
+ * to match the new given parameters.
+ *
+ *
+ * Currently incompatibility and hence recreation is given if
+ * the size or sample count doesn't match for subsequent calls.
+ *
+ *
+ * Leaves the FBO bound state untouched
+ *
+ * @param gl the current GL context
+ * @param newWidth
+ * @param newHeight
+ * @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
+ * @throws GLException in case of an error
+ */
+ public final void reset(GL gl, int newWidth, int newHeight, int newSamples) {
+ if(!initialized) {
+ init(gl, newWidth, newHeight, newSamples);
+ return;
+ }
+ newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
+
+ if( newWidth != width || newHeight != height || newSamples != samples ) {
+ if(DEBUG) {
+ System.err.println("FBObject.reset - START - "+this);
+ }
+
+ final boolean wasBound = isBound();
+
+ width = newWidth;
+ height = newHeight;
+ samples = newSamples;
+ detachAllImpl(gl, true , true);
+ resetMSAATexture2DSink(gl);
+
+ if(wasBound) {
+ bind(gl);
+ } else {
+ unbind(gl);
+ }
+
+ if(DEBUG) {
+ System.err.println("FBObject.reset - END - "+this);
+ }
+ }
+ }
+
+ /**
+ * Note that the status may reflect an incomplete state during transition of attachments.
+ * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
+ * @see #validateStatus()
+ */
+ public final int getStatus() {
+ return vStatus;
+ }
+
+ /** return the {@link #getStatus()} as a string. */
+ public final String getStatusString() {
+ return getStatusString(vStatus);
+ }
+
+ public static final String getStatusString(int fbStatus) {
+ switch(fbStatus) {
+ case -1:
+ return "NOT A FBO";
+
+ case GL.GL_FRAMEBUFFER_COMPLETE:
+ return "OK";
+
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ return("GL FBO: incomplete, incomplete attachment\n");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ return("GL FBO: incomplete, missing attachment");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ return("GL FBO: incomplete, attached images must have same dimensions");
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+ return("GL FBO: incomplete, attached images must have same format");
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ return("GL FBO: incomplete, missing draw buffer");
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ return("GL FBO: incomplete, missing read buffer");
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ return("GL FBO: incomplete, missing multisample buffer");
+ case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ return("GL FBO: incomplete, layer targets");
+
+ case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+ return("GL FBO: Unsupported framebuffer format");
+ case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+ return("GL FBO: framebuffer undefined");
+
+ case 0:
+ return("GL FBO: incomplete, implementation fault");
+ default:
+ return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus));
+ }
+ }
+
+ /**
+ * The status may even be valid if incomplete during transition of attachments.
+ * @see #getStatus()
+ */
+ public final boolean isStatusValid() {
+ switch(vStatus) {
+ case GL.GL_FRAMEBUFFER_COMPLETE:
+ return true;
+
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ if(0 == colorAttachmentCount || null == depth) {
+ // we are in transition
+ return true;
+ }
+
+ case GL.GL_FRAMEBUFFER_UNSUPPORTED:
+ case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
+
+ case 0:
+ default:
+ System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
+ " : " + getStatusString(vStatus));
+ return false;
+ }
+ }
+
+ private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
+ if(GL.GL_NO_ERROR != err) {
+ if(null != gl) {
+ destroy(gl);
+ }
+ if(null != exceptionMessage) {
+ throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+ }
+ return false;
+ }
+ return true;
+ }
+
+ private final void checkInitialized() throws GLException {
+ if(!initialized) {
+ throw new GLException("FBO not initialized, call init(GL) first.");
+ }
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * selecting the texture data type and format automatically.
+ *
+ * Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+ return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * selecting the texture data type and format automatically.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
+ final int textureInternalFormat, textureDataFormat, textureDataType;
+ if(gl.isGLES()) {
+ textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataType = GL.GL_UNSIGNED_BYTE;
+ } else {
+ textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+ textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+ }
+ return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint,
+ int internalFormat, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
+ return attachTexture2D(gl, attachmentPoint,
+ new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
+ magFilter, minFilter, wrapS, wrapT, 0 /* name */));
+ }
+
+ /**
+ * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ *
+ *
+ * In case the passed TextureAttachment texA
is uninitialized, i.e. it's texture name is zero
,
+ * a new texture name is generated and setup w/ the texture parameter.
+ * Otherwise, i.e. texture name is not zero
, the passed TextureAttachment texA
is
+ * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
+ *
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above.
+ * @return the passed TextureAttachment texA
instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ */
+ public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
+ validateAddColorAttachment(attachmentPoint, texA);
+
+ if(samples>0) {
+ removeColorAttachment(attachmentPoint, texA);
+ throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+ }
+
+ texA.initialize(gl);
+ addColorAttachment(attachmentPoint, texA);
+
+ bind(gl);
+
+ // Set up the color buffer for use as a renderable texture:
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, texA.getName(), 0);
+ updateStatus(gl);
+
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint);
+ throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.attachTexture2D: "+this);
+ }
+ return texA;
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+ * selecting the format automatically.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated
+ */
+ public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
+ final int internalFormat;
+ if( rgba8Avail ) {
+ internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+ } else {
+ internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
+ }
+ return attachColorbuffer(gl, attachmentPoint, internalFormat);
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param internalFormat usually {@link GL#GL_RGBA4}, {@link GL#GL_RGB5_A1}, {@link GL#GL_RGB565}, {@link GL#GL_RGB8} or {@link GL#GL_RGBA8}
+ * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated
+ * @throws IllegalArgumentException if internalFormat
doesn't reflect a colorbuffer
+ */
+ public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
+ final Attachment.Type atype = Attachment.Type.determine(internalFormat);
+ if( Attachment.Type.COLOR != atype ) {
+ throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ }
+
+ return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+ }
+
+ /**
+ * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl
+ * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
+ * @param colA the template for the new {@link ColorAttachment}
+ * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated
+ */
+ public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException {
+ validateAddColorAttachment(attachmentPoint, colA);
+
+ colA.initialize(gl);
+ addColorAttachment(attachmentPoint, colA);
+
+ bind(gl);
+
+ // Attach the color buffer
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_RENDERBUFFER, colA.getName());
+
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint);
+ throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.attachColorbuffer: "+this);
+ }
+ return colA;
+ }
+
+
+ /**
+ * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
+ * selecting the internalFormat automatically.
+ *
+ * Stencil and depth buffer can be attached only once.
+ *
+ *
+ * In case the desired type or bit-number is not supported, the next available one is chosen.
+ *
+ *
+ * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details
+ * about the attached buffer. The details cannot be returned, since it's possible 2 buffers
+ * are being created, depth and stencil.
+ *
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl
+ * @param atype either {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#DEPTH_STENCIL}
+ * @param reqBits desired bits for depth or -1 for default (24 bits)
+ * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached.
+ * @throws IllegalArgumentException
+ * @see #getDepthAttachment()
+ * @see #getStencilAttachment()
+ */
+ public final void attachRenderbuffer(GL gl, Attachment.Type atype, int reqBits) throws GLException, IllegalArgumentException {
+ if( 0 > reqBits ) {
+ reqBits = 24;
+ }
+ final int internalFormat;
+ int internalStencilFormat = -1;
+
+ switch ( atype ) {
+ case DEPTH:
+ if( 32 <= reqBits && depth32Avail ) {
+ internalFormat = GL.GL_DEPTH_COMPONENT32;
+ } else if( 24 <= reqBits && depth24Avail ) {
+ internalFormat = GL.GL_DEPTH_COMPONENT24;
+ } else {
+ internalFormat = GL.GL_DEPTH_COMPONENT16;
+ }
+ break;
+
+ case STENCIL:
+ if( 16 <= reqBits && stencil16Avail ) {
+ internalFormat = GL2GL3.GL_STENCIL_INDEX16;
+ } else if( 8 <= reqBits && stencil08Avail ) {
+ internalFormat = GL.GL_STENCIL_INDEX8;
+ } else if( 4 <= reqBits && stencil04Avail ) {
+ internalFormat = GL.GL_STENCIL_INDEX4;
+ } else if( 1 <= reqBits && stencil01Avail ) {
+ internalFormat = GL.GL_STENCIL_INDEX1;
+ } else {
+ throw new GLException("stencil buffer n/a");
+ }
+ break;
+
+ case DEPTH_STENCIL:
+ if( packedDepthStencilAvail ) {
+ internalFormat = GL.GL_DEPTH24_STENCIL8;
+ } else {
+ if( 24 <= reqBits && depth24Avail ) {
+ internalFormat = GL.GL_DEPTH_COMPONENT24;
+ } else {
+ internalFormat = GL.GL_DEPTH_COMPONENT16;
+ }
+ if( stencil08Avail ) {
+ internalStencilFormat = GL.GL_STENCIL_INDEX8;
+ } else if( stencil04Avail ) {
+ internalStencilFormat = GL.GL_STENCIL_INDEX4;
+ } else if( stencil01Avail ) {
+ internalStencilFormat = GL.GL_STENCIL_INDEX1;
+ } else {
+ throw new GLException("stencil buffer n/a");
+ }
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
+ }
+
+ attachRenderbufferImpl(gl, atype, internalFormat);
+
+ if(0<=internalStencilFormat) {
+ attachRenderbufferImpl(gl, Attachment.Type.STENCIL, internalStencilFormat);
+ }
+ }
+
+ /**
+ * Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
+ * depending on the internalFormat
.
+ *
+ * Stencil and depth buffer can be attached only once.
+ *
+ *
+ * Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details
+ * about the attached buffer. The details cannot be returned, since it's possible 2 buffers
+ * are being created, depth and stencil.
+ *
+ *
+ * Leaves the FBO bound.
+ *
+ * @param gl the current GL context
+ * @param internalFormat {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24}, {@link GL#GL_DEPTH_COMPONENT32},
+ * {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8}
+ * or {@link GL#GL_DEPTH24_STENCIL8}
+ * @throws GLException in case the renderbuffer couldn't be allocated or one is already attached.
+ * @throws IllegalArgumentException
+ * @see #getDepthAttachment()
+ * @see #getStencilAttachment()
+ */
+ public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException {
+ final Attachment.Type atype = Attachment.Type.determine(internalFormat);
+ if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) {
+ throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ }
+ attachRenderbufferImpl(gl, atype, internalFormat);
+ }
+
+ protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
+ if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
+ throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ }
+ if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
+ throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ }
+ attachRenderbufferImpl2(gl, atype, internalFormat);
+ }
+
+ private final void attachRenderbufferImpl2(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
+ if( Attachment.Type.DEPTH == atype ) {
+ if(null == depth) {
+ depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+ } else {
+ depth.setSize(width, height);
+ depth.setSamples(samples);
+ }
+ depth.initialize(gl);
+ } else if( Attachment.Type.STENCIL == atype ) {
+ if(null == stencil) {
+ stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, 0);
+ } else {
+ stencil.setSize(width, height);
+ stencil.setSamples(samples);
+ }
+ stencil.initialize(gl);
+ } else if( Attachment.Type.DEPTH_STENCIL == atype ) {
+ if(null == depth) {
+ depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+ } else {
+ depth.setSize(width, height);
+ depth.setSamples(samples);
+ }
+ depth.initialize(gl);
+ if(null == stencil) {
+ stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, depth.getName());
+ } else {
+ stencil.setName(depth.getName());
+ stencil.setSize(width, height);
+ stencil.setSamples(samples);
+ }
+ stencil.initialize(gl);
+ }
+
+ bind(gl);
+
+ // Attach the buffer
+ if( Attachment.Type.DEPTH == atype ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
+ } else if( Attachment.Type.STENCIL == atype ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
+ } else if( Attachment.Type.DEPTH_STENCIL == atype ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
+ }
+
+ updateStatus(gl);
+ if( !isStatusValid() ) {
+ detachRenderbuffer(gl, atype);
+ throw new GLException("renderbuffer attachment failed: "+this.getStatusString());
+ }
+
+ if(DEBUG) {
+ System.err.println("FBObject.attachRenderbuffer: "+this);
+ }
+ }
+
+ /**
+ * Leaves the FBO bound!
+ * @param gl
+ * @param ca
+ * @throws IllegalArgumentException
+ */
+ public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException {
+ if(null == detachColorbufferImpl(gl, attachmentPoint, false)) {
+ throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.detachAll: "+this);
+ }
+ }
+
+ private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) {
+ final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+
+ if(null == colbuf) {
+ return null;
+ }
+
+ bind(gl);
+
+ if(colbuf instanceof TextureAttachment) {
+ final TextureAttachment texA = (TextureAttachment) colbuf;
+ if( 0 != texA.getName() ) {
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, 0, 0);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ }
+ texA.free(gl);
+ removeColorAttachment(attachmentPoint, texA);
+ if(recreate) {
+ texA.setSize(width, height);
+ attachTexture2D(gl, attachmentPoint, texA);
+ }
+ } else if(colbuf instanceof ColorAttachment) {
+ final ColorAttachment colA = (ColorAttachment) colbuf;
+ if( 0 != colA.getName() ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
+ GL.GL_RENDERBUFFER, 0);
+ }
+ colA.free(gl);
+ removeColorAttachment(attachmentPoint, colbuf);
+ if(recreate) {
+ colA.setSize(width, height);
+ colA.setSamples(samples);
+ attachColorbuffer(gl, attachmentPoint, colA);
+ }
+ }
+ return colbuf;
+ }
+
+ /**
+ *
+ * @param gl
+ * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL}
+ */
+ public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException {
+ detachRenderbufferImpl(gl, atype, false);
+ }
+
+ public final boolean isDepthStencilPackedFormat() {
+ final boolean res = null != depth && null != stencil &&
+ depth.format == stencil.format ;
+ if(res && depth.getName() != stencil.getName() ) {
+ throw new InternalError("depth/stencil packed format not sharing: depth "+depth+", stencil "+stencil);
+ }
+ return res;
+ }
+
+ private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException {
+ switch ( atype ) {
+ case DEPTH:
+ case STENCIL:
+ case DEPTH_STENCIL:
+ break;
+ default:
+ throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
+ }
+ if( null == depth && null == stencil ) {
+ return ; // nop
+ }
+ // reduction of possible combinations, create unique atype command(s)
+ final ArrayList actions = new ArrayList(2);
+ if( isDepthStencilPackedFormat() ) {
+ // packed
+ actions.add(Attachment.Type.DEPTH_STENCIL);
+ } else {
+ // individual
+ switch ( atype ) {
+ case DEPTH:
+ if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
+ break;
+ case STENCIL:
+ if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
+ break;
+ case DEPTH_STENCIL:
+ if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
+ if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
+ break;
+ default: // handled
+ }
+ }
+
+ bind(gl);
+
+ for(int i = 0; i < actions.size(); i++) {
+ final int format;
+
+ Attachment.Type action = actions.get(i);
+ switch ( action ) {
+ case DEPTH:
+ format = depth.format;
+ if( 0 != depth.getName() ) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ }
+ depth.free(gl);
+ if(!recreate) {
+ depth = null;
+ }
+ break;
+ case STENCIL:
+ format = stencil.format;
+ if(0 != stencil.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ }
+ stencil.free(gl);
+ if(!recreate) {
+ stencil = null;
+ }
+ break;
+ case DEPTH_STENCIL:
+ format = depth.format;
+ if(0 != depth.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ }
+ depth.free(gl);
+ stencil.free(gl);
+ if(!recreate) {
+ depth = null;
+ stencil = null;
+ }
+ break;
+ default:
+ throw new InternalError("XXX");
+ }
+ if(recreate) {
+ attachRenderbufferImpl2(gl, action, format);
+ }
+ }
+ }
+
+ /**
+ * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s.
+ * Leaves the FBO bound!
+ *
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ *
+ * @param gl the current GL context
+ */
+ public final void detachAll(GL gl) {
+ if(null != samplesSink) {
+ samplesSink.detachAll(gl);
+ }
+ detachAllImpl(gl, true/* detachNonColorbuffer */, false /* recreate */);
+ }
+
+ /**
+ * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s.
+ * Leaves the FBO bound!
+ *
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ *
+ * @param gl the current GL context
+ */
+ public final void detachAllColorbuffer(GL gl) {
+ if(null != samplesSink) {
+ samplesSink.detachAllColorbuffer(gl);
+ }
+ detachAllImpl(gl, false/* detachNonColorbuffer */, false /* recreate */);
+ }
+
+ /**
+ * Detaches all {@link TextureAttachment}s
+ * Leaves the FBO bound!
+ *
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ *
+ * @param gl the current GL context
+ */
+ public final void detachAllTexturebuffer(GL gl) {
+ if(null != samplesSink) {
+ samplesSink.detachAllTexturebuffer(gl);
+ }
+ for(int i=0; i0 ) {
+ throw new InternalError("Non zero ColorAttachments "+this);
+ }
+
+ if(detachNonColorbuffer) {
+ detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate);
+ }
+
+ if(DEBUG) {
+ System.err.println("FBObject.detachAll: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
+ }
+ }
+
+ /**
+ * @param gl the current GL context
+ */
+ public final void destroy(GL gl) {
+ if(null != samplesSink) {
+ samplesSink.destroy(gl);
+ }
+
+ detachAllImpl(gl, true /* detachNonColorbuffer */, false /* recreate */);
+
+ // cache FB names, preset exposed to zero,
+ // braking ties w/ GL/GLContext link to getReadFramebuffer()/getWriteFramebuffer()
+ final int fb_cache = fbName;
+ fbName = 0;
+
+ int name[] = new int[1];
+ if(0!=fb_cache) {
+ name[0] = fb_cache;
+ gl.glDeleteFramebuffers(1, name, 0);
+ }
+ initialized = false;
+ bound = false;
+ if(DEBUG) {
+ System.err.println("FBObject.destroy: "+this);
+ }
+ }
+
+ private final boolean sampleSinkSizeMismatch() {
+ return samplesSink.getWidth() != width || samplesSink.getHeight() != height ;
+ }
+ private final boolean sampleSinkTexMismatch() {
+ return null == samplesSinkTexture || 0 == samplesSinkTexture.getName() ;
+ }
+ private final boolean sampleSinkDepthStencilMismatch() {
+ final boolean depthMismatch = ( null != depth && null == samplesSink.depth ) ||
+ ( null != depth && null != samplesSink.depth &&
+ depth.format != samplesSink.depth.format );
+
+ final boolean stencilMismatch = ( null != stencil && null == samplesSink.stencil ) ||
+ ( null != stencil && null != samplesSink.stencil &&
+ stencil.format != samplesSink.stencil.format );
+
+ return depthMismatch || stencilMismatch;
+ }
+
+ private final void resetMSAATexture2DSink(GL gl) throws GLException {
+ if(0 == samples) {
+ // MSAA off
+ if(null != samplesSink) {
+ samplesSink.detachAll(gl);
+ }
+ return;
+ }
+
+ boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
+ boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
+ boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
+
+ /** if(DEBUG) {
+ System.err.println("FBObject.resetMSAATexture2DSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ } */
+
+ if(!sampleSinkSizeMismatch && !sampleSinkTexMismatch && !sampleSinkDepthStencilMismatch) {
+ // all properties match ..
+ return;
+ }
+
+ unbind(gl);
+
+ if(DEBUG) {
+ System.err.println("FBObject.resetMSAATexture2DSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ }
+
+ if( sampleSinkDepthStencilMismatch ) {
+ samplesSink.detachAllRenderbuffer(gl);
+ }
+
+ if( sampleSinkSizeMismatch ) {
+ samplesSink.reset(gl, width, height);
+ }
+
+ if(null == samplesSinkTexture) {
+ samplesSinkTexture = samplesSink.attachTexture2D(gl, 0, true);
+ } else if( 0 == samplesSinkTexture.getName() ) {
+ samplesSinkTexture.setSize(width, height);
+ samplesSink.attachTexture2D(gl, 0, samplesSinkTexture);
+ }
+
+ if( sampleSinkDepthStencilMismatch ) {
+ samplesSink.attachRenderbuffer(gl, depth.format);
+ if( null != stencil && !isDepthStencilPackedFormat() ) {
+ samplesSink.attachRenderbuffer(gl, stencil.format);
+ }
+ }
+
+ sampleSinkSizeMismatch = sampleSinkSizeMismatch();
+ sampleSinkTexMismatch = sampleSinkTexMismatch();
+ sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
+ if(sampleSinkSizeMismatch || sampleSinkTexMismatch || sampleSinkDepthStencilMismatch) {
+ throw new InternalError("Samples sink mismatch after reset: \n\tTHIS "+this+",\n\t SINK "+samplesSink+
+ "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ }
+
+ if(DEBUG) {
+ System.err.println("FBObject.resetMSAATexture2DSink: END\n\tTHIS "+this+",\n\tSINK "+samplesSink+
+ "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ }
+ }
+
+ /**
+ * Bind this FBO, i.e. bind write framebuffer to {@link #getWriteFramebuffer()}.
+ *
+ * If multisampling is used, it sets the read framebuffer to the sampling sink {@link #getWriteFramebuffer()},
+ * if full FBO is supported.
+ *
+ *
+ * In case you have attached more than one color buffer,
+ * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
+ *
+ * @param gl the current GL context
+ * @throws GLException
+ */
+ public final void bind(GL gl) throws GLException {
+ if(!bound || fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER)) {
+ checkInitialized();
+ if(samples > 0 && fullFBOSupport) {
+ // draw to multisampling - read from samplesSink
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, getWriteFramebuffer());
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getReadFramebuffer());
+ } else {
+ // one for all
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());
+ }
+
+ checkNoError(null, gl.glGetError(), "FBObject post-bind"); // throws GLException if error
+ bound = true;
+ samplesSinkDirty = true;
+ }
+ }
+
+ /**
+ * Unbind this FBO, i.e. bind read and write framebuffer to default, see {@link GLBase#getDefaultDrawFramebuffer()}.
+ *
+ * If full FBO is supported, sets the read and write framebuffer individually to default, hence not disturbing
+ * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ *
+ * @param gl the current GL context
+ * @throws GLException
+ */
+ public final void unbind(GL gl) throws GLException {
+ if(bound) {
+ if(fullFBOSupport) {
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+ } else {
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
+ }
+ checkNoError(null, gl.glGetError(), "FBObject post-unbind"); // throws GLException if error
+ bound = false;
+ }
+ }
+
+ /**
+ * Returns true
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
.
+ *
+ * Method verifies the bound state via {@link GL#getBoundFramebuffer(int)}.
+ *
+ * @param gl the current GL context
+ */
+ public final boolean isBound(GL gl) {
+ bound = bound && fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER) ;
+ return bound;
+ }
+
+ /** Returns true
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
. */
+ public final boolean isBound() { return bound; }
+
+ /**
+ * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
+ *
+ * The operation is skipped, if no multisampling is used or
+ * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)},
+ * see {@link #isSamplingBufferDirty()}
+ *
+ * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
+ * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ *
+ * In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
+ * you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
+ *
+ *
+ * Leaves the FBO unbound.
+ *
+ * @param gl the current GL context
+ * @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
+ * @throws IllegalArgumentException
+ */
+ public final void syncSamplingBuffer(GL gl) {
+ unbind(gl);
+ if(samples>0 && samplesSinkDirty) {
+ samplesSinkDirty = false;
+ resetMSAATexture2DSink(gl);
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer());
+ ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK
+ GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
+ if(fullFBOSupport) {
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+ } else {
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
+ }
+ }
+ }
+
+ /**
+ * Bind the given texture colorbuffer.
+ *
+ * If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.
+ *
+ * Leaves the FBO unbound!
+ *
+ * @param gl the current GL context
+ * @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
+ * @throws IllegalArgumentException
+ */
+ public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
+ if(null == ta) { throw new IllegalArgumentException("null TextureAttachment"); }
+ if(samples > 0 && samplesSinkTexture == ta) {
+ syncSamplingBuffer(gl);
+ } else {
+ unbind(gl);
+ }
+ gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
+ }
+
+ /**
+ * Unbind texture, ie bind 'non' texture 0
+ *
+ * Leaves the FBO unbound.
+ */
+ public final void unuse(GL gl) {
+ unbind(gl);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
+ }
+
+ /**
+ * Returns true
if basic or full FBO is supported, otherwise false
.
+ * @param full true
for full FBO supported query, otherwise false
for basic FBO support query.
+ * @see #supportsFullFBO(GL)
+ * @see #supportsBasicFBO(GL)
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+
+ /**
+ * Returns true
if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise false
.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsRGBA8() throws GLException { checkInitialized(); return rgba8Avail; }
+
+ /**
+ * Returns true
if {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32} is supported, otherwise false
.
+ * @param bits 16, 24 or 32 bits
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsDepth(int bits) throws GLException {
+ checkInitialized();
+ switch(bits) {
+ case 16: return basicFBOSupport;
+ case 24: return depth24Avail;
+ case 32: return depth32Avail;
+ default: return false;
+ }
+ }
+
+ /**
+ * Returns true
if {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8} or {@link GL2GL3#GL_STENCIL_INDEX16} is supported, otherwise false
.
+ * @param bits 1, 4, 8 or 16 bits
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsStencil(int bits) throws GLException {
+ checkInitialized();
+ switch(bits) {
+ case 1: return stencil01Avail;
+ case 4: return stencil04Avail;
+ case 8: return stencil08Avail;
+ case 16: return stencil16Avail;
+ default: return false;
+ }
+ }
+
+ /**
+ * Returns true
if {@link GL#GL_DEPTH24_STENCIL8} is supported, otherwise false
.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final boolean supportsPackedDepthStencil() throws GLException { checkInitialized(); return packedDepthStencilAvail; }
+
+ /**
+ * Returns the maximum number of colorbuffer attachments.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
+
+ /**
+ * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported.
+ * @throws GLException if {@link #init(GL)} hasn't been called.
+ */
+ public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+
+ /**
+ * Returns true
if this instance has been initialized with {@link #reset(GL, int, int)}
+ * or {@link #reset(GL, int, int, int)}, otherwise false
+ */
+ public final boolean isInitialized() { return initialized; }
+ /** Returns the width */
+ public final int getWidth() { return width; }
+ /** Returns the height */
+ public final int getHeight() { return height; }
+ /** Returns the number of samples for multisampling (MSAA). zero if no multisampling is used. */
+ public final int getNumSamples() { return samples; }
+ /** Returns the framebuffer name to render to. */
+ public final int getWriteFramebuffer() { return fbName; }
+ /** Returns the framebuffer name to read from. Depending on multisampling, this may be a different framebuffer. */
+ public final int getReadFramebuffer() { return ( samples > 0 ) ? samplesSink.getReadFramebuffer() : fbName; }
+ /** Return the number of color/texture attachments */
+ public final int getColorAttachmentCount() { return colorAttachmentCount; }
+ /** Return the stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */
+ public final RenderAttachment getStencilAttachment() { return stencil; }
+ /** Return the depth {@link RenderAttachment} attachment. Maybe share the same {@link Attachment#getName()} as {@link #getStencilAttachment()}, if packed depth-stencil is being used. */
+ public final RenderAttachment getDepthAttachment() { return depth; }
+
+ /** Return the complete multisampling {@link FBObject} sink, if using multisampling. */
+ public final FBObject getSamplingSinkFBO() { return samplesSink; }
+
+ /** Return the multisampling {@link TextureAttachment} sink, if using multisampling. */
+ public final TextureAttachment getSamplingSink() { return samplesSinkTexture; }
+ /**
+ * Returns true
if the multisampling colorbuffer (msaa-buffer)
+ * has been flagged dirty by a previous call of {@link #bind(GL)},
+ * otherwise false
.
+ */
+ public final boolean isSamplingBufferDirty() { return samplesSinkDirty; }
+
+ int objectHashCode() { return super.hashCode(); }
+
+ public final String toString() {
+ final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ;
+ return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+", samples "+samples+"/"+maxSamples+
+ ", depth "+depth+", stencil "+stencil+", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
+ ": "+caps+", msaa-sink "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
+ ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ }
+
+ private final void updateStatus(GL gl) {
+ if( 0 == fbName ) {
+ vStatus = -1;
+ } else {
+ vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+ }
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
new file mode 100644
index 000000000..f7e25fa01
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl;
+
+/**
+ * Class holding OpenGL extension strings, commonly used by JOGL's implementation.
+ */
+public class GLExtensions {
+ public static final String VERSION_1_2 = "GL_VERSION_1_2";
+ public static final String VERSION_1_4 = "GL_VERSION_1_4";
+ public static final String VERSION_1_5 = "GL_VERSION_1_5";
+ public static final String VERSION_2_0 = "GL_VERSION_2_0";
+
+ public static final String ARB_debug_output = "GL_ARB_debug_output";
+ public static final String AMD_debug_output = "GL_AMD_debug_output";
+
+ public static final String ARB_framebuffer_object = "GL_ARB_framebuffer_object";
+ public static final String OES_framebuffer_object = "GL_OES_framebuffer_object";
+ public static final String EXT_framebuffer_object = "GL_EXT_framebuffer_object";
+ public static final String EXT_framebuffer_blit = "GL_EXT_framebuffer_blit";
+ public static final String EXT_framebuffer_multisample = "GL_EXT_framebuffer_multisample";
+ public static final String EXT_packed_depth_stencil = "GL_EXT_packed_depth_stencil";
+ public static final String OES_depth24 = "GL_OES_depth24";
+ public static final String OES_depth32 = "GL_OES_depth32";
+ public static final String OES_packed_depth_stencil = "GL_OES_packed_depth_stencil";
+ public static final String NV_fbo_color_attachments = "GL_NV_fbo_color_attachments";
+
+ public static final String ARB_ES2_compatibility = "GL_ARB_ES2_compatibility";
+
+ public static final String EXT_abgr = "GL_EXT_abgr";
+ public static final String OES_rgb8_rgba8 = "GL_OES_rgb8_rgba8";
+ public static final String OES_stencil1 = "GL_OES_stencil1";
+ public static final String OES_stencil4 = "GL_OES_stencil4";
+ public static final String OES_stencil8 = "GL_OES_stencil8";
+ public static final String APPLE_float_pixels = "GL_APPLE_float_pixels";
+
+ public static final String ARB_texture_non_power_of_two = "GL_ARB_texture_non_power_of_two";
+ public static final String ARB_texture_rectangle = "GL_ARB_texture_rectangle";
+ public static final String EXT_texture_rectangle = "GL_EXT_texture_rectangle";
+ public static final String NV_texture_rectangle = "GL_NV_texture_rectangle";
+ public static final String EXT_texture_format_BGRA8888 = "GL_EXT_texture_format_BGRA8888";
+ public static final String IMG_texture_format_BGRA8888 = "GL_IMG_texture_format_BGRA8888";
+ public static final String EXT_texture_compression_s3tc = "GL_EXT_texture_compression_s3tc";
+ public static final String NV_texture_compression_vtc = "GL_NV_texture_compression_vtc";
+ public static final String SGIS_generate_mipmap = "GL_SGIS_generate_mipmap";
+ public static final String OES_read_format = "GL_OES_read_format";
+
+ public static final String OES_EGL_image_external = "GL_OES_EGL_image_external";
+
+ //
+ // Aliased GLX/WGL/.. extensions
+ //
+
+ public static final String ARB_pixel_format = "GL_ARB_pixel_format";
+ public static final String ARB_pbuffer = "GL_ARB_pbuffer";
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 75785fd86..cdb4b82bb 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -93,11 +93,13 @@ public class JoglVersion extends JogampVersion {
return sb;
}
- public static StringBuilder getDefaultOpenGLInfo(StringBuilder sb, boolean withCapabilitiesInfo) {
+ public static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, boolean withCapabilitiesInfo) {
if(null==sb) {
sb = new StringBuilder();
}
- final AbstractGraphicsDevice device = GLProfile.getDefaultDevice();
+ if(null == device) {
+ device = GLProfile.getDefaultDevice();
+ }
sb.append("Default Profiles on device ").append(device).append(Platform.getNewline());
if(null!=device) {
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
@@ -120,13 +122,21 @@ public class JoglVersion extends JogampVersion {
if(null==sb) {
sb = new StringBuilder();
}
- GLContext ctx = gl.getContext();
-
+
sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
sb.append(device.getClass().getSimpleName()).append("[type ")
.append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ").append(Platform.getNewline());
GLProfile.glAvailabilityToString(device, sb, "\t", 1);
sb.append(Platform.getNewline());
+
+ return getGLStrings(gl, sb);
+ }
+
+ public static StringBuilder getGLStrings(GL gl, StringBuilder sb) {
+ if(null==sb) {
+ sb = new StringBuilder();
+ }
+ final GLContext ctx = gl.getContext();
sb.append("Swap Interval ").append(gl.getSwapInterval());
sb.append(Platform.getNewline());
sb.append("GL Profile ").append(gl.getGLProfile());
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
new file mode 100644
index 000000000..1ea8595c6
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl;
+
+import javax.media.opengl.GLAutoDrawableDelegate;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+/**
+ * Platform-independent class exposing FBO offscreen functionality to
+ * applications.
+ *
+ * This class distinguishes itself from {@link GLAutoDrawableDelegate}
+ * with it's {@link #setSize(int, int)} functionality.
+ *
+ */
+public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
+
+ public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, Object upstreamWidget) {
+ super(drawable, context, upstreamWidget);
+ }
+
+ /**
+ * Attempts to resize this offscreen auto drawable, if supported
+ * by the underlying {@link GLDrawable).
+ * @param newWidth
+ * @param newHeight
+ * @return true
if resize was executed, otherwise false
.
+ * @throws GLException in case of an error during the resize operation
+ */
+ public boolean setSize(int newWidth, int newHeight) throws GLException {
+ boolean done = false;
+ if(drawable instanceof GLFBODrawableImpl) {
+ context.makeCurrent();
+ try {
+ ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
+ done = true;
+ } finally {
+ context.release();
+ }
+ }
+ if(done) {
+ this.defaultWindowResizedOp();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If the underlying {@link GLDrawable} is an FBO implementation
+ * and contains an {#link FBObject}, the same is returned.
+ * Otherwise returns null
.
+ */
+ public FBObject getFBObject() {
+ if(drawable instanceof GLFBODrawableImpl) {
+ return ((GLFBODrawableImpl)drawable).getFBObject();
+ }
+ return null;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 5ee58b78d..0d9d3ddf5 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -231,6 +231,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
/* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite) */
device = SWTAccessor.getDevice(this);
+ /* Since we have no means of querying the screen index yet, assume 0. Good choice due to Xinerama alike settings anyways. */
+ final int screenIdx = 0;
/* Native handle for the control, used to associate with GLContext */
nativeWindowHandle = SWTAccessor.getWindowHandle(this);
@@ -243,7 +245,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
final GLDrawableFactory glFactory = GLDrawableFactory.getFactory(caps.getGLProfile());
/* Create a NativeWindow proxy for the SWT canvas */
- proxySurface = glFactory.createProxySurface(device, nativeWindowHandle, caps, chooser);
+ proxySurface = glFactory.createProxySurface(device, screenIdx, nativeWindowHandle, caps, chooser, swtCanvasUpStreamHook);
/* Associate a GL surface with the proxy */
drawable = glFactory.createGLDrawable(proxySurface);
@@ -265,12 +267,58 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
addControlListener(new ControlAdapter() {
@Override
public void controlResized(final ControlEvent arg0) {
- clientArea = GLCanvas.this.getClientArea();
- /* Mark for OpenGL reshape next time the control is painted */
- sendReshape = true;
+ updateSizeCheck();
}
});
}
+ private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+ @Override
+ public final void create(ProxySurface s) { /* nop */ }
+
+ @Override
+ public final void destroy(ProxySurface s) { /* nop */ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return clientArea.width;
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return clientArea.height;
+ }
+
+ @Override
+ public String toString() {
+ return "SETUpstreamSurfaceHook[upstream: "+GLCanvas.this.toString()+"]";
+ }
+
+ };
+
+ protected final void updateSizeCheck() {
+ clientArea = GLCanvas.this.getClientArea();
+ if (clientArea != null &&
+ proxySurface.getWidth() != clientArea.width &&
+ proxySurface.getHeight() != clientArea.height) {
+ sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+ }
+ sendReshape = false;
+ }
+
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
+ @Override
+ public int getWidth() {
+ return clientArea.width;
+ }
+
+ @Override
+ public int getHeight() {
+ return clientArea.height;
+ }
@Override
public void addGLEventListener(final GLEventListener arg0) {
@@ -417,25 +465,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return (drawable != null) ? drawable.getHandle() : 0;
}
- @Override
- public int getHeight() {
- final Rectangle clientArea = this.clientArea;
- if (clientArea == null) return 0;
- return clientArea.height;
- }
-
@Override
public NativeSurface getNativeSurface() {
return (drawable != null) ? drawable.getNativeSurface() : null;
}
- @Override
- public int getWidth() {
- final Rectangle clientArea = this.clientArea;
- if (clientArea == null) return 0;
- return clientArea.width;
- }
-
@Override
public boolean isRealized() {
return (drawable != null) ? drawable.isRealized() : false;
@@ -515,7 +549,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
final Display display = new Display();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java b/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
deleted file mode 100644
index 3e049a334..000000000
--- a/src/jogl/classes/com/jogamp/opengl/util/FBObject.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2011 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.
- *
- */
-
-package com.jogamp.opengl.util;
-
-import javax.media.opengl.*;
-
-public class FBObject {
- static final int MAX_FBO_TEXTURES = 32; // just for our impl .. not the real 'max' FBO color attachments
- private int[] fbo_tex_names;
- private int[] fbo_tex_units;
- private int fbo_tex_num;
- private int colorattachment_num;
-
- private boolean initialized;
- private int width, height;
- private int fb, depth_rb, stencil_rb, vStatus;
- private boolean bound;
-
- public FBObject(int width, int height) {
- this.fbo_tex_names = new int[MAX_FBO_TEXTURES];
- this.fbo_tex_units = new int[MAX_FBO_TEXTURES];
- this.fbo_tex_num = 0;
- this.colorattachment_num = 0;
- this.initialized = false;
- this.width = width;
- this.height = height;
- this.fb = 0;
- this.depth_rb = 0;
- this.stencil_rb = 0;
- this.bound = false;
- }
-
- /**
- * @return true if the FB status is valid, otherwise false
- * @see #getStatus()
- */
- public boolean isStatusValid() {
- switch(vStatus) {
- case GL.GL_FRAMEBUFFER_COMPLETE:
- return true;
- case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- //case GL2.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
- case 0:
- default:
- System.out.println("Framebuffer " + fb + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
- " : " + getStatusString(vStatus));
- return false;
- }
- }
-
- /**
- * @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
- * @see #validateStatus()
- */
- public int getStatus() {
- return vStatus;
- }
-
- public String getStatusString() {
- return getStatusString(vStatus);
- }
-
- public static final String getStatusString(int fbStatus) {
- switch(fbStatus) {
- case -1:
- return "NOT A FBO";
- case GL.GL_FRAMEBUFFER_COMPLETE:
- return "OK";
- case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- return("GL FBO: Unsupported framebuffer format");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- return("GL FBO: incomplete, incomplete attachment\n");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- return("GL FBO: incomplete, missing attachment");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- return("GL FBO: incomplete, attached images must have same dimensions");
- case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- return("GL FBO: incomplete, attached images must have same format");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- return("GL FBO: incomplete, missing draw buffer");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- return("GL FBO: incomplete, missing read buffer");
- case GL2.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- return("GL FBO: incomplete, missing multisample buffer");
- case 0:
- return("GL FBO: incomplete, implementation fault");
- default:
- return("GL FBO: incomplete, implementation ERROR");
- }
- }
-
- private boolean checkNoError(GL gl, int err, String exceptionMessage) {
- if(GL.GL_NO_ERROR != err) {
- if(null != gl) {
- destroy(gl);
- }
- if(null != exceptionMessage) {
- throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
- }
- return false;
- }
- return true;
- }
-
- private final void checkInitialized() {
- if(!initialized) {
- throw new GLException("FBO not initialized, call init(GL) first.");
- }
- }
-
- private final void checkBound(GL gl, boolean shallBeBound) {
- checkInitialized();
- if(bound != shallBeBound) {
- final String s0 = shallBeBound ? "not" : "already" ;
- throw new GLException("FBO "+s0+" bound "+toString());
- }
- checkNoError(null, gl.glGetError(), "FBObject pre"); // throws GLException if error
- }
-
- /**
- * Initializes this FBO's instance with it's texture.
- *
- * Leaves the FBO bound!
- *
- * @param gl the current GL context
- * @throws GLException in case of an error
- */
- public void init(GL gl) throws GLException {
- if(initialized) {
- throw new GLException("FBO already initialized");
- }
- checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
-
- // generate fbo ..
- int name[] = new int[1];
-
- gl.glGenFramebuffers(1, name, 0);
- fb = name[0];
- if(fb==0) {
- throw new GLException("null generated framebuffer");
- }
-
- // bind fbo ..
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
- checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error
- if(!gl.glIsFramebuffer(fb)) {
- checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
- }
- bound = true;
- initialized = true;
-
- updateStatus(gl);
- }
-
- /**
- * Attaches a[nother] Texture2D Color Buffer to this FBO's instance,
- * selecting the texture data type and format automatically.
- * This may be done as many times as many color attachments are supported,
- * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.
- *
- * Assumes a bound FBO
- * Leaves the FBO bound!
- *
- * @param gl the current GL context
- * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)}
- * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
- * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
- * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
- * @return idx of the new attached texture, otherwise -1
- * @throws GLException in case of an error
- */
- public int attachTexture2D(GL gl, int texUnit, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- final int textureInternalFormat, textureDataFormat, textureDataType;
- if(gl.isGLES()) {
- textureInternalFormat=GL.GL_RGBA;
- textureDataFormat=GL.GL_RGBA;
- textureDataType=GL.GL_UNSIGNED_BYTE;
- } else {
- textureInternalFormat=GL.GL_RGBA8;
- textureDataFormat=GL.GL_BGRA;
- textureDataType=GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV;
- }
- return attachTexture2D(gl, texUnit, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
- }
-
- /**
- * Attaches a[nother] Texture2D Color Buffer to this FBO's instance,
- * selecting the texture data type and format automatically.
- * This may be done as many times as many color attachments are supported,
- * see {@link GL2GL3#GL_MAX_COLOR_ATTACHMENTS}.
- *
- * Assumes a bound FBO
- * Leaves the FBO bound!
- *
- * @param gl the current GL context
- * @param texUnit the desired texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit shall be activate at {@link #use(GL, int)}
- * @param textureInternalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
- * @param textureDataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
- * @param textureDataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
- * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
- * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
- * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
- * @return index of the texture colorbuffer if bound and configured successfully, otherwise -1
- * @throws GLException in case the texture colorbuffer couldn't be allocated
- */
- public int attachTexture2D(GL gl, int texUnit,
- int textureInternalFormat, int textureDataFormat, int textureDataType,
- int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- checkBound(gl, true);
- final int fbo_tex_idx = fbo_tex_num;
- gl.glGenTextures(1, fbo_tex_names, fbo_tex_num);
- if(fbo_tex_names[fbo_tex_idx]==0) {
- throw new GLException("null generated texture");
- }
- fbo_tex_units[fbo_tex_idx] = texUnit;
- fbo_tex_num++;
- if(0<=texUnit) {
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
- }
- gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx]);
- checkNoError(gl, gl.glGetError(), "FBObject Init.bindTex"); // throws GLException if error
- gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, textureInternalFormat, width, height, 0,
- textureDataFormat, textureDataType, null);
- int glerr = gl.glGetError();
- if(GL.GL_NO_ERROR != glerr) {
- int[] sz = new int[1];
- gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, sz, 0);
- // throws GLException if error
- checkNoError(gl, glerr, "FBObject Init.texImage2D: "+
- " int-fmt 0x"+Integer.toHexString(textureInternalFormat)+
- ", "+width+"x"+height+
- ", data-fmt 0x"+Integer.toHexString(textureDataFormat)+
- ", data-type 0x"+Integer.toHexString(textureDataType)+
- ", max tex-sz "+sz[0]);
- }
- if( 0 < magFilter ) {
- gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
- }
- if( 0 < minFilter ) {
- gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, minFilter);
- }
- if( 0 < wrapS ) {
- gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
- }
- if( 0 < wrapT ) {
- gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
- }
-
- // Set up the color buffer for use as a renderable texture:
- gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + colorattachment_num++,
- GL.GL_TEXTURE_2D, fbo_tex_names[fbo_tex_idx], 0);
-
- updateStatus(gl);
- return isStatusValid() ? fbo_tex_idx : -1;
- }
-
- /**
- * Attaches one Depth Buffer to this FBO's instance.
- * This may be done only one time.
- *
- * Assumes a bound FBO
- * Leaves the FBO bound!
- * @param gl the current GL context
- * @param depthComponentType {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32}
- * @return true if the depth renderbuffer could be bound and configured, otherwise false
- * @throws GLException in case the depth renderbuffer couldn't be allocated or one is already attached.
- */
- public boolean attachDepthBuffer(GL gl, int depthComponentType) throws GLException {
- checkBound(gl, true);
- if(depth_rb != 0) {
- throw new GLException("FBO depth buffer already attached (rb "+depth_rb+")");
- }
- int name[] = new int[1];
- gl.glGenRenderbuffers(1, name, 0);
- depth_rb = name[0];
- if(depth_rb==0) {
- throw new GLException("null generated renderbuffer");
- }
- // Initialize the depth buffer:
- gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, depth_rb);
- if(!gl.glIsRenderbuffer(depth_rb)) {
- System.err.println("not a depthbuffer: "+ depth_rb);
- name[0] = depth_rb;
- gl.glDeleteRenderbuffers(1, name, 0);
- depth_rb=0;
- return false;
- }
-
- gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, depthComponentType, width, height);
- // Set up the depth buffer attachment:
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_DEPTH_ATTACHMENT,
- GL.GL_RENDERBUFFER, depth_rb);
- updateStatus(gl);
- return isStatusValid();
- }
-
- /**
- * Attaches one Stencil Buffer to this FBO's instance.
- * This may be done only one time.
- *
- * Assumes a bound FBO
- * Leaves the FBO bound!
- * @param gl the current GL context
- * @param stencilComponentType {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4} or {@link GL#GL_STENCIL_INDEX8}
- * @return true if the stencil renderbuffer could be bound and configured, otherwise false
- * @throws GLException in case the stencil renderbuffer couldn't be allocated or one is already attached.
- */
- public boolean attachStencilBuffer(GL gl, int stencilComponentType) throws GLException {
- checkBound(gl, true);
- if(stencil_rb != 0) {
- throw new GLException("FBO stencil buffer already attached (rb "+stencil_rb+")");
- }
- int name[] = new int[1];
- gl.glGenRenderbuffers(1, name, 0);
- stencil_rb = name[0];
- if(stencil_rb==0) {
- throw new GLException("null generated stencilbuffer");
- }
- // Initialize the stencil buffer:
- gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, stencil_rb);
- if(!gl.glIsRenderbuffer(stencil_rb)) {
- System.err.println("not a stencilbuffer: "+ stencil_rb);
- name[0] = stencil_rb;
- gl.glDeleteRenderbuffers(1, name, 0);
- stencil_rb=0;
- return false;
- }
- gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, stencilComponentType, width, height);
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_STENCIL_ATTACHMENT,
- GL.GL_RENDERBUFFER, stencil_rb);
- updateStatus(gl);
- return isStatusValid();
- }
-
- /**
- * @param gl the current GL context
- */
- public void destroy(GL gl) {
- if(bound) {
- unbind(gl);
- }
-
- int name[] = new int[1];
-
- if(0!=stencil_rb) {
- name[0] = stencil_rb;
- gl.glDeleteRenderbuffers(1, name, 0);
- stencil_rb = 0;
- }
- if(0!=depth_rb) {
- name[0] = depth_rb;
- gl.glDeleteRenderbuffers(1, name, 0);
- depth_rb=0;
- }
- if(null!=fbo_tex_names && fbo_tex_num>0) {
- gl.glDeleteTextures(1, fbo_tex_names, fbo_tex_num);
- fbo_tex_names = new int[MAX_FBO_TEXTURES];
- fbo_tex_units = new int[MAX_FBO_TEXTURES];
- fbo_tex_num = 0;
- }
- colorattachment_num = 0;
- if(0!=fb) {
- name[0] = fb;
- gl.glDeleteFramebuffers(1, name, 0);
- fb = 0;
- }
- initialized = false;
- }
-
- /**
- * Bind this FBO
- * In case you have attached more than one color buffer,
- * you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
- * @param gl the current GL context
- */
- public void bind(GL gl) {
- checkBound(gl, false);
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fb);
- bound = true;
- }
-
- /**
- * Unbind FBO, ie bind 'non' FBO 0
- * @param gl the current GL context
- */
- public void unbind(GL gl) {
- checkBound(gl, true);
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
- bound = false;
- }
-
- /**
- * Bind the texture with given index.
- *
- * If a valid texture unit was named via {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)},
- * the unit is activated via {@link GL#glActiveTexture(int) glActiveTexture(GL.GL_TEXTURE0 + unit)}.
- * @param gl the current GL context
- * @param texIdx index of the texture to use, prev. attached w/ {@link #attachTexture2D(GL, int, int, int, int, int) attachTexture2D(..)}
- */
- public void use(GL gl, int texIdx) {
- checkBound(gl, false);
- if(texIdx >= fbo_tex_num) {
- throw new GLException("Invalid texId, only "+fbo_tex_num+" textures are attached");
- }
- if(0<=fbo_tex_units[texIdx]) {
- gl.glActiveTexture(GL.GL_TEXTURE0 + fbo_tex_units[texIdx]);
- }
- gl.glBindTexture(GL.GL_TEXTURE_2D, fbo_tex_names[texIdx]); // use it ..
- }
-
- /** Unbind texture, ie bind 'non' texture 0 */
- public void unuse(GL gl) {
- checkBound(gl, false);
- gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
- }
-
- public final boolean isBound() { return bound; }
- public final int getWidth() { return width; }
- public final int getHeight() { return height; }
- public final int getFBName() { return fb; }
- public final int getTextureNumber() { return fbo_tex_num; }
- public final int getTextureName(int idx) { return fbo_tex_names[idx]; }
-
- /** @return the named texture unit ranging from [0..{@link GL2#GL_MAX_TEXTURE_UNITS}-1], or -1 if no unit was desired. */
- public final int getTextureUnit(int idx) { return fbo_tex_units[idx]; }
- public final int getColorAttachmentNumber() { return colorattachment_num; }
- public final int getStencilBuffer() { return stencil_rb; }
- public final int getDepthBuffer() { return depth_rb; }
- public final String toString() {
- return "FBO[name "+fb+", size "+width+"x"+height+", color num "+colorattachment_num+", tex num "+fbo_tex_num+", depth "+depth_rb+", stencil "+stencil_rb+"]";
- }
-
- private void updateStatus(GL gl) {
- if(!gl.glIsFramebuffer(fb)) {
- vStatus = -1;
- } else {
- vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
- }
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index 8401b9cd2..331d6fa4e 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -39,6 +39,7 @@
package com.jogamp.opengl.util;
import com.jogamp.common.nio.Buffers;
+
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES2;
@@ -56,22 +57,32 @@ import java.nio.*;
public class GLBuffers extends Buffers {
/**
- * @param glType shall be one of
- * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
- * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE,
- * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
- * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
- * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
- * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
- * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
- * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
- * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
+ * @param glType shall be one of (29)
+ * GL_BYTE, GL_UNSIGNED_BYTE,
+ * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
+ *
+ * GL_SHORT, GL_UNSIGNED_SHORT,
+ * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
+ * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ * GL.GL_HALF_FLOAT, GLES2.GL_HALF_FLOAT_OES:
+ *
+ * GL_FIXED, GL_INT
+ * GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8,
+ * GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2,
+ * GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8,
+ * GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV
+ *
+ * GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ *
+ * GL_FLOAT, GL_DOUBLE
+ *
* @return -1 if glType is unhandled, otherwise the actual value > 0
*/
public static final int sizeOfGLType(int glType) {
- switch (glType) { // 25
+ switch (glType) { // 29
+ // case GL2.GL_BITMAP:
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -86,6 +97,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL.GL_HALF_FLOAT:
+ case GLES2.GL_HALF_FLOAT_OES:
return SIZEOF_SHORT;
case GL.GL_FIXED:
@@ -108,29 +121,38 @@ public class GLBuffers extends Buffers {
case GL.GL_FLOAT:
return SIZEOF_FLOAT;
- case GL2.GL_DOUBLE:
+ case GL2GL3.GL_DOUBLE:
return SIZEOF_DOUBLE;
}
return -1;
}
/**
- * @param glType shall be one of
- * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
- * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE,
- * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
- * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
- * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
- * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
- * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
- * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
- * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
+ * @param glType shall be one of (29)
+ * GL_BYTE, GL_UNSIGNED_BYTE,
+ * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
+ *
+ * GL_SHORT, GL_UNSIGNED_SHORT,
+ * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
+ * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ * GL_HALF_FLOAT, GL_HALF_FLOAT_OES
+ *
+ * GL_FIXED, GL_INT
+ * GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8,
+ * GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2,
+ * GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8,
+ * GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV
+ *
+ * GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ *
+ * GL_FLOAT, GL_DOUBLE
+ *
* @return null if glType is unhandled, otherwise the new Buffer object
*/
public static final Buffer newDirectGLBuffer(int glType, int numElements) {
- switch (glType) {
+ switch (glType) { // 29
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -145,6 +167,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL.GL_HALF_FLOAT:
+ case GLES2.GL_HALF_FLOAT_OES:
return newDirectShortBuffer(numElements);
case GL.GL_FIXED:
@@ -174,18 +198,26 @@ public class GLBuffers extends Buffers {
}
/**
- * @param glType shall be one of
- * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
- * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE,
- * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
- * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
- * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
- * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
- * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
- * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
- * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
+ * @param glType shall be one of (29)
+ * GL_BYTE, GL_UNSIGNED_BYTE,
+ * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
+ *
+ * GL_SHORT, GL_UNSIGNED_SHORT,
+ * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
+ * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ * GL_HALF_FLOAT, GL_HALF_FLOAT_OES
+ *
+ * GL_FIXED, GL_INT
+ * GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8,
+ * GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2,
+ * GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8,
+ * GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV
+ *
+ * GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ *
+ * GL_FLOAT, GL_DOUBLE
* @return null if glType is unhandled or parent is null or bufLen is 0, otherwise the new Buffer object
*/
public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
@@ -195,7 +227,7 @@ public class GLBuffers extends Buffers {
parent.position(bytePos);
parent.limit(bytePos + byteLen);
- switch (glType) {
+ switch (glType) { // 29
case GL.GL_BYTE:
case GL.GL_UNSIGNED_BYTE:
case GL2GL3.GL_UNSIGNED_BYTE_3_3_2:
@@ -210,6 +242,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL2GL3.GL_UNSIGNED_SHORT_5_5_5_1:
case GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL.GL_HALF_FLOAT:
+ case GLES2.GL_HALF_FLOAT_OES:
return parent.asShortBuffer();
case GL.GL_FIXED:
@@ -362,28 +396,46 @@ public class GLBuffers extends Buffers {
*
* @param tmp a pass through integer array of size >= 1 used to store temp data (performance)
*
- * @param format must be one of
- * GL_COLOR_INDEX, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL,
- * GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_LUMINANCE,
- * GL_RG, GL_LUMINANCE_ALPHA,
- * GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_ABGR_EXT,
- * GL_RED_INTEGER, GL_GREEN_INTEGER, GL_BLUE_INTEGER,
- * GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER,
- * GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_HILO_NV, GL_SIGNED_HILO_NV (26)
+ * @param format must be one of (26)
+ * GL_COLOR_INDEX GL_STENCIL_INDEX
+ * GL_DEPTH_COMPONENT GL_DEPTH_STENCIL
+ * GL_RED GL_RED_INTEGER
+ * GL_GREEN GL_GREEN_INTEGER
+ * GL_BLUE GL_BLUE_INTEGER
+ * GL_ALPHA GL_LUMINANCE (12)
+ *
+ * GL_LUMINANCE_ALPHA GL_RG
+ * GL_RG_INTEGER GL_HILO_NV
+ * GL_SIGNED_HILO_NV (5)
+ *
+ * GL_RGB GL_RGB_INTEGER
+ * GL_BGR GL_BGR_INTEGER (4)
+ *
+ * GL_RGBA GL_RGBA_INTEGER
+ * GL_BGRA GL_BGRA_INTEGER
+ * GL_ABGR_EXT (5)
*
- * @param type must be one of
- * GL_BITMAP,
- * GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
- * GL_UNSIGNED_INT, GL_INT, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE,
- * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
- * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
- * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
- * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- * GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
- * GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
- * GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
- * GL_HILO16_NV, GL_SIGNED_HILO16_NV (28)
+ * @param type must be one of (30)
+ * GL_BITMAP,
+ * GL_BYTE, GL_UNSIGNED_BYTE,
+ * GL_UNSIGNED_BYTE_3_3_2, GL_UNSIGNED_BYTE_2_3_3_REV,
+ *
+ * GL_SHORT, GL_UNSIGNED_SHORT,
+ * GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_5_6_5_REV,
+ * GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ * GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ * GL_HALF_FLOAT, GL_HALF_FLOAT_OES
+ *
+ * GL_FIXED, GL_INT
+ * GL_UNSIGNED_INT, GL_UNSIGNED_INT_8_8_8_8,
+ * GL_UNSIGNED_INT_8_8_8_8_REV, GL_UNSIGNED_INT_10_10_10_2,
+ * GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_24_8,
+ * GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_5_9_9_9_REV
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV
+ *
+ * GL_FLOAT_32_UNSIGNED_INT_24_8_REV
+ *
+ * GL_FLOAT, GL_DOUBLE
*
* @param width in pixels
* @param height in pixels
@@ -402,7 +454,7 @@ public class GLBuffers extends Buffers {
if (height < 0) return 0;
if (depth < 0) return 0;
- switch (format) /* 24 */ {
+ switch (format) /* 26 */ {
case GL2.GL_COLOR_INDEX:
case GL2GL3.GL_STENCIL_INDEX:
case GL2GL3.GL_DEPTH_COMPONENT:
@@ -445,7 +497,7 @@ public class GLBuffers extends Buffers {
throw new GLException("format 0x"+Integer.toHexString(format)+" not supported [yet], pls notify the maintainer in case this is our bug.");
}
- switch (type) /* 26 */ {
+ switch (type) /* 30 */ {
case GL2.GL_BITMAP:
if (GL2.GL_COLOR_INDEX == format || GL2GL3.GL_STENCIL_INDEX == format) {
return (depth * (height * ((width+7)/8)));
@@ -460,6 +512,7 @@ public class GLBuffers extends Buffers {
case GLES2.GL_HALF_FLOAT_OES:
esize = 2;
break;
+ case GL.GL_FIXED:
case GL2ES2.GL_INT:
case GL.GL_UNSIGNED_INT:
case GL.GL_FLOAT:
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
index 368cbc0a2..b0fae8a6d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -35,6 +35,7 @@ import java.io.IOException;
import java.nio.*;
import javax.media.opengl.*;
+import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;
@@ -67,6 +68,10 @@ public class GLReadBufferUtil {
return null!=readTextureData && null!=readPixelBuffer ;
}
+ public boolean hasAlpha() { return 4 == components ? true : false ; }
+
+ public GLPixelStorageModes getGLPixelStorageModes() { return psm; }
+
/**
* @return the raw pixel ByteBuffer, filled by {@link #readPixels(GLAutoDrawable, boolean)}
*/
@@ -104,13 +109,14 @@ public class GLReadBufferUtil {
/**
* Read the drawable's pixels to TextureData and Texture, if requested at construction
*
- * @param gl the current GL object
+ * @param gl the current GL context object. It's read drawable is being used as the pixel source.
* @param drawable the drawable to read from
* @param flip weather to flip the data vertically or not
*
* @see #GLReadBufferUtil(boolean, boolean)
*/
- public boolean readPixels(GL gl, GLDrawable drawable, boolean flip) {
+ public boolean readPixels(GL gl, boolean flip) {
+ final GLDrawable drawable = gl.getContext().getGLReadDrawable();
final int textureInternalFormat, textureDataFormat, textureDataType;
final int[] glImplColorReadVals = new int[] { 0, 0 };
@@ -118,7 +124,7 @@ public class GLReadBufferUtil {
textureInternalFormat=GL.GL_RGB;
textureDataFormat=GL.GL_RGB;
textureDataType = GL.GL_UNSIGNED_BYTE;
- } else if(gl.isGLES2Compatible() || gl.isExtensionAvailable("GL_OES_read_format")) {
+ } else if(gl.isGLES2Compatible() || gl.isExtensionAvailable(GLExtensions.OES_read_format)) {
gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_FORMAT, glImplColorReadVals, 0);
gl.glGetIntegerv(GL.GL_IMPLEMENTATION_COLOR_READ_TYPE, glImplColorReadVals, 1);
textureInternalFormat = (4 == components) ? GL.GL_RGBA : GL.GL_RGB;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
index 3b817afcf..cf0373044 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/ImmModeSink.java
@@ -1,15 +1,20 @@
package com.jogamp.opengl.util;
-import com.jogamp.common.util.*;
-import com.jogamp.opengl.util.glsl.ShaderState;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
-import javax.media.opengl.*;
-import javax.media.opengl.fixedfunc.*;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
-import java.nio.*;
-import java.util.Iterator;
-import java.util.ArrayList;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.util.glsl.ShaderState;
public class ImmModeSink {
@@ -337,10 +342,8 @@ public class ImmModeSink {
enableBuffer(gl, true);
if (buffer!=null) {
- GL2ES1 glf = gl.getGL2ES1();
-
if(null==indices) {
- glf.glDrawArrays(mode, 0, count);
+ gl.glDrawArrays(mode, 0, count);
} else {
Class> clazz = indices.getClass();
int type=-1;
@@ -352,7 +355,7 @@ public class ImmModeSink {
if(0>type) {
throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
}
- glf.glDrawElements(mode, indices.remaining(), type, indices);
+ gl.glDrawElements(mode, indices.remaining(), type, indices);
// GL2: gl.glDrawRangeElements(mode, 0, indices.remaining()-1, indices.remaining(), type, indices);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
index fa66673fd..0022d5c2d 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java
@@ -48,6 +48,7 @@ import javax.media.opengl.GLException;
import javax.media.opengl.glu.gl2.GLUgl2;
import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.GLPixelStorageModes;
import com.jogamp.opengl.util.TGAWriter;
@@ -392,7 +393,7 @@ public class Screenshot {
private static void checkExtABGR() {
GL2 gl = GLUgl2.getCurrentGL2();
- if (!gl.isExtensionAvailable("GL_EXT_abgr")) {
+ if (!gl.isExtensionAvailable(GLExtensions.EXT_abgr)) {
throw new IllegalArgumentException("Saving alpha channel requires GL_EXT_abgr");
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index 622ee1b79..1735fcddd 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -41,6 +41,7 @@ package com.jogamp.opengl.util.awt;
import com.jogamp.common.nio.Buffers;
+import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.*;
import com.jogamp.opengl.util.packrect.*;
import com.jogamp.opengl.util.texture.*;
@@ -1976,7 +1977,7 @@ public class TextRenderer {
private final boolean is15Available(GL gl) {
if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) {
- isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5");
+ isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable(GLExtensions.VERSION_1_5);
checkFor_isExtensionAvailable_GL_VERSION_1_5 = true;
}
return isExtensionAvailable_GL_VERSION_1_5;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index 49d4add5f..e7bf87a36 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -44,6 +44,7 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.opengl.*;
+import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.texture.spi.*;
/**
@@ -262,8 +263,8 @@ public class Texture {
*
* See the performance tips above for hints
* on how to maximize performance when using many Texture objects.
- * @param gl TODO
- *
+ *
+ * @param gl the current GL context
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
@@ -448,12 +449,12 @@ public class Texture {
// See whether we have automatic mipmap generation support
boolean haveAutoMipmapGeneration =
- (gl.isExtensionAvailable("GL_VERSION_1_4") ||
- gl.isExtensionAvailable("GL_SGIS_generate_mipmap"));
+ (gl.isExtensionAvailable(GLExtensions.VERSION_1_4) ||
+ gl.isExtensionAvailable(GLExtensions.SGIS_generate_mipmap));
// Indicate to the TextureData what functionality is available
- data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
- data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+ data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+ data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
// Indicates whether both width and height are power of two
boolean isPOT = isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight);
@@ -646,7 +647,7 @@ public class Texture {
int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR);
int magFilter = GL.GL_LINEAR;
- int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
+ int wrapMode = (gl.isExtensionAvailable(GLExtensions.VERSION_1_2) || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
// REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB
if (texTarget != GL2.GL_TEXTURE_RECTANGLE_ARB) {
@@ -925,8 +926,8 @@ public class Texture {
private void updateSubImageImpl(GL gl, TextureData data, int newTarget, int mipmapLevel,
int dstx, int dsty,
int srcx, int srcy, int width, int height) throws GLException {
- data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
- data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+ data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+ data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
Buffer buffer = data.getBuffer();
if (buffer == null && data.getMipmapData() == null) {
@@ -1044,8 +1045,8 @@ public class Texture {
case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc") &&
- !gl.isExtensionAvailable("GL_NV_texture_compression_vtc")) {
+ if (!gl.isExtensionAvailable(GLExtensions.EXT_texture_compression_s3tc) &&
+ !gl.isExtensionAvailable(GLExtensions.NV_texture_compression_vtc)) {
throw new GLException("DXTn compressed textures not supported by this graphics card");
}
break;
@@ -1081,7 +1082,7 @@ public class Texture {
private static boolean haveTexRect(GL gl) {
return (!disableTexRect &&
TextureIO.isTexRectEnabled() &&
- gl.isExtensionAvailable("GL_ARB_texture_rectangle"));
+ gl.isExtensionAvailable(GLExtensions.ARB_texture_rectangle));
}
private static boolean preferTexRect(GL gl) {
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index ca97cdc4b..b878c6002 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -155,6 +155,14 @@ public class TextureIO {
file. */
public static final String TIFF = "tiff";
+ /** Constant which can be used as a file suffix to indicate a PAM
+ file, NetPbm magic 7 - binary RGB and RGBA. Write support only. */
+ public static final String PAM = "pam";
+
+ /** Constant which can be used as a file suffix to indicate a PAM
+ file, NetPbm magic 6 - binary RGB. Write support only. */
+ public static final String PPM = "ppm";
+
private static final boolean DEBUG = Debug.debug("TextureIO");
// For manually disabling the use of the texture rectangle
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 5ee2104a3..6b41c0bc8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -102,7 +102,6 @@ import javax.media.opengl.GL;
*/
public interface TextureSequence {
public static final String GL_OES_EGL_image_external_Required_Prelude = "#extension GL_OES_EGL_image_external : enable\n";
- public static final String GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
public static final String samplerExternalOES = "samplerExternalOES";
public static final String sampler2D = "sampler2D";
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
index c2b131b97..cd42a1157 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/NetPbmTextureWriter.java
@@ -77,8 +77,10 @@ public class NetPbmTextureWriter implements TextureWriter {
public int getMagic() { return magic; }
- public static final String PPM = "ppm";
- public static final String PAM = "pam";
+ /** @see TextureIO#PPM */
+ public static final String PPM = TextureIO.PPM;
+ /** @see TextureIO#PAM */
+ public static final String PAM = TextureIO.PAM;
public String getSuffix() { return (magic==6)?PPM:PAM; }
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index b57b85e5c..1b84bd9bd 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -141,7 +141,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
for (int i = 0; i < scores.length; i++) {
scores[i] = NO_SCORE;
}
- final int gldes_samples = gldes.getSampleBuffers() ? gldes.getNumSamples() : 0;
+ final int gldes_samples = gldes.getNumSamples();
// Compute score for each
for (int i = 0; i < availnum; i++) {
@@ -158,8 +158,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (gldes.getStereo() != cur.getStereo()) {
continue;
}
- final int cur_samples =
- cur.getSampleBuffers() ? cur.getNumSamples() : 0;
+ final int cur_samples = cur.getNumSamples() ;
int score = 0;
// Compute difference in color depth
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 80d4f796c..0b2c664fe 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -51,8 +51,8 @@ import jogamp.opengl.Debug;
calls to {@link GLContext#makeCurrent makeCurrent} will block if
the context is current on another thread. This allows the internal
GLContext for the GLAutoDrawable to be used both by the event
- based rendering mechanism as well by end users directly.
-
+ based rendering mechanism as well by end users directly.
+
The implementation shall initialize itself as soon as possible,
ie if the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible/realized.
The following protocol shall be satisfied:
@@ -64,18 +64,18 @@ import jogamp.opengl.Debug;
registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.
Send a reshape event by calling {@link GLEventListener#reshape reshape(..)} for all
registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.
-
-
+
+
Another implementation detail is the drawable reconfiguration. One use case is where a window is being
dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
- shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.
+ shall be able to detect such cases in conjunction with the associated {@link javax.media.nativewindow.NativeSurface NativeSurface}.
For example, AWT's {@link java.awt.Canvas} 's {@link java.awt.Canvas#getGraphicsConfiguration getGraphicsConfiguration()}
is capable to determine a display device change. This is demonstrated within {@link javax.media.opengl.awt.GLCanvas}'s
and NEWT's AWTCanvas
{@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
- implementation on the Windows platform, which utilizes the native platform's MonitorFromWindow(HWND) function.
+ implementation on the Windows platform, which utilizes the native platform's MonitorFromWindow(HWND) function.
All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
- to be choosen again. The following protocol shall be satisfied.
+ to be chosen again. The following protocol shall be satisfied.
Controlled disposal:
@@ -97,16 +97,16 @@ import jogamp.opengl.Debug;
Note: Current graphics driver keep the surface configuration for a given window, even if the window is moved to
a monitor with a different pixel configuration, ie 32bpp to 16bpp. However, it is best to not assume such behavior
- and make your application comply with the above protocol.
-
- However, to not introduce to much breakage with older applications and because of the situation
+ and make your application comply with the above protocol.
+
+ Avoiding breakage with older applications and because of the situation
mentioned above, the boolean
system property jogl.screenchange.action
will control the
- screen change action as follows:
-
+ screen change action as follows:
-Djogl.screenchange.action=false Disable the drawable reconfiguration (the default)
-Djogl.screenchange.action=true Enable the drawable reconfiguration
+
*/
public interface GLAutoDrawable extends GLDrawable {
/** Flag reflecting wheather the drawable reconfiguration will be issued in
@@ -362,5 +362,29 @@ public interface GLAutoDrawable extends GLDrawable {
demos for examples.
@return the set GL pipeline or null if not successful */
public GL setGL(GL gl);
+
+ /**
+ * Method may return the upstream UI toolkit object
+ * holding this {@link GLAutoDrawable} instance, if exist.
+ *
+ * Currently known Java UI toolkits and it's known return types are:
+ *
+ *
+ * Toolkit GLAutoDrawable Implementation ~ Return Type of getUpstreamWidget()
+ * NEWT {@link com.jogamp.newt.opengl.GLWindow} has a {@link com.jogamp.newt.Window}
+ * SWT {@link com.jogamp.opengl.swt.GLCanvas} is a {@link org.eclipse.swt.widgets.Canvas}
+ * AWT {@link javax.media.opengl.awt.GLCanvas} is a {@link java.awt.Canvas}
+ * AWT {@link javax.media.opengl.awt.GLJPanel} is a {@link javax.swing.JPanel}
+ *
+ * However, the result may be other object types than the listed above
+ * due to new supported toolkits.
+ *
+ *
+ * This method may also return null
if no UI toolkit is being used,
+ * as common for offscreen rendering.
+ *
+ * @return
+ */
+ public Object getUpstreamWidget();
}
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
index 89d5cc4cb..1f6166719 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
@@ -56,8 +56,14 @@ import jogamp.opengl.GLDrawableImpl;
public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context) {
+ /**
+ * @param drawable
+ * @param context
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ */
+ public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget) {
super((GLDrawableImpl)drawable, (GLContextImpl)context);
+ this.upstreamWidget = null;
}
//
@@ -80,8 +86,14 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
// Complete GLAutoDrawable
//
- private RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
-
+ private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
+ private final Object upstreamWidget;
+
+ @Override
+ public final Object getUpstreamWidget() {
+ return upstreamWidget;
+ }
+
/**
* {@inheritDoc}
*
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index bd24b15bc..f5831a72d 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -340,5 +340,60 @@ public interface GLBase {
* completeness.
*/
public Object getExtension(String extensionName);
+
+ /** Aliased entrypoint of void {@native glClearDepth}(GLclampd depth);
and void {@native glClearDepthf}(GLclampf depth);
. */
+ public void glClearDepth( double depth );
+
+ /** Aliased entrypoint of void {@native glDepthRange}(GLclampd depth);
and void {@native glDepthRangef}(GLclampf depth);
. */
+ public void glDepthRange(double zNear, double zFar);
+
+ /**
+ * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
+ * @return the GL buffer (VBO) name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+ */
+ public int glGetBoundBuffer(int target);
+
+ /**
+ * @param buffer a GL buffer name, generated with {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)} for example.
+ * @return the size of the given GL buffer
+ */
+ public long glGetBufferSize(int buffer);
+
+ /**
+ * @return true if a VBO is bound to {@link GL.GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+ */
+ public boolean glIsVBOArrayEnabled();
+
+ /**
+ * @return true if a VBO is bound to {@link GL.GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false
+ */
+ public boolean glIsVBOElementArrayEnabled();
+
+ /**
+ * Return the framebuffer name bound to this context,
+ * see {@link GL#glBindFramebuffer(int, int)}.
+ */
+ public int getBoundFramebuffer(int target);
+
+ /**
+ * Return the default draw framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ */
+ public int getDefaultDrawFramebuffer();
+
+ /**
+ * Return the default read framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ */
+ public int getDefaultReadFramebuffer();
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index e5258bcfd..8845ec665 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -183,8 +183,8 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
return -1;
}
- final int ms = sampleBuffers ? numSamples : 0;
- final int xms = caps.getSampleBuffers() ? caps.getNumSamples() : 0;
+ final int ms = getNumSamples();
+ final int xms = caps.getNumSamples() ;
if(ms > xms) {
return 1;
@@ -231,15 +231,13 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
/**
* Enables or disables pbuffer usage.
*
- * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
- * and {@link #setFBO(int) setFBO(false)}
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
* Defaults to false.
*/
public void setPBuffer(boolean enable) {
if(enable) {
setOnscreen(false);
- setFBO(false);
}
isPBuffer = enable;
}
@@ -252,28 +250,28 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
/**
* Enables or disables FBO usage.
*
- * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}
- * and {@link #setPBuffer(int) setPBuffer(false)}
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
* Defaults to false.
*/
public void setFBO(boolean enable) {
if(enable) {
setOnscreen(false);
- setPBuffer(false);
}
isFBO = enable;
}
/**
* Sets whether the drawable surface supports onscreen.
- * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
+ * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
+ * and {@link #setFBO(int) setFBO(false)}
* Defaults to true.
*/
@Override
public void setOnscreen(boolean onscreen) {
if(onscreen) {
setPBuffer(false);
+ setFBO(false);
}
super.setOnscreen(onscreen);
}
@@ -413,15 +411,18 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
return sampleBuffers;
}
- /** If sample buffers are enabled, indicates the number of buffers
- to be allocated. Defaults to 2. */
+ /**
+ * If sample buffers are enabled, indicates the number of buffers
+ * to be allocated. Defaults to 2.
+ * @see #getNumSamples()
+ */
public void setNumSamples(int numSamples) {
this.numSamples = numSamples;
}
@Override
public final int getNumSamples() {
- return numSamples;
+ return sampleBuffers ? numSamples : 0;
}
/** For pbuffers only, indicates whether floating-point buffers
@@ -492,12 +493,14 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
if(!isOnscreen()) {
if(isFBO) {
sink.append(", fbo");
- } else if(isPBuffer) {
+ }
+ if(isPBuffer) {
sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
.append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
.append(", float ").append(pbufferFloatingPointBuffers?1:0)
.append("]");
- } else {
+ }
+ if(!isFBO && !isPBuffer) {
sink.append(", pixmap");
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
index 883f3912e..7e0459b2d 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -111,7 +111,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
/**
* Returns the number of sample buffers to be allocated if sample
- * buffers are enabled. Defaults to 2.
+ * buffers are enabled, otherwise returns 0. Defaults to 2.
*/
int getNumSamples();
@@ -144,12 +144,12 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
boolean getStereo();
/**
- * Indicates whether pbuffer is used/requested.
+ * Indicates whether pbuffer offscreen is used/requested.
*/
boolean isPBuffer();
/**
- * Indicates whether FBO is used/requested.
+ * Indicates whether FBO offscreen is used/requested.
*/
boolean isFBO();
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 351f90027..63a02ad9c 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -55,6 +55,7 @@ import com.jogamp.common.os.Platform;
import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLExtensions;
/** Abstraction for an OpenGL rendering context. In order to perform
OpenGL rendering, a context must be "made current" on the current
@@ -69,6 +70,7 @@ import com.jogamp.common.util.locks.RecursiveLock;
abstraction provides a stable object which clients can use to
refer to a given context. */
public abstract class GLContext {
+
/**
* If true
(default), bootstrapping the available GL profiles
* will use the highest compatible GL context for each profile,
@@ -120,13 +122,13 @@ public abstract class GLContext {
protected static final int CTX_PROFILE_ES = 1 << 3;
/** ARB_create_context
related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
protected static final int CTX_OPTION_FORWARD = 1 << 4;
- /** ARB_create_context
related: flag debug. Not a cache key. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ /** ARB_create_context
related: flag debug. Cache key value. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
public static final int CTX_OPTION_DEBUG = 1 << 5;
/** GL_ARB_ES2_compatibility
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 supports FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasFBO()}.
* Not a cache key.
* @see #hasFBO()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
@@ -136,16 +138,6 @@ public abstract class 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;
- 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 currentContext = new ThreadLocal();
private final HashMap attachedObjectsByString = new HashMap();
@@ -639,11 +631,19 @@ public abstract class GLContext {
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
- * GL_ARB_ES2_compatibility
, ARB_framebuffer_object
or all of
- * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
- * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ /**
+ * Returns true
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * GL_ARB_ES2_compatibility
, GL_ARB_framebuffer_object
, GL_EXT_framebuffer_object
or GL_OES_framebuffer_object
.
+ *
+ *
+ * Basic FBO support may only include one color attachment and no multisampling,
+ * as well as limited internal formats for renderbuffer.
+ *
* @see #CTX_IMPL_FBO
+ * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
+ * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
*/
public final boolean hasFBO() {
return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
@@ -659,13 +659,13 @@ public abstract class GLContext {
/** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns true
. */
public boolean isNPOTTextureAvailable() {
- return isGL3() || isGLES2Compatible() || isExtensionAvailable(GL_ARB_texture_non_power_of_two);
+ return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
}
public boolean isTextureFormatBGRA8888Available() {
return isGL2GL3() ||
- isExtensionAvailable(GL_EXT_texture_format_BGRA8888) ||
- isExtensionAvailable(GL_IMG_texture_format_BGRA8888) ;
+ isExtensionAvailable(GLExtensions.EXT_texture_format_BGRA8888) ||
+ isExtensionAvailable(GLExtensions.IMG_texture_format_BGRA8888) ;
}
/** @see GLProfile#isGL4bc() */
@@ -798,7 +798,32 @@ public abstract class GLContext {
}
protected boolean bindSwapBarrierImpl(int group, int barrier) { /** nop per default .. **/ return false; }
-
+ /**
+ * Return the framebuffer name bound to this context,
+ * see {@link GL#glBindFramebuffer(int, int)}.
+ */
+ public abstract int getBoundFramebuffer(int target);
+
+ /**
+ * Return the default draw framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ */
+ public abstract int getDefaultDrawFramebuffer();
+
+ /**
+ * Return the default read framebuffer name.
+ *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link FBObject}) based drawable
+ * is being used.
+ *
+ */
+ public abstract int getDefaultReadFramebuffer();
+
/**
* @return The extension implementing the GLDebugOutput feature,
* either GL_ARB_debug_output or GL_AMD_debug_output .
@@ -984,6 +1009,7 @@ public abstract class GLContext {
deviceVersionsAvailableSet.add(devKey);
if (DEBUG) {
System.err.println(getThreadName() + ": createContextARB: SET mappedVersionsAvailableSet "+devKey);
+ System.err.println(GLContext.dumpAvailableGLVersions(null).toString());
}
}
}
@@ -1010,6 +1036,10 @@ public abstract class GLContext {
validateProfileBits(profile, "profile");
validateProfileBits(resCtp, "resCtp");
+ if(DEBUG) {
+ System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
+ // Thread.dumpStack();
+ }
final String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
final Integer val = new Integer(composeBits(resMajor, resMinor, resCtp));
synchronized(deviceVersionAvailable) {
@@ -1122,7 +1152,9 @@ public abstract class GLContext {
} else /* if (glpImpl.isGL2()) */ {
reqMajorCTP[0]=2;
}
- if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc
+ if( glpImpl.isGLES() ) {
+ reqMajorCTP[1]=CTX_PROFILE_ES;
+ } else if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc
reqMajorCTP[1]=CTX_PROFILE_COMPAT;
} else {
reqMajorCTP[1]=CTX_PROFILE_CORE;
@@ -1141,8 +1173,7 @@ public abstract class GLContext {
int _major[] = { 0 };
int _minor[] = { 0 };
int _ctp[] = { 0 };
- if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1],
- _major, _minor, _ctp)) {
+ if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], _major, _minor, _ctp)) {
return _ctp[0];
}
return 0; // n/a
@@ -1180,6 +1211,23 @@ public abstract class GLContext {
return null;
}
+ /**
+ * Returns true if it is possible to create an framebuffer object (FBO).
+ *
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+ *
+ *
+ * FBO support is queried as described in {@link #hasFBO()}.
+ *
+ *
+ * @param device the device to request whether FBO is available for
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ * @see GLContext#hasFBO()
+ */
+ public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
+ return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
+ }
+
/**
* @param device the device to request whether the profile is available for
* @param reqMajor Key Value either 1, 2, 3 or 4
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index d6480e7aa..612a02f14 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -50,9 +50,11 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.opengl.Debug;
@@ -398,9 +400,18 @@ public abstract class GLDrawableFactory {
/**
* Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
*
- * A Pbuffer drawable/surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
- * Otherwise a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+ *
+ *
+ * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ *
+ *
+ * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ *
+ *
+ * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
*
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be null
for the platform's default device.
@@ -421,42 +432,31 @@ public abstract class GLDrawableFactory {
throws GLException;
/**
- * Creates an offscreen NativeSurface.
- * A Pbuffer surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
- * Otherwise a simple pixmap/bitmap surface is created. The latter is unlikely to be hardware accelerated.
- *
- * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
for the platform's default device.
- * @param caps the requested GLCapabilties
- * @param chooser the custom chooser, may be null for default
- * @param width the requested offscreen width
- * @param height the requested offscreen height
- * @return the created offscreen native surface
- *
- * @throws GLException if any window system-specific errors caused
- * the creation of the GLDrawable to fail.
- */
- public abstract NativeSurface createOffscreenSurface(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable caps,
- GLCapabilitiesChooser chooser,
- int width, int height);
-
- /**
- * Highly experimental API entry, allowing developer of new windowing system bindings
- * to leverage the native window handle to produce a NativeSurface implementation (ProxySurface), having the required GLCapabilities.
- * Such surface can be used to instantiate a GLDrawable and hence test your new binding w/o the
- * costs of providing a full set of abstraction like the AWT GLCanvas or even the native NEWT bindings.
+ * Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
+ *
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}.
+ *
+ *
+ * Lifecycle (destruction) of the given surface handle shall be handled by the caller.
+ *
+ *
+ * Such surface can be used to instantiate a GLDrawable. With the help of {@link GLAutoDrawableDelegate}
+ * you will be able to implement a new native windowing system binding almost on-the-fly, see {@link com.jogamp.opengl.swt.GLCanvas}.
+ *
*
- * @param device the platform's target device, shall not be null
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
for the platform's default device.
+ * Caller has to ensure it is compatible w/ the given windowHandle
+ * @param screenIdx matching screen index of given windowHandle
* @param windowHandle the native window handle
* @param caps the requested GLCapabilties
* @param chooser the custom chooser, may be null for default
- * @return The proxy surface wrapping the windowHandle on the device
+ * @param upstream optional {@link ProxySurface.UpstreamSurfaceHook} allowing control of the {@link ProxySurface}'s lifecycle and data it presents.
+ * @return the created {@link ProxySurface} instance w/ defined surface handle.
*/
- public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ int screenIdx,
long windowHandle,
- GLCapabilitiesImmutable caps,
- GLCapabilitiesChooser chooser);
+ GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
/**
* Returns true if it is possible to create a GLPbuffer. Some older
@@ -492,23 +492,7 @@ public abstract class GLDrawableFactory {
GLContext shareWith)
throws GLException;
- /**
- * Returns true if it is possible to create an framebuffer object (FBO).
- *
- * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
- *
- *
- * FBO support is queried as described in {@link GLContext#hasFBO()}.
- *
- *
- * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
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 a7200b560..73d13a387 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -117,10 +117,12 @@ public class GLProfile {
* @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL.
*/
public static void initSingleton(final boolean firstUIActionOnProcess) {
+ final boolean justInitialized;
initLock.lock();
try {
if(!initialized) { // volatile: ok
initialized = true;
+ justInitialized = true;
if(DEBUG) {
System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
Thread.dumpStack();
@@ -166,10 +168,17 @@ public class GLProfile {
return null;
}
});
+ } else {
+ justInitialized = false;
}
} finally {
initLock.unlock();
}
+ if(DEBUG) {
+ if( justInitialized && ( hasGL234Impl || hasGLES1Impl || hasGLES2Impl ) ) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
+ }
+ }
}
/**
@@ -1532,18 +1541,17 @@ public class GLProfile {
if(DEBUG) {
// System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
- System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile);
- System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
- System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
- System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
- System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
- System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
- System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
- System.err.println("GLProfile.init defaultDevice "+defaultDevice);
- System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
- if(hasGL234Impl || hasGLES1Impl || hasGLES2Impl) { // avoid deadlock
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true));
- }
+ System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile);
+ System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
+ System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
+ System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
+ System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
+ System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
+ System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.init defaultDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
+ System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice);
+ System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
}
}
@@ -1642,24 +1650,6 @@ public class GLProfile {
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
}
- if( hasGLES2Impl ) {
- // The native ES2 impl. overwrites a previous mapping using 'ES2 compatibility' by a desktop profile
- GLContext.mapAvailableGLVersion(device,
- 2, GLContext.CTX_PROFILE_ES,
- 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_IMPL_ES2_COMPAT);
- if (DEBUG) {
- System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES2 -> ES 2.0");
- }
- }
- if( hasGLES1Impl ) {
- // Always favor the native ES1 impl.
- GLContext.mapAvailableGLVersion(device,
- 1, GLContext.CTX_PROFILE_ES,
- 1, 0, GLContext.CTX_PROFILE_ES);
- if (DEBUG) {
- System.err.println(GLContext.getThreadName() + ": initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES1 -> ES 1.0");
- }
- }
addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
@@ -1767,7 +1757,7 @@ public class GLProfile {
}
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
- System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
+ System.err.println("GLProfile.init map "+glProfile+" on device "+device.getConnection());
}
if(null==defaultGLProfileHW && isHardwareRasterizer[0]) {
defaultGLProfileHW=glProfile;
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 48f7ea24a..c2e36ef9b 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -261,6 +261,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
this.device = device;
}
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
@Override
public void setShallUseOffscreenLayer(boolean v) {
shallUseOffscreenLayer = v;
@@ -1070,7 +1075,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
final GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDevice()) );
final Frame frame = new Frame("JOGL AWT Test");
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index cd18c5098..acb8f2183 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -87,7 +87,7 @@ import jogamp.opengl.awt.Java2D;
import jogamp.opengl.awt.Java2DGLContext;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.util.GLBuffers;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
@@ -250,6 +250,11 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
this.shareWith = shareWith;
}
+ @Override
+ public final Object getUpstreamWidget() {
+ return this;
+ }
+
@Override
public void display() {
if (EventQueue.isDispatchThread()) {
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
index 804e9ee14..aabef29b0 100644
--- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
+++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PES2.java
@@ -32,7 +32,6 @@ import java.nio.FloatBuffer;
import javax.media.opengl.GL2ES2;
// FIXME: Subsume GL2GL3.GL_DRAW_FRAMEBUFFER -> GL2ES2.GL_DRAW_FRAMEBUFFER !
import javax.media.opengl.GL;
-import javax.media.opengl.GLException;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
@@ -45,7 +44,9 @@ import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RenderState;
-import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.TextureAttachment;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderState;
@@ -60,6 +61,7 @@ public class VBORegion2PES2 extends GLRegion {
private FBObject fbo;
+ private TextureAttachment texA;
private PMVMatrix fboPMVMatrix;
GLUniformData mgl_fboPMVMatrix;
@@ -72,7 +74,7 @@ public class VBORegion2PES2 extends GLRegion {
super(renderModes);
fboPMVMatrix = new PMVMatrix();
mgl_fboPMVMatrix = new GLUniformData(UniformNames.gcu_PMVMatrix, 4, 4, fboPMVMatrix.glGetPMvMatrixf());
- mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);
+ mgl_ActiveTexture = new GLUniformData(UniformNames.gcu_TextureUnit, textureEngine);
}
public void update(GL2ES2 gl, RenderState rs) {
@@ -214,8 +216,9 @@ public class VBORegion2PES2 extends GLRegion {
final ShaderState st = rs.getShaderState();
gl.glViewport(0, 0, width, hight);
- st.uniform(gl, mgl_ActiveTexture);
- fbo.use(gl, 0);
+ st.uniform(gl, mgl_ActiveTexture);
+ gl.glActiveTexture(GL.GL_TEXTURE0 + mgl_ActiveTexture.intValue());
+ fbo.use(gl, texA);
verticeFboAttr.enableBuffer(gl, true);
texCoordFboAttr.enableBuffer(gl, true);
indicesFbo.enableBuffer(gl, true);
@@ -244,20 +247,16 @@ public class VBORegion2PES2 extends GLRegion {
// System.out.println("FBO Scale: " + m.glGetMatrixf().get(0) +" " + m.glGetMatrixf().get(5));
if(null != fbo && fbo.getWidth() != tex_width_c && fbo.getHeight() != tex_height_c ) {
- fbo.destroy(gl);
- fbo = null;
+ fbo.reset(gl, tex_width_c, tex_height_c);
}
- if(null == fbo) {
- fbo = new FBObject(tex_width_c, tex_height_c);
- fbo.init(gl);
+ if(null == fbo) {
+ fbo = new FBObject();
+ fbo.reset(gl, tex_width_c, tex_height_c);
// FIXME: shall not use bilinear, due to own AA ? However, w/o bilinear result is not smooth
- fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
- // fbo.attachTexture2D(gl, mgl_ActiveTexture.intValue(), GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
- fbo.attachDepthBuffer(gl, GL.GL_DEPTH_COMPONENT16); // FIXME: or shall we use 24 or 32 bit depth ?
- if(!fbo.isStatusValid()) {
- throw new GLException("FBO invalid: "+fbo);
- }
+ texA = fbo.attachTexture2D(gl, 0, true, GL2ES2.GL_LINEAR, GL2ES2.GL_LINEAR, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+ // texA = fbo.attachTexture2D(gl, 0, GL2ES2.GL_NEAREST, GL2ES2.GL_NEAREST, GL2ES2.GL_CLAMP_TO_EDGE, GL2ES2.GL_CLAMP_TO_EDGE);
+ fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
} else {
fbo.bind(gl);
}
@@ -305,6 +304,7 @@ public class VBORegion2PES2 extends GLRegion {
if(null != fbo) {
fbo.destroy(gl);
fbo = null;
+ texA = null;
}
if(null != verticeTxtAttr) {
st.ownAttribute(verticeTxtAttr, false);
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 4dd8806fa..e730bc62e 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -49,8 +49,9 @@ import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
-import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
+import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -88,13 +89,14 @@ public abstract class GLContextImpl extends GLContext {
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
private GLBufferSizeTracker bufferSizeTracker; // Singleton - Set by GLContextShareSet
- private GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
- private GLStateTracker glStateTracker = new GLStateTracker();
+ private final GLBufferStateTracker bufferStateTracker = new GLBufferStateTracker();
+ private final GLStateTracker glStateTracker = new GLStateTracker();
private GLDebugMessageHandler glDebugHandler = null;
+ private final int[] boundFBOTarget = new int[] { 0, 0 }; // { draw, read }
protected GLDrawableImpl drawable;
protected GLDrawableImpl drawableRead;
-
+
protected GL gl;
protected static final Object mappedContextTypeObjectLock;
@@ -140,11 +142,11 @@ public abstract class GLContextImpl extends GLContext {
bufferSizeTracker.clearCachedBufferSizes();
}
- if (bufferStateTracker != null) {
+ if (bufferStateTracker != null) { //
bufferStateTracker.clearBufferObjectState();
}
- if (glStateTracker != null) {
+ if (glStateTracker != null) { //
glStateTracker.clearStates(false);
}
@@ -156,6 +158,11 @@ public abstract class GLContextImpl extends GLContext {
glRenderer = "";
glRendererLowerCase = glRenderer;
+
+ if (boundFBOTarget != null) { //
+ boundFBOTarget[0] = 0; // draw
+ boundFBOTarget[1] = 0; // read
+ }
super.resetStates();
}
@@ -199,7 +206,7 @@ public abstract class GLContextImpl extends GLContext {
drawableRead = (GLDrawableImpl) readWrite;
}
final GLDrawable old = drawable;
- drawable = ( null != readWrite ) ? (GLDrawableImpl) readWrite : null;
+ drawable = (GLDrawableImpl) readWrite ;
if(lockHeld) {
makeCurrent();
}
@@ -252,16 +259,19 @@ public abstract class GLContextImpl extends GLContext {
public void release() throws GLException {
release(false);
}
- private void release(boolean force) throws GLException {
+ private void release(boolean inDestruction) throws GLException {
if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+force+", "+lock);
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - release() - force: "+inDestruction+", "+lock);
}
if ( !lock.isOwner(Thread.currentThread()) ) {
throw new GLException("Context not current on current thread "+Thread.currentThread().getName()+": "+this);
}
- final boolean actualRelease = ( force || lock.getHoldCount() == 1 ) && 0 != contextHandle;
+ final boolean actualRelease = ( inDestruction || lock.getHoldCount() == 1 ) && 0 != contextHandle;
try {
if( actualRelease ) {
+ if( !inDestruction ) {
+ drawable.contextMadeCurrent(this, false);
+ }
releaseImpl();
}
} finally {
@@ -306,13 +316,12 @@ public abstract class GLContextImpl extends GLContext {
}
try {
// release current context
- if(null != glDebugHandler) {
- if(lock.getHoldCount() == 1) {
- // needs current context to disable debug handler
- makeCurrent();
- }
- glDebugHandler.enable(false);
+ if(lock.getHoldCount() == 1) {
+ // needs current context to disable debug handler
+ makeCurrent();
}
+ drawable.contextRealized(this, false);
+ glDebugHandler.enable(false);
if(lock.getHoldCount() > 1) {
// pending release() after makeCurrent()
release(true);
@@ -488,11 +497,18 @@ public abstract class GLContextImpl extends GLContext {
if(TRACE_GL) {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
}
+
+ drawable.contextRealized(this, true);
+
if(DEBUG || TRACE_SWITCH) {
System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
}
- } else if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
+ } else {
+ drawable.contextMadeCurrent(this, true);
+
+ if(TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
+ }
}
/* FIXME: refactor dependence on Java 2D / JOGL bridge
@@ -543,14 +559,11 @@ public abstract class GLContextImpl extends GLContext {
final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice device = config.getScreen().getDevice();
- if( !GLContext.getAvailableGLVersionsSet(device) ) {
- final int reqMajor;
- final int reqProfile;
- if( 0 != ( ctxOptions & GLContext.CTX_PROFILE_ES) ) {
- // ES1 or ES2
- reqMajor = ctxMajorVersion;
- reqProfile = GLContext.CTX_PROFILE_ES;
- } else {
+ // Non ARB desktop profiles may not have been registered
+ if( !GLContext.getAvailableGLVersionsSet(device) ) { // not yet set
+ if( 0 == ( ctxOptions & GLContext.CTX_PROFILE_ES) ) { // not ES profile
+ final int reqMajor;
+ final int reqProfile;
if(ctxMajorVersion<3 || ctxMajorVersion==3 && ctxMinorVersion==0) {
reqMajor = 2;
} else {
@@ -561,12 +574,13 @@ public abstract class GLContextImpl extends GLContext {
} else {
reqProfile = GLContext.CTX_PROFILE_COMPAT;
}
- }
- GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
- ctxMajorVersion, ctxMinorVersion, ctxOptions);
- GLContext.setAvailableGLVersionsSet(device);
- if (DEBUG) {
- System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
+ ctxMajorVersion, ctxMinorVersion, ctxOptions);
+ GLContext.setAvailableGLVersionsSet(device);
+
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": createContextOLD-MapVersionsAvailable HAVE: " + device+" -> "+reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ }
}
}
}
@@ -776,7 +790,7 @@ public abstract class GLContextImpl extends GLContext {
}
/**
- * Note: Since context creation is temproary, caller need to issue {@link #resetStates()}, if creation was successful, i.e. returns true.
+ * Note: Since context creation is temporary, caller need to issue {@link #resetStates()}, if creation was successful, i.e. returns true.
* This method does not reset the states, allowing the caller to utilize the state variables.
**/
private final boolean createContextARBMapVersionsAvailable(int reqMajor, int reqProfile) {
@@ -1034,22 +1048,29 @@ public abstract class GLContextImpl extends GLContext {
table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
}
- private final void initGLRendererStrings() {
+ private final boolean initGLRendererStrings() {
final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
if(0 == _glGetString) {
// FIXME
System.err.println("Warning: Entry point to 'glGetString' is NULL.");
- Thread.dumpStack();
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ return false;
} else {
final String _glRenderer = glGetStringInt(GL.GL_RENDERER, _glGetString);
if(null == _glRenderer) {
// FIXME
- System.err.println("Warning: GL_RENDERER is NULL.");
- Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("Warning: GL_RENDERER is NULL.");
+ Thread.dumpStack();
+ }
+ return false;
} else {
glRenderer = _glRenderer;
glRendererLowerCase = glRenderer.toLowerCase();
+ return true;
}
}
}
@@ -1088,17 +1109,20 @@ public abstract class GLContextImpl extends GLContext {
}
updateGLXProcAddressTable();
- initGLRendererStrings();
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+
+ if( !initGLRendererStrings() && DEBUG) {
+ System.err.println("Warning: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ }
if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
- final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
- final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
- System.err.println(getThreadName() + ": Context FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
}
//
@@ -1154,11 +1178,10 @@ public abstract class GLContextImpl extends GLContext {
}
}
- if( 0 != ( CTX_PROFILE_ES & ctxProfileBits ) && ctxMajorVersion >= 2 ||
- isExtensionAvailable(GL_ARB_ES2_compatibility) ) {
+ if( ( 0 != ( CTX_PROFILE_ES & ctxProfileBits ) && major >= 2 ) || isExtensionAvailable(GLExtensions.ARB_ES2_compatibility) ) {
ctxProfileBits |= CTX_IMPL_ES2_COMPAT;
ctxProfileBits |= CTX_IMPL_FBO;
- } else if( hasFBOImpl(ctxMajorVersion, ctxProfileBits, extensionAvailability) ) {
+ } else if( hasFBOImpl(major, ctxProfileBits, extensionAvailability) ) {
ctxProfileBits |= CTX_IMPL_FBO;
}
@@ -1168,23 +1191,26 @@ public abstract class GLContextImpl extends GLContext {
setContextVersion(major, minor, ctxProfileBits, true);
setDefaultSwapInterval();
+
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.X: "+contextFQN+" - "+GLContext.getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, null));
+ }
}
- protected static final boolean hasFBOImpl(int ctxMajorVersion, int ctxProfileBits, ExtensionAvailabilityCache extCache) {
- return ( ctxMajorVersion >= 3 ) || // any >= 3.0 GL ctx
+ protected static final boolean hasFBOImpl(int major, int ctp, ExtensionAvailabilityCache extCache) {
+ return ( 0 != (ctp & CTX_PROFILE_ES) && major >= 2 ) || // ES >= 2.0
- ( 0 != (ctxProfileBits & CTX_PROFILE_ES) && ctxMajorVersion >= 2 ) || // ES >= 2.0
+ major >= 3 || // any >= 3.0 GL ctx
( null != extCache &&
- ( extCache.isExtensionAvailable(GL_ARB_ES2_compatibility) ) || // ES 2.0 compatible
+ extCache.isExtensionAvailable(GLExtensions.ARB_ES2_compatibility) || // ES 2.0 compatible
- ( extCache.isExtensionAvailable(GL_ARB_framebuffer_object) ) || // ARB_framebuffer_object
+ extCache.isExtensionAvailable(GLExtensions.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) ) );
+ extCache.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) || // EXT_framebuffer_object
+
+ extCache.isExtensionAvailable(GLExtensions.OES_framebuffer_object) ) ; // OES_framebuffer_object excluded
}
protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
@@ -1259,11 +1285,11 @@ public abstract class GLContextImpl extends GLContext {
// dynamic function lookup at last incl name aliasing (not cached)
DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper();
- String tmpBase = GLExtensionNames.normalizeVEN(GLExtensionNames.normalizeARB(glFunctionName, true), true);
+ String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true);
long addr = 0;
- int variants = GLExtensionNames.getFuncNamePermutationNumber(tmpBase);
+ int variants = GLNameResolver.getFuncNamePermutationNumber(tmpBase);
for(int i = 0; 0==addr && i < variants; i++) {
- String tmp = GLExtensionNames.getFuncNamePermutation(tmpBase, i);
+ String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i);
try {
addr = dynLookup.dynamicLookupFunction(tmp);
} catch (Exception e) { }
@@ -1317,7 +1343,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 | GLContext.CTX_IMPL_FBO ) ;
+ ctxProfileBits &= ~( GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) ;
return device.getUniqueID() + "-" + toHexString(composeBits(major, minor, ctxProfileBits));
}
@@ -1371,6 +1397,56 @@ public abstract class GLContextImpl extends GLContext {
return lock.getQueueLength()>0;
}
+ //---------------------------------------------------------------------------
+ // Special FBO hook
+ //
+
+ /**
+ * Tracks {@link GL#GL_FRAMEBUFFER}, {@link GL2GL3#GL_DRAW_FRAMEBUFFER} and {@link GL2GL3#GL_READ_FRAMEBUFFER}
+ * to be returned via {@link #getBoundFramebuffer(int)}.
+ *
+ * Invoked by {@link GL#glBindFramebuffer(int, int)}.
+ *
+ * Assumes valid framebufferName
range of [0..{@link Integer#MAX_VALUE}]
+ *
+ * Does not throw an exception if target
is unknown or framebufferName
invalid.
+ */
+ public final void setBoundFramebuffer(int target, int framebufferName) {
+ if(0 > framebufferName) {
+ return; // ignore invalid name
+ }
+ switch(target) {
+ case GL.GL_FRAMEBUFFER:
+ boundFBOTarget[0] = framebufferName; // draw
+ boundFBOTarget[1] = framebufferName; // read
+ break;
+ case GL2GL3.GL_DRAW_FRAMEBUFFER:
+ boundFBOTarget[0] = framebufferName; // draw
+ break;
+ case GL2GL3.GL_READ_FRAMEBUFFER:
+ boundFBOTarget[1] = framebufferName; // read
+ break;
+ default: // ignore untracked target
+ }
+ }
+ @Override
+ public final int getBoundFramebuffer(int target) {
+ switch(target) {
+ case GL.GL_FRAMEBUFFER:
+ case GL2GL3.GL_DRAW_FRAMEBUFFER:
+ return boundFBOTarget[0]; // draw
+ case GL2GL3.GL_READ_FRAMEBUFFER:
+ return boundFBOTarget[1]; // read
+ default:
+ throw new InternalError("Invalid FBO target name: "+toHexString(target));
+ }
+ }
+
+ @Override
+ public final int getDefaultDrawFramebuffer() { return drawable.getDefaultDrawFramebuffer(); }
+ @Override
+ public final int getDefaultReadFramebuffer() { return drawable.getDefaultReadFramebuffer(); }
+
//---------------------------------------------------------------------------
// GL_ARB_debug_output, GL_AMD_debug_output helpers
//
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index b950c2fdf..0000e6199 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -37,6 +37,8 @@ import javax.media.opengl.GLException;
import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.opengl.GLExtensions;
+
import jogamp.opengl.gl4.GL4bcProcAddressTable;
/**
@@ -54,12 +56,6 @@ import jogamp.opengl.gl4.GL4bcProcAddressTable;
* the messages are translated to ARB {@link GLDebugMessage}, using {@link GLDebugMessage#translateAMDEvent(javax.media.opengl.GLContext, long, int, int, int, String)}.
*/
public class GLDebugMessageHandler {
- /** Extension GL_ARB_debug_output implementing GLDebugMessage */
- public static final String GL_ARB_debug_output = "GL_ARB_debug_output".intern();
-
- /** Extension GL_AMD_debug_output implementing GLDebugMessage */
- public static final String GL_AMD_debug_output = "GL_AMD_debug_output".intern();
-
private static final boolean DEBUG = Debug.debug("GLDebugMessageHandler");
private static final int EXT_ARB = 1;
@@ -131,11 +127,11 @@ public class GLDebugMessageHandler {
}
return;
}
- if( ctx.isExtensionAvailable(GL_ARB_debug_output) ) {
- extName = GL_ARB_debug_output;
+ if( ctx.isExtensionAvailable(GLExtensions.ARB_debug_output) ) {
+ extName = GLExtensions.ARB_debug_output;
extType = EXT_ARB;
- } else if( ctx.isExtensionAvailable(GL_AMD_debug_output) ) {
- extName = GL_AMD_debug_output;
+ } else if( ctx.isExtensionAvailable(GLExtensions.AMD_debug_output) ) {
+ extName = GLExtensions.AMD_debug_output;
extType = EXT_AMD;
}
if(DEBUG) {
@@ -145,6 +141,8 @@ public class GLDebugMessageHandler {
if(0 == extType) {
if(DEBUG) {
System.err.println("GLDebugMessageHandler: No extension available! "+ctx.getGLVersion());
+ System.err.println("GL_EXTENSIONS "+ctx.getGLExtensionCount());
+ System.err.println(ctx.getGLExtensionsString());
}
return;
}
@@ -190,11 +188,11 @@ public class GLDebugMessageHandler {
}
public final boolean isExtensionARB() {
- return extName == GL_ARB_debug_output;
+ return extName == GLExtensions.ARB_debug_output;
}
public final boolean isExtensionAMD() {
- return extName == GL_AMD_debug_output;
+ return extName == GLExtensions.AMD_debug_output;
}
/**
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index e5c44a8d4..897d3fcaf 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -1,22 +1,22 @@
/*
* 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
@@ -29,11 +29,11 @@
* 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.
*/
@@ -47,7 +47,8 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -88,7 +89,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
return null;
}
protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
-
+
/**
* Returns the shared device mapped to the device
{@link AbstractGraphicsDevice#getConnection()},
* either a preexisting or newly created, or null
if creation failed or not supported.
@@ -115,7 +116,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
protected abstract AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device);
- /**
+ /**
* Returns the GLDynamicLookupHelper
* @param profile if EGL/ES, profile 1
refers to ES1 and 2
to ES2,
* otherwise the profile is ignored.
@@ -125,6 +126,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
// Dispatching GLDrawable construction in respect to the NativeSurface Capabilities
//
+ @Override
public GLDrawable createGLDrawable(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
@@ -132,23 +134,37 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final boolean isFBOAvailable = GLContext.isFBOAvailable(adevice, chosenCaps.getGLProfile());
GLDrawable result = null;
adevice.lock();
try {
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
if(null != ols) {
- // layered surface -> Offscreen/PBuffer
+ // layered surface -> Offscreen/[FBO|PBuffer]
final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
chosenCapsMod.setOnscreen(false);
- chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice));
+ if( isFBOAvailable ) {
+ chosenCapsMod.setFBO(true);
+ } else if(canCreateGLPbuffer(adevice)) {
+ chosenCapsMod.setPBuffer(true);
+ } else {
+ chosenCapsMod.setFBO(false);
+ chosenCapsMod.setPBuffer(false);
+ }
config.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
}
- if( ! ( target instanceof SurfaceChangeable ) ) {
+ if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
+ }
+ if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+ // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
+ result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ } else {
+ result = createOffscreenDrawableImpl(target);
}
- result = createOffscreenDrawableImpl(target);
} else if(chosenCaps.isOnscreen()) {
// onscreen
if(DEBUG) {
@@ -158,12 +174,18 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
} else {
// offscreen
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO-chosen(-avail)/PBuffer: "+chosenCaps.isFBO()+"("+isFBOAvailable+")/"+chosenCaps.isPBuffer()+": "+target);
}
- if( ! ( target instanceof SurfaceChangeable ) ) {
+ if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
}
- result = createOffscreenDrawableImpl(target);
+ if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
+ // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
+ result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ } else {
+ result = createOffscreenDrawableImpl(target);
+ }
}
} finally {
adevice.unlock();
@@ -176,43 +198,42 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // Onscreen GLDrawable construction
+ // Onscreen GLDrawable construction
//
protected abstract GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target);
//---------------------------------------------------------------------------
//
- // PBuffer Offscreen GLDrawable construction
+ // PBuffer Offscreen GLDrawable construction
//
-
+
+ @Override
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
+ @Override
public GLPbuffer createGLPbuffer(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
int width,
int height,
GLContext shareWith) {
- if(height<=0 || height<=0) {
- throw new GLException("Width and height of pbuffer must be positive (were (" +
- width + ", " + height + "))");
+ if(width<=0 || height<=0) {
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
}
-
AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
-
- if (!canCreateGLPbuffer(device)) {
- throw new GLException("Pbuffer support not available with device: "+device);
+ if ( !canCreateGLPbuffer(device) ) {
+ throw new GLException("Pbuffer not available with device: "+device);
}
-
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
+
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(capsRequested);
GLDrawableImpl drawable = null;
device.lock();
try {
- drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+ drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
if(null != drawable) {
drawable.setRealized(true);
}
@@ -228,75 +249,155 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // Offscreen GLDrawable construction
+ // Offscreen GLDrawable construction
//
- protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
-
+ @Override
public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
- int width,
- int height) {
+ int width, int height) {
if(width<=0 || height<=0) {
- throw new GLException("Width and height of pbuffer must be positive (were (" +
- width + ", " + height + "))");
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
}
- AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
+
+ if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+ device.lock();
+ try {
+ return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+ } finally {
+ device.unlock();
+ }
+ }
+
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
device.lock();
try {
- return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+ return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
} finally {
device.unlock();
}
}
- public NativeSurface createOffscreenSurface(AbstractGraphicsDevice deviceReq,
- GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- int width, int height) {
- AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ /** Creates a platform independent offscreen FBO GLDrawable implementation */
+ protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ int initialWidth, int initialHeight) {
+ final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+
+ return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+ }
+
+ /** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */
+ protected abstract GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) ;
+
+ /**
+ * Creates a mutable {@link ProxySurface} w/o defined surface handle.
+ *
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}.
+ *
+ *
+ * Lifecycle (destruction) of the TBD surface handle shall be handled by the caller.
+ *
+ * @param device a valid platform dependent target device.
+ * @param createNewDevice if true
a new device instance is created using device
details,
+ * otherwise device
instance is used as-is.
+ * @param capsChosen
+ * @param capsRequested
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ * @param lifecycleHook optional control of the surface's lifecycle
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
+ */
+ protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+
+ /**
+ * A dummy surface is not visible on screen and will not be used to render directly to,
+ * it maybe on- or offscreen.
+ *
+ * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information.
+ * It also allows creation of framebuffer objects which are used for rendering.
+ *
+ * @param deviceReq which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be null
for the platform's default device.
+ * @param requestedCaps
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ *
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
+ */
+ public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ int width, int height) {
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
- GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
-
device.lock();
try {
- return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height);
+ return createDummySurfaceImpl(device, true, requestedCaps, chooser, width, height);
} finally {
device.unlock();
}
}
-
+
/**
- * creates an offscreen NativeSurface, which must implement SurfaceChangeable as well,
- * so the windowing system related implementation is able to set the surface handle.
+ * A dummy surface is not visible on screen and will not be used to render directly to,
+ * it maybe on- or offscreen.
+ *
+ * It is used to allow the creation of a {@link GLDrawable} and {@link GLContext} to query information.
+ * It also allows creation of framebuffer objects which are used for rendering.
+ *
+ * @param device a valid platform dependent target device.
+ * @param createNewDevice if true
a new device instance is created using device
details,
+ * otherwise device
instance is used as-is.
+ * @param requestedCaps
+ * @param chooser the custom chooser, may be null for default
+ * @param width the initial width
+ * @param height the initial height
+ * @return the created {@link MutableSurface} instance w/o defined surface handle
*/
- protected abstract NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- int width, int height);
+ public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
- public ProxySurface createProxySurface(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
+ //---------------------------------------------------------------------------
+ //
+ // ProxySurface (Wrapped pre-existing native surface) construction
+ //
+
+ @Override
+ public ProxySurface createProxySurface(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle,
+ GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
- throw new GLException("No shared device for requested: "+device);
+ throw new GLException("No shared device for requested: "+deviceReq);
}
device.lock();
try {
- return createProxySurfaceImpl(device, windowHandle, capsRequested, chooser);
+ return createProxySurfaceImpl(device, screenIdx, windowHandle, capsRequested, chooser, upstream);
} finally {
device.unlock();
}
- }
-
- protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
+ }
+
+ /**
+ * Creates a {@link ProxySurface} with a set surface handle.
+ *
+ * Implementation is also required to allocate it's own {@link AbstractGraphicsDevice} instance.
+ *
+ * @param upstream TODO
+ */
+ protected abstract ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle,
+ GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
//---------------------------------------------------------------------------
//
@@ -304,7 +405,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//
protected abstract GLContext createExternalGLContextImpl();
-
+
+ @Override
public GLContext createExternalGLContext() {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
@@ -316,6 +418,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected abstract GLDrawable createExternalGLDrawableImpl();
+ @Override
public GLDrawable createExternalGLDrawable() {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
@@ -398,7 +501,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* normal ahead of time, use resetDisplayGamma(). Throws
* IllegalArgumentException if any of the parameters were
* out-of-bounds.
- *
+ *
* @param gamma The gamma value, typically > 1.0 (default value is
* 1.0)
* @param brightness The brightness value between -1.0 and 1.0,
@@ -484,7 +587,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
return;
if (gammaShutdownHook == null) {
gammaShutdownHook = new Thread(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
synchronized (GLDrawableFactoryImpl.this) {
resetGammaRamp(originalGammaRamp);
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 58a4ac6b4..abf2bf557 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -42,6 +42,7 @@ package jogamp.opengl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -75,7 +76,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
if( !realized ) {
return; // destroyed already
}
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
if ( caps.getDoubleBuffered() ) {
if(!surface.surfaceSwap()) {
int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
@@ -149,6 +150,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
realized = realizedArg;
AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
if(realizedArg) {
+ if(surface instanceof ProxySurface) {
+ ((ProxySurface)surface).createNotify();
+ }
if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
throw new GLException("GLDrawableImpl.setRealized(true): Surface not ready (lockSurface)");
}
@@ -156,17 +160,21 @@ public abstract class GLDrawableImpl implements GLDrawable {
aDevice.lock();
}
try {
- setRealizedImpl();
if(realizedArg) {
+ setRealizedImpl();
updateHandle();
} else {
destroyHandle();
+ setRealizedImpl();
}
} finally {
if(realizedArg) {
unlockSurface();
} else {
aDevice.unlock();
+ if(surface instanceof ProxySurface) {
+ ((ProxySurface)surface).destroyNotify();
+ }
}
}
} else if(DEBUG) {
@@ -175,6 +183,39 @@ public abstract class GLDrawableImpl implements GLDrawable {
}
protected abstract void setRealizedImpl();
+ /**
+ * Callback for special implementations, allowing GLContext to trigger GL related lifecycle: construct
, destroy
.
+ *
+ * If realized
is true
, the context has just been created and made current.
+ *
+ *
+ * If realized
is false
, the context is still current and will be release and destroyed after this method returns.
+ *
+ *
+ * @see #contextMadeCurrent(GLContext, boolean)
+ */
+ protected void contextRealized(GLContext glc, boolean realized) {}
+
+ /**
+ * Callback for special implementations, allowing GLContext to trigger GL related lifecycle: makeCurrent
, release
.
+ *
+ * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
+ *
+ *
+ * If current
is true
, the context has just been made current.
+ *
+ *
+ * If current
is false
, the context is still current and will be release after this method returns.
+ *
+ * @see #contextRealized(GLContext, boolean)
+ */
+ protected void contextMadeCurrent(GLContext glc, boolean current) { }
+
+ /** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
+ protected int getDefaultDrawFramebuffer() { return 0; }
+ /** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
+ protected int getDefaultReadFramebuffer() { return 0; }
+
@Override
public final synchronized boolean isRealized() {
return realized;
@@ -190,10 +231,12 @@ public abstract class GLDrawableImpl implements GLDrawable {
return surface.getHeight();
}
+ /** @see NativeSurface#lockSurface() */
public final int lockSurface() throws GLException {
return surface.lockSurface();
}
+ /** @see NativeSurface#unlockSurface() */
public final void unlockSurface() {
surface.unlockSurface();
}
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
new file mode 100644
index 000000000..b7ea4f826
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -0,0 +1,138 @@
+package jogamp.opengl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/**
+ * Offscreen GLDrawable implementation using framebuffer object (FBO)
+ * as it's offscreen rendering mechanism.
+ *
+ * @see GLDrawableImpl#contextRealized(GLContext, boolean)
+ * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
+ * @see GLDrawableImpl#getDefaultDrawFramebuffer()
+ * @see GLDrawableImpl#getDefaultReadFramebuffer()
+ */
+public class GLFBODrawableImpl extends GLDrawableImpl {
+ final GLDrawableImpl parent;
+ final FBObject fbo;
+ int texUnit;
+ int samplesTexUnit = 0;
+ int width=0, height=0, samples=0;
+
+ protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent,
+ NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) {
+ super(factory, surface, false);
+ this.parent = parent;
+ this.texUnit = textureUnit;
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ this.width = initialWidth;
+ this.height = initialHeight;
+ this.samples = caps.getNumSamples();
+ this.fbo = new FBObject();
+ }
+
+ @Override
+ protected void contextRealized(GLContext glc, boolean realized) {
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ final GL gl = glc.getGL();
+ if(realized) {
+ fbo.reset(gl, width, height, samples);
+ samples = fbo.getNumSamples(); // update, maybe capped
+ if(samples > 0) {
+ fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ } else {
+ fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ }
+ if( caps.getStencilBits() > 0 ) {
+ fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+ } else {
+ fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ }
+ } else if(null != fbo) {
+ fbo.destroy(gl);
+ }
+ }
+
+ @Override
+ protected void contextMadeCurrent(GLContext glc, boolean current) {
+ final GL gl = glc.getGL();
+ if(current) {
+ fbo.bind(gl);
+ } else {
+ fbo.unbind(gl);
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+ fbo.use(gl, samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) );
+ if( samples > 0) {
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+ }
+ }
+ }
+
+ @Override
+ protected int getDefaultDrawFramebuffer() { return fbo.getWriteFramebuffer(); }
+
+ @Override
+ protected int getDefaultReadFramebuffer() { return fbo.getReadFramebuffer(); }
+
+ public FBObject getFBObject() { return fbo; }
+
+ public void setSize(GL gl, int newWidth, int newHeight) throws GLException {
+ width = newWidth;
+ height = newHeight;
+ fbo.reset(gl, width, height, samples);
+ samples = fbo.getNumSamples(); // update, maybe capped
+ }
+
+ public void setSamples(GL gl, int newSamples) throws GLException {
+ samples = newSamples;
+ fbo.reset(gl, width, height, samples);
+ samples = fbo.getNumSamples(); // update, maybe capped
+ }
+
+
+ @Override
+ public GLContext createContext(GLContext shareWith) {
+ final GLContext ctx = parent.createContext(shareWith);
+ ctx.setGLDrawable(this, false);
+ return ctx;
+ }
+
+ @Override
+ public GLDynamicLookupHelper getGLDynamicLookupHelper() {
+ return parent.getGLDynamicLookupHelper();
+ }
+
+ @Override
+ protected void swapBuffersImpl() {
+ }
+
+ @Override
+ protected void setRealizedImpl() {
+ parent.setRealized(realized);
+ if(realized) {
+ final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) msConfig.getChosenCapabilities();
+ final GLCapabilitiesImmutable chosenFBOCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, true /*FBO*/, false /*PBO*/);
+ msConfig.setChosenCapabilities(chosenFBOCaps);
+ }
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index b7c15bfda..900d6a2a0 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -38,7 +38,8 @@ public class GLGraphicsConfigurationUtil {
public static final int WINDOW_BIT = 1 << 0;
public static final int BITMAP_BIT = 1 << 1;
public static final int PBUFFER_BIT = 1 << 2;
- public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ;
+ public static final int FBO_BIT = 1 << 3;
+ public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
if(null==sb) {
@@ -61,30 +62,43 @@ public class GLGraphicsConfigurationUtil {
sb.append(", ");
}
sb.append("PBUFFER");
+ seperator=true;
+ }
+ if( 0 != ( FBO_BIT & winattrbits ) ) {
+ if(seperator) {
+ sb.append(", ");
+ }
+ sb.append("FBO");
}
return sb;
}
/**
+ * @param isFBO TODO
* @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
*/
- public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) {
+ public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer, boolean isFBO) {
int winattrbits = 0;
if(isOnscreen) {
winattrbits |= WINDOW_BIT;
- } else if (!isPBuffer) {
- winattrbits |= BITMAP_BIT;
} else {
- winattrbits |= PBUFFER_BIT;
+ if(isFBO) {
+ winattrbits |= FBO_BIT;
+ }
+ if (!isPBuffer) {
+ winattrbits |= BITMAP_BIT;
+ } else {
+ winattrbits |= PBUFFER_BIT;
+ }
}
return winattrbits;
}
/**
- * @see #getWinAttributeBits(boolean, boolean)
+ * @see #getWinAttributeBits(boolean, boolean, boolean)
*/
public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
- return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
+ return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer(), false);
}
public static final boolean addGLCapabilitiesPermutations(List capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
@@ -92,43 +106,58 @@ public class GLGraphicsConfigurationUtil {
if( 0 != ( WINDOW_BIT & winattrbits ) ) {
GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
cpy.setOnscreen(true);
+ cpy.setPBuffer(false);
+ cpy.setFBO(false);
capsBucket.add(cpy);
}
- if( 0 != ( PBUFFER_BIT & winattrbits ) ) {
+ if( 0 != ( PBUFFER_BIT & winattrbits ) || 0 != ( FBO_BIT & winattrbits ) ) {
GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setPBuffer(true);
+ cpy.setFBO(0 != ( FBO_BIT & winattrbits ));
+ cpy.setPBuffer(0 != ( PBUFFER_BIT & winattrbits ));
capsBucket.add(cpy);
}
if( 0 != ( BITMAP_BIT & winattrbits ) ) {
GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
cpy.setOnscreen(false);
cpy.setPBuffer(false);
+ cpy.setFBO(false);
capsBucket.add(cpy);
}
return capsBucket.size() > preSize;
}
- public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
{
if( !capsRequested.isOnscreen() ) {
- return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable);
+ return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
}
- return capsRequested;
+ return fixOnscreenGLCapabilities(capsRequested);
}
- public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
+ {
+ if( !capsRequested.isOnscreen() ) {
+ // fix caps ..
+ GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setOnscreen(true);
+ return caps2;
+ }
+ return capsRequested;
+ }
+
+ public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
{
if( capsRequested.getDoubleBuffered() ||
capsRequested.isOnscreen() ||
- ( !pbufferAvailable && capsRequested.isPBuffer() ) )
+ ( fboAvailable != capsRequested.isFBO() ) ||
+ ( pbufferAvailable != capsRequested.isPBuffer() ) )
{
// fix caps ..
GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
caps2.setOnscreen(false);
- if(caps2.isPBuffer() && !pbufferAvailable) {
- caps2.setPBuffer(false);
- }
+ caps2.setFBO( fboAvailable );
+ caps2.setPBuffer( pbufferAvailable );
return caps2;
}
return capsRequested;
@@ -136,12 +165,13 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer()) {
+ if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer() || capsRequested.isFBO() ) {
// fix caps ..
GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
caps2.setOnscreen(false);
caps2.setPBuffer(true);
+ caps2.setFBO(false);
return caps2;
}
return capsRequested;
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index a8277fd71..bbc28e283 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -54,8 +54,7 @@ import javax.media.opengl.GLPbuffer;
public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
private int floatMode;
- public GLPbufferImpl(GLDrawableImpl pbufferDrawable,
- GLContext sharedContext) {
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext) {
super(pbufferDrawable, null); // drawable := pbufferDrawable
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
@@ -111,6 +110,11 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
// GLAutoDrawable completion
//
+ @Override
+ public final Object getUpstreamWidget() {
+ return null;
+ }
+
@Override
public void destroy() {
defaultDestroyOp();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 65a4c3ece..c5d0df645 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -110,14 +110,8 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected void makeCurrentImpl() throws GLException {
- if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
- throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable);
- }
if (EGL.eglGetCurrentContext() != contextHandle) {
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- drawable.getHandle(),
- drawableRead.getHandle(),
- contextHandle)) {
+ if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
throw new GLException("Error making context 0x" +
Long.toHexString(contextHandle) + " current: error code 0x" + Integer.toHexString(EGL.eglGetError()));
}
@@ -126,10 +120,7 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected void releaseImpl() throws GLException {
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- EGL.EGL_NO_SURFACE,
- EGL.EGL_NO_SURFACE,
- EGL.EGL_NO_CONTEXT)) {
+ if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT)) {
throw new GLException("Error freeing OpenGL context 0x" +
Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(EGL.eglGetError()));
}
@@ -137,7 +128,7 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected void destroyImpl() throws GLException {
- if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) {
+ if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle)) {
final int eglError = EGL.eglGetError();
if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
throw new GLException("Error destroying OpenGL context 0x" +
@@ -158,16 +149,16 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected boolean createImpl(GLContextImpl shareWith) throws GLException {
- long eglDisplay = ((EGLDrawable)drawable).getDisplay();
- EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
- GLProfile glProfile = drawable.getGLProfile();
- long eglConfig = config.getNativeConfig();
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ final long eglDisplay = config.getScreen().getDevice().getHandle();
+ final GLProfile glProfile = drawable.getGLProfile();
+ final long eglConfig = config.getNativeConfig();
long shareWithHandle = EGL.EGL_NO_CONTEXT;
- if (eglDisplay == 0) {
+ if ( 0 == eglDisplay ) {
throw new GLException("Error: attempted to create an OpenGL context without a display connection");
}
- if (eglConfig == 0) {
+ if ( 0 == eglConfig ) {
throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
}
@@ -217,10 +208,7 @@ public abstract class EGLContext extends GLContextImpl {
",\n\t"+this+
",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
}
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- drawable.getHandle(),
- drawableRead.getHandle(),
- contextHandle)) {
+ if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
throw new GLException("Error making context 0x" +
Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
}
@@ -269,8 +257,7 @@ public abstract class EGLContext extends GLContextImpl {
eglQueryStringInitialized = true;
}
if (eglQueryStringAvailable) {
- final String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(),
- EGL.EGL_EXTENSIONS);
+ final String ret = EGL.eglQueryString(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_EXTENSIONS);
if (DEBUG) {
System.err.println("EGL extensions: " + ret);
}
@@ -291,7 +278,7 @@ public abstract class EGLContext extends GLContextImpl {
}
return false;
}
- return EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval);
+ return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
@Override
@@ -300,6 +287,45 @@ public abstract class EGLContext extends GLContextImpl {
@Override
public abstract void releasePbufferFromTexture();
+ //
+ // Accessible ..
+ //
+
+ /**
+ * If context is an ES profile, map it to the given device
+ * via {@link GLContext#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, int, int, int)}.
+ *
+ * We intentionally override a non native EGL device ES profile mapping,
+ * i.e. this will override/modify an already 'set' X11/WGL/.. mapping.
+ *
+ *
+ * @param device
+ */
+ protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
+ mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
+ }
+
+ protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
+ int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES );
+ mapCurrentAvailableGLVersionImpl(device, major, 0, ctp);
+ }
+ private static void mapCurrentAvailableGLVersionImpl(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
+ // ES1 or ES2
+ final int reqMajor = major;
+ final int reqProfile = GLContext.CTX_PROFILE_ES;
+ GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
+ major, minor, ctp);
+ }
+ }
+
+ protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ return GLContext.getAvailableGLVersionsSet(device);
+ }
+ protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ GLContext.setAvailableGLVersionsSet(device);
+ }
+
protected static String toHexString(int hex) {
return GLContext.toHexString(hex);
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 7f10d3bd9..432010f49 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -136,7 +136,17 @@ public class EGLDisplayUtil {
return res;
}
- public static final EGLGraphicsDevice.EGLTerminateCallback eglTerminateCallback = new EGLGraphicsDevice.EGLTerminateCallback() {
+ public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
+ public long eglGetAndInitDisplay(long nativeDisplayID) {
+ long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
+ if (eglDisplay == EGL.EGL_NO_DISPLAY) {
+ throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
+ throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ }
+ return eglDisplay;
+ }
public void eglTerminate(long eglDisplayHandle) {
EGLDisplayUtil.eglTerminate(eglDisplayHandle);
}
@@ -148,17 +158,12 @@ public class EGLDisplayUtil {
* @param unitID
* @return an initialized EGLGraphicsDevice
* @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails
- * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLTerminateCallback)
+ * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback)
*/
public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) {
- long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID);
- if (eglDisplay == EGL.EGL_NO_DISPLAY) {
- throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
- if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
- throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- }
- return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, connection, unitID, eglTerminateCallback);
+ final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback);
+ eglDisplay.open();
+ return eglDisplay;
}
/**
@@ -189,6 +194,6 @@ public class EGLDisplayUtil {
throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
}
final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
- return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglTerminateCallback);
+ return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index d777c4f04..383b61f88 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,82 +36,65 @@
package jogamp.opengl.egl;
-import jogamp.opengl.GLDynamicLookupHelper;
-import jogamp.opengl.GLDrawableImpl;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
-import javax.media.opengl.*;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
-import com.jogamp.nativewindow.egl.*;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public abstract class EGLDrawable extends GLDrawableImpl {
- private boolean ownEGLDisplay = false; // for destruction
private boolean ownEGLSurface = false; // for destruction
- private EGLGraphicsConfiguration eglConfig;
- private EGLGraphicsDevice eglDevice;
- private long eglSurface;
- protected EGLDrawable(EGLDrawableFactory factory,
- NativeSurface component) throws GLException {
+ protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
super(factory, component, false);
- eglSurface=EGL.EGL_NO_SURFACE;
- eglDevice=null;
- }
-
- public final long getDisplay() {
- return null != eglDevice ? eglDevice.getHandle() : 0;
- }
-
- @Override
- public final long getHandle() {
- return eglSurface;
- }
-
- public final EGLGraphicsConfiguration getGraphicsConfiguration() {
- return eglConfig;
- }
-
- @Override
- public final GLCapabilitiesImmutable getChosenGLCapabilities() {
- return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities();
}
@Override
public abstract GLContext createContext(GLContext shareWith);
- protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle);
+ protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
private final void recreateSurface() {
- // create a new EGLSurface ..
- if(EGL.EGL_NO_SURFACE!=eglSurface) {
- EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface);
- }
-
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
if(DEBUG) {
- System.err.println(getThreadName() + ": createSurface using "+eglDevice+", "+eglConfig);
+ System.err.println(getThreadName() + ": createSurface using "+eglConfig);
+ }
+ if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
}
-
- eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surface.getSurfaceHandle());
- int eglError0 = EGL.EGL_SUCCESS;
+
+ final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
+ final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
+ long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+
+ int eglError0;
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
if(EGL.EGL_BAD_NATIVE_WINDOW == eglError0) {
// Try window handle if available and differs (Windows HDC / HWND).
// ANGLE impl. required HWND on Windows.
- if(surface instanceof NativeWindow) {
- final NativeWindow nw = (NativeWindow) surface;
+ if(upstreamSurface instanceof NativeWindow) {
+ final NativeWindow nw = (NativeWindow) upstreamSurface;
if(nw.getWindowHandle() != nw.getSurfaceHandle()) {
if(DEBUG) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
}
- eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), nw.getWindowHandle());
+ eglSurface = createSurface(eglConfig, nw.getWindowHandle());
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
}
}
}
}
+ } else {
+ eglError0 = EGL.EGL_SUCCESS;
}
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
@@ -120,6 +103,8 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if(DEBUG) {
System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
}
+
+ ((MutableSurface)surface).setSurfaceHandle(eglSurface);
}
@Override
@@ -131,123 +116,71 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
protected final void setRealizedImpl() {
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
if (realized) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
- AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
- if(aDevice instanceof EGLGraphicsDevice) {
+ final long eglDisplayHandle = eglDevice.getHandle();
+ if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
+ throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+ }
+ int[] tmp = new int[1];
+ boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
+ if(eglSurfaceValid) {
+ eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
+ if(!eglSurfaceValid) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
+ }
+ }
+ }
+ if(eglSurfaceValid) {
+ // surface holds valid EGLSurface
if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): using existing EGL config - START");
+ System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle()));
+ }
+ ownEGLSurface=false;
+ } else {
+ // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
+ // However .. let's validate the surface object first
+ if( ! (surface instanceof ProxySurface) ) {
+ throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface);
}
- // just fetch the data .. trust but verify ..
- ownEGLDisplay = false;
- eglDevice = (EGLGraphicsDevice) aDevice;
- if (eglDevice.getHandle() == EGL.EGL_NO_DISPLAY) {
- throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+ final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
+ if( null == upstreamHook ) {
+ throw new InternalError("null upstreamHook of: "+surface);
}
- if(aConfig instanceof EGLGraphicsConfiguration) {
- eglConfig = (EGLGraphicsConfiguration) aConfig; // done ..
- if (null == eglConfig) {
- throw new GLException("Null EGLGraphicsConfiguration from "+aConfig);
- }
-
- int[] tmp = new int[1];
- if ( 0 != surface.getSurfaceHandle() &&
- EGL.eglQuerySurface(eglDevice.getHandle(), surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) {
- // surface holds static EGLSurface
- eglSurface = surface.getSurfaceHandle();
- if(DEBUG) {
- System.err.println(getThreadName() + ": setSurface re-using component's EGLSurface: handle "+toHexString(eglSurface));
- }
- ownEGLSurface=false;
- } else {
- // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
- ownEGLSurface=true;
- }
- } else {
- throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig);
+ if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
+ throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
}
- } else {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): creating new EGL config - START");
+ if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
+ throw new InternalError("null upstream surface");
}
- // create a new EGL config ..
- ownEGLDisplay=true;
- // EGLSurface is ours ..
ownEGLSurface=true;
-
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
- AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
- final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
- if(aConfig instanceof EGLGraphicsConfiguration) {
- final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
- if(0 == capsChosen.getEGLConfig()) {
- // 'refresh' the native EGLConfig handle
- capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
- if(0 == capsChosen.getEGLConfig()) {
- throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
- }
- }
- eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
- if(DEBUG) {
- System.err.println(getThreadName() + ": Reusing chosenCaps: "+eglConfig);
- }
- } else {
- eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
-
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
- } else if(DEBUG) {
- System.err.println(getThreadName() + ": Chosen eglConfig: "+eglConfig);
- }
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
}
- // subsequent updateHandle() will issue recreateSurface();
- }
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): END: ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface);
}
- } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) {
+ } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
}
// Destroy the window surface
- if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) {
+ if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
throw new GLException("Error destroying window surface (eglDestroySurface)");
}
- eglSurface = EGL.EGL_NO_SURFACE;
- eglConfig=null;
- eglDevice.close();
- eglDevice=null;
+ ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE);
}
}
@Override
protected final void swapBuffersImpl() {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
// single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- if(!EGL.eglSwapBuffers(eglDevice.getHandle(), eglSurface)) {
+ if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
}
}
- /**
- * Surface not realizes yet (onscreen) .. Quering EGL surface size only makes sense for external drawable.
- * Leave it here for later impl. of an EGLExternalDrawable.
- public int getWidth() {
- int[] tmp = new int[1];
- if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
- throw new GLException("Error querying surface width, eglError "+toHexString(EGL.eglGetError()));
- }
- return tmp[0];
- }
-
- public int getHeight() {
- int[] tmp = new int[1];
- if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) {
- throw new GLException("Error querying surface height, eglError "+toHexString(EGL.eglGetError()));
- }
- return tmp[0];
- } */
-
@Override
public GLDynamicLookupHelper getGLDynamicLookupHelper() {
if (getGLProfile().usesNativeGLES2()) {
@@ -263,10 +196,9 @@ public abstract class EGLDrawable extends GLDrawableImpl {
public String toString() {
return getClass().getName()+"[realized "+isRealized()+
",\n\tfactory "+getFactory()+
- ",\n\tdevice "+eglDevice+
",\n\tsurface "+getNativeSurface()+
- ",\n\teglSurface "+toHexString(eglSurface)+
- ",\n\teglConfig "+eglConfig+
+ ",\n\teglSurface "+toHexString(surface.getSurfaceHandle())+
+ ",\n\teglConfig "+surface.getGraphicsConfiguration()+
",\n\trequested "+getRequestedGLCapabilities()+
",\n\tchosen "+getChosenGLCapabilities()+"]";
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index f4fa1f13f..c848e3e5c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -46,21 +46,29 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.nativewindow.VisualIDHolder;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLProfile.ShutdownType;
+import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.os.Platform;
@@ -69,6 +77,9 @@ import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+ /* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true);
+ /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
+
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
private static boolean isANGLE = false;
@@ -231,7 +242,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// final EGLContext getContextES1() { return contextES1; }
// final EGLContext getContextES2() { return contextES2; }
final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
- final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
}
@Override
@@ -245,35 +256,98 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
}
- /**
- private boolean isEGLContextAvailable(EGLGraphicsDevice sharedDevice, String profile) {
- boolean madeCurrent = false;
- final GLCapabilities caps = new GLCapabilities(GLProfile.get(profile));
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setPBuffer(true);
- final EGLDrawable drawable = (EGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
- if(null!=drawable) {
+ private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) {
+ if( !GLProfile.isAvailable(adevice, profileString) ) {
+ return false;
+ }
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
+ final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
+ EGLGraphicsDevice eglDevice = null;
+ NativeSurface surface = null;
+ ProxySurface upstreamSurface = null; // X11, GLX, ..
+ boolean success = false;
+ boolean deviceFromUpstreamSurface = false;
+ try {
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
+ if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) {
+ eglDevice = sharedEGLDevice; // reuse
+ surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen
+ upstreamSurface = (ProxySurface)surface;
+ upstreamSurface.createNotify();
+ deviceFromUpstreamSurface = false;
+ } else {
+ surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window
+ upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
+ if(null != upstreamSurface) {
+ upstreamSurface.createNotify();
+ }
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+ deviceFromUpstreamSurface = true;
+ }
+
+ final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
+ drawable.setRealized(true);
final EGLContext context = (EGLContext) drawable.createContext(null);
if (null != context) {
- context.setSynchronized(true);
try {
context.makeCurrent(); // could cause exception
- madeCurrent = context.isCurrent();
+ success = context.isCurrent();
+ if(success) {
+ final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+ if(null == glVersion) {
+ // Oops .. something is wrong
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+ }
+ success = false;
+ }
+ }
+ if(success) {
+ context.mapCurrentAvailableGLVersion(eglDevice);
+ if(eglDevice != adevice) {
+ context.mapCurrentAvailableGLVersion(adevice);
+ }
+ }
} catch (GLException gle) {
if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: INFO: makeCurrent failed");
+ System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
gle.printStackTrace();
}
} finally {
context.destroy();
}
}
- drawable.destroy();
+ drawable.setRealized(false);
+ } catch (Throwable t) {
+ if(DEBUG) {
+ System.err.println("Catched Exception:");
+ t.printStackTrace();
+ }
+ success = false;
+ } finally {
+ if(eglDevice == sharedEGLDevice) {
+ if(null != upstreamSurface) {
+ upstreamSurface.destroyNotify();
+ }
+ } else if( deviceFromUpstreamSurface ) {
+ if(null != eglDevice) {
+ eglDevice.close();
+ }
+ if(null != upstreamSurface) {
+ upstreamSurface.destroyNotify();
+ }
+ } else {
+ if(null != upstreamSurface) {
+ upstreamSurface.destroyNotify();
+ }
+ if(null != eglDevice) {
+ eglDevice.close();
+ }
+ }
}
- return madeCurrent;
- } */
+ return success;
+ }
/* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
@@ -285,18 +359,41 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
sr = sharedMap.get(connection);
}
if(null==sr) {
- final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, connection, adevice.getUnitID());
+ final boolean madeCurrentES1;
+ final boolean madeCurrentES2;
+ final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
- // final boolean madeCurrentES1 = isEGLContextAvailable(sharedDevice, GLProfile.GLES1);
- // final boolean madeCurrentES2 = isEGLContextAvailable(sharedDevice, GLProfile.GLES2);
- final boolean madeCurrentES1 = true; // FIXME
- final boolean madeCurrentES2 = true; // FIXME
+ if(QUERY_EGL_ES) {
+ madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1);
+ madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2);
+ } else {
+ madeCurrentES1 = true;
+ madeCurrentES2 = true;
+ EGLContext.mapStaticGLESVersion(sharedDevice, 1);
+ if(sharedDevice != adevice) {
+ EGLContext.mapStaticGLESVersion(adevice, 1);
+ }
+ EGLContext.mapStaticGLESVersion(sharedDevice, 2);
+ if(sharedDevice != adevice) {
+ EGLContext.mapStaticGLESVersion(adevice, 2);
+ }
+ }
+
+ if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
+ // Even though we override the non EGL native mapping intentionally,
+ // avoid exception due to double 'set' - carefull exception of the rule.
+ EGLContext.setAvailableGLVersionsSet(adevice);
+ }
sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
+
synchronized(sharedMap) {
sharedMap.put(connection, sr);
+ if(adevice != sharedDevice) {
+ sharedMap.put(sharedDevice.getConnection(), sr);
+ }
}
if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: device: " + sharedDevice);
+ System.err.println("EGLDrawableFactory.createShared: devices: queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice);
System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
}
@@ -367,8 +464,51 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, target);
+ return new EGLOnscreenDrawable(this, getEGLSurface(target));
+ }
+
+ protected static NativeSurface getEGLSurface(NativeSurface surface) {
+ AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
+ AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+ if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
+ // already in native EGL format
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig);
+ }
+ return surface;
+ }
+ // create EGL instance out of platform native types
+ final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+ final EGLGraphicsConfiguration eglConfig;
+ if( aConfig instanceof EGLGraphicsConfiguration ) {
+ // Config is already in EGL type - reuse ..
+ final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+ if( 0 == capsChosen.getEGLConfig() ) {
+ // 'refresh' the native EGLConfig handle
+ capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
+ if( 0 == capsChosen.getEGLConfig() ) {
+ throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
+ }
+ }
+ eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig);
+ }
+ } else {
+ eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
+
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+ } else if(DEBUG) {
+ System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig);
+ }
+ }
+ return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface));
}
+ static String getThreadName() { return Thread.currentThread().getName(); }
@Override
protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
@@ -390,22 +530,115 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
- WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser));
- ns.surfaceSizeChanged(width, height);
- return ns;
+ protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ final EGLGraphicsDevice device;
+ if(createNewDevice) {
+ final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ } else {
+ device = (EGLGraphicsDevice) deviceReq;
+ }
+ final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
+ }
+ return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ }
+
+ @Override
+ public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq));
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ }
+ private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
+ @Override
+ public final void create(ProxySurface s) {
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ s.setImplBitfield(ProxySurface.OWN_DEVICE);
+ }
+ createPBufferSurfaceImpl(s, false);
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
+ }
+ }
+ }
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) {
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration();
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
+ EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
+ eglDevice.close();
+ }
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
+ }
+ }
+ }
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return s.initialWidth;
+ }
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return s.initialHeight;
+ }
+ @Override
+ public String toString() {
+ return "EGLSurfaceLifecycleHook[]";
+ }
+
+ };
+
+ /**
+ * @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface.
+ * It will also hold the resulting pbuffer surface handle.
+ * @param useTexture
+ * @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
+ */
+ protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration();
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final int texFormat;
+
+ if(useTexture) {
+ texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ } else {
+ texFormat = EGL.EGL_NO_TEXTURE;
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
+
+ final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat);
+ final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0);
+ if (EGL.EGL_NO_SURFACE==surf) {
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+ }
+ ms.setSurfaceHandle(surf);
+ return ms;
}
@Override
- protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
- // FIXME device/windowHandle -> screen ?!
- EGLGraphicsDevice device = (EGLGraphicsDevice) adevice;
- DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- WrappedSurface ns = new WrappedSurface(cfg, windowHandle);
- return ns;
+ protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
+ final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
+ final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
+ return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 56e7a4d22..214b36493 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -151,7 +151,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
List bucket = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
return (EGLGLCapabilities) bucket.get(0);
} else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 809e2b688..6be9cb547 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -38,7 +38,6 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
-import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.VisualIDHolder.VIDType;
@@ -47,6 +46,7 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLDrawableFactory;
@@ -180,6 +180,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
EGLGraphicsDevice eglDevice = sharedResource.getDevice();
long eglDisplay = eglDevice.getHandle();
+ if(0 == eglDisplay) {
+ throw new GLException("null eglDisplay");
+ }
List availableCaps = null;
IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
@@ -236,11 +239,9 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
ownEGLDisplay = true;
}
- EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) );
-
- GLProfile glp = capsChosen.getGLProfile();
- GLCapabilities fixedCaps;
+ final GLProfile glp = capsChosen.getGLProfile();
+ final EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(absDevice, glp), factory.canCreateGLPbuffer(absDevice) );
EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
if(null==res) {
@@ -251,13 +252,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
// Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..]
//
// rgb888 - d16, s4
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
fixedCaps.setRedBits(8);
fixedCaps.setGreenBits(8);
fixedCaps.setBlueBits(8);
fixedCaps.setDepthBits(16);
fixedCaps.setSampleBuffers(true);
fixedCaps.setNumSamples(4);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (1): "+fixedCaps);
}
@@ -266,11 +272,16 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(null==res) {
//
// rgb565 - d16, s0
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
fixedCaps.setRedBits(5);
fixedCaps.setGreenBits(6);
fixedCaps.setBlueBits(5);
fixedCaps.setDepthBits(16);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (2): "+fixedCaps);
}
@@ -279,13 +290,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(null==res) {
//
// rgb565 - d16, s4
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
fixedCaps.setRedBits(5);
fixedCaps.setGreenBits(6);
fixedCaps.setBlueBits(5);
fixedCaps.setDepthBits(16);
fixedCaps.setSampleBuffers(true);
fixedCaps.setNumSamples(4);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (3): "+fixedCaps);
}
@@ -309,7 +325,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
final GLProfile glp = capsChosen.getGLProfile();
final boolean onscreen = capsChosen.isOnscreen();
final boolean usePBuffer = capsChosen.isPBuffer();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
List availableCaps = null;
int recommendedIndex = -1;
long recommendedEGLConfig = -1;
@@ -322,8 +338,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
}
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig maxConfigs: "+numConfigs.get(0));
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglDisplay "+toHexString(eglDisplay)+", "+capsChosen+", nativeVisualID "+toHexString(nativeVisualID));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", onscreen "+onscreen+", usePBuffer "+usePBuffer+", "+capsChosen+", numConfigs "+numConfigs.get(0));
}
final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
@@ -362,7 +377,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
}
}
@@ -370,6 +385,8 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
+ availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
+ printCaps("AllCaps", availableCaps, System.err);
}
return null;
}
@@ -428,27 +445,5 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
out.println(prefix+"["+i+"] "+caps.get(i));
}
}
-
- static EGLGraphicsConfiguration createOffscreenGraphicsConfiguration(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser) {
- if(capsChosen.isOnscreen()) {
- throw new GLException("Error: Onscreen set: "+capsChosen);
- }
-
- if(capsChosen.getDoubleBuffered()) {
- // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
- GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
- caps2.setDoubleBuffered(false);
- capsChosen = caps2;
- }
-
- DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- EGLGraphicsConfiguration eglConfig = chooseGraphicsConfigurationStatic(capsChosen, capsReq, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+screen);
- } else if(DEBUG) {
- System.err.println("Chosen eglConfig: "+eglConfig);
- }
- return eglConfig;
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index 3768f1588..d54057775 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -54,8 +54,8 @@ public class EGLOnscreenDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
- return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
+ protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+ return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index b2217c095..4a36625bd 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -40,15 +40,11 @@
package jogamp.opengl.egl;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
-import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
public class EGLPbufferDrawable extends EGLDrawable {
- private int texFormat;
protected static final boolean useTexture = false; // No yet ..
protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeSurface target) {
@@ -56,30 +52,12 @@ public class EGLPbufferDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
- final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-
- if(useTexture) {
- texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
- } else {
- texFormat = EGL.EGL_NO_TEXTURE;
- }
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + config);
- }
-
- NativeSurface nw = getNativeSurface();
- int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
- long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
- if (EGL.EGL_NO_SURFACE==surf) {
- throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+nw.getWidth()+"x"+nw.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- } else if(DEBUG) {
- System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+ protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+ final MutableSurface ms = (MutableSurface)getNativeSurface();
+ if(config != ms.getGraphicsConfiguration()) {
+ throw new InternalError("Not same: "+config.hashCode()+", "+ms.getGraphicsConfiguration()+": "+config+", "+ms.getGraphicsConfiguration());
}
- ((SurfaceChangeable)nw).setSurfaceHandle(surf);
- return surf;
+ return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
new file mode 100644
index 000000000..42c6e100e
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -0,0 +1,56 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+ private final NativeSurface upstreamSurface;
+
+ public EGLUpstreamSurfaceHook(NativeSurface upstream) {
+ upstreamSurface = upstream;
+ }
+
+ public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+
+ @Override
+ public final void create(ProxySurface surface) {
+ if(upstreamSurface instanceof ProxySurface) {
+ ((ProxySurface)upstreamSurface).createNotify();
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+ throw new GLException("Could not lock: "+upstreamSurface);
+ }
+ }
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ eglDevice.open();
+ }
+
+ @Override
+ public final void destroy(ProxySurface surface) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ eglDevice.close();
+ if(upstreamSurface instanceof ProxySurface) {
+ upstreamSurface.unlockSurface();
+ ((ProxySurface)upstreamSurface).destroyNotify();
+ }
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return upstreamSurface.getWidth();
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return upstreamSurface.getHeight();
+ }
+
+ @Override
+ public String toString() {
+ final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil";
+ return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index aa66aa9d1..4bf2a3c9d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ProxySurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
@@ -63,6 +64,7 @@ import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
public abstract class MacOSXCGLContext extends GLContextImpl
{
@@ -252,9 +254,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
protected void makeCurrentImpl() throws GLException {
+ /** FIXME: won't work w/ special drawables (like FBO) - check for CGL mode regressions!
+ *
if (getOpenGLMode() != ((MacOSXCGLDrawable)drawable).getOpenGLMode()) {
setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode());
- }
+ } */
if (!impl.makeCurrent(contextHandle)) {
throw new GLException("Error making Context current: "+this);
}
@@ -338,8 +342,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public boolean isExtensionAvailable(String glExtensionName) {
- if (glExtensionName.equals("GL_ARB_pbuffer") ||
- glExtensionName.equals("GL_ARB_pixel_format")) {
+ if (glExtensionName.equals(GLExtensions.ARB_pbuffer) ||
+ glExtensionName.equals(GLExtensions.ARB_pixel_format)) {
return true;
}
return super.isExtensionAvailable(glExtensionName);
@@ -426,10 +430,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl
@Override
public long create(long share, int ctp, int major, int minor) {
long ctx = 0;
- final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.drawable;
final NativeSurface surface = drawable.getNativeSurface();
final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ boolean allowIncompleteView = null != backingLayerHost;
+ if( !allowIncompleteView && surface instanceof ProxySurface ) {
+ allowIncompleteView = 0 != ( ProxySurface.INVISIBLE_WINDOW & ((ProxySurface)surface).getImplBitfield() ) ;
+ }
final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
if (pixelFormat == 0) {
@@ -443,13 +450,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl
screenVSyncTimeout = 1000000f / sRefreshRate;
if(DEBUG) {
System.err.println("NS create OSX>=lion "+isLionOrLater);
- System.err.println("NS create backendType: "+drawable.getOpenGLMode());
+ System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
System.err.println("NS create backingLayerHost: "+backingLayerHost);
System.err.println("NS create share: "+share);
System.err.println("NS create chosenCaps: "+chosenCaps);
System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
- System.err.println("NS create drawable NSView-handle: "+toHexString(drawable.getNSViewHandle()));
System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
// Thread.dumpStack();
}
@@ -457,7 +463,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
int[] viewNotReady = new int[1];
// Try to allocate a context with this
ctx = CGL.createContext(share,
- drawable.getNSViewHandle(), null!=backingLayerHost,
+ drawable.getHandle(), allowIncompleteView,
pixelFormat,
chosenCaps.isBackgroundOpaque(),
viewNotReady, 0);
@@ -473,10 +479,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
CGL.setContextOpacity(ctx, 0);
}
- if(DEBUG) {
- GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat);
- System.err.println("NS create pixelformat2GLCaps: "+caps0);
- }
GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
config.setChosenCapabilities(fixedCaps);
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index 257635b8c..841edb2b0 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -106,10 +106,6 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
protected void setRealizedImpl() {
}
- protected long getNSViewHandle() {
- return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
- }
-
protected void registerContext(MacOSXCGLContext ctx) {
// NOTE: we need to keep track of the created contexts in order to
// implement swapBuffers() because of how Mac OS X implements its
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 4e9d18fed..9689d9f64 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -50,8 +50,8 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -62,15 +62,19 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLProfile.ShutdownType;
+import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
+import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
+import com.jogamp.opengl.GLExtensions;
public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null;
@@ -214,44 +218,39 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- caps.setDepthBits(5);
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setPBuffer(true);
- final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
- if(null!=drawable) {
- drawable.setRealized(true);
- final GLContext context = drawable.createContext(null);
- if (null != context) {
- try {
- context.makeCurrent(); // could cause exception
- madeCurrent = context.isCurrent();
- if(madeCurrent) {
- GL gl = context.getGL();
- hasNPOTTextures = gl.isNPOTTextureAvailable();
- hasRECTTextures = gl.isExtensionAvailable("GL_EXT_texture_rectangle");
- hasAppleFloatPixels = gl.isExtensionAvailable("GL_APPLE_float_pixels");
- }
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:");
- gle.printStackTrace();
- }
- } finally {
- try {
- context.destroy();
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:");
- gle.printStackTrace();
- }
- }
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+ sharedDrawable.setRealized(true);
+
+ final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+
+ try {
+ sharedContext.makeCurrent(); // could cause exception
+ madeCurrent = sharedContext.isCurrent();
+ if(madeCurrent) {
+ GL gl = sharedContext.getGL();
+ hasNPOTTextures = gl.isNPOTTextureAvailable();
+ hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle);
+ hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels);
+ }
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent catched exception:");
+ gle.printStackTrace();
+ }
+ } finally {
+ try {
+ sharedContext.destroy();
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: destroy catched exception:");
+ gle.printStackTrace();
}
}
- drawable.setRealized(false);
}
+ sharedDrawable.setRealized(false);
}
sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels);
synchronized(sharedMap) {
@@ -332,18 +331,82 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
- AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
- WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true));
- ns.surfaceSizeChanged(width, height);
- return ns;
+ protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ final MacOSXGraphicsDevice device;
+ if(createNewDevice) {
+ device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
+ } else {
+ device = (MacOSXGraphicsDevice)deviceReq;
+ }
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
+ }
+ return new WrappedSurface(config, 0, width, height, lifecycleHook);
}
@Override
- protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice device, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
- AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true), windowHandle);
- return ns;
+ public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ }
+ private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
+ long nsWindow = 0;
+ @Override
+ public final void create(ProxySurface s) {
+ if(0 == nsWindow && 0 == s.getSurfaceHandle()) {
+ nsWindow = OSXUtil.CreateNSWindow(0, 0, s.getWidth(), s.getHeight());
+ if(0 == nsWindow) {
+ throw new GLException("Error NS window 0");
+ }
+ long nsView = OSXUtil.GetNSView(nsWindow);
+ if(0 == nsView) {
+ throw new GLException("Error NS view 0");
+ }
+ s.setSurfaceHandle(nsView);
+ s.setImplBitfield(ProxySurface.INVISIBLE_WINDOW);
+ if(DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
+ }
+ }
+ }
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(0 != nsWindow && 0 != s.getSurfaceHandle()) {
+ OSXUtil.DestroyNSWindow(nsWindow);
+ nsWindow = 0;
+ s.setSurfaceHandle(0);
+ if(DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
+ }
+ }
+ }
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return s.initialWidth;
+ }
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return s.initialHeight;
+ }
+
+ @Override
+ public String toString() {
+ return "MacOSXLSurfaceLifecycleHook[]";
+ }
+
+ };
+
+ @Override
+ protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final MacOSXGraphicsDevice device = new MacOSXGraphicsDevice(deviceReq.getUnitID());
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
+ final MacOSXCGLGraphicsConfiguration config = MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true);
+ return new WrappedSurface(config, windowHandle, 0, 0, upstream);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 8393a688e..421e1ef96 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -154,7 +154,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
break;
case CGL.NSOpenGLPFASamples:
- ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0;
+ ivalues[idx] = caps.getNumSamples() ;
break;
default:
@@ -233,7 +233,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
return fmt.get(0);
}
- static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {
+ static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {
return PixelFormat2GLCapabilities(null, pixelFormat, false);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index ad4c06af2..6be9e386d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -114,8 +114,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
// set a fake marker stating a valid drawable
currentDrawable = 1;
}
- WrappedSurface ns = new WrappedSurface(cfg);
- ns.setSurfaceHandle(currentDrawable);
+ WrappedSurface ns = new WrappedSurface(cfg, currentDrawable, 64, 64, null);
return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index 242cea068..b144c020d 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -42,7 +42,7 @@ package jogamp.opengl.macosx.cgl;
import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2GL3;
@@ -95,12 +95,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
return ctx;
}
- @Override
- protected long getNSViewHandle() {
- // pbuffer handle is NSOpenGLPixelBuffer
- return 0;
- }
-
@Override
public long getHandle() {
return pBuffer;
@@ -115,7 +109,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
NativeSurface ns = getNativeSurface();
impl.destroy(pBuffer);
this.pBuffer = 0;
- ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ ((MutableSurface)ns).setSurfaceHandle(0);
}
}
@@ -174,7 +168,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
}
- ((SurfaceChangeable)ns).setSurfaceHandle(pBuffer);
+ ((MutableSurface)ns).setSurfaceHandle(pBuffer);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
index 31f13297b..6bf8839af 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/EGLMediaPlayerImpl.java
@@ -113,7 +113,7 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
// create EGLImage from texture
clientBuffer = null; // FIXME
nioTmp.put(0, EGL.EGL_NONE);
- image = eglExt.eglCreateImageKHR( eglDrawable.getDisplay(), eglCtx.getHandle(),
+ image = eglExt.eglCreateImageKHR( eglDrawable.getNativeSurface().getDisplayHandle(), eglCtx.getHandle(),
EGLExt.EGL_GL_TEXTURE_2D_KHR,
clientBuffer, nioTmp);
if (0==image) {
@@ -130,7 +130,7 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
// rendering the EGLImage texture before we tell OpenMAX to fill
// it with a new frame.
tmp[0] = EGL.EGL_NONE;
- sync = eglExt.eglCreateSyncKHR(eglDrawable.getDisplay(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
+ sync = eglExt.eglCreateSyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), EGLExt.EGL_SYNC_FENCE_KHR, tmp, 0);
if (0==sync) {
throw new RuntimeException("EGLSync creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", err "+toHexString(EGL.eglGetError()));
}
@@ -159,10 +159,10 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
final EGLTextureFrame eglTex = (EGLTextureFrame) imgTex;
if(0!=eglTex.getImage()) {
- eglExt.eglDestroyImageKHR(eglDrawable.getDisplay(), eglTex.getImage());
+ eglExt.eglDestroyImageKHR(eglDrawable.getNativeSurface().getDisplayHandle(), eglTex.getImage());
}
if(0!=eglTex.getSync()) {
- eglExt.eglDestroySyncKHR(eglDrawable.getDisplay(), eglTex.getSync());
+ eglExt.eglDestroySyncKHR(eglDrawable.getNativeSurface().getDisplayHandle(), eglTex.getSync());
}
super.destroyTexImage(gl, imgTex);
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index 296d53ce3..cf6f43b1c 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -41,7 +41,7 @@
package jogamp.opengl.windows.wgl;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
@@ -139,7 +139,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
hbitmap = 0;
throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr);
}
- ((SurfaceChangeable)ns).setSurfaceHandle(hdc);
+ ((MutableSurface)ns).setSurfaceHandle(hdc);
if(DEBUG) {
System.err.println("WindowsBitmapWGLDrawable (2): "+ns);
}
@@ -164,7 +164,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
GDI.DeleteDC(ns.getSurfaceHandle());
origbitmap = 0;
hbitmap = 0;
- ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ ((MutableSurface)ns).setSurfaceHandle(0);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
deleted file mode 100644
index 05d6d9862..000000000
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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 jogamp.opengl.windows.wgl;
-
-import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.NativeSurface;
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
-
-import jogamp.nativewindow.windows.GDI;
-import jogamp.nativewindow.windows.GDISurface;
-import jogamp.nativewindow.windows.GDIUtil;
-
-public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
- private long hwnd;
- private boolean handleHwndLifecycle;
-
- private WindowsDummyWGLDrawable(GLDrawableFactory factory, GDISurface ns, boolean handleHwndLifecycle) {
- super(factory, ns, true);
- this.handleHwndLifecycle = handleHwndLifecycle;
-
- if(NativeSurface.LOCK_SURFACE_NOT_READY >= ns.lockSurface()) {
- throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)");
- }
- try {
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
- config.updateGraphicsConfiguration(factory, ns, null);
- if (DEBUG) {
- System.err.println("WindowsDummyWGLDrawable: "+config);
- }
- } catch (Throwable t) {
- setRealized(false);
- throw new GLException(t);
- } finally {
- unlockSurface();
- }
- }
-
- public static WindowsDummyWGLDrawable create(GLDrawableFactory factory, GLProfile glp, AbstractGraphicsScreen absScreen,
- long windowHandle, int width, int height, boolean handleWindowLifecycle) {
- if(0 == windowHandle) {
- throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
- }
- GLCapabilities caps = new GLCapabilities(glp);
- WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen);
- GDISurface ns = new GDISurface(cfg, windowHandle);
- ns.surfaceSizeChanged(width, height);
- return new WindowsDummyWGLDrawable(factory, ns, handleWindowLifecycle);
- }
-
- @Override
- public GLContext createContext(GLContext shareWith) {
- // FIXME: figure out how to hook back in the Java 2D / JOGL bridge
- return new WindowsWGLContext(this, shareWith);
- }
-
- @Override
- protected void setRealizedImpl() {
- super.setRealizedImpl();
- if(!realized) {
- if (handleHwndLifecycle && hwnd != 0) {
- GDI.ShowWindow(hwnd, GDI.SW_HIDE);
- GDIUtil.DestroyDummyWindow(hwnd);
- hwnd = 0;
- }
- }
- }
-}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index 86441c688..96c1187d3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -55,7 +55,6 @@ import com.jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextShareSet;
-
public class WindowsExternalWGLContext extends WindowsWGLContext {
private GLContext lastContext;
@@ -103,7 +102,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
System.err.println("WindowsExternalWGLContext valid hdc/pfd, retrieved cfg: " + cfg);
}
}
- return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc)), ctx, cfg);
+ return new WindowsExternalWGLContext(new Drawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null)), ctx, cfg);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
index 8f22aa60e..15bd005dc 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -50,6 +50,7 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
import com.jogamp.nativewindow.WrappedSurface;
@@ -69,9 +70,9 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError());
}
- AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
- WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
- return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc));
+ final AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
+ final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.createFromExternal(factory, hdc, pfdID, glp, aScreen, true);
+ return new WindowsExternalWGLDrawable(factory, new WrappedSurface(cfg, hdc, 64, 64, null));
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
index a11d6e78e..7dda6a1f1 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
@@ -42,6 +42,8 @@ package jogamp.opengl.windows.wgl;
import javax.media.opengl.*;
+import com.jogamp.opengl.GLExtensions;
+
import jogamp.opengl.GLContextImpl;
public class WindowsPbufferWGLContext extends WindowsWGLContext {
@@ -112,7 +114,7 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext {
} else {
hasRTT = true;
- if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ if (rect && !gl.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) {
System.err.println("WindowsPbufferWGLContext: WARNING: GL_NV_texture_rectangle extension not " +
"supported; skipping requested render_to_texture_rectangle support for pbuffer");
rect = false;
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index b00c796ec..175622343 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -42,7 +42,7 @@ package jogamp.opengl.windows.wgl;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -92,7 +92,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
if (wglExt.wglReleasePbufferDCARB(buffer, ns.getSurfaceHandle()) == 0) {
throw new GLException("Error releasing pbuffer device context: error code " + GDI.GetLastError());
}
- ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ ((MutableSurface)ns).setSurfaceHandle(0);
}
if (!wglExt.wglDestroyPbufferARB(buffer)) {
throw new GLException("Error destroying pbuffer: error code " + GDI.GetLastError());
@@ -121,7 +121,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
}
try {
long sharedHdc = sharedSurface.getSurfaceHandle();
- WGLExt wglExt = sharedResource.getContext().getWGLExt();
+ WGLExt wglExt = ((WindowsWGLContext)sharedResource.getContext()).getWGLExt();
if (DEBUG) {
System.out.println("Pbuffer config: " + config);
@@ -131,7 +131,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
float[] fattributes = new float[1];
int[] floatModeTmp = new int[1];
int niattribs = 0;
- int width, height;
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
GLProfile glProfile = chosenCaps.getGLProfile();
@@ -206,7 +205,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
iattributes[niattribs++] = GL.GL_FALSE;
- iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB; // exact
iattributes[niattribs++] = GL.GL_FALSE;
}
@@ -235,7 +234,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
NativeSurface ns = getNativeSurface();
// Set up instance variables
buffer = tmpBuffer;
- ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc);
+ ((MutableSurface)ns).setSurfaceHandle(tmpHdc);
cachedWGLExt = wglExt;
// Re-query chosen pixel format
@@ -249,14 +248,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
}
config.setCapsPFD(newCaps);
}
-
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
- width = tmp[0];
- wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
- height = tmp[0];
- ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
} finally {
sharedSurface.unlockSurface();
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index f143c158b..8825bad0a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -53,6 +53,8 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
+
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
@@ -77,8 +79,8 @@ public class WindowsWGLContext extends GLContextImpl {
functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
extensionNameMap = new HashMap();
- extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
- extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+ extensionNameMap.put(GLExtensions.ARB_pbuffer, WindowsWGLDrawableFactory.WGL_ARB_pbuffer);
+ extensionNameMap.put(GLExtensions.ARB_pixel_format, WindowsWGLDrawableFactory.WGL_ARB_pixel_format);
}
// FIXME: figure out how to hook back in the Java 2D / JOGL bridge
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 176d27a71..09e97ff79 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -51,9 +51,10 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -67,9 +68,11 @@ import jogamp.nativewindow.windows.GDISurface;
import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.RegisteredClassFactory;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
+import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
import com.jogamp.common.JogampRuntimeException;
@@ -79,6 +82,7 @@ import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
+import com.jogamp.opengl.GLExtensions;
public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
private static DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper = null;
@@ -203,8 +207,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
static class SharedResource implements SharedResourceRunner.Resource {
private WindowsGraphicsDevice device;
private AbstractGraphicsScreen screen;
- private WindowsDummyWGLDrawable drawable;
- private WindowsWGLContext context;
+ private GLDrawableImpl drawable;
+ private GLContextImpl context;
private boolean hasARBPixelFormat;
private boolean hasARBMultisample;
private boolean hasARBPBuffer;
@@ -214,7 +218,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
private boolean isVendorNVIDIA;
private boolean needsCurrenContext4ARBPFDQueries;
- SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
+ SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, GLDrawableImpl draw, GLContextImpl ctx,
boolean arbPixelFormat, boolean arbMultisample, boolean arbPBuffer, boolean arbReadDrawable, String glVendor) {
device = dev;
screen = scrn;
@@ -250,9 +254,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
final public AbstractGraphicsScreen getScreen() { return screen; }
@Override
- final public WindowsWGLDrawable getDrawable() { return drawable; }
+ final public GLDrawableImpl getDrawable() { return drawable; }
@Override
- final public WindowsWGLContext getContext() { return context; }
+ final public GLContextImpl getContext() { return context; }
final boolean hasARBPixelFormat() { return hasARBPixelFormat; }
final boolean hasARBMultisample() { return hasARBMultisample; }
@@ -302,21 +306,18 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public SharedResourceRunner.Resource createSharedResource(String connection) {
- WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
sharedDevice.lock();
try {
- AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
+ final AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
+ final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
- final int f_dim = 64;
- long hwnd = GDIUtil.CreateDummyWindow(0, 0, f_dim, f_dim);
- WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen, hwnd, f_dim, f_dim, true);
- if (null == sharedDrawable) {
- throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
- }
- WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null);
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+ sharedDrawable.setRealized(true);
+
+ final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
if (null == sharedContext) {
throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
}
@@ -329,7 +330,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
try {
hasARBPixelFormat = sharedContext.isExtensionAvailable(WGL_ARB_pixel_format);
hasARBMultisample = sharedContext.isExtensionAvailable(WGL_ARB_multisample);
- hasARBPBuffer = sharedContext.isExtensionAvailable(GL_ARB_pbuffer);
+ hasARBPBuffer = sharedContext.isExtensionAvailable(GLExtensions.ARB_pbuffer);
hasARBReadDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) &&
sharedContext.isFunctionAvailable(wglMakeContextCurrent);
vendor = sharedContext.getGL().glGetString(GL.GL_VENDOR);
@@ -401,7 +402,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- final static String GL_ARB_pbuffer = "GL_ARB_pbuffer";
+ final static String WGL_ARB_pbuffer = "WGL_ARB_pbuffer";
final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format";
final static String WGL_ARB_multisample = "WGL_ARB_multisample";
final static String WGL_NV_float_buffer = "WGL_NV_float_buffer";
@@ -534,22 +535,89 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
- AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
- WrappedSurface ns = new WrappedSurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- capsChosen, capsRequested, chooser, screen) );
- ns.surfaceSizeChanged(width, height);
- return ns;
+ protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ final WindowsGraphicsDevice device;
+ if(createNewDevice) {
+ device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
+ } else {
+ device = (WindowsGraphicsDevice)deviceReq;
+ }
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
+ }
+ return new WrappedSurface(config, 0, width, height, lifecycleHook);
}
@Override
- protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
- // FIXME device/windowHandle -> screen ?!
- WindowsGraphicsDevice device = (WindowsGraphicsDevice) adevice;
- AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
- GDISurface ns = new GDISurface(cfg, windowHandle);
- return ns;
+ public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ final WindowsGraphicsDevice device;
+ if(createNewDevice) {
+ device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
+ } else {
+ device = (WindowsGraphicsDevice)deviceReq;
+ }
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ final WindowsWGLGraphicsConfiguration config = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(chosenCaps, requestedCaps, chooser, screen);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+requestedCaps+" on "+screen);
+ }
+ return new GDISurface(config, 0, width, height, dummySurfaceLifecycleHook);
+ }
+ private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
+ @Override
+ public final void create(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if(0 == ms.getWindowHandle()) {
+ final long windowHandle = GDIUtil.CreateDummyWindow(0, 0, s.getWidth(), s.getHeight());
+ if(0 == windowHandle) {
+ throw new GLException("Error windowHandle 0, werr: "+GDI.GetLastError());
+ }
+ ms.setWindowHandle(windowHandle);
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.create: "+ms);
+ }
+ }
+ }
+ @Override
+ public final void destroy(ProxySurface s) {
+ final GDISurface ms = (GDISurface)s;
+ if(0 != ms.getWindowHandle()) {
+ GDI.ShowWindow(ms.getWindowHandle(), GDI.SW_HIDE);
+ GDIUtil.DestroyDummyWindow(ms.getWindowHandle());
+ ms.setWindowHandle(0);
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.dummySurfaceLifecycleHook.destroy: "+ms);
+ }
+ }
+ }
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return s.initialWidth;
+ }
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return s.initialHeight;
+ }
+
+ @Override
+ public String toString() {
+ return "GDISurfaceLifecycleHook[]";
+ }
+ };
+
+
+ @Override
+ protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final WindowsGraphicsDevice device = new WindowsGraphicsDevice(deviceReq.getConnection(), deviceReq.getUnitID());
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
+ final WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
+ return new GDISurface(cfg, windowHandle, 0, 0, upstream);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 408d8b074..209589b29 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -48,11 +48,13 @@ import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.opengl.GLExtensions;
import jogamp.nativewindow.windows.DWM_BLURBEHIND;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.MARGINS;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
+import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
@@ -160,7 +162,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
if (!WGLUtil.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) {
- throw new GLException("Unable to set pixel format " + caps +
+ throw new GLException("Unable to set pixel format " + caps.getPFDID() + " of " + caps +
" for device context " + toHexString(hdc) +
": error code " + GDI.GetLastError());
}
@@ -250,7 +252,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
if(sharedResource.hasARBPBuffer()) {
- WindowsWGLContext sharedCtx = sharedResource.getContext();
+ GLContextImpl sharedCtx = sharedResource.getContext();
if(null != sharedCtx && sharedCtx.isExtensionAvailable(WindowsWGLDrawableFactory.WGL_NV_float_buffer)) {
// pbo float buffer
iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
@@ -313,12 +315,12 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
int niattribs = fillAttribsForGeneralWGLARBQuery(sharedResource, iattributes);
- if (!sharedResource.getContext().getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+ if (!((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID +
" of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
}
List bucket = new ArrayList(1);
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
return (WGLGLCapabilities) bucket.get(0);
}
@@ -342,7 +344,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
int[] numFormatsTmp = new int[1];
- if ( !sharedResource.getContext().getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
+ if ( !((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
fattributes, 0,
WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
pformatsTmp, 0, numFormatsTmp, 0))
@@ -374,7 +376,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
static List wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) {
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits);
}
@@ -398,7 +400,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
for(int i = 0; i= 1 &&
- sharedResource.getContext().getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
+ ((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
} else if (DEBUG) {
System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
@@ -507,9 +509,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
}
- WindowsWGLContext sharedCtx = sharedResource.getContext();
+ GLContextImpl sharedCtx = sharedResource.getContext();
if (rect) {
- if (!sharedCtx.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ if (!sharedCtx.isExtensionAvailable(GLExtensions.NV_texture_rectangle)) {
throw new GLException("Render-to-texture-rectangle requires GL_NV_texture_rectangle extension");
}
}
@@ -658,7 +660,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
List capsBucket = new ArrayList(1);
if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
return (WGLGLCapabilities) capsBucket.get(0);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 850b64aa8..943c7fec4 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -52,6 +52,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
+import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
import jogamp.opengl.GLGraphicsConfigurationUtil;
@@ -99,10 +100,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if(null==absScreen) {
absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
}
- AbstractGraphicsDevice absDevice = absScreen.getDevice();
-
+ final AbstractGraphicsDevice absDevice = absScreen.getDevice();
+ final GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
- capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) );
+ capsChosen, GLContext.isFBOAvailable(absDevice, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(absDevice) );
return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
}
@@ -112,9 +113,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if(null == sharedResource) {
throw new GLException("Shared resource for device n/a: "+device);
}
- WindowsWGLDrawable sharedDrawable = sharedResource.getDrawable();
+ GLDrawableImpl sharedDrawable = sharedResource.getDrawable();
GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- WindowsWGLContext sharedContext = sharedResource.getContext();
+ GLContext sharedContext = sharedResource.getContext();
List availableCaps = null;
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -150,7 +151,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
static List getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) {
- int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc);
+ int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile);
}
@@ -265,7 +266,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
AbstractGraphicsDevice device = config.getScreen().getDevice();
WindowsWGLDrawableFactory.SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(device);
- WindowsWGLContext sharedContext = null;
+ GLContext sharedContext = null;
if (null != sharedResource && sharedResource.needsCurrentContext4ARBPFDQueries()) {
sharedContext = sharedResource.getContext();
if(GLContext.CONTEXT_NOT_CURRENT == sharedContext.makeCurrent()) {
@@ -355,7 +356,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
}
// 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
- pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedResource.getContext(), hdc);
+ pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
if (DEBUG) {
final int len = ( null != pformats ) ? pformats.length : 0;
System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
@@ -451,7 +452,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if(null == pformats) {
pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
}
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
for (int i = 0; i < pformats.length; i++) {
WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
deleted file mode 100644
index 8914e2db9..000000000
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright 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:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package jogamp.opengl.x11.glx;
-
-import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLDrawableFactory;
-import javax.media.opengl.GLProfile;
-
-import jogamp.nativewindow.x11.X11Lib;
-
-import com.jogamp.nativewindow.WrappedSurface;
-import com.jogamp.nativewindow.x11.X11GraphicsDevice;
-import com.jogamp.nativewindow.x11.X11GraphicsScreen;
-
-public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
- private static final int f_dim = 64;
- private long dummyWindow = 0;
-
- /**
- * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
- * we cannot switch the Display as we please,
- * hence we reuse the target's screen configuration.
- */
- public X11DummyGLXDrawable(X11GraphicsScreen screen, GLDrawableFactory factory, GLCapabilitiesImmutable caps) {
- super(factory,
- new WrappedSurface(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- caps, caps, null, screen)));
- this.realized = true;
-
- WrappedSurface ns = (WrappedSurface) getNativeSurface();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)ns.getGraphicsConfiguration();
-
- X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
- long dpy = device.getHandle();
- int scrn = screen.getIndex();
- int visualID = config.getXVisualID();
-
- dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim);
- ns.setSurfaceHandle( dummyWindow );
- ns.surfaceSizeChanged(f_dim, f_dim);
-
- updateHandle();
- }
-
- public static X11DummyGLXDrawable create(X11GraphicsScreen screen, GLDrawableFactory factory, GLProfile glp) {
- GLCapabilities caps = new GLCapabilities(glp);
- return new X11DummyGLXDrawable(screen, factory, caps);
- }
-
- public void setSize(int width, int height) {
- }
-
- @Override
- public int getWidth() {
- return 1;
- }
-
- @Override
- public int getHeight() {
- return 1;
- }
-
-
- @Override
- protected void setRealizedImpl() {
- super.setRealizedImpl();
- if(!realized) {
- if(0!=dummyWindow) {
- destroyHandle();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
- X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
- }
- }
- }
-}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index 53776386c..b847363e0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -76,8 +76,15 @@ public class X11ExternalGLXContext extends X11GLXContext {
long drawable = GLX.glXGetCurrentDrawable();
if (drawable == 0) {
throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current");
- }
+ }
int[] val = new int[1];
+
+ int w, h;
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0);
+ w=val[0];
+ GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0);
+ h=val[0];
+
GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0);
X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
@@ -97,8 +104,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
}
- WrappedSurface ns = new WrappedSurface(cfg);
- ns.setSurfaceHandle(drawable);
+ final WrappedSurface ns = new WrappedSurface(cfg, drawable, w, h, null);
return new X11ExternalGLXContext(new Drawable(factory, ns), ctx);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index 3fabe7a13..8652e2d4a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -87,10 +87,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")");
}
}
- WrappedSurface ns = new WrappedSurface(cfg);
- ns.setSurfaceHandle(drawable);
- ns.surfaceSizeChanged(w, h);
- return new X11ExternalGLXDrawable(factory, ns);
+ return new X11ExternalGLXDrawable(factory, new WrappedSurface(cfg, drawable, w, h, null));
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 0afadc677..e6b74a769 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -61,6 +61,7 @@ import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLExtensions;
public abstract class X11GLXContext extends GLContextImpl {
private static final Map functionNameMap;
@@ -83,8 +84,8 @@ public abstract class X11GLXContext extends GLContextImpl {
functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
extensionNameMap = new HashMap();
- extensionNameMap.put("GL_ARB_pbuffer", "GLX_SGIX_pbuffer");
- extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough
+ extensionNameMap.put(GLExtensions.ARB_pbuffer, X11GLXDrawableFactory.GLX_SGIX_pbuffer);
+ extensionNameMap.put(GLExtensions.ARB_pixel_format, X11GLXDrawableFactory.GLX_SGIX_pbuffer); // good enough
}
X11GLXContext(GLDrawableImpl drawable,
@@ -508,8 +509,8 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
public boolean isExtensionAvailable(String glExtensionName) {
- if (glExtensionName.equals("GL_ARB_pbuffer") ||
- glExtensionName.equals("GL_ARB_pixel_format")) {
+ if (glExtensionName.equals(GLExtensions.ARB_pbuffer) ||
+ glExtensionName.equals(GLExtensions.ARB_pixel_format)) {
return getGLDrawable().getFactory().canCreateGLPbuffer(
drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice() );
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 9a563bdb8..8ffbf3951 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -49,6 +49,8 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -64,6 +66,7 @@ import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
import com.jogamp.common.util.VersionNumber;
@@ -79,6 +82,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
public static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0);
public static final VersionNumber versionOneFour = new VersionNumber(1, 4, 0);
+ static final String GLX_SGIX_pbuffer = "GLX_SGIX_pbuffer";
+
private static DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper = null;
public X11GLXDrawableFactory() {
@@ -153,8 +158,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
static class SharedResource implements SharedResourceRunner.Resource {
X11GraphicsDevice device;
X11GraphicsScreen screen;
- X11DummyGLXDrawable drawable;
- X11GLXContext context;
+ GLDrawableImpl drawable;
+ GLContextImpl context;
String glXServerVendorName;
boolean isGLXServerVendorATI;
boolean isGLXServerVendorNVIDIA;
@@ -164,7 +169,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
boolean glXMultisampleAvailable;
SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
- X11DummyGLXDrawable draw, X11GLXContext ctx,
+ GLDrawableImpl draw, GLContextImpl ctx,
VersionNumber glXServerVer, String glXServerVendor, boolean glXServerMultisampleAvail) {
device = dev;
screen = scrn;
@@ -224,13 +229,15 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@Override
public SharedResourceRunner.Resource createSharedResource(String connection) {
- X11GraphicsDevice sharedDevice =
+ final X11GraphicsDevice sharedDevice =
new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- true); // own non-shared display connection, no locking
+ true); // own non-shared display connection, w/ locking
// new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
- // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, no locking
+ // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, w/o locking
sharedDevice.lock();
try {
+ final X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+
if(!GLXUtil.isGLXAvailableOnServer(sharedDevice)) {
throw new GLException("GLX not available on device/server: "+sharedDevice);
}
@@ -242,20 +249,20 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
X11Util.setMarkAllDisplaysUnclosable(true);
X11Util.markDisplayUncloseable(sharedDevice.getHandle());
}
- X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
-
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
+
+ final GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
- X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp);
- if (null == sharedDrawable) {
- throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp);
- }
- X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null);
+
+ final GLDrawableImpl sharedDrawable = createOnscreenDrawableImpl(createDummySurfaceImpl(sharedDevice, false, new GLCapabilities(glp), null, 64, 64));
+ sharedDrawable.setRealized(true);
+
+ final GLContextImpl sharedContext = (GLContextImpl) sharedDrawable.createContext(null);
if (null == sharedContext) {
throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
}
+
boolean madeCurrent = false;
sharedContext.makeCurrent();
try {
@@ -298,7 +305,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if (null != sr.context) {
// may cause JVM SIGSEGV:
- sr.context.destroy();
+ sr.context.destroy(); // will also pull the dummy MutuableSurface
sr.context = null;
}
@@ -394,7 +401,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new X11OnscreenGLXDrawable(this, target);
+ return new X11OnscreenGLXDrawable(this, target, false);
}
@Override
@@ -495,40 +502,88 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq,
- GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- int width, int height) {
- if(null == deviceReq) {
- throw new InternalError("deviceReq is null");
- }
- final SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(deviceReq);
- if(null==sr) {
- throw new InternalError("No SharedResource for: "+deviceReq);
+ protected final ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ final X11GraphicsDevice device;
+ if(createNewDevice) {
+ // Null X11 locking, due to private non-shared Display handle
+ device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ } else {
+ device = (X11GraphicsDevice)deviceReq;
}
- final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sr.getScreen();
- final AbstractGraphicsDevice sharedDevice = sharedScreen.getDevice(); // should be same ..
-
- // create screen/device pair - Null X11 locking, due to private non-shared Display handle
- final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(sharedDevice.getConnection()), AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), true);
- final X11GraphicsScreen screen = new X11GraphicsScreen(device, sharedScreen.getIndex());
-
- WrappedSurface ns = new WrappedSurface(
- X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen) );
- if(ns != null) {
- ns.surfaceSizeChanged(width, height);
+ final X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
+ final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return ns;
+ return new WrappedSurface( config, 0, width, height, lifecycleHook);
}
@Override
- protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
- // FIXME device/windowHandle -> screen ?!
- X11GraphicsDevice device = (X11GraphicsDevice) adevice;
- X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
- X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
- WrappedSurface ns = new WrappedSurface(cfg, windowHandle);
- return ns;
+ public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ }
+ private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
+ @Override
+ public final void create(ProxySurface s) {
+ if( 0 == s.getSurfaceHandle() ) {
+ final X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
+ final X11GraphicsScreen screen = (X11GraphicsScreen) cfg.getScreen();
+ final X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
+ if(0 == device.getHandle()) {
+ device.open();
+ s.setImplBitfield(ProxySurface.OWN_DEVICE);
+ }
+ final long windowHandle = X11Lib.CreateDummyWindow(device.getHandle(), screen.getIndex(), cfg.getXVisualID(), s.getWidth(), s.getHeight());
+ if(0 == windowHandle) {
+ throw new GLException("Creating dummy window failed w/ "+cfg+", "+s.getWidth()+"x"+s.getHeight());
+ }
+ s.setSurfaceHandle(windowHandle);
+ if(DEBUG) {
+ System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
+ }
+ }
+ }
+ @Override
+ public final void destroy(ProxySurface s) {
+ if(0 != s.getSurfaceHandle()) {
+ final X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) s.getGraphicsConfiguration();
+ final X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
+ X11Lib.DestroyDummyWindow(device.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(0);
+ if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
+ device.close();
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXDrawableFactory.dummySurfaceLifecycleHook.destroy: "+s);
+ }
+ }
+ }
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return s.initialWidth;
+ }
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return s.initialHeight;
+ }
+ @Override
+ public String toString() {
+ return "X11SurfaceLifecycleHook[]";
+ }
+ };
+
+
+ @Override
+ protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
+ final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
+ final X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
+ return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b54b5150c..b5b80e0b3 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -36,12 +36,14 @@ package jogamp.opengl.x11.glx;
import java.util.ArrayList;
import java.util.List;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -67,7 +69,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
- final long display = x11Screen.getDevice().getHandle();
+ final AbstractGraphicsDevice device = x11Screen.getDevice();
+ final long display = device.getHandle();
if(0==display) {
throw new GLException("Display null of "+x11Screen);
}
@@ -80,7 +83,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
glp = GLProfile.getDefault(x11Screen.getDevice());
}
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(x11Screen.getDevice()));
+ final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, device, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(device));
if(null==caps) {
throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
}
@@ -233,11 +236,11 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return true;
}
- static int FBCfgDrawableTypeBits(final long display, final long fbcfg) {
+ static int FBCfgDrawableTypeBits(final AbstractGraphicsDevice device, GLProfile glp, final long fbcfg) {
int val = 0;
int[] tmp = new int[1];
- int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
+ int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
@@ -248,17 +251,20 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
}
+ if ( GLContext.isFBOAvailable(device, glp) ) {
+ val |= GLGraphicsConfigurationUtil.FBO_BIT;
+ }
return val;
}
- static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
+ static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
boolean relaxed, boolean onscreen, boolean usePBuffer,
boolean isMultisampleAvailable) {
ArrayList bucket = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
- if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) {
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
+ if( GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, winattrmask, isMultisampleAvailable) ) {
return (X11GLCapabilities) bucket.get(0);
- } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+ } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
return (X11GLCapabilities) bucket.get(0);
}
return null;
@@ -273,11 +279,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
static boolean GLXFBConfig2GLCapabilities(List capsBucket,
- GLProfile glp, long display, long fbcfg,
+ GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
int winattrmask, boolean isMultisampleAvailable) {
- final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg);
+ final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp, fbcfg);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
+
+ final long display = device.getHandle();
int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg);
XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg);
if(null == visualInfo) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 8377d2453..331401c06 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -44,6 +44,7 @@ import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -161,7 +162,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
return null;
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
@@ -209,7 +210,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) );
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(x11Device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(x11Device) );
boolean usePBuffer = capsChosen.isPBuffer();
X11GLXGraphicsConfiguration res = null;
@@ -245,7 +246,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
+ final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, absDevice, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
@@ -258,6 +259,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
GLProfile glProfile = capsChosen.getGLProfile();
boolean onscreen = capsChosen.isOnscreen();
boolean usePBuffer = capsChosen.isPBuffer();
+ boolean useFBO = capsChosen.isFBO();
// Utilizing FBConfig
//
@@ -270,13 +272,12 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
List availableCaps = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
-
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
if (fbcfgsL != null && fbcfgsL.limit()>0) {
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
@@ -309,7 +310,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
@@ -338,7 +339,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
GLProfile glProfile = capsChosen.getGLProfile();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */);
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */, false);
List availableCaps = new ArrayList();
int recommendedIndex = -1;
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 9e22afa6d..363299321 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -51,10 +51,13 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
long glXWindow; // GLXWindow, a GLXDrawable representation
boolean useGLXWindow;
- protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeSurface component) {
- super(factory, component, false);
+ protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeSurface component, boolean realized) {
+ super(factory, component, realized);
glXWindow=0;
useGLXWindow=false;
+ if(realized) {
+ updateHandle();
+ }
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index cdf81ebd3..e1fe2f27e 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -43,7 +43,7 @@ package jogamp.opengl.x11.glx;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
@@ -77,7 +77,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
if (ns.getSurfaceHandle() != 0) {
GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle());
}
- ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ ((MutableSurface)ns).setSurfaceHandle(0);
}
private void createPbuffer() {
@@ -108,12 +108,14 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
// Create the p-buffer.
int niattribs = 0;
- int[] iattributes = new int[5];
+ int[] iattributes = new int[7];
iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH;
iattributes[niattribs++] = ns.getWidth();
iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT;
iattributes[niattribs++] = ns.getHeight();
+ iattributes[niattribs++] = GLX.GLX_LARGEST_PBUFFER; // exact
+ iattributes[niattribs++] = 0;
iattributes[niattribs++] = 0;
long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0);
@@ -123,15 +125,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
// Set up instance variables
- ((SurfaceChangeable)ns).setSurfaceHandle(pbuffer);
-
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_WIDTH, tmp, 0);
- int width = tmp[0];
- GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
- int height = tmp[0];
- ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
+ ((MutableSurface)ns).setSurfaceHandle(pbuffer);
if (DEBUG) {
System.err.println("Created pbuffer " + this);
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index 1e7b89828..04627724c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -43,7 +43,7 @@ package jogamp.opengl.x11.glx;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -93,7 +93,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
pixmap = 0;
throw new GLException("glXCreateGLXPixmap failed");
}
- ((SurfaceChangeable)ns).setSurfaceHandle(drawable);
+ ((MutableSurface)ns).setSurfaceHandle(drawable);
if (DEBUG) {
System.err.println("Created pixmap " + toHexString(pixmap) +
", GLXPixmap " + toHexString(drawable) +
@@ -133,7 +133,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
X11Lib.XFreePixmap(display, pixmap);
drawable = 0;
pixmap = 0;
- ((SurfaceChangeable)ns).setSurfaceHandle(0);
+ ((MutableSurface)ns).setSurfaceHandle(0);
display = 0;
}
}
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
index 776284cfc..b81b43e54 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
@@ -32,7 +32,6 @@
int texWidth;
int texHeight;
GLuint textureID;
- struct timespec lastWaitTime;
#ifdef HAS_CADisplayLink
CADisplayLink* displayLink;
#else
@@ -41,6 +40,7 @@
int tc;
struct timespec t0;
@public
+ struct timespec lastWaitTime;
GLint swapInterval;
GLint swapIntervalCounter;
pthread_mutex_t renderLock;
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 8ac9f4700..d3f703142 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -503,7 +503,7 @@ NSView* getNSView(NSOpenGLContext* ctx) {
NSOpenGLContext* createContext(NSOpenGLContext* share,
NSView* view,
- Bool isBackingLayerView,
+ Bool allowIncompleteView,
NSOpenGLPixelFormat* fmt,
Bool opaque,
int* viewNotReady)
@@ -512,13 +512,13 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
getRendererInfo();
- DBG_PRINT("createContext.0: share %p, view %p, isBackingLayer %d, pixfmt %p, opaque %d\n",
- share, view, (int)isBackingLayerView, fmt, opaque);
+ DBG_PRINT("createContext.0: share %p, view %p, allowIncompleteView %d, pixfmt %p, opaque %d\n",
+ share, view, (int)allowIncompleteView, fmt, opaque);
if (view != NULL) {
Bool viewReady = true;
- if(!isBackingLayerView) {
+ if(!allowIncompleteView) {
if ([view lockFocusIfCanDraw] == NO) {
DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n");
viewReady = false;
@@ -527,7 +527,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
if(viewReady) {
NSRect frame = [view frame];
if ((frame.size.width == 0) || (frame.size.height == 0)) {
- if(!isBackingLayerView) {
+ if(!allowIncompleteView) {
[view unlockFocus];
}
DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
@@ -558,7 +558,7 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
[ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
}
[ctx setView:view];
- if(!isBackingLayerView) {
+ if(!allowIncompleteView) {
[view unlockFocus];
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
index 04f616daf..b7f6ba45d 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
@@ -30,51 +30,49 @@ package com.jogamp.nativewindow;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.SurfaceChangeable;
+public class WrappedSurface extends ProxySurface {
+ protected long surfaceHandle;
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
- protected long surfaceHandle;
-
- public WrappedSurface(AbstractGraphicsConfiguration cfg) {
- this(cfg, 0);
- }
-
- public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle) {
- super(cfg);
+ public WrappedSurface(AbstractGraphicsConfiguration cfg, long handle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+ super(cfg, initialWidth, initialHeight, upstream);
surfaceHandle=handle;
}
@Override
- protected final void invalidateImpl() {
+ protected void invalidateImpl() {
surfaceHandle = 0;
}
@Override
- final public long getSurfaceHandle() {
+ public final long getSurfaceHandle() {
return surfaceHandle;
}
@Override
- final public void setSurfaceHandle(long surfaceHandle) {
+ public final void setSurfaceHandle(long surfaceHandle) {
this.surfaceHandle=surfaceHandle;
}
-
+
@Override
- final protected int lockSurfaceImpl() {
- return LOCK_SUCCESS;
+ protected final int lockSurfaceImpl() {
+ return LOCK_SUCCESS;
}
@Override
- final protected void unlockSurfaceImpl() {
+ protected final void unlockSurfaceImpl() {
}
@Override
public String toString() {
+ final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
+ final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";
+
return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
", size " + getWidth() + "x" + getHeight() +
- ", surfaceLock "+surfaceLock+"]";
+ ", surfaceLock "+surfaceLock+
+ ", upstreamSurfaceHook "+ush_s+"]";
}
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index d161f2f34..389949e90 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.*;
*/
public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
final long nativeDisplayID;
- final EGLTerminateCallback eglTerminateCallback;
+ final EGLDisplayLifecycleCallback eglLifecycleCallback;
/**
* Hack to allow inject a EGL termination call.
@@ -47,7 +47,14 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
* since then it can be utilized directly.
*
*/
- public interface EGLTerminateCallback {
+ public interface EGLDisplayLifecycleCallback {
+ /**
+ * Implementation should issue an EGL.eglGetDisplay(nativeDisplayID)
+ * inclusive EGL.eglInitialize(eglDisplayHandle, ..)
call.
+ * @param eglDisplayHandle
+ */
+ public long eglGetAndInitDisplay(long nativeDisplayID);
+
/**
* Implementation should issue an EGL.eglTerminate(eglDisplayHandle)
call.
* @param eglDisplayHandle
@@ -61,28 +68,45 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public EGLGraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID);
- this.nativeDisplayID = 0;
- this.eglTerminateCallback = null;
+ this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ this.eglLifecycleCallback = null;
}
- public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLTerminateCallback eglTerminateCallback) {
+ public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
this.nativeDisplayID = nativeDisplayID;
- this.eglTerminateCallback = eglTerminateCallback;
+ this.eglLifecycleCallback = eglLifecycleCallback;
}
public long getNativeDisplayID() { return nativeDisplayID; }
+ @Override
public Object clone() {
return super.clone();
}
+
+ @Override
+ public boolean open() {
+ if(null != eglLifecycleCallback && 0 == handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.open(): "+this);
+ }
+ handle = eglLifecycleCallback.eglGetAndInitDisplay(nativeDisplayID);
+ if(0 == handle) {
+ throw new NativeWindowException("EGLGraphicsDevice.open() failed: "+this);
+ }
+ return true;
+ }
+ return false;
+ }
+ @Override
public boolean close() {
- if(null != eglTerminateCallback) {
+ if(null != eglLifecycleCallback && 0 != handle) {
if(DEBUG) {
- System.err.println(Thread.currentThread().getName() + " - eglTerminate: "+this);
+ System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.close(): "+this);
}
- eglTerminateCallback.eglTerminate(handle);
+ eglLifecycleCallback.eglTerminate(handle);
}
return super.close();
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index 735d85fb1..0494bb408 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -43,7 +43,6 @@ import com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice;
import com.jogamp.nativewindow.windows.WindowsGraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
-import jogamp.common.awt.AWTEDTExecutor;
import jogamp.nativewindow.macosx.OSXUtil;
public class SWTAccessor {
@@ -204,8 +203,6 @@ public class SWTAccessor {
if( null != OS_gtk_class ) {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
- // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
- // to avoid locking problems !
return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index a02332413..7a98e3c25 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -33,7 +33,6 @@
package com.jogamp.nativewindow.x11;
-import jogamp.nativewindow.Debug;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
@@ -46,7 +45,7 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- final boolean closeDisplay;
+ final boolean handleOwner;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
* {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.
@@ -56,7 +55,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public X11GraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
- closeDisplay = false;
+ handleOwner = false;
}
/** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
@@ -69,7 +68,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
if(0==display) {
throw new NativeWindowException("null display");
}
- closeDisplay = owner;
+ handleOwner = owner;
}
/**
@@ -82,16 +81,39 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
if(0==display) {
throw new NativeWindowException("null display");
}
- closeDisplay = owner;
+ handleOwner = owner;
}
+ public int getDefaultVisualID() {
+ // It still could be an AWT hold handle ..
+ final long display = getHandle();
+ final int scrnIdx = X11Lib.DefaultScreen(display);
+ return (int) X11Lib.DefaultVisualID(display, scrnIdx);
+ }
+
+ @Override
public Object clone() {
return super.clone();
}
+ @Override
+ public boolean open() {
+ if(handleOwner && 0 == handle) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.open(): "+this);
+ }
+ handle = X11Util.openDisplay(connection);
+ if(0 == handle) {
+ throw new NativeWindowException("X11GraphicsDevice.open() failed: "+this);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
public boolean close() {
- // FIXME: shall we respect the unitID ?
- if(closeDisplay && 0 != handle) {
+ if(handleOwner && 0 != handle) {
if(DEBUG) {
System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this);
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 94013ec38..014f4f688 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -56,13 +56,11 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
}
- public long getDefaultVisualID() {
+ public int getVisualID() {
// It still could be an AWT hold handle ..
- long display = getDevice().getHandle();
- int scrnIdx = X11Lib.DefaultScreen(display);
- return X11Lib.DefaultVisualID(display, scrnIdx);
+ return (int) X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
}
-
+
private static int fetchScreen(X11GraphicsDevice device, int screen) {
// It still could be an AWT hold handle ..
if(X11Util.XineramaIsEnabled(device.getHandle())) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 4979f1949..756e4451b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -113,16 +113,33 @@ public interface AbstractGraphicsDevice extends Cloneable {
*/
public void unlock();
+ /**
+ * Optionally [re]opening the device if handle is null
.
+ *
+ * The default implementation is a NOP
.
+ *
+ *
+ * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
+ * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice}
+ * issue the native open operation in case handle is null
.
+ *
+ *
+ * @return true if the handle was null
and opening was successful, otherwise false.
+ */
+ public boolean open();
+
/**
- * Optionally closing the device.
+ * Optionally closing the device if handle is not null
.
*
* The default implementation is a NOP
, just setting the handle to null
.
*
- * The specific implementing, ie {@link com.jogamp.nativewindow.x11.X11GraphicsDevice},
- * shall have a enable/disable like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},
- * which shall be invoked at creation time to determine ownership/role of freeing the resource.
+ *
+ * Example implementations like {@link com.jogamp.nativewindow.x11.X11GraphicsDevice}
+ * or {@link com.jogamp.nativewindow.egl.EGLGraphicsDevice}
+ * issue the native close operation or skip it depending on the handles's ownership.
+ *
*
- * @return true if the handle was not null
, otherwise false.
+ * @return true if the handle was not null
and closing was successful, otherwise false.
*/
public boolean close();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index 187959a67..583fde07f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -97,22 +97,27 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
}
+ @Override
public final String getType() {
return type;
}
+ @Override
public final String getConnection() {
return connection;
}
+ @Override
public final int getUnitID() {
return unitID;
}
+ @Override
public final String getUniqueID() {
return uniqueID;
}
+ @Override
public final long getHandle() {
return handle;
}
@@ -124,6 +129,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
*/
+ @Override
public final void lock() {
toolkitLock.lock();
}
@@ -135,10 +141,17 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
*/
+ @Override
public final void unlock() {
toolkitLock.unlock();
}
+
+ @Override
+ public boolean open() {
+ return false;
+ }
+ @Override
public boolean close() {
if(0 != handle) {
handle = 0;
diff --git a/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
new file mode 100644
index 000000000..ff53c8109
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/MutableSurface.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.nativewindow;
+
+/**
+ * Provides a {@link NativeSurface} with a mutable surfaceHandle
+ * via {@link #setSurfaceHandle(long)}.
+ *
+ * @see NativeSurface
+ */
+public interface MutableSurface extends NativeSurface {
+
+ /**
+ * Sets the surface handle which is created outside of this implementation.
+ */
+ public void setSurfaceHandle(long surfaceHandle);
+}
+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index 1dabc3dcd..7fc9789c2 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,38 +28,108 @@
package javax.media.nativewindow;
-
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.SurfaceUpdatedHelper;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-public abstract class ProxySurface implements NativeSurface {
+public abstract class ProxySurface implements NativeSurface, MutableSurface {
public static final boolean DEBUG = Debug.debug("ProxySurface");
+
+ /**
+ * Implementation specific bitvalue stating the upstream's {@link AbstractGraphicsDevice} is owned by this {@link ProxySurface}.
+ * @see #setImplBitfield(int)
+ * @see #getImplBitfield()
+ */
+ public static final int OWN_DEVICE = 1 << 7;
+
+ /**
+ * Implementation specific bitvalue stating the upstream's {@link NativeSurface} is an invisible window, i.e. maybe incomplete.
+ * @see #setImplBitfield(int)
+ * @see #getImplBitfield()
+ */
+ public static final int INVISIBLE_WINDOW = 1 << 8;
- private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- private AbstractGraphicsConfiguration config; // control access due to delegation
- protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ /** Interface allowing upstream caller to pass lifecycle actions and size info to a {@link ProxySurface} instance. */
+ public interface UpstreamSurfaceHook {
+ /** called within {@link ProxySurface#createNotify()} within lock, before using surface. */
+ public void create(ProxySurface s);
+ /** called within {@link ProxySurface#destroyNotify()} within lock, before clearing fields. */
+ public void destroy(ProxySurface s);
+
+ /** Returns the width of the upstream surface */
+ public int getWidth(ProxySurface s);
+ /** Returns the height of the upstream surface */
+ public int getHeight(ProxySurface s);
+ }
+
+ private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ private final AbstractGraphicsConfiguration config; // control access due to delegation
+ private final UpstreamSurfaceHook upstream;
+ public final int initialWidth;
+ public final int initialHeight;
private long surfaceHandle_old;
+ protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
protected long displayHandle;
- protected int height;
protected int scrnIndex;
- protected int width;
+ protected int implBitfield;
- public ProxySurface(AbstractGraphicsConfiguration cfg) {
- invalidate();
- config = cfg;
- displayHandle=cfg.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
- surfaceHandle_old = 0;
+ /**
+ * @param cfg the {@link AbstractGraphicsConfiguration} to be used
+ * @param initialWidth the initial width
+ * @param initialHeight the initial height
+ */
+ protected ProxySurface(AbstractGraphicsConfiguration cfg, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+ if(null == cfg) {
+ throw new IllegalArgumentException("null config");
+ }
+ this.config = cfg;
+ this.upstream = upstream;
+ this.initialWidth = initialWidth;
+ this.initialHeight = initialHeight;
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.surfaceHandle_old = 0;
+ this.implBitfield = 0;
}
- void invalidate() {
- displayHandle = 0;
- invalidateImpl();
+ public final UpstreamSurfaceHook getUpstreamSurfaceHook() { return upstream; }
+
+ /**
+ * If a valid {@link UpstreamSurfaceHook} instance is passed in the
+ * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
+ * {@link UpstreamSurfaceHook#create(ProxySurface)} is being issued and the proxy surface/window handles shall be set.
+ */
+ public void createNotify() {
+ if(null != upstream) {
+ upstream.create(this);
+ }
+ this.displayHandle=config.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
+ this.surfaceHandle_old = 0;
}
- protected abstract void invalidateImpl();
-
+
+ /**
+ * If a valid {@link UpstreamSurfaceHook} instance is passed in the
+ * {@link ProxySurface#ProxySurface(AbstractGraphicsConfiguration, int, int, UpstreamSurfaceHook) constructor},
+ * {@link UpstreamSurfaceHook#destroy(ProxySurface)} is being issued and all fields are cleared.
+ */
+ public void destroyNotify() {
+ if(null != upstream) {
+ upstream.destroy(this);
+ invalidateImpl();
+ }
+ this.displayHandle = 0;
+ this.surfaceHandle_old = 0;
+ }
+
+ /**
+ * Must be overridden by implementations allowing having a {@link UpstreamSurfaceHook} being passed.
+ * @see #destroyNotify()
+ */
+ protected void invalidateImpl() {
+ throw new InternalError("UpstreamSurfaceHook given, but required method not implemented.");
+ }
+
@Override
public final long getDisplayHandle() {
return displayHandle;
@@ -82,19 +152,23 @@ public abstract class ProxySurface implements NativeSurface {
@Override
public abstract long getSurfaceHandle();
+ @Override
+ public abstract void setSurfaceHandle(long surfaceHandle);
+
@Override
public final int getWidth() {
- return width;
+ if(null != upstream) {
+ return upstream.getWidth(this);
+ }
+ return initialWidth;
}
@Override
public final int getHeight() {
- return height;
- }
-
- public void surfaceSizeChanged(int width, int height) {
- this.width = width;
- this.height = height;
+ if(null != upstream) {
+ return upstream.getHeight(this);
+ }
+ return initialHeight;
}
@Override
@@ -187,7 +261,10 @@ public abstract class ProxySurface implements NativeSurface {
public final Thread getSurfaceLockOwner() {
return surfaceLock.getOwner();
}
-
+
@Override
public abstract String toString();
+
+ public int getImplBitfield() { return implBitfield; }
+ public void setImplBitfield(int v) { implBitfield=v; }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
deleted file mode 100644
index 956e68e61..000000000
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package javax.media.nativewindow;
-
-public interface SurfaceChangeable {
-
- /** Sets the surface handle which is created outside of this implementation */
- public void setSurfaceHandle(long surfaceHandle);
-
- /**
- * The surface's size has been determined or changed.
- * Implementation shall update the stored surface size with the given ones.
- */
- public void surfaceSizeChanged(int width, int height);
-
-}
-
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
index 4877d5c4f..4f68c6945 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -34,8 +34,8 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.SurfaceUpdatedListener;
public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
- private Object surfaceUpdatedListenersLock = new Object();
- private ArrayList surfaceUpdatedListeners = new ArrayList();
+ private final Object surfaceUpdatedListenersLock = new Object();
+ private final ArrayList surfaceUpdatedListeners = new ArrayList();
//
// Management Utils
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 42fd08df1..e81d61e0f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -48,7 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
@@ -62,7 +62,7 @@ import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
import jogamp.nativewindow.jawt.macosx.JAWT_MacOSXDrawingSurfaceInfo;
import jogamp.nativewindow.macosx.OSXUtil;
-public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
+public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
super(comp, config);
if(DEBUG) {
@@ -103,24 +103,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
if(DEBUG) {
System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
}
- sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
this.surfaceHandle = surfaceHandle;
}
- public void surfaceSizeChanged(int width, int height) {
- sscSet = true;
- sscWidth = width;
- sscHeight = height;
- }
-
- public int getWidth() {
- return sscSet ? sscWidth : super.getWidth();
- }
-
- public int getHeight() {
- return sscSet ? sscHeight: super.getHeight();
- }
-
protected JAWT fetchJAWTImpl() throws NativeWindowException {
// use offscreen if supported and [ applet or requested ]
return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
@@ -280,8 +265,6 @@ public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
private long rootSurfaceLayerHandle = 0; // attached to the JAWT_SurfaceLayer
private long surfaceHandle = 0;
- private int sscWidth, sscHeight;
- private boolean sscSet = false;
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 4d472b01a..99fc9244e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -63,19 +63,15 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
- public static long CreateNSView(int x, int y, int width, int height) {
- return CreateNSView0(x, y, width, height);
- }
- public static void DestroyNSView(long nsView) {
- DestroyNSView0(nsView);
- }
-
public static long CreateNSWindow(int x, int y, int width, int height) {
return CreateNSWindow0(x, y, width, height);
}
public static void DestroyNSWindow(long nsWindow) {
DestroyNSWindow0(nsWindow);
}
+ public static long GetNSView(long nsWindow) {
+ return GetNSView0(nsWindow);
+ }
public static long CreateCALayer(int x, int y, int width, int height) {
return CreateCALayer0(x, y, width, height);
@@ -134,10 +130,9 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
- private static native long CreateNSView0(int x, int y, int width, int height);
- private static native void DestroyNSView0(long nsView);
private static native long CreateNSWindow0(int x, int y, int width, int height);
private static native void DestroyNSWindow0(long nsWindow);
+ private static native long GetNSView0(long nsWindow);
private static native long CreateCALayer0(int x, int y, int width, int height);
private static native void AddCASublayer0(long rootCALayer, long subCALayer);
private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index c24f64b32..e368aa6a1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -31,6 +31,7 @@ package jogamp.nativewindow.windows;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
/**
@@ -43,22 +44,49 @@ public class GDISurface extends ProxySurface {
protected long windowHandle;
protected long surfaceHandle;
- public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle) {
- super(cfg);
- if(0 == windowHandle) {
- throw new NativeWindowException("Error hwnd 0, werr: "+GDI.GetLastError());
- }
+ public GDISurface(AbstractGraphicsConfiguration cfg, long windowHandle, int initialWidth, int initialHeight, UpstreamSurfaceHook upstream) {
+ super(cfg, initialWidth, initialHeight, upstream);
this.windowHandle=windowHandle;
+ this.surfaceHandle=0;
}
@Override
- protected final void invalidateImpl() {
- windowHandle=0;
- surfaceHandle=0;
+ protected void invalidateImpl() {
+ if(0 != surfaceHandle) {
+ throw new NativeWindowException("didn't release surface Handle: "+this);
+ }
+ windowHandle = 0;
+ // surfaceHandle = 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Actually the window handle (HWND), since the surfaceHandle (HDC) is derived
+ * from it at {@link #lockSurface()}.
+ *
+ */
+ @Override
+ public final void setSurfaceHandle(long surfaceHandle) {
+ this.windowHandle = surfaceHandle;
+ }
+
+ /**
+ * Sets the window handle (HWND).
+ */
+ public final void setWindowHandle(long windowHandle) {
+ this.windowHandle = windowHandle;
+ }
+
+ public final long getWindowHandle() {
+ return windowHandle;
}
@Override
final protected int lockSurfaceImpl() {
+ if (0 == windowHandle) {
+ throw new NativeWindowException("null window handle: "+this);
+ }
if (0 != surfaceHandle) {
throw new InternalError("surface not released");
}
@@ -89,12 +117,15 @@ public class GDISurface extends ProxySurface {
@Override
final public String toString() {
- return "GDISurface[config "+getPrivateGraphicsConfiguration()+
+ final UpstreamSurfaceHook ush = getUpstreamSurfaceHook();
+ final String ush_s = null != ush ? ( ush.getClass().getName() + ": " + ush ) : "nil";
+ return getClass().getSimpleName()+"[config "+getPrivateGraphicsConfiguration()+
", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
", windowHandle 0x"+Long.toHexString(windowHandle)+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
", size "+getWidth()+"x"+getHeight()+
- ", surfaceLock "+surfaceLock+"]";
+ ", surfaceLock "+surfaceLock+
+ ", upstreamSurfaceHook "+ush_s+"]";
}
}
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e010fc440..ebfefe345 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -148,37 +148,6 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
return res;
}
-/*
- * Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: CreateNSView0
- * Signature: (IIIIZ)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0
- (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSRect rect = NSMakeRect(x, y, width, height);
- NSView * view = [[NSView alloc] initWithFrame: rect] ;
- [view setCanDrawConcurrently: YES];
- [pool release];
-
- return (jlong) (intptr_t) view;
-}
-
-/*
- * Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: DestroyNSView0
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0
- (JNIEnv *env, jclass unused, jlong nsView)
-{
- NSView* view = (NSView*) (intptr_t) nsView;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [view release];
- [pool release];
-}
-
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: CreateNSWindow0
@@ -222,6 +191,27 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
[pool release];
}
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: GetNSView0
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSView0
+ (JNIEnv *env, jclass unused, jlong window)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+
+ DBG_PRINT( "contentView0 - window: %p (START)\n", win);
+
+ jlong res = (jlong) ((intptr_t) [win contentView]);
+
+ DBG_PRINT( "contentView0 - window: %p (END)\n", win);
+
+ [pool release];
+ return res;
+}
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: CreateCALayer0
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 71e86d520..e8537fec5 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -40,8 +40,20 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.WindowClosingProtocol;
/**
- * Specifying the public Window functionality for the
- * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
+ * Specifying NEWT's Window functionality:
+ *
+ * On- and offscreen windows
+ * Keyboard and multi-pointer input
+ * Native reparenting
+ * Toggable fullscreen and decoration mode
+ * Transparency
+ * ... and more
+ *
+ *
+ * One use case is {@link com.jogamp.newt.opengl.GLWindow}, which delegates
+ * window operation to an instance of this interface while providing OpenGL
+ * functionality.
+ *
*/
public interface Window extends NativeWindow, WindowClosingProtocol {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 44fcea49c..4db661eeb 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -43,7 +43,7 @@ public class KeyEvent extends InputEvent
this.keyChar=keyChar;
}
- /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */
+ /** Only valid on all platforms at {@link KeyListener#keyTyped(KeyEvent)} */
public char getKeyChar() {
return keyChar;
}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index f08fbc8fa..c50ab77c4 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -124,6 +124,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
this.window.setLifecycleHook(new GLLifecycleHook());
}
+ @Override
+ public final Object getUpstreamWidget() {
+ return window;
+ }
+
/**
* Creates a new GLWindow attaching a new Window referencing a
* new default Screen and default Display with the given GLCapabilities.
@@ -762,7 +767,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
System.err.println(GlueGenVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- System.err.println(JoglVersion.getDefaultOpenGLInfo(null, true).toString());
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
final GLProfile glp = GLProfile.getDefault();
final GLCapabilitiesImmutable caps = new GLCapabilities( glp );
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index 050e24b6c..be543aba9 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -34,15 +34,24 @@
package jogamp.newt;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
-public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
+public class OffscreenWindow extends WindowImpl implements MutableSurface {
long surfaceHandle = 0;
-
+ ProxySurface.UpstreamSurfaceHook upstreamHook;
+ ProxySurface dummySurface;
+
public OffscreenWindow() {
+ upstreamHook = null;
+ dummySurface = null;
}
static long nextWindowHandle = 0x100; // start here - a marker
@@ -52,6 +61,17 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
throw new NativeWindowException("Capabilities is onscreen");
}
final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ /** Cannot use OpenGL here ..
+ if(capsRequested instanceof GLCapabilitiesImmutable) {
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) capsRequested;
+ if(caps.isFBO() && GLContext.isFBOAvailable(aScreen.getDevice(), caps.getGLProfile()) ) {
+ final GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(caps);
+ final ProxySurface dummySurface = factory.createDummySurfaceImpl(aScreen.getDevice(), false, dummyCaps, null, 64, 64);
+ upstreamHook = dummySurface.getUpstreamSurfaceHook();
+ dummySurface.createNotify();
+ }
+ } */
final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, aScreen);
if (null == cfg) {
@@ -68,13 +88,14 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
// nop
}
- public void surfaceSizeChanged(int width, int height) {
- sizeChanged(false, width, height, false);
- }
-
@Override
public synchronized void destroy() {
super.destroy();
+ if(null != dummySurface) {
+ dummySurface.destroyNotify();
+ dummySurface = null;
+ upstreamHook = null;
+ }
surfaceHandle = 0;
}
@@ -84,8 +105,12 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
@Override
public long getSurfaceHandle() {
+ if(null != dummySurface) {
+ return dummySurface.getSurfaceHandle();
+ // return upstreamHook.getWidth();
+ }
return surfaceHandle;
- }
+ }
protected void requestFocusImpl(boolean reparented) {
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/MD.java b/src/newt/classes/jogamp/newt/driver/android/MD.java
index 403eae383..f2f30937b 100644
--- a/src/newt/classes/jogamp/newt/driver/android/MD.java
+++ b/src/newt/classes/jogamp/newt/driver/android/MD.java
@@ -43,7 +43,7 @@ public class MD {
.append(JoglVersion.getInstance()).append(Platform.NEWLINE)
.append(Platform.NEWLINE);
- JoglVersion.getDefaultOpenGLInfo(sb, true);
+ JoglVersion.getDefaultOpenGLInfo(null, sb, true);
return sb.toString();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index 942994c13..fcca5c843 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
@@ -50,7 +50,7 @@ import jogamp.newt.driver.DriverUpdatePosition;
import com.jogamp.newt.event.KeyEvent;
-public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus, DriverUpdatePosition {
+public class MacWindow extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
static {
MacDisplay.initSingleton();
@@ -131,10 +131,6 @@ public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverCl
}
}
- public void surfaceSizeChanged(int width, int height) {
- sizeChanged(false, width, height, false);
- }
-
@Override
protected void setTitleImpl(final String title) {
setTitle0(getWindowHandle(), title);
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index f914467af..b58b99e38 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -972,7 +972,7 @@ static jint mods2JavaMods(NSUInteger mods)
NSView* nsview = [self contentView];
if( ! [nsview isMemberOfClass:[NewtView class]] ) {
- return;
+ return NO;
}
NewtView* view = (NewtView *) nsview;
@@ -981,14 +981,14 @@ static jint mods2JavaMods(NSUInteger mods)
DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
DBG_PRINT("windowWillClose: null javaWindowObject\n");
- return;
+ return NO;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
DBG_PRINT("windowWillClose: null JNIEnv\n");
- return;
+ return NO;
}
[view setDestroyNotifySent: true]; // earmark assumption of being closed
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index a09cc76ac..b22be0a93 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -194,7 +194,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
pw.printf("%s-%03dx%03d-T%04d", objName, drawable.getWidth(), drawable.getHeight(), texSize[0]);
final String filename = dir + sw +".png";
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+ if(screenshot.readPixels(drawable.getGL(), false)) {
screenshot.write(new File(filename));
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
index a3182a30f..6378c1ee3 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java
@@ -194,7 +194,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener {
pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), texSize[0], objName);
final String filename = dir + tech + sw +".png";
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+ if(screenshot.readPixels(drawable.getGL(), false)) {
screenshot.write(new File(filename));
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
index d0093ad0c..15daf70cd 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIListenerBase01.java
@@ -180,7 +180,7 @@ public abstract class UIListenerBase01 implements GLEventListener {
pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getWidth(), drawable.getHeight(), (int)Math.abs(zoom), 0, objName);
final String filename = dir + tech + sw +".png";
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
+ if(screenshot.readPixels(drawable.getGL(), false)) {
screenshot.write(new File(filename));
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
new file mode 100644
index 000000000..1a33845b3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
@@ -0,0 +1,272 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.OffscreenAutoDrawable;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.FBOMix2DemosES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+public class TestFBODrawableNEWT extends UITestCase {
+
+ static final int widthStep = 800/4;
+ static final int heightStep = 600/4;
+ volatile int szStep = 2;
+
+ @Test
+ public void testGL2ES2_Demo1Normal() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ }
+
+ @Test
+ public void testGL2ES2_Demo1MSAA4() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ }
+
+ @Test
+ public void testGL2ES2_Demo2Normal() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ testGLFBODrawableImpl(caps, new MultisampleDemoES2(false));
+ }
+
+ @Test
+ public void testGL2ES2_Demo2MSAA4() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, new MultisampleDemoES2(true));
+ }
+
+ @Test
+ public void testGL2ES2_FBODemoNormal() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+ demo.setDoRotation(false);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ testGLFBODrawableImpl(caps, demo);
+ }
+
+ @Test
+ public void testGL2ES2_FBODemoMSAA4() throws InterruptedException {
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final FBOMix2DemosES2 demo = new FBOMix2DemosES2(0);
+ demo.setDoRotation(false);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, demo);
+ }
+
+ @Test
+ public void testEGLES2_Demo0Normal() throws InterruptedException {
+ if( GLProfile.isAvailable(GLProfile.GLES2) ) {
+ final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ } else {
+ System.err.println("EGL ES2 n/a");
+ }
+ }
+
+ @Test
+ public void testEGLES2_Demo0MSAA4() throws InterruptedException {
+ if( GLProfile.isAvailable(GLProfile.GLES2) ) {
+ final GLProfile glp = GLProfile.get(GLProfile.GLES2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ testGLFBODrawableImpl(caps, new GearsES2(0));
+ } else {
+ System.err.println("EGL ES2 n/a");
+ }
+ }
+
+ boolean skipShot = false;
+
+ void testGLFBODrawableImpl(GLCapabilities caps, GLEventListener demo) throws InterruptedException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
+ caps.setFBO(true);
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile());
+ final GLDrawable fboDrawable = factory.createOffscreenDrawable(null, caps, null, widthStep*szStep, heightStep*szStep);
+ Assert.assertNotNull(fboDrawable);
+ Assert.assertTrue("Not an FBO Drawable", fboDrawable instanceof GLFBODrawableImpl);
+
+ fboDrawable.setRealized(true);
+ Assert.assertTrue(fboDrawable.isRealized());
+
+ final FBObject fbo = ((GLFBODrawableImpl)fboDrawable).getFBObject();
+
+ System.out.println("Realized: "+fboDrawable);
+ System.out.println("Realized: "+fboDrawable.getChosenGLCapabilities());
+ System.out.println("Realized: "+fbo);
+
+ final GLContext context = fboDrawable.createContext(null);
+ Assert.assertNotNull(context);
+
+ int res = context.makeCurrent();
+ Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+ context.release();
+
+ System.out.println("Post Create-Ctx: "+fbo);
+ final FBObject.Colorbuffer colorA = fbo.getColorbuffer(0);
+ Assert.assertNotNull(colorA);
+ final FBObject.RenderAttachment depthA = fbo.getDepthAttachment();
+ Assert.assertNotNull(depthA);
+
+ final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, null);
+
+ glad.addGLEventListener(demo);
+ glad.addGLEventListener(new GLEventListener() {
+ volatile int displayCount=0;
+ volatile int reshapeCount=0;
+ public void init(GLAutoDrawable drawable) {}
+ public void dispose(GLAutoDrawable drawable) {}
+ public void display(GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ // System.err.println(Thread.currentThread().getName()+": ** display: "+displayCount+": step "+szStep+" "+drawable.getWidth()+"x"+drawable.getHeight());
+ // System.err.println(Thread.currentThread().getName()+": ** FBO-THIS: "+fbo);
+ // System.err.println(Thread.currentThread().getName()+": ** FBO-SINK: "+fbo.getSamplingSinkFBO());
+ // System.err.println(Thread.currentThread().getName()+": ** drawable-read: "+gl.getDefaultReadFramebuffer());
+ if(skipShot) {
+ skipShot=false;
+ } else {
+ snapshot(getSimpleTestName("."), displayCount, "msaa"+fbo.getNumSamples(), gl, screenshot, TextureIO.PNG, null);
+ }
+ Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
+ Assert.assertEquals(drawable.getHeight(), heightStep*szStep);
+ displayCount++;
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ System.err.println(Thread.currentThread().getName()+": ** reshape: "+reshapeCount+": step "+szStep+" "+width+"x"+height+" - "+drawable.getWidth()+"x"+drawable.getHeight());
+ Assert.assertEquals(drawable.getWidth(), widthStep*szStep);
+ Assert.assertEquals(drawable.getHeight(), heightStep*szStep);
+ reshapeCount++;
+ }
+ });
+
+ // 0 - szStep = 2
+ glad.display();
+
+ // 1, 2 (resize + display)
+ szStep = 1;
+ skipShot=true;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ glad.display();
+ Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+ Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+ {
+ // Check whether the attachment reference are still valid!
+ FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
+ Assert.assertNotNull(_colorA);
+ Assert.assertTrue(colorA == _colorA);
+ Assert.assertTrue(colorA.equals(_colorA));
+ FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
+ Assert.assertNotNull(_depthA);
+ Assert.assertTrue(depthA == _depthA);
+ Assert.assertTrue(depthA.equals(_depthA));
+
+ _colorA = fbo.getColorbuffer(colorA);
+ Assert.assertNotNull(_colorA);
+ Assert.assertTrue(colorA == _colorA);
+ Assert.assertTrue(colorA.equals(_colorA));
+ }
+
+ // 3, 4 (resize + display)
+ szStep = 4;
+ skipShot=true;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ glad.display();
+ Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+ Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+ {
+ // Check whether the attachment reference are still valid!
+ FBObject.Colorbuffer _colorA = fbo.getColorbuffer(0);
+ Assert.assertNotNull(_colorA);
+ Assert.assertTrue(colorA == _colorA);
+ final FBObject.RenderAttachment _depthA = fbo.getDepthAttachment();
+ Assert.assertNotNull(_depthA);
+ Assert.assertTrue(depthA == _depthA);
+
+ _colorA = fbo.getColorbuffer(colorA);
+ Assert.assertNotNull(_colorA);
+ Assert.assertTrue(colorA == _colorA);
+ }
+
+ // 5
+ glad.display();
+ Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+ Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+
+ // 6, 7 (resize + display)
+ szStep = 3;
+ skipShot=true;
+ glad.setSize(widthStep*szStep, heightStep*szStep);
+ glad.display();
+ Assert.assertEquals(glad.getWidth(), widthStep*szStep);
+ Assert.assertEquals(glad.getHeight(), heightStep*szStep);
+
+ glad.destroy();
+ System.out.println("Fin: "+fboDrawable);
+
+ // final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(fboDrawable, context);
+ }
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestFBODrawableNEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
new file mode 100644
index 000000000..f7c83a03b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOMRTNEWT01.java
@@ -0,0 +1,266 @@
+/**
+ * Copyright 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.FBObject.Attachment.Type;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.NEWTGLContext;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLPipelineFactory;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLUniformData;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestFBOMRTNEWT01 extends UITestCase {
+ static long durationPerTest = 10*40*2; // ms
+
+ @Test
+ public void test01() throws InterruptedException {
+ final int step = 4;
+ final int width = 800;
+ final int height = 600;
+ // preset ..
+ if(!GLProfile.isAvailable(GLProfile.GL2GL3)) {
+ System.err.println("Test requires GL2/GL3 profile.");
+ return;
+ }
+ final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(
+ new GLCapabilities(GLProfile.getGL2GL3()), width/step, height/step, true);
+ final GLDrawable drawable = winctx.context.getGLDrawable();
+ GL2GL3 gl = winctx.context.getGL().getGL2GL3();
+ gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", null, gl, null) ).getGL2GL3();
+ System.err.println(winctx.context);
+
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+ // test code ..
+ final ShaderState st = new ShaderState();
+ // st.setVerbose(true);
+
+ final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "fbo-mrt-1", false);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "fbo-mrt-1", false);
+ final ShaderProgram sp0 = new ShaderProgram();
+ sp0.add(gl, vp0, System.err);
+ sp0.add(gl, fp0, System.err);
+ Assert.assertTrue(0<=sp0.program());
+ Assert.assertTrue(!sp0.inUse());
+ Assert.assertTrue(!sp0.linked());
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+ st.attachShaderProgram(gl, sp0, false);
+
+ final ShaderCode vp1 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "fbo-mrt-2", false);
+ final ShaderCode fp1 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquareES2.class, "shader",
+ "shader/bin", "fbo-mrt-2", false);
+ final ShaderProgram sp1 = new ShaderProgram();
+ sp1.add(gl, vp1, System.err);
+ sp1.add(gl, fp1, System.err);
+ Assert.assertTrue(0<=sp1.program());
+ Assert.assertTrue(!sp1.inUse());
+ Assert.assertTrue(!sp1.linked());
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+ st.attachShaderProgram(gl, sp1, true);
+
+ final PMVMatrix pmvMatrix = new PMVMatrix();
+ final GLUniformData pmvMatrixUniform = new GLUniformData("gcu_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ final GLArrayDataServer vertices0 = GLArrayDataServer.createGLSL("gca_Vertices", 3, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ // st.bindAttribLocation(gl, 0, vertices0);
+ vertices0.putf(0); vertices0.putf(1); vertices0.putf(0);
+ vertices0.putf(1); vertices0.putf(1); vertices0.putf(0);
+ vertices0.putf(0); vertices0.putf(0); vertices0.putf(0);
+ vertices0.putf(1); vertices0.putf(0); vertices0.putf(0);
+ vertices0.seal(gl, true);
+ st.ownAttribute(vertices0, true);
+ vertices0.enableBuffer(gl, false);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ final GLArrayDataServer colors0 = GLArrayDataServer.createGLSL("gca_Colors", 4, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ // st.bindAttribLocation(gl, 1, colors0);
+ colors0.putf(1); colors0.putf(0); colors0.putf(1); colors0.putf(1);
+ colors0.putf(0); colors0.putf(0); colors0.putf(1); colors0.putf(1);
+ colors0.putf(0); colors0.putf(0); colors0.putf(0); colors0.putf(1);
+ colors0.putf(0); colors0.putf(1); colors0.putf(1); colors0.putf(1);
+ colors0.seal(gl, true);
+ st.ownAttribute(colors0, true);
+ colors0.enableBuffer(gl, false);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ final GLUniformData texUnit0 = new GLUniformData("gcs_TexUnit0", 0);
+ st.ownUniform(texUnit0);
+ st.uniform(gl, texUnit0);
+ final GLUniformData texUnit1 = new GLUniformData("gcs_TexUnit1", 1);
+ st.ownUniform(texUnit1);
+ st.uniform(gl, texUnit1);
+
+ final GLArrayDataServer texCoords0 = GLArrayDataServer.createGLSL("gca_TexCoords", 2, GL.GL_FLOAT, false, 4, GL.GL_STATIC_DRAW);
+ // st.bindAttribLocation(gl, 2, texCoords0);
+ texCoords0.putf(0f); texCoords0.putf(1f);
+ texCoords0.putf(1f); texCoords0.putf(1f);
+ texCoords0.putf(0f); texCoords0.putf(0f);
+ texCoords0.putf(1f); texCoords0.putf(0f);
+ texCoords0.seal(gl, true);
+ st.ownAttribute(texCoords0, true);
+ texCoords0.enableBuffer(gl, false);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ final int texA0Point = 0; // attachment point for texA0
+ final int texA1Point = 1; // attachment point for texA1
+
+ // FBO w/ 2 texture2D color buffers
+ final FBObject fbo_mrt = new FBObject();
+ fbo_mrt.reset(gl, drawable.getWidth(), drawable.getHeight());
+ final TextureAttachment texA0 = fbo_mrt.attachTexture2D(gl, texA0Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ final TextureAttachment texA1 = fbo_mrt.attachTexture2D(gl, texA1Point, true, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ fbo_mrt.attachRenderbuffer(gl, Type.DEPTH, 24);
+ Assert.assertTrue( fbo_mrt.isStatusValid() ) ;
+ fbo_mrt.unbind(gl);
+
+ // misc GL setup
+ gl.glClearColor(1, 1, 1, 1);
+ gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ // reshape
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glOrthof(0f, 1f, 0f, 1f, -10f, 10f);
+ pmvMatrix.glMatrixMode(PMVMatrix.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+ st.uniform(gl, pmvMatrixUniform);
+ Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
+
+ final int[] two_buffers = new int[] { GL.GL_COLOR_ATTACHMENT0+texA0Point, GL.GL_COLOR_ATTACHMENT0+texA1Point };
+ final int[] bck_buffers = new int[] { GL2GL3.GL_BACK_LEFT };
+
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ int step_i = 0;
+ int[] last_snap_size = new int[] { 0, 0 };
+
+ for(int i=0; i buffer0, Green -> buffer1
+ st.attachShaderProgram(gl, sp0, true);
+ vertices0.enableBuffer(gl, true);
+ colors0.enableBuffer(gl, true);
+
+ fbo_mrt.bind(gl);
+ gl.glDrawBuffers(2, two_buffers, 0);
+ gl.glViewport(0, 0, fbo_mrt.getWidth(), fbo_mrt.getHeight());
+
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+ fbo_mrt.unbind(gl);
+ vertices0.enableBuffer(gl, false);
+ colors0.enableBuffer(gl, false);
+
+ // pass 2 - mix buffer0, buffer1 and blue
+ // rg = buffer0.rg + buffer1.rg, b = Blue - length(rg);
+ st.attachShaderProgram(gl, sp1, true);
+ vertices0.enableBuffer(gl, true);
+ colors0.enableBuffer(gl, true);
+ texCoords0.enableBuffer(gl, true);
+ gl.glDrawBuffers(1, bck_buffers, 0);
+
+ gl.glViewport(0, 0, drawable.getWidth(), drawable.getHeight());
+
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ fbo_mrt.use(gl, texA0);
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+ fbo_mrt.use(gl, texA1);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+ fbo_mrt.unuse(gl);
+ vertices0.enableBuffer(gl, false);
+ colors0.enableBuffer(gl, false);
+ texCoords0.enableBuffer(gl, false);
+
+ {
+ final NativeSurface ns = gl.getContext().getGLReadDrawable().getNativeSurface();
+ if(last_snap_size[0] != ns.getWidth() && last_snap_size[1] != ns.getHeight()) {
+ gl.glFinish(); // sync .. no swap buffers yet!
+ snapshot(getSimpleTestName("."), step_i, null, gl, screenshot, TextureIO.PNG, null); // overwrite ok
+ last_snap_size[0] = ns.getWidth();
+ last_snap_size[1] = ns.getHeight();
+ }
+ }
+
+ drawable.swapBuffers();
+ Thread.sleep(50);
+ int j = (int) ( (long)i / (durationPerTest/(long)step) ) + 1;
+ if(j>step_i) {
+ int w = width/step * j;
+ int h = height/step * j;
+ System.err.println("resize: "+step_i+" -> "+j+" - "+w+"x"+h);
+ fbo_mrt.reset(gl, w, h);
+ winctx.window.setSize(w, h);
+ step_i = j;
+ }
+ }
+
+ NEWTGLContext.destroyWindow(winctx);
+ }
+
+ public static void main(String args[]) throws IOException {
+ System.err.println("main - start");
+ for(int i=0; i "+num);
+ demo.setMSAA(num);
+ }
+ }
+ }
+ });
+
+ animator.start();
+ // glWindow.setSkipContextReleaseThread(animator.getThread());
+
+ glWindow.setVisible(true);
+
+ System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities());
+ System.err.println("GL chosen: "+glWindow.getChosenCapabilities());
+ System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
+
+ animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()= 0; i--) {
- immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)),
- (float) (radius * Math.sin(i * increment)),
- 0f);
- immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)),
- (float) (-1.0 * radius * Math.sin(i * increment)),
- 0f);
- }
- immModeSink.glEnd(gl, false);
- }
-
- public void dispose(GLAutoDrawable drawable) {
- immModeSink.destroy(drawable.getGL());
- immModeSink = null;
- }
-
- public void display(GLAutoDrawable drawable) {
- GL2ES1 gl = drawable.getGL().getGL2ES1();
- if (multisample) {
- gl.glEnable(GL.GL_MULTISAMPLE);
- }
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- immModeSink.draw(gl, true);
- if (multisample) {
- gl.glDisable(GL.GL_MULTISAMPLE);
- }
- }
-
- // Unused routines
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- }
-
- public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
- }
-}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
index 4b0caf898..478bd4543 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1AWT.java
@@ -40,7 +40,6 @@
package com.jogamp.opengl.test.junit.jogl.caps;
-import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.awt.BorderLayout;
import java.awt.Frame;
@@ -48,14 +47,15 @@ import java.awt.Frame;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
-import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.MultisampleDemoES1;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
import org.junit.Test;
@@ -75,13 +75,6 @@ public class TestMultisampleES1AWT extends UITestCase {
org.junit.runner.JUnitCore.main(tstname);
}
- protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
- screenshot.write(new File(filename));
- }
- }
-
@Test
public void testOnscreenMultiSampleAA0() throws InterruptedException, InvocationTargetException {
testMultiSampleAAImpl(0);
@@ -98,6 +91,7 @@ public class TestMultisampleES1AWT extends UITestCase {
}
private void testMultiSampleAAImpl(int reqSamples) throws InterruptedException, InvocationTargetException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
GLProfile glp = GLProfile.getMaxFixedFunc(true);
GLCapabilities caps = new GLCapabilities(glp);
GLCapabilitiesChooser chooser = new MultisampleChooser01();
@@ -110,14 +104,11 @@ public class TestMultisampleES1AWT extends UITestCase {
canvas = new GLCanvas(caps, chooser, null, null);
canvas.addGLEventListener(new MultisampleDemoES1(reqSamples>0?true:false));
canvas.addGLEventListener(new GLEventListener() {
+ int displayCount = 0;
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
- final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
- final String aaext = caps.getSampleExtension();
- final int samples = caps.getSampleBuffers() ? caps.getNumSamples() : 0 ;
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-S"+samples+"-"+aaext+"-"+drawable.getGLProfile().getName()+".png");
+ snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
index 2e47b6841..ed8e2bd85 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES1NEWT.java
@@ -40,21 +40,20 @@
package com.jogamp.opengl.test.junit.jogl.caps;
-import java.io.File;
-
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
-import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import org.junit.Test;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es1.MultisampleDemoES1;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
public class TestMultisampleES1NEWT extends UITestCase {
static long durationPerTest = 60; // ms
@@ -71,13 +70,6 @@ public class TestMultisampleES1NEWT extends UITestCase {
org.junit.runner.JUnitCore.main(tstname);
}
- protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
- screenshot.write(new File(filename));
- }
- }
-
@Test
public void testOnscreenMultiSampleAA0() throws InterruptedException {
testMultiSampleAAImpl(true, 0);
@@ -119,6 +111,7 @@ public class TestMultisampleES1NEWT extends UITestCase {
}
private void testMultiSampleAAImpl(boolean onscreen, int reqSamples) throws InterruptedException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
GLProfile glp = GLProfile.getMaxFixedFunc(true);
GLCapabilities caps = new GLCapabilities(glp);
GLCapabilitiesChooser chooser = new MultisampleChooser01();
@@ -136,14 +129,11 @@ public class TestMultisampleES1NEWT extends UITestCase {
window.setCapabilitiesChooser(chooser);
window.addGLEventListener(new MultisampleDemoES1(reqSamples>0?true:false));
window.addGLEventListener(new GLEventListener() {
+ int displayCount = 0;
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
- final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
- final String aaext = caps.getSampleExtension();
- final int samples = caps.getSampleBuffers() ? caps.getNumSamples() : 0 ;
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-S"+samples+"-"+aaext+"-"+drawable.getGLProfile().getName()+".png");
+ snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
new file mode 100644
index 000000000..b2dad1f39
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
@@ -0,0 +1,143 @@
+/*
+ * 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 com.jogamp.opengl.test.junit.jogl.caps;
+
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.MultisampleDemoES2;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+public class TestMultisampleES2NEWT extends UITestCase {
+ static long durationPerTest = 60; // ms
+ private GLWindow window;
+
+ public static void main(String[] args) {
+ for(int i=0; i0) {
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(reqSamples);
+ }
+
+ window = GLWindow.create(caps);
+ window.setCapabilitiesChooser(chooser);
+ window.addGLEventListener(new MultisampleDemoES2(reqSamples>0?true:false));
+ window.addGLEventListener(new GLEventListener() {
+ int displayCount = 0;
+ public void init(GLAutoDrawable drawable) {}
+ public void dispose(GLAutoDrawable drawable) {}
+ public void display(GLAutoDrawable drawable) {
+ snapshot(getSimpleTestName("."), displayCount++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ });
+ window.setSize(512, 512);
+ window.setVisible(true);
+ window.requestFocus();
+
+ Thread.sleep(durationPerTest);
+
+ window.destroy();
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 5c82a43c6..e81d1b4af 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -129,12 +129,13 @@ public class GearsES1 implements GLEventListener {
gl.glEnable(GL2ES1.GL_NORMALIZE);
- if (drawable.getNativeSurface() instanceof Window) {
- Window window = (Window) drawable.getNativeSurface();
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.addMouseListener(gearsMouse);
window.addKeyListener(gearsKeys);
- } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
- java.awt.Component comp = (java.awt.Component) drawable;
+ } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+ final java.awt.Component comp = (java.awt.Component) upstreamWidget;
new com.jogamp.newt.event.awt.AWTMouseAdapter(gearsMouse).addTo(comp);
new com.jogamp.newt.event.awt.AWTKeyAdapter(gearsKeys).addTo(comp);
}
@@ -165,8 +166,9 @@ public class GearsES1 implements GLEventListener {
public void dispose(GLAutoDrawable drawable) {
System.err.println(Thread.currentThread()+" GearsES1.dispose ... ");
- if (drawable.getNativeSurface() instanceof Window) {
- Window window = (Window) drawable.getNativeSurface();
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.removeMouseListener(gearsMouse);
window.removeKeyListener(gearsKeys);
}
@@ -188,8 +190,9 @@ public class GearsES1 implements GLEventListener {
GL2ES1 gl = drawable.getGL().getGL2ES1();
final boolean hasFocus;
- if(drawable.getNativeSurface() instanceof NativeWindow) {
- hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if(upstreamWidget instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)upstreamWidget).hasFocus();
} else {
hasFocus = true;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
new file mode 100644
index 000000000..aad56581b
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/MultisampleDemoES1.java
@@ -0,0 +1,123 @@
+/*
+ * 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 com.jogamp.opengl.test.junit.jogl.demos.es1;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES1;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+
+import com.jogamp.opengl.util.ImmModeSink;
+
+public class MultisampleDemoES1 implements GLEventListener {
+
+ boolean multisample;
+ ImmModeSink immModeSink;
+
+ public MultisampleDemoES1(boolean multisample) {
+ this.multisample = multisample;
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ System.err.println();
+ System.err.println("Requested: " + drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
+ System.err.println();
+ System.err.println("Chosen : " + drawable.getChosenGLCapabilities());
+ System.err.println();
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+ if (multisample) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+ gl.glClearColor(0, 0, 0, 0);
+ // gl.glEnable(GL.GL_DEPTH_TEST);
+ // gl.glDepthFunc(GL.GL_LESS);
+ gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glMatrixMode(GL2ES1.GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glOrtho(-1, 1, -1, 1, -1, 1);
+ if (multisample) {
+ gl.glDisable(GL.GL_MULTISAMPLE);
+ }
+ immModeSink = ImmModeSink.createFixed(gl, GL.GL_STATIC_DRAW, 40,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT,// normal
+ 0, GL.GL_FLOAT); // texture
+ final int numSteps = 20;
+ final double increment = Math.PI / numSteps;
+ final double radius = 1;
+ immModeSink.glBegin(GL.GL_LINES);
+ for (int i = numSteps - 1; i >= 0; i--) {
+ immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)),
+ (float) (radius * Math.sin(i * increment)),
+ 0f);
+ immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)),
+ (float) (-1.0 * radius * Math.sin(i * increment)),
+ 0f);
+ }
+ immModeSink.glEnd(gl, false);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ immModeSink.destroy(drawable.getGL());
+ immModeSink = null;
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ GL2ES1 gl = drawable.getGL().getGL2ES1();
+ if (multisample) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ immModeSink.draw(gl, true);
+ if (multisample) {
+ gl.glDisable(GL.GL_MULTISAMPLE);
+ }
+ }
+
+ // Unused routines
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
new file mode 100644
index 000000000..3dfbb4893
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/FBOMix2DemosES2.java
@@ -0,0 +1,309 @@
+/**
+ * Copyright (C) 2011 JogAmp Community. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.FBObject.Attachment.Type;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class FBOMix2DemosES2 implements GLEventListener {
+ private final GearsES2 demo0;
+ private final RedSquareES2 demo1;
+ private final int swapInterval;
+ private int numSamples;
+ private boolean demo0Only;
+
+
+ private final ShaderState st;
+ private final PMVMatrix pmvMatrix;
+
+ private final FBObject fbo0;
+ private final FBObject fbo1;
+
+ private TextureAttachment fbo0Tex;
+ private TextureAttachment fbo1Tex;
+
+ private ShaderProgram sp0;
+ private GLUniformData pmvMatrixUniform;
+ private GLArrayDataServer interleavedVBO;
+ private GLUniformData texUnit0;
+ private GLUniformData texUnit1;
+
+ public FBOMix2DemosES2(int swapInterval) {
+ demo0 = new GearsES2(-1);
+ demo0.setIsFBOSlave(true);
+ demo1 = new RedSquareES2(-1);
+ demo1.setIsFBOSlave(true);
+ this.swapInterval = swapInterval;
+
+ st = new ShaderState();
+ // st.setVerbose(true);
+ pmvMatrix = new PMVMatrix();
+
+ fbo0 = new FBObject();
+ fbo1 = new FBObject();
+
+ numSamples = 0;
+ demo0Only = false;
+ }
+
+ public void setDemo0Only(boolean v) {
+ this.demo0Only = v;
+ }
+ public boolean getDemo0Only() { return demo0Only; }
+
+ public void setMSAA(int numSamples) {
+ this.numSamples=numSamples;
+ }
+ public int getMSAA() { return numSamples; }
+
+ public void setDoRotation(boolean rotate) { demo1.setDoRotation(rotate); }
+
+ static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
+ static final String gl2_prelude = "#version 110\n";
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ demo0.init(drawable);
+ demo1.init(drawable);
+
+ final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, FBOMix2DemosES2.class, "shader",
+ "shader/bin", "texture01_xxx", true);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, FBOMix2DemosES2.class, "shader",
+ "shader/bin", "texture02_xxx", true);
+
+ // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
+ int fp0Pos;
+ if(gl.isGLES2()) {
+ vp0.insertShaderSource(0, 0, es2_prelude[0]);
+ fp0Pos = fp0.insertShaderSource(0, 0, es2_prelude[0]);
+ } else {
+ vp0.insertShaderSource(0, 0, gl2_prelude);
+ fp0Pos = fp0.insertShaderSource(0, 0, gl2_prelude);
+ }
+ if(gl.isGLES2()) {
+ fp0Pos = fp0.insertShaderSource(0, fp0Pos, es2_prelude[1]);
+ }
+
+ sp0 = new ShaderProgram();
+ sp0.add(gl, vp0, System.err);
+ sp0.add(gl, fp0, System.err);
+ st.attachShaderProgram(gl, sp0, true);
+
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+
+ interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
+ {
+ interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
+ //interleavedVBO.addGLSLSubArray("mgl_Normal", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+
+ FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
+
+ for(int i=0; i<4; i++) {
+ ib.put(s_quadVertices, i*3, 3);
+ ib.put(s_quadColors, i*4, 4);
+ //ib.put(s_cubeNormals, i*3, 3);
+ ib.put(s_quadTexCoords, i*2, 2);
+ }
+ }
+ interleavedVBO.seal(gl, true);
+ interleavedVBO.enableBuffer(gl, false);
+ st.ownAttribute(interleavedVBO, true);
+
+ texUnit0 = new GLUniformData("mgl_Texture0", 0);
+ st.ownUniform(texUnit0);
+ st.uniform(gl, texUnit0);
+ texUnit1 = new GLUniformData("mgl_Texture1", 1);
+ st.ownUniform(texUnit1);
+ st.uniform(gl, texUnit1);
+
+ st.useProgram(gl, false);
+
+ System.err.println("**** Init");
+ resetFBOs(gl, drawable);
+
+ fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
+ fbo0.unbind(gl);
+ fbo1.attachRenderbuffer(gl, Type.DEPTH, 24);
+ fbo1.unbind(gl);
+ gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+
+ numSamples=fbo0.getNumSamples();
+ }
+
+ /** Since we switch MSAA and non-MSAA we need to take extra care, i.e. sync msaa for both FBOs ..*/
+ private void resetFBOs(GL gl, GLAutoDrawable drawable) {
+ // remove all texture attachments, since MSAA uses just color-render-buffer
+ // and non-MSAA uses texture2d-buffer
+ fbo0.detachAllColorbuffer(gl);
+ fbo1.detachAllColorbuffer(gl);
+
+ fbo0.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+ fbo1.reset(gl, drawable.getWidth(), drawable.getHeight(), numSamples);
+ if(fbo0.getNumSamples() != fbo1.getNumSamples()) {
+ throw new InternalError("sample size mismatch: \n\t0: "+fbo0+"\n\t1: "+fbo1);
+ }
+ numSamples = fbo0.getNumSamples();
+
+ if(numSamples>0) {
+ fbo0.attachColorbuffer(gl, 0, true);
+ fbo1.attachColorbuffer(gl, 0, true);
+ fbo0Tex = fbo0.getSamplingSink();
+ fbo1Tex = fbo1.getSamplingSink();
+ } else {
+ fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
+ fbo1Tex = fbo1.attachTexture2D(gl, 0, true);
+ }
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ demo0.dispose(drawable);
+ demo1.dispose(drawable);
+ fbo0.destroy(gl);
+ fbo1.destroy(gl);
+ st.destroy(gl);
+
+ fbo0Tex = null;
+ fbo1Tex = null;
+ sp0 = null;
+ pmvMatrixUniform = null;
+ interleavedVBO = null;
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if( fbo0.getNumSamples() != numSamples ) {
+ System.err.println("**** NumSamples: "+fbo0.getNumSamples()+" -> "+numSamples);
+ resetFBOs(gl, drawable);
+ }
+
+ if(0 < numSamples) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+
+ fbo0.bind(gl);
+ demo0.display(drawable);
+ fbo0.unbind(gl);
+
+ if(!demo0Only) {
+ fbo1.bind(gl);
+ demo1.display(drawable);
+ fbo1.unbind(gl);
+ }
+
+ st.useProgram(gl, true);
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ fbo0.use(gl, fbo0Tex);
+ if(!demo0Only) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit1.intValue());
+ fbo1.use(gl, fbo1Tex);
+ }
+ interleavedVBO.enableBuffer(gl, true);
+
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+
+ interleavedVBO.enableBuffer(gl, false);
+ fbo0.unuse(gl);
+ if(!demo0Only) {
+ fbo1.unuse(gl);
+ }
+
+ st.useProgram(gl, false);
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
+
+ // if(drawable.getWidth() == fbo0.getWidth() && drawable.getHeight() == fbo0.getHeight() ) {
+ System.err.println("**** Reshape: "+width+"x"+height);
+ resetFBOs(gl, drawable);
+ //}
+
+ fbo0.bind(gl);
+ demo0.reshape(drawable, x, y, width, height);
+ fbo0.unbind(gl);
+ fbo1.bind(gl);
+ demo1.reshape(drawable, x, y, width, height);
+ fbo1.unbind(gl);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+
+ }
+
+ private static final float[] s_quadVertices = {
+ -1f, -1f, 0f, // LB
+ 1f, -1f, 0f, // RB
+ -1f, 1f, 0f, // LT
+ 1f, 1f, 0f // RT
+ };
+ private static final float[] s_quadColors = {
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f };
+ private static final float[] s_quadTexCoords = {
+ 0f, 0f, // LB
+ 1f, 0f, // RB
+ 0f, 1f, // LT
+ 1f, 1f // RT
+ };
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 6aea5bb9c..38e8a15ce 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -65,6 +65,7 @@ public class GearsES2 implements GLEventListener {
private int prevMouseX, prevMouseY;
private boolean isInitialized = false;
+ boolean isFBOSlave = false;
public GearsES2(int swapInterval) {
this.swapInterval = swapInterval;
@@ -74,6 +75,8 @@ public class GearsES2 implements GLEventListener {
this.swapInterval = 1;
}
+ public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
+
public void setPMVUseBackingArray(boolean pmvUseBackingArray) {
this.pmvUseBackingArray = pmvUseBackingArray;
}
@@ -115,7 +118,6 @@ public class GearsES2 implements GLEventListener {
System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
- gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_DEPTH_TEST);
st = new ShaderState();
@@ -168,13 +170,14 @@ public class GearsES2 implements GLEventListener {
gear3 = new GearsObjectES2(gear3, pmvMatrix, pmvMatrixUniform, colorU);
System.err.println("gear3 reused: "+gear3);
}
-
- if (drawable.getNativeSurface() instanceof Window) {
- Window window = (Window) drawable.getNativeSurface();
+
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.addMouseListener(gearsMouse);
window.addKeyListener(gearsKeys);
- } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
- java.awt.Component comp = (java.awt.Component) drawable;
+ } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+ final java.awt.Component comp = (java.awt.Component) upstreamWidget;
new com.jogamp.newt.event.awt.AWTMouseAdapter(gearsMouse).addTo(comp);
new com.jogamp.newt.event.awt.AWTKeyAdapter(gearsKeys).addTo(comp);
}
@@ -187,7 +190,9 @@ public class GearsES2 implements GLEventListener {
System.err.println(Thread.currentThread()+" GearsES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
st.useProgram(gl, true);
pmvMatrix.glMatrixMode(PMVMatrix.GL_PROJECTION);
@@ -218,8 +223,9 @@ public class GearsES2 implements GLEventListener {
}
isInitialized = false;
System.err.println(Thread.currentThread()+" GearsES2.dispose ... ");
- if (drawable.getNativeSurface() instanceof Window) {
- Window window = (Window) drawable.getNativeSurface();
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.removeMouseListener(gearsMouse);
window.removeKeyListener(gearsKeys);
}
@@ -235,6 +241,7 @@ public class GearsES2 implements GLEventListener {
colorU = null;
st.destroy(gl);
st = null;
+
System.err.println(Thread.currentThread()+" GearsES2.dispose FIN");
}
@@ -246,12 +253,16 @@ public class GearsES2 implements GLEventListener {
GL2ES2 gl = drawable.getGL().getGL2ES2();
final boolean hasFocus;
- if(drawable.getNativeSurface() instanceof NativeWindow) {
- hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if(upstreamWidget instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)upstreamWidget).hasFocus();
} else {
hasFocus = true;
}
- if(hasFocus) {
+
+ gl.glEnable(GL.GL_CULL_FACE);
+
+ if( isFBOSlave || hasFocus ) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
} else {
gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
@@ -278,7 +289,9 @@ public class GearsES2 implements GLEventListener {
gear2.draw(gl, 3.1f, -2.0f, -2f * angle - 9.0f, GearsObject.green);
gear3.draw(gl, -3.1f, 4.2f, -2f * angle - 25.0f, GearsObject.blue);
pmvMatrix.glPopMatrix();
- st.useProgram(gl, false);
+ st.useProgram(gl, false);
+
+ gl.glDisable(GL.GL_CULL_FACE);
}
boolean confinedFixedCenter = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
new file mode 100644
index 000000000..5facc1a49
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/MultisampleDemoES2.java
@@ -0,0 +1,178 @@
+/*
+ * 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 com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.util.ImmModeSink;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class MultisampleDemoES2 implements GLEventListener {
+
+ private boolean multisample;
+ private final ShaderState st;
+ private final PMVMatrix pmvMatrix;
+ private ShaderProgram sp0;
+ private GLUniformData pmvMatrixUniform;
+ private ImmModeSink immModeSink;
+
+ public MultisampleDemoES2(boolean multisample) {
+ this.multisample = multisample;
+ st = new ShaderState();
+ st.setVerbose(true);
+ pmvMatrix = new PMVMatrix();
+ }
+
+ static final String[] es2_prelude = { "#version 100\n", "precision mediump float;\n" };
+ static final String gl2_prelude = "#version 110\n";
+
+ public void init(GLAutoDrawable glad) {
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ System.err.println();
+ System.err.println("Requested: " + glad.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
+ System.err.println();
+ System.err.println("Chosen : " + glad.getChosenGLCapabilities());
+ System.err.println();
+
+ final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MultisampleDemoES2.class, "shader",
+ "shader/bin", "mgl_default_xxx", true);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MultisampleDemoES2.class, "shader",
+ "shader/bin", "mgl_default_xxx", true);
+
+ // Prelude shader code w/ GLSL profile specifics [ 1. pre-proc, 2. other ]
+ int fp0Pos;
+ if(gl.isGLES2()) {
+ vp0.insertShaderSource(0, 0, es2_prelude[0]);
+ fp0Pos = fp0.insertShaderSource(0, 0, es2_prelude[0]);
+ } else {
+ vp0.insertShaderSource(0, 0, gl2_prelude);
+ fp0Pos = fp0.insertShaderSource(0, 0, gl2_prelude);
+ }
+ if(gl.isGLES2()) {
+ fp0Pos = fp0.insertShaderSource(0, fp0Pos, es2_prelude[1]);
+ }
+
+ sp0 = new ShaderProgram();
+ sp0.add(gl, vp0, System.err);
+ sp0.add(gl, fp0, System.err);
+ st.attachShaderProgram(gl, sp0, true);
+
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+
+ // Using predef array names, see
+ // GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex);
+ immModeSink = ImmModeSink.createGLSL(gl, GL.GL_STATIC_DRAW, 40,
+ 3, GL.GL_FLOAT, // vertex
+ 4, GL.GL_FLOAT, // color
+ 0, GL.GL_FLOAT,// normal
+ 0, GL.GL_FLOAT); // texture
+ final int numSteps = 20;
+ final double increment = Math.PI / numSteps;
+ final double radius = 1;
+ immModeSink.glBegin(GL.GL_LINES);
+ for (int i = numSteps - 1; i >= 0; i--) {
+ immModeSink.glVertex3f((float) (radius * Math.cos(i * increment)),
+ (float) (radius * Math.sin(i * increment)),
+ 0f);
+ immModeSink.glColor4f( 1f, 1f, 1f, 1f );
+ immModeSink.glVertex3f((float) (-1.0 * radius * Math.cos(i * increment)),
+ (float) (-1.0 * radius * Math.sin(i * increment)),
+ 0f);
+ immModeSink.glColor4f( 1f, 1f, 1f, 1f );
+ }
+ immModeSink.glEnd(gl, false);
+
+ st.useProgram(gl, false);
+ }
+
+ public void dispose(GLAutoDrawable glad) {
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ immModeSink.destroy(gl);
+ immModeSink = null;
+ st.destroy(gl);
+ }
+
+ public void display(GLAutoDrawable glad) {
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ if (multisample) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+ gl.glClearColor(0, 0, 0, 0);
+ // gl.glEnable(GL.GL_DEPTH_TEST);
+ // gl.glDepthFunc(GL.GL_LESS);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ st.useProgram(gl, true);
+
+ immModeSink.draw(gl, true);
+
+ st.useProgram(gl, false);
+ }
+
+ // Unused routines
+ public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
+ System.err.println("reshape ..");
+ final GL2ES2 gl = glad.getGL().getGL2ES2();
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ // pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
+ pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index 6982d61b7..436c44759 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -27,9 +27,9 @@
*/
package com.jogamp.opengl.test.junit.jogl.demos.es2;
+import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
-import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
@@ -37,10 +37,8 @@ import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
-import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLRunnable;
import javax.media.opengl.GLUniformData;
public class RedSquareES2 implements GLEventListener {
@@ -52,10 +50,11 @@ public class RedSquareES2 implements GLEventListener {
long t0;
private int swapInterval = 0;
MyMouseAdapter myMouse = new MyMouseAdapter();
- GLWindow glWindow = null;
+ Window window = null;
float aspect = 1.0f;
boolean doRotate = true;
boolean isInitialized = false;
+ boolean isFBOSlave = false;
public RedSquareES2(int swapInterval) {
this.swapInterval = swapInterval;
@@ -65,6 +64,7 @@ public class RedSquareES2 implements GLEventListener {
this.swapInterval = 1;
}
+ public void setIsFBOSlave(boolean v) { isFBOSlave = v; }
public void setAspect(float aspect) { this.aspect = aspect; }
public void setDoRotation(boolean rotate) { this.doRotate = rotate; }
@@ -129,13 +129,13 @@ public class RedSquareES2 implements GLEventListener {
colors.enableBuffer(gl, false);
// OpenGL Render Settings
- gl.glClearColor(0, 0, 0, 0);
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
st.useProgram(gl, false);
- if (glad instanceof GLWindow) {
- glWindow = (GLWindow) glad;
- glWindow.addMouseListener(myMouse);
+ final Object upstreamWidget = glad.getUpstreamWidget();
+ if (!isFBOSlave && upstreamWidget instanceof Window) {
+ window = (Window) upstreamWidget;
+ window.addMouseListener(myMouse);
}
t0 = System.currentTimeMillis();
System.err.println(Thread.currentThread()+" RedSquareES2.init FIN");
@@ -145,6 +145,7 @@ public class RedSquareES2 implements GLEventListener {
long t1 = System.currentTimeMillis();
GL2ES2 gl = glad.getGL().getGL2ES2();
+ gl.glClearColor(0, 0, 0, 0);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
st.useProgram(gl, true);
// One rotation every four seconds
@@ -171,7 +172,9 @@ public class RedSquareES2 implements GLEventListener {
System.err.println(Thread.currentThread()+" RedSquareES2.reshape "+x+"/"+y+" "+width+"x"+height+", swapInterval "+swapInterval);
GL2ES2 gl = glad.getGL().getGL2ES2();
- gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
st.useProgram(gl, true);
// Set location in front of camera
@@ -192,9 +195,9 @@ public class RedSquareES2 implements GLEventListener {
}
isInitialized = false;
System.err.println(Thread.currentThread()+" RedSquareES2.dispose ... ");
- if (null != glWindow) {
- glWindow.removeMouseListener(myMouse);
- glWindow = null;
+ if (null != window) {
+ window.removeMouseListener(myMouse);
+ window = null;
}
GL2ES2 gl = glad.getGL().getGL2ES2();
st.destroy(gl);
@@ -207,24 +210,9 @@ public class RedSquareES2 implements GLEventListener {
class MyMouseAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
System.err.println(e);
- if(null != glWindow && e.getSource() == glWindow.getDelegatedWindow()) {
- if(e.getX() < glWindow.getWidth()/2) {
- glWindow.setFullscreen(!glWindow.isFullscreen());
- System.err.println("setFullscreen: "+glWindow.isFullscreen());
- } else {
- glWindow.invoke(false, new GLRunnable() {
- public boolean run(GLAutoDrawable drawable) {
- GL gl = drawable.getGL();
- gl.setSwapInterval(gl.getSwapInterval()<=0?1:0);
- System.err.println("setSwapInterval: "+gl.getSwapInterval());
- final GLAnimatorControl a = drawable.getAnimator();
- if( null != a ) {
- a.resetFPSCounter();
- }
- return true;
- }
- });
- }
+ if(null != window && e.getSource() == window) {
+ window.setFullscreen(!window.isFullscreen());
+ System.err.println("setFullscreen: "+window.isFullscreen());
}
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
index b04bd07c1..9217e2b53 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
@@ -265,11 +265,12 @@ public class TextureSequenceCubeES2 implements GLEventListener {
st.useProgram(gl, false);
- if (drawable instanceof Window) {
- Window window = (Window) drawable;
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.addMouseListener(mouseAction);
- } else if (GLProfile.isAWTAvailable() && drawable instanceof java.awt.Component) {
- java.awt.Component comp = (java.awt.Component) drawable;
+ } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
+ final java.awt.Component comp = (java.awt.Component) upstreamWidget;
new com.jogamp.newt.event.awt.AWTMouseAdapter(mouseAction).addTo(comp);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index 0b83aacd8..7f2713354 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -163,8 +163,9 @@ public class MovieCube implements GLEventListener, GLMediaEventListener {
mPlayer.start();
boolean added;
- if (drawable instanceof Window) {
- Window window = (Window) drawable;
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.addKeyListener(keyAction);
added = true;
} else { added = false; }
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index 8210065ab..e17c9e88b 100755
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -400,8 +400,9 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
startTime = System.currentTimeMillis();
- if (drawable instanceof Window) {
- Window window = (Window) drawable;
+ final Object upstreamWidget = drawable.getUpstreamWidget();
+ if (upstreamWidget instanceof Window) {
+ final Window window = (Window) upstreamWidget;
window.addMouseListener(mouseAction);
winWidth = window.getWidth();
winHeight = window.getHeight();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index 04563d62e..797a16485 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -258,7 +258,6 @@ public class TestGearsES2NEWT extends UITestCase {
public static void main(String args[]) throws IOException {
int x=0, y=0, w=640, h=480;
- boolean useSize = false;
boolean usePos = false;
for(int i=0; i= height.
+ *
+ * Draws the Gears demo in a window that's twice as wide than it is tall,
+ * and checks to see if a particular pixel in the right half of the frame
+ * is colored.
+ *
+ * @author Wade Walker (adapted from TestGearsGLJPanelAWT)
+ */
+public class TestGLJPanelAWTBug450 extends UITestCase {
+ static GLProfile glp;
+ static int width, height;
+ static int r_x, r_y;
+ /** Set this if test fails. Needed because we can't throw an exception
+ * all the way up the stack from where we test the pixel. */
+ static boolean failed;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.getGL2ES2();
+ Assert.assertNotNull(glp);
+ height = 256;
+ width = 2*height;
+ r_x = 5*height/4; // 5/8 * width
+ r_y = height/2;
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ protected void runTestGL(GLCapabilities caps)
+ throws AWTException, InterruptedException, InvocationTargetException
+ {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ JFrame frame = new JFrame("Swing GLJPanel");
+ Assert.assertNotNull(frame);
+
+ GLJPanel glJPanel = new GLJPanel(caps);
+ Assert.assertNotNull(glJPanel);
+ RedSquareES2 demo = new RedSquareES2();
+ demo.setAspect((float)width/(float)height);
+ demo.setDoRotation(false);
+ glJPanel.addGLEventListener(demo);
+ glJPanel.addGLEventListener(new GLEventListener() {
+ int f = 0;
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ // drawable.getGL().glClearColor(0, 0, 1, 1);
+ }
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ // look at one pixel at the bottom of the frame, just right of
+ // the center line, and make sure it's not black
+ GL2 gl = GLUgl2.getCurrentGL2();
+ ByteBuffer bytebuffer = ByteBuffer.allocateDirect( 3 );
+ gl.glReadPixels( r_x, r_y, 1, 1, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, bytebuffer );
+ byte byte0 = bytebuffer.get( 0 );
+ byte byte1 = bytebuffer.get( 1 );
+ byte byte2 = bytebuffer.get( 2 );
+ if( (byte0 == 0) && (byte1 == 0) && (byte2 == 0) ) {
+ failed = true;
+ }
+ if(0 == f) {
+ System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
+ snapshot(getSimpleTestName("."), f, null, gl, screenshot, TextureIO.PNG, null);
+ }
+ f++;
+ }
+ @Override
+ public void dispose(GLAutoDrawable drawable) {}
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ });
+
+ FPSAnimator animator = new FPSAnimator(glJPanel, 60);
+
+ final JFrame _frame = frame;
+ final GLJPanel _glJPanel = glJPanel;
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ _frame.getContentPane().add(_glJPanel, BorderLayout.CENTER);
+ _frame.setSize(width, height);
+ _frame.setVisible(true);
+ } } ) ;
+
+ animator.setUpdateFPSFrames(1, null);
+ animator.start();
+ Assert.assertEquals(true, animator.isAnimating());
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()= height.
- *
- * Draws the Gears demo in a window that's twice as wide than it is tall,
- * and checks to see if a particular pixel in the right half of the frame
- * is colored.
- *
- * @author Wade Walker (adapted from TestGearsGLJPanelAWT)
- */
-public class TestGearsGLJPanelAWTBug450 extends UITestCase {
- static GLProfile glp;
- static int width, height;
- static int r_x, r_y;
- /** Set this if test fails. Needed because we can't throw an exception
- * all the way up the stack from where we test the pixel. */
- static boolean failed;
-
- @BeforeClass
- public static void initClass() {
- glp = GLProfile.getGL2ES2();
- Assert.assertNotNull(glp);
- height = 256;
- width = 2*height;
- r_x = 5*height/4; // 5/8 * width
- r_y = height/2;
- }
-
- @AfterClass
- public static void releaseClass() {
- }
-
- protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
- screenshot.write(new File(filename));
- }
- }
-
- protected void runTestGL(GLCapabilities caps)
- throws AWTException, InterruptedException, InvocationTargetException
- {
- JFrame frame = new JFrame("Swing GLJPanel");
- Assert.assertNotNull(frame);
-
- GLJPanel glJPanel = new GLJPanel(caps);
- Assert.assertNotNull(glJPanel);
- RedSquareES2 demo = new RedSquareES2();
- demo.setAspect((float)width/(float)height);
- demo.setDoRotation(false);
- glJPanel.addGLEventListener(demo);
- glJPanel.addGLEventListener(new GLEventListener() {
- int f = 0;
- @Override
- public void init(GLAutoDrawable drawable) {
- // drawable.getGL().glClearColor(0, 0, 1, 1);
- }
- @Override
- public void display(GLAutoDrawable drawable) {
- // look at one pixel at the bottom of the frame, just right of
- // the center line, and make sure it's not black
- GL2 gl = GLUgl2.getCurrentGL2();
- ByteBuffer bytebuffer = ByteBuffer.allocateDirect( 3 );
- gl.glReadPixels( r_x, r_y, 1, 1, GL2.GL_BGR, GL2.GL_UNSIGNED_BYTE, bytebuffer );
- byte byte0 = bytebuffer.get( 0 );
- byte byte1 = bytebuffer.get( 1 );
- byte byte2 = bytebuffer.get( 2 );
- if( (byte0 == 0) && (byte1 == 0) && (byte2 == 0) ) {
- failed = true;
- }
- if(0 == f) {
- System.err.println("BGR ("+r_x+"/"+r_y+"): "+byte0+", "+byte1+", "+byte2+" - OK "+(!failed));
- snapshot(drawable, true, false, getSimpleTestName(".")+".png");
- }
- f++;
- }
- @Override
- public void dispose(GLAutoDrawable drawable) {}
- @Override
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
- });
-
- FPSAnimator animator = new FPSAnimator(glJPanel, 60);
-
- final JFrame _frame = frame;
- final GLJPanel _glJPanel = glJPanel;
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- _frame.getContentPane().add(_glJPanel, BorderLayout.CENTER);
- _frame.setSize(width, height);
- _frame.setVisible(true);
- } } ) ;
-
- animator.setUpdateFPSFrames(1, null);
- animator.start();
- Assert.assertEquals(true, animator.isAnimating());
-
- while(animator.isAnimating() && animator.getTotalFPSDuration() buffer0, Green -> buffer1
- st.attachShaderProgram(gl, sp0, true);
- vertices0.enableBuffer(gl, true);
- colors0.enableBuffer(gl, true);
-
- fbo_mrt.bind(gl);
- gl.glDrawBuffers(2, two_buffers, 0);
- gl.glViewport(0, 0, fbo_mrt.getWidth(), fbo_mrt.getHeight());
-
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
- fbo_mrt.unbind(gl);
- vertices0.enableBuffer(gl, false);
- colors0.enableBuffer(gl, false);
-
- // pass 2 - mix buffer0, buffer1 and blue
- // rg = buffer0.rg + buffer1.rg, b = Blue - length(rg);
- st.attachShaderProgram(gl, sp1, true);
- vertices0.enableBuffer(gl, true);
- colors0.enableBuffer(gl, true);
- texCoords0.enableBuffer(gl, true);
- gl.glDrawBuffers(1, bck_buffers, 0);
-
- gl.glViewport(0, 0, drawable.getWidth(), drawable.getHeight());
- fbo_mrt.use(gl, 0);
- fbo_mrt.use(gl, 1);
- gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
- fbo_mrt.unuse(gl);
- vertices0.enableBuffer(gl, false);
- colors0.enableBuffer(gl, false);
- texCoords0.enableBuffer(gl, false);
-
- drawable.swapBuffers();
- Thread.sleep(50);
- }
-
- NEWTGLContext.destroyWindow(winctx);
- }
-
- public static void main(String args[]) throws IOException {
- System.err.println("main - start");
- for(int i=0; i 0 ? "rgba" : "rgb_";
- snapshot(drawable, true, false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
+ snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ f++;
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
index b5b12035d..5681df0ad 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite01NEWT.java
@@ -28,8 +28,6 @@
package com.jogamp.opengl.test.junit.jogl.util.texture;
-import java.io.File;
-
import com.jogamp.newt.opengl.GLWindow;
import javax.media.opengl.GLAutoDrawable;
@@ -37,6 +35,7 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -62,32 +61,26 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
height = 256;
}
- protected void snapshot(GLAutoDrawable drawable, boolean alpha, boolean flip, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(alpha, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, flip)) {
- screenshot.write(new File(filename));
- }
- }
-
@Test
public void testOnscreenWritePNG_TGA_PAM() throws InterruptedException {
+ final GLReadBufferUtil screenshotRGB = new GLReadBufferUtil(false, false);
+ final GLReadBufferUtil screenshotRGBA = new GLReadBufferUtil(true, false);
GLWindow glWindow = GLWindow.create(caps);
Assert.assertNotNull(glWindow);
glWindow.setTitle("Shared Gears NEWT Test");
glWindow.setSize(width, height);
glWindow.addGLEventListener(new GearsES2(1));
glWindow.addGLEventListener(new GLEventListener() {
+ int f = 0;
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
- // snapshot(drawable, false, true, getSimpleTestName(".")+"-rgb_-"+drawable.getGLProfile().getName()+".ppm");
- snapshot(drawable, true, false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
- snapshot(drawable, true, false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".tga");
- snapshot(drawable, true, true, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".pam");
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".tga");
- snapshot(drawable, false, true, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".pam");
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.TGA, null);
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.TGA, null);
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGBA, TextureIO.PAM, null);
+ snapshot(getSimpleTestName("."), f++, null, drawable.getGL(), screenshotRGB, TextureIO.PAM, null);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
@@ -98,18 +91,21 @@ public class TestGLReadBufferUtilTextureIOWrite01NEWT extends UITestCase {
@Test
public void testOffscreenWritePNG() throws InterruptedException {
+ final GLReadBufferUtil screenshotRGB = new GLReadBufferUtil(false, false);
+ final GLReadBufferUtil screenshotRGBA = new GLReadBufferUtil(true, false);
final GLCapabilities caps2 = WindowUtilNEWT.fixCaps(caps, false, true, false);
GLWindow glWindow = GLWindow.create(caps2);
Assert.assertNotNull(glWindow);
glWindow.setSize(width, height);
glWindow.addGLEventListener(new GearsES2(1));
glWindow.addGLEventListener(new GLEventListener() {
+ int f = 0;
public void init(GLAutoDrawable drawable) {}
public void dispose(GLAutoDrawable drawable) {}
public void display(GLAutoDrawable drawable) {
- final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
- snapshot(drawable, true, false, getSimpleTestName(".")+"-F_rgba-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
- snapshot(drawable, false, false, getSimpleTestName(".")+"-F_rgb_-I_"+pfmt+"-"+drawable.getGLProfile().getName()+".png");
+ snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGBA, TextureIO.PNG, null);
+ snapshot(getSimpleTestName("."), f, null, drawable.getGL(), screenshotRGB, TextureIO.PNG, null);
+ f++;
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
});
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
index 10dd4ea70..43641fe6d 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02AWT.java
@@ -30,9 +30,6 @@ package com.jogamp.opengl.test.junit.jogl.util.texture;
import java.awt.Dimension;
import java.awt.Frame;
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
@@ -45,6 +42,7 @@ import jogamp.nativewindow.jawt.JAWTUtil;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -71,20 +69,6 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
height = 64;
}
- protected void snapshot(GLAutoDrawable drawable, GLReadBufferUtil screenshot, int i) {
- final StringWriter filename = new StringWriter();
- {
- final PrintWriter pw = new PrintWriter(filename);
- final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
- pw.printf("%s-F_rgba-I_%s-%s-n%03d-%04dx%04d.png",
- getSimpleTestName("."), pfmt, drawable.getGLProfile().getName(), i, drawable.getWidth(), drawable.getHeight());
- }
- drawable.getGL().glFinish(); // poor mans sync ..
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
- screenshot.write(new File(filename.toString()));
- }
- }
-
protected void testWritePNGWithResizeImpl(boolean offscreenLayer) throws InterruptedException {
if(!offscreenLayer && JAWTUtil.isOffscreenLayerRequired()) {
System.err.println("onscreen layer n/a");
@@ -127,7 +111,7 @@ public class TestGLReadBufferUtilTextureIOWrite02AWT extends UITestCase {
if(snap) {
System.err.println("XXX: ["+fw_old+", "+dw_old+"], "+fw+"x"+fh+", "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
c=0;
- snapshot(drawable, screenshot, i++);
+ snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
dw_old = dw;
fw_old = fw;
Threading.invoke(true, new Runnable() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
index ed0791f7c..d1ffa84cf 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestGLReadBufferUtilTextureIOWrite02NEWT.java
@@ -28,10 +28,6 @@
package com.jogamp.opengl.test.junit.jogl.util.texture;
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
import com.jogamp.newt.opengl.GLWindow;
import javax.media.opengl.GLAutoDrawable;
@@ -41,6 +37,7 @@ import javax.media.opengl.GLProfile;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -66,19 +63,6 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
height = 64;
}
- protected void snapshot(GLAutoDrawable drawable, GLReadBufferUtil screenshot, int i) {
- final StringWriter filename = new StringWriter();
- {
- final PrintWriter pw = new PrintWriter(filename);
- final String pfmt = drawable.getChosenGLCapabilities().getAlphaBits() > 0 ? "rgba" : "rgb_";
- pw.printf("%s-F_rgba-I_%s-%s-n%03d-%04dx%04d.png",
- getSimpleTestName("."), pfmt, drawable.getGLProfile().getName(), i, drawable.getWidth(), drawable.getHeight());
- }
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
- screenshot.write(new File(filename.toString()));
- }
- }
-
private void testWritePNGWithResizeImpl(boolean offscreen) throws InterruptedException {
final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
final GLCapabilities caps2 = offscreen ? WindowUtilNEWT.fixCaps(caps, false, true, false) : caps;
@@ -110,7 +94,7 @@ public class TestGLReadBufferUtilTextureIOWrite02NEWT extends UITestCase {
if(snap) {
System.err.println("XXX: ["+dw_old+"], "+dw+"x"+dh+", sz_changed "+sz_changed+", snap "+snap);
c=0;
- snapshot(drawable, screenshot, i++);
+ snapshot(getSimpleTestName("."), i++, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
dw_old = dw;
new Thread() {
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
index 068732696..0d4f2b01e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
@@ -52,7 +52,6 @@ import com.jogamp.opengl.util.GLReadBufferUtil;
import java.awt.Dimension;
import java.awt.Frame;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
@@ -96,16 +95,10 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
testTextureStream = null;
}
- protected void snapshot(GLAutoDrawable drawable, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
- screenshot.write(new File(filename));
- }
- }
-
public void testImpl(boolean useFFP, final InputStream istream, final boolean useAWTIIOP)
throws InterruptedException, IOException
{
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
GLProfile glp;
if(useFFP && GLProfile.isAvailable(GLProfile.GL2GL3)) {
glp = GLProfile.getGL2GL3();
@@ -137,7 +130,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
// the bug submitter was doing it
final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
glc.addGLEventListener(gle);
- glc.addGLEventListener(new GLEventListener() {
+ glc.addGLEventListener(new GLEventListener() {
boolean shot = false;
@Override public void init(GLAutoDrawable drawable) {}
@@ -147,7 +140,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
// 1 snapshot
if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
shot = true;
- snapshot(drawable, getSimpleTestName(".")+".png");
+ snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index d973dea2d..b4faafbe7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -48,7 +48,6 @@ import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLReadBufferUtil;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
@@ -80,14 +79,8 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
testTextureStream = null;
}
- protected void snapshot(GLAutoDrawable drawable, String filename) {
- GLReadBufferUtil screenshot = new GLReadBufferUtil(false, false);
- if(screenshot.readPixels(drawable.getGL(), drawable, false)) {
- screenshot.write(new File(filename));
- }
- }
-
public void testImpl(boolean useFFP, final InputStream istream) throws InterruptedException, IOException {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
GLProfile glp;
if(useFFP && GLProfile.isAvailable(GLProfile.GL2GL3)) {
glp = GLProfile.getGL2GL3();
@@ -119,7 +112,7 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
// 1 snapshot
if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) {
shot = true;
- snapshot(drawable, getSimpleTestName(".")+".png");
+ snapshot(getSimpleTestName("."), 0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
index 672675fab..c07d5b741 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/UITestCase.java
@@ -28,7 +28,17 @@
package com.jogamp.opengl.test.junit.util;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawable;
+
import com.jogamp.common.util.locks.SingletonInstance;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.texture.TextureIO;
import org.junit.Assume;
import org.junit.Before;
@@ -108,6 +118,49 @@ public abstract class UITestCase {
}
static final String unsupportedTestMsg = "Test not supported on this platform.";
-
+
+ /**
+ * Takes a snapshot of the drawable's current framebuffer. Example filenames:
+ *
+ * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0004-0800x0600.png
+ * TestFBODrawableNEWT.test01-F_rgba-I_rgba-S0_default-GL2-n0005-0800x0600.png
+ *
+ *
+ * @param simpleTestName will be used as the filename prefix
+ * @param sn sequential number
+ * @param postSNDetail optional detail to be added to the filename after sn
+ * @param gl the current GL context object. It's read drawable is being used as the pixel source and to gather some details which will end up in the filename.
+ * @param readBufferUtil the {@link GLReadBufferUtil} to be used to read the pixels for the screenshot.
+ * @param fileSuffix Optional file suffix without a dot defining the file type, i.e. "png"
.
+ * If null
the "png"
as defined in {@link TextureIO#PNG} is being used.
+ * @param destPath Optional platform dependent file path. It shall use {@link File#separatorChar} as is directory separator.
+ * It shall not end with a directory separator, {@link File#separatorChar}.
+ * If null
the current working directory is being used.
+ */
+ public static void snapshot(String simpleTestName, int sn, String postSNDetail, GL gl, GLReadBufferUtil readBufferUtil, String fileSuffix, String destPath) {
+ if(null == fileSuffix) {
+ fileSuffix = TextureIO.PNG;
+ }
+ final StringWriter filenameSW = new StringWriter();
+ {
+ final GLDrawable drawable = gl.getContext().getGLReadDrawable();
+ final GLCapabilitiesImmutable caps = drawable.getChosenGLCapabilities();
+ final String F_pfmt = readBufferUtil.hasAlpha() ? "rgba" : "rgb_";
+ final String pfmt = caps.getAlphaBits() > 0 ? "rgba" : "rgb_";
+ final String aaext = caps.getSampleExtension();
+ final int samples = caps.getNumSamples() ;
+ postSNDetail = null != postSNDetail ? "-"+postSNDetail : "";
+ final PrintWriter pw = new PrintWriter(filenameSW);
+ pw.printf("%s-n%04d%s-F_%s-I_%s-S%d_%s-%s-%04dx%04d.%s",
+ simpleTestName, sn, postSNDetail, F_pfmt, pfmt, samples, aaext, drawable.getGLProfile().getName(),
+ drawable.getWidth(), drawable.getHeight(), fileSuffix);
+ }
+ final String filename = null != destPath ? destPath + File.separator + filenameSW.toString() : filenameSW.toString();
+ System.err.println(Thread.currentThread().getName()+": ** screenshot: "+filename);
+ gl.glFinish(); // just make sure rendering finished ..
+ if(readBufferUtil.readPixels(gl, false)) {
+ readBufferUtil.write(new File(filename));
+ }
+ }
}
--
cgit v1.2.3
From 4a08de4511a627c3d87d6a33debbd561962c0312 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 20 Jul 2012 14:08:49 +0200
Subject: GLCapabilities Native Aquisition: Set alpha bits at last - due to
it's auto setting by setSampleBuffers(true) and setBackgroundOpaque(false)
This bug lead to X11 GLCapabilities rgba: 8/8/8/1 - which ofc is invalid. Sideeffect was a bad selected GLXFB configuration
and the GLContext couldn't be made current.
Patch sets alpha bits reflecting reality carefully after opaque/samples. Added API doc note.
---
.../media/opengl/DefaultGLCapabilitiesChooser.java | 3 +-
.../jogamp/opengl/GLGraphicsConfigurationUtil.java | 4 +-
.../opengl/egl/EGLGraphicsConfiguration.java | 37 +++++++--------
.../egl/EGLGraphicsConfigurationFactory.java | 8 ++--
.../macosx/cgl/MacOSXCGLGraphicsConfiguration.java | 5 ++-
.../opengl/windows/wgl/WGLGLCapabilities.java | 8 +++-
.../jogamp/opengl/x11/glx/X11GLXContext.java | 2 +-
.../x11/glx/X11GLXGraphicsConfiguration.java | 52 +++++++++++-----------
.../javax/media/nativewindow/Capabilities.java | 15 +++++--
.../junit/jogl/caps/TestMultisampleES2NEWT.java | 9 ++--
.../test/junit/jogl/caps/TestTranslucencyAWT.java | 1 -
.../parenting/TestTranslucentParentingAWT.java | 1 -
12 files changed, 82 insertions(+), 63 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 1b84bd9bd..5fa8ce32d 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -117,6 +117,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
final int availnum = available.size();
if (DEBUG) {
+ Thread.dumpStack();
System.err.println("Desired: " + gldes);
System.err.println("Available: " + availnum);
for (int i = 0; i < available.size(); i++) {
@@ -241,7 +242,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (i > 0) {
System.err.print(",");
}
- System.err.print(" " + scores[i]);
+ System.err.print(" " + i +": " + scores[i]);
}
System.err.println(" ]");
}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 900d6a2a0..3f38f33bc 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -177,14 +177,16 @@ public class GLGraphicsConfigurationUtil {
return capsRequested;
}
+ /** Fix opaque setting while preserve alpha bits */
public static GLCapabilitiesImmutable fixOpaqueGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean isOpaque)
{
GLCapabilities caps2 = null;
if( capsRequested.isBackgroundOpaque() != isOpaque) {
- // fix caps ..
+ final int alphaBits = capsRequested.getAlphaBits();
caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setBackgroundOpaque(isOpaque);
+ caps2.setAlphaBits(alphaBits);
return caps2;
}
return capsRequested;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 214b36493..73867fb40 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -209,24 +209,6 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return false;
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val)) {
- caps.setRedBits(val.get(0));
- }
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_GREEN_SIZE, val)) {
- caps.setGreenBits(val.get(0));
- }
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_BLUE_SIZE, val)) {
- caps.setBlueBits(val.get(0));
- }
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_ALPHA_SIZE, val)) {
- caps.setAlphaBits(val.get(0));
- }
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_STENCIL_SIZE, val)) {
- caps.setStencilBits(val.get(0));
- }
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
- caps.setDepthBits(val.get(0));
- }
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val)) {
caps.setSampleBuffers(val.get(0)>0?true:false);
caps.setNumSamples(val.get(0));
@@ -262,6 +244,25 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
caps.setTransparentAlphaValue(val.get(0)==EGL.EGL_DONT_CARE?-1:val.get(0));
} */
}
+ // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val)) {
+ caps.setRedBits(val.get(0));
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_GREEN_SIZE, val)) {
+ caps.setGreenBits(val.get(0));
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_BLUE_SIZE, val)) {
+ caps.setBlueBits(val.get(0));
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_ALPHA_SIZE, val)) {
+ caps.setAlphaBits(val.get(0));
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_STENCIL_SIZE, val)) {
+ caps.setStencilBits(val.get(0));
+ }
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
+ caps.setDepthBits(val.get(0));
+ }
return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 6be9cb547..d79c351a0 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -253,12 +253,12 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
//
// rgb888 - d16, s4
final GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
fixedCaps.setRedBits(8);
fixedCaps.setGreenBits(8);
fixedCaps.setBlueBits(8);
fixedCaps.setDepthBits(16);
- fixedCaps.setSampleBuffers(true);
- fixedCaps.setNumSamples(4);
if( !capsChosen.isOnscreen() ) {
fixedCaps.setOnscreen(false);
fixedCaps.setPBuffer(capsChosen.isPBuffer());
@@ -291,12 +291,12 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
//
// rgb565 - d16, s4
final GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
fixedCaps.setRedBits(5);
fixedCaps.setGreenBits(6);
fixedCaps.setBlueBits(5);
fixedCaps.setDepthBits(16);
- fixedCaps.setSampleBuffers(true);
- fixedCaps.setNumSamples(4);
if( !capsChosen.isOnscreen() ) {
fixedCaps.setOnscreen(false);
fixedCaps.setPBuffer(capsChosen.isPBuffer());
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 421e1ef96..202644bb3 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -281,6 +281,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
glp = GLProfile.get(GLProfile.GL2);
}
GLCapabilities caps = new GLCapabilities(glp);
+ int alphaBits = 0;
for (int i = 0; i < len; i++) {
int attr = cglInternalAttributeToken[i+off];
switch (attr) {
@@ -317,7 +318,8 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
break;
case CGL.NSOpenGLPFAAlphaSize:
- caps.setAlphaBits(ivalues[i]);
+ // ALPHA shall be set at last - due to it's auto setting by !opaque / samples
+ alphaBits = ivalues[i];
break;
case CGL.NSOpenGLPFADepthSize:
@@ -350,6 +352,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
break;
}
}
+ caps.setAlphaBits(alphaBits);
return caps;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
index e255a0672..6a4ce5a4e 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLGLCapabilities.java
@@ -52,10 +52,11 @@ public class WGLGLCapabilities extends GLCapabilities {
public boolean setValuesByGDI() {
arb_pixelformat = -1;
+ // ALPHA shall be set at last - due to it's auto setting by !opaque / samples
setRedBits(pfd.getCRedBits());
setGreenBits(pfd.getCGreenBits());
setBlueBits(pfd.getCBlueBits());
- setAlphaBits(pfd.getCAlphaBits());
+ setAlphaBits(pfd.getCAlphaBits());
setAccumRedBits(pfd.getCAccumRedBits());
setAccumGreenBits(pfd.getCAccumGreenBits());
setAccumBlueBits(pfd.getCAccumBlueBits());
@@ -77,6 +78,7 @@ public class WGLGLCapabilities extends GLCapabilities {
public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) {
arb_pixelformat = 1;
+ int alphaBits = 0;
for (int i = 0; i < niattribs; i++) {
int attr = iattribs[i];
switch (attr) {
@@ -143,7 +145,8 @@ public class WGLGLCapabilities extends GLCapabilities {
break;
case WGLExt.WGL_ALPHA_BITS_ARB:
- setAlphaBits(iresults[i]);
+ // ALPHA shall be set at last - due to it's auto setting by !opaque / samples
+ alphaBits = iresults[i];
break;
case WGLExt.WGL_ACCUM_RED_BITS_ARB:
@@ -174,6 +177,7 @@ public class WGLGLCapabilities extends GLCapabilities {
throw new GLException("Unknown pixel format attribute " + iattribs[i]);
}
}
+ setAlphaBits(alphaBits);
return true;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index e6b74a769..e1e25be67 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -152,7 +152,7 @@ public abstract class X11GLXContext extends GLContextImpl {
throw new InternalError("Given readDrawable but no driver support");
}
} catch (RuntimeException re) {
- if(TRACE_SWITCH) {
+ if(DEBUG || TRACE_SWITCH) {
System.err.println(getThreadName()+": Warning: X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+
"dpy "+toHexString(dpy)+
", write "+toHexString(writeDrawable)+
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b5b80e0b3..95b1cc457 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -308,19 +308,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
- res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
- res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
- res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
- res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0));
- res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0));
- res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0));
- res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0));
- res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0));
- res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0));
- res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
- res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
- res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
- res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
if (isMultisampleAvailable) {
res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
@@ -336,6 +323,20 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setTransparentBlueValue(xrmask.getBlueMask());
res.setTransparentAlphaValue(alphaMask);
}
+ // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
+ res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
+ res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
+ res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
+ res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0));
try {
res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
@@ -429,18 +430,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
// Note: use of hardware acceleration is determined by
// glXCreateContext, not by the XVisualInfo. Optimistically claim
// that all GLCapabilities have the capability to be hardware
- // accelerated.
- res.setHardwareAccelerated(true);
- res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
- res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
- res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
- res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
- res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
- res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
- res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
- res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
- res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
- res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
+ // accelerated.
if (isMultisampleEnabled) {
res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
@@ -456,6 +446,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setTransparentBlueValue(xrmask.getBlueMask());
res.setTransparentAlphaValue(alphaMask);
}
+ // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
+ res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
+ res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
index 196f23598..cb33aec5e 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
@@ -211,9 +211,18 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
return alphaBits;
}
- /** Sets the number of bits requested for the color buffer's alpha
- component. On some systems only the color depth, which is the
- sum of the red, green, and blue bits, is considered. */
+ /**
+ * Sets the number of bits requested for the color buffer's alpha
+ * component. On some systems only the color depth, which is the
+ * sum of the red, green, and blue bits, is considered.
+ *
+ * Note: If alpha bits are zero
, they are set to one
+ * by {@link #setBackgroundOpaque(boolean)} and it's OpenGL specialization GLCapabilities::setSampleBuffers(boolean)
.
+ * Ensure to call this method after the above to ensure a zero
value.
+ * The above automated settings takes into account, that the user calls this method to request alpha bits,
+ * not to reflect a current state. Nevertheless if this is the case - call it at last.
+ *
+ */
public void setAlphaBits(int alphaBits) {
this.alphaBits = alphaBits;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
index b2dad1f39..02fcae6ef 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestMultisampleES2NEWT.java
@@ -57,7 +57,6 @@ import com.jogamp.opengl.util.texture.TextureIO;
public class TestMultisampleES2NEWT extends UITestCase {
static long durationPerTest = 60; // ms
- private GLWindow window;
public static void main(String[] args) {
for(int i=0; i0?true:false));
window.addGLEventListener(new GLEventListener() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
index 8e720965c..7cce5d1e4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
@@ -65,7 +65,6 @@ public class TestTranslucencyAWT extends UITestCase {
public static void initClass() {
size = new Dimension(400,200);
glCaps = new GLCapabilities(null);
- glCaps.setAlphaBits(8);
glCaps.setBackgroundOpaque(false);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
index 57b8517a6..373c83fce 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
@@ -69,7 +69,6 @@ public class TestTranslucentParentingAWT extends UITestCase {
public static void initClass() {
size = new Dimension(400,200);
glCaps = new GLCapabilities(null);
- glCaps.setAlphaBits(8);
glCaps.setBackgroundOpaque(false);
}
--
cgit v1.2.3
From 4b5a0f6557d7152ec770bc13ad3c494449de0529 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sun, 22 Jul 2012 04:16:55 +0200
Subject: Fix Bug 606 - New AWT threading implementation breaks .. ; Fix
GLAutoDrawable multi-threading w/ proper pattern (hope so)
Considering code changes and remarks:
3ed491213f8f7f05d7b9866b50d764370d8ff5f6
1a91ec5c8b6fd9d9db7bc115569c369fe7b38e9b
3334a924309a9361a448d69bc707d4cce416b430
4f27bcecf7484dc041551f52a5c49e2884cb3867
It seems necessary to have
- recursive locking employed for all semantic actions which changes drawable & context (and the Window resource)
- to avoid deadlock, we have to ensure the locked code segment will not spawn
off to another thread, or a thread holds the lock, spawns of an action requiring the lock. .. sure
- other read-only methods (flags, ..) shall at least utilize a safe local copy of a volatile field
if further use to produce the result is necessary.
- flags like sendReshape require to be volatile to guarantee it's being processed
Patch impacts: AWT/SWT GLCanvas, GLAutoDrawableBase [and it's specializations]
and hopefully closes any loopholes of missing a cache hit, etc.
If you review this and find optimizations, i.e. removing a lock due to semantics etc,
don't hold back and discuss it, please.
---
.../classes/com/jogamp/opengl/swt/GLCanvas.java | 172 ++++++-----
.../javax/media/opengl/GLAutoDrawableDelegate.java | 44 ++-
.../classes/javax/media/opengl/awt/GLCanvas.java | 317 +++++++++++----------
.../classes/jogamp/opengl/GLAutoDrawableBase.java | 249 +++++++++++-----
.../classes/jogamp/opengl/GLDrawableHelper.java | 17 +-
src/jogl/classes/jogamp/opengl/GLPbufferImpl.java | 29 +-
.../classes/com/jogamp/newt/opengl/GLWindow.java | 36 +--
src/newt/classes/jogamp/newt/WindowImpl.java | 99 +++----
.../jogl/acore/TestGLAutoDrawableDelegateNEWT.java | 10 +-
.../acore/TestGLContextDrawableSwitchNEWT.java | 10 +-
.../jogl/acore/TestGLContextSurfaceLockNEWT.java | 92 ++++--
11 files changed, 649 insertions(+), 426 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 0d9d3ddf5..64ee1c1ad 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -63,25 +63,13 @@ import org.eclipse.swt.widgets.Shell;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionUtil;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.opengl.JoglVersion;
/**
* Native SWT Canvas implementing GLAutoDrawable
- *
- * FIXME: If this instance runs in multithreading mode, see {@link Threading#isSingleThreaded()} (impossible),
- * proper recursive locking is required for drawable/context @ destroy and display.
- * Recreation etc could pull those instances while animating!
- * Simply locking before using drawable/context offthread
- * would allow a deadlock situation!
- *
- *
- * NOTE: [MT-0] Methods utilizing [volatile] drawable/context are not synchronized.
- In case any of the methods are called outside of a locked state
- extra care should be added. Maybe we shall expose locking facilities to the user.
- However, since the user shall stick to the GLEventListener model while utilizing
- GLAutoDrawable implementations, she is safe due to the implicit locked state.
- *
*/
public class GLCanvas extends Canvas implements GLAutoDrawable {
@@ -97,8 +85,9 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
//private static final boolean useSWTThread = ThreadingImpl.getMode() != ThreadingImpl.WORKER;
/* GL Stuff */
+ private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
- private volatile GLDrawable drawable; // volatile avoids locking all accessors. FIXME still need to sync destroy/display
+ private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
private GLContext context;
/* Native window surface */
@@ -112,7 +101,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable glCapsRequested;
/* Flag indicating whether an unprocessed reshape is pending. */
- private volatile boolean sendReshape;
+ private volatile boolean sendReshape; // volatile: maybe written by WindowManager thread w/o locking
/*
* Invokes init(...) on all GLEventListeners. Assumes context is current when run.
@@ -141,10 +130,16 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Action to make specified context current prior to running displayAction */
- private final Runnable makeCurrentAndDisplayAction = new Runnable() {
+ private final Runnable makeCurrentAndDisplayOnEDTAction = new Runnable() {
@Override
public void run() {
- helper.invokeGL(drawable, context, displayAction, initAction);
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ } finally {
+ _lock.unlock();
+ }
}
};
@@ -157,10 +152,16 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
};
/* Swaps buffers, making the GLContext current first */
- private final Runnable makeCurrentAndSwapBuffersAction = new Runnable() {
+ private final Runnable makeCurrentAndSwapBuffersOnEDTAction = new Runnable() {
@Override
public void run() {
- helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ } finally {
+ _lock.unlock();
+ }
}
};
@@ -181,16 +182,33 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final Runnable disposeOnEDTGLAction = new Runnable() {
@Override
public void run() {
- helper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
- }
- };
-
- private final Runnable disposeGraphicsDeviceAction = new Runnable() {
- @Override
- public void run() {
- if (null != device) {
- device.close();
- device = null;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if (null != drawable && null != context) {
+ boolean animatorPaused = false;
+ final GLAnimatorControl animator = getAnimator();
+ if (null != animator) {
+ animatorPaused = animator.pause();
+ }
+
+ if(context.isCreated()) {
+ helper.disposeGL(GLCanvas.this, drawable, context, postDisposeGLAction);
+ }
+
+ if (animatorPaused) {
+ animator.resume();
+ }
+ }
+ // SWT is owner of the device handle, not us.
+ // Hence close() operation is a NOP.
+ if (null != device) {
+ device.close();
+ device = null;
+ }
+ SWTAccessor.setRealized(GLCanvas.this, false); // unrealize ..
+ } finally {
+ _lock.unlock();
}
}
};
@@ -229,7 +247,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
clientArea = GLCanvas.this.getClientArea();
- /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite) */
+ /* Get the nativewindow-Graphics Device associated with this control (which is determined by the parent Composite).
+ * Note: SWT is owner of the native handle, hence no closing operation will be a NOP. */
device = SWTAccessor.getDevice(this);
/* Since we have no means of querying the screen index yet, assume 0. Good choice due to Xinerama alike settings anyways. */
final int screenIdx = 0;
@@ -345,7 +364,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void display() {
- runInGLThread(makeCurrentAndDisplayAction);
+ runInGLThread(makeCurrentAndDisplayOnEDTAction);
}
@Override
@@ -370,7 +389,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public GL getGL() {
- return (null == context) ? null : context.getGL();
+ final GLContext _context = context;
+ return (null == _context) ? null : _context.getGL();
}
@Override
@@ -400,27 +420,35 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public GLContext setContext(GLContext newCtx) {
- final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
- context=(GLContextImpl)newCtx;
- if(newCtxCurrent) {
- context.makeCurrent();
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLContext oldCtx = context;
+ final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ context=(GLContextImpl)newCtx;
+ if(newCtxCurrent) {
+ context.makeCurrent();
+ }
+ return oldCtx;
+ } finally {
+ _lock.unlock();
}
- return oldCtx;
}
@Override
public void setContextCreationFlags(final int arg0) {
additionalCtxCreationFlags = arg0;
- if(null != context) {
- context.setContextCreationFlags(additionalCtxCreationFlags);
+ final GLContext _context = context;
+ if(null != _context) {
+ _context.setContextCreationFlags(additionalCtxCreationFlags);
}
}
@Override
public GL setGL(final GL arg0) {
- if (null != context) {
- context.setGL(arg0);
+ final GLContext _context = context;
+ if (null != _context) {
+ _context.setGL(arg0);
return arg0;
}
return null;
@@ -428,12 +456,18 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public GLContext createContext(final GLContext shareWith) {
- if(drawable != null) {
- final GLContext _ctx = drawable.createContext(shareWith);
- _ctx.setContextCreationFlags(additionalCtxCreationFlags);
- return _ctx;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if(drawable != null) {
+ final GLContext _ctx = drawable.createContext(shareWith);
+ _ctx.setContextCreationFlags(additionalCtxCreationFlags);
+ return _ctx;
+ }
+ return null;
+ } finally {
+ _lock.unlock();
}
- return null;
}
@Override
@@ -452,7 +486,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public GLDrawableFactory getFactory() {
- return (drawable != null) ? drawable.getFactory() : null;
+ final GLDrawable _drawable = drawable;
+ return (_drawable != null) ? _drawable.getFactory() : null;
}
@Override
@@ -462,17 +497,20 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public long getHandle() {
- return (drawable != null) ? drawable.getHandle() : 0;
+ final GLDrawable _drawable = drawable;
+ return (_drawable != null) ? _drawable.getHandle() : 0;
}
@Override
public NativeSurface getNativeSurface() {
- return (drawable != null) ? drawable.getNativeSurface() : null;
+ final GLDrawable _drawable = drawable;
+ return (_drawable != null) ? _drawable.getNativeSurface() : null;
}
@Override
public boolean isRealized() {
- return (drawable != null) ? drawable.isRealized() : false;
+ final GLDrawable _drawable = drawable;
+ return (_drawable != null) ? _drawable.isRealized() : false;
}
@Override
@@ -482,41 +520,19 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
@Override
public void swapBuffers() throws GLException {
- runInGLThread(makeCurrentAndSwapBuffersAction);
+ runInGLThread(makeCurrentAndSwapBuffersOnEDTAction);
}
// FIXME: API of update() method ?
@Override
public void update() {
- // FIXME: display();
+ // FIXME: display(); ?
}
@Override
public void dispose() {
- if (null != drawable && null != context) { // drawable is volatile!
- boolean animatorPaused = false;
- final GLAnimatorControl animator = getAnimator();
- if (null != animator) {
- // can't remove us from animator for recreational addNotify()
- animatorPaused = animator.pause();
- }
-
- if(context.isCreated()) {
- runInGLThread(disposeOnEDTGLAction);
- }
-
- if (animatorPaused) {
- animator.resume();
- }
- }
- final Display display = getDisplay();
-
- if (display.getThread() == Thread.currentThread()) {
- disposeGraphicsDeviceAction.run();
- } else {
- display.syncExec(disposeGraphicsDeviceAction);
- }
- super.dispose();
+ runInGLThread(disposeOnEDTGLAction);
+ super.dispose();
}
/**
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
index 1f6166719..76959f3f4 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
@@ -67,18 +67,18 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
}
//
- // make protected methods accessible
+ // expose default methods
//
- public void defaultWindowRepaintOp() {
+ public final void windowRepaintOp() {
super.defaultWindowRepaintOp();
}
- public void defaultWindowResizedOp() {
+ public final void windowResizedOp() {
super.defaultWindowResizedOp();
}
- public void defaultWindowDestroyNotifyOp() {
+ public final void windowDestroyNotifyOp() {
super.defaultWindowDestroyNotifyOp();
}
@@ -89,6 +89,9 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
private final Object upstreamWidget;
+ @Override
+ protected final RecursiveLock getLock() { return lock; }
+
@Override
public final Object getUpstreamWidget() {
return upstreamWidget;
@@ -97,39 +100,21 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
/**
* {@inheritDoc}
*
- * This implementation calls {@link #defaultDestroyOp()}.
+ * This implementation calls {@link #defaultDestroy()}.
*
*
* User still needs to destroy the upstream window, which details are hidden from this aspect.
+ * This can be performed by overriding {@link #destroyImplInLock()}.
*
*/
@Override
- public void destroy() {
- lock.lock();
- try {
- defaultDestroyOp();
- } finally {
- lock.unlock();
- }
+ public final void destroy() {
+ defaultDestroy();
}
@Override
public void display() {
- if( sendDestroy ) {
- sendDestroy=false;
- destroy();
- return;
- }
-
- lock.lock(); // sync: context/drawable could been recreated/destroyed while animating
- try {
- if( null != drawable && drawable.isRealized() && null != context ) {
- // surface is locked/unlocked implicit by context's makeCurrent/release
- helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction);
- }
- } finally {
- lock.unlock();
- }
+ defaultDisplay();
}
//
@@ -145,4 +130,9 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
public final void setRealized(boolean realized) {
}
+ @Override
+ public final void swapBuffers() throws GLException {
+ defaultSwapBuffers();
+ }
+
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index c2e36ef9b..694a081b8 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -84,6 +84,8 @@ import javax.media.opengl.Threading;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
@@ -132,20 +134,6 @@ import jogamp.opengl.GLDrawableHelper;
*
- *
- * FIXME: If this instance runs in multithreading mode, see {@link Threading#isSingleThreaded()} (default: single-thread),
- * proper recursive locking is required for drawable/context @ destroy and display.
- * Recreation etc could pull those instances while animating!
- * Simply locking before using drawable/context offthread
- * would allow a deadlock situation!
- *
- *
- * NOTE: [MT-0] Methods utilizing [volatile] drawable/context are not synchronized.
- In case any of the methods are called outside of a locked state
- extra care should be added. Maybe we shall expose locking facilities to the user.
- However, since the user shall stick to the GLEventListener model while utilizing
- GLAutoDrawable implementations, she is safe due to the implicit locked state.
- *
*/
@SuppressWarnings("serial")
@@ -153,11 +141,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private static final boolean DEBUG = Debug.debug("GLCanvas");
+ private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
private AWTGraphicsConfiguration awtConfig;
- private volatile GLDrawable drawable; // volatile avoids locking all accessors. FIXME still need to sync destroy/display
+ private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
private GLContextImpl context;
- private boolean sendReshape = false;
+ private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
// copy of the cstr args, mainly for recreation
private GLCapabilitiesImmutable capsReqUser;
@@ -278,8 +267,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public final boolean isOffscreenLayerSurfaceEnabled() {
- if(null != drawable) {
- return ((JAWTWindow)drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+ final GLDrawable _drawable = drawable;
+ if(null != _drawable) {
+ return ((JAWTWindow)_drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
}
return false;
}
@@ -398,12 +388,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GLContext createContext(final GLContext shareWith) {
- if(drawable != null) {
- final GLContext _ctx = drawable.createContext(shareWith);
- _ctx.setContextCreationFlags(additionalCtxCreationFlags);
- return _ctx;
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if(drawable != null) {
+ final GLContext _ctx = drawable.createContext(shareWith);
+ _ctx.setContextCreationFlags(additionalCtxCreationFlags);
+ return _ctx;
+ }
+ return null;
+ } finally {
+ _lock.unlock();
}
- return null;
}
@Override
@@ -412,7 +408,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public boolean isRealized() {
- return (null != drawable) ? drawable.isRealized() : false;
+ final GLDrawable _drawable = drawable;
+ return ( null != _drawable ) ? _drawable.isRealized() : false;
}
@Override
@@ -427,50 +424,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void display() {
- if( !validateGLDrawable() ) {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
- }
- return; // not yet available ..
- }
Threading.invoke(true, displayOnEDTAction, getTreeLock());
-
awtWindowClosingProtocol.addClosingListenerOneShot();
}
private void dispose(boolean regenerate) {
- final GLAnimatorControl animator = getAnimator();
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: dispose("+regenerate+") - START, hasContext " +
- (null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
- Thread.dumpStack();
- }
-
- if(null!=drawable && null!=context) { // drawable is volatile!
- boolean animatorPaused = false;
- if(null!=animator) {
- // can't remove us from animator for recreational addNotify()
- animatorPaused = animator.pause();
- }
-
- disposeRegenerate=regenerate;
-
- if(context.isCreated()) {
- Threading.invoke(true, disposeOnEDTAction, getTreeLock());
- }
-
- if(animatorPaused) {
- animator.resume();
- }
- }
-
- if(!regenerate) {
- disposeAbstractGraphicsDevice();
- }
-
- if(DEBUG) {
- System.err.println(getThreadName()+": dispose("+regenerate+") - END, "+animator);
- }
+ disposeRegenerate=regenerate;
+ Threading.invoke(true, disposeOnEDTAction, getTreeLock());
}
/**
@@ -530,43 +490,49 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@SuppressWarnings("deprecation")
@Override
public void addNotify() {
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds());
- Thread.dumpStack();
- }
-
- /**
- * 'super.addNotify()' determines the GraphicsConfiguration,
- * while calling this class's overriden 'getGraphicsConfiguration()' method
- * after which it creates the native peer.
- * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
- * is being used in getGraphicsConfiguration().
- * This code order also allows recreation, ie re-adding the GLCanvas.
- */
- awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
- if(null==awtConfig) {
- throw new GLException("Error: NULL AWTGraphicsConfiguration");
- }
-
- // before native peer is valid: X11
- disableBackgroundErase();
-
- // issues getGraphicsConfiguration() and creates the native peer
- super.addNotify();
-
- // after native peer is valid: Windows
- disableBackgroundErase();
-
- if (!Beans.isDesignTime()) {
- createDrawableAndContext();
- }
-
- // init drawable by paint/display makes the init sequence more equal
- // for all launch flavors (applet/javaws/..)
- // validateGLDrawable();
-
- if(DEBUG) {
- System.err.println(getThreadName()+": Info: addNotify - end: peer: "+getPeer());
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: addNotify - start, bounds: "+this.getBounds());
+ Thread.dumpStack();
+ }
+
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overriden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
+ awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
+
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
+ // issues getGraphicsConfiguration() and creates the native peer
+ super.addNotify();
+
+ // after native peer is valid: Windows
+ disableBackgroundErase();
+
+ if (!Beans.isDesignTime()) {
+ createDrawableAndContext();
+ }
+
+ // init drawable by paint/display makes the init sequence more equal
+ // for all launch flavors (applet/javaws/..)
+ // validateGLDrawable();
+
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: addNotify - end: peer: "+getPeer());
+ }
+ } finally {
+ _lock.unlock();
}
}
@@ -585,23 +551,24 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
private boolean validateGLDrawable() {
- boolean realized = false;
- if (!Beans.isDesignTime()) {
- if ( null != drawable ) { // OK: drawable is volatile
- realized = drawable.isRealized();
- if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) {
- // make sure drawable realization happens on AWT EDT, due to AWTTree lock
- AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
- realized = true;
- sendReshape=true; // ensure a reshape is being send ..
- if(DEBUG) {
- System.err.println(getThreadName()+": Realized Drawable: "+drawable.toString());
- Thread.dumpStack();
- }
+ final GLDrawable _drawable = drawable;
+ if ( null != _drawable ) {
+ if( _drawable.isRealized() ) {
+ return true;
+ }
+ if (!Beans.isDesignTime() &&
+ 0 < _drawable.getWidth() * _drawable.getHeight() ) {
+ // make sure drawable realization happens on AWT EDT, due to AWTTree lock
+ AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
+ sendReshape=true; // ensure a reshape is being send ..
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
+ Thread.dumpStack();
}
+ return true;
}
}
- return realized;
+ return false;
}
private Runnable setRealizedOnEDTAction = new Runnable() {
@Override
@@ -633,9 +600,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
try {
dispose(false);
} finally {
- context=null;
- drawable=null;
- awtConfig=null;
super.removeNotify();
}
}
@@ -655,7 +619,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
- if(null != drawable && drawable.isRealized() && !drawable.getChosenGLCapabilities().isOnscreen()) {
+ final GLDrawable _drawable = drawable;
+ if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) {
dispose(true);
} else {
sendReshape = true;
@@ -710,13 +675,19 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public GLContext setContext(GLContext newCtx) {
- final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
- context=(GLContextImpl)newCtx;
- if(newCtxCurrent) {
- context.makeCurrent();
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLContext oldCtx = context;
+ final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ context=(GLContextImpl)newCtx;
+ if(newCtxCurrent) {
+ context.makeCurrent();
+ }
+ return oldCtx;
+ } finally {
+ _lock.unlock();
}
- return oldCtx;
}
@Override
@@ -729,15 +700,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if (Beans.isDesignTime()) {
return null;
}
- GLContext ctx = getContext();
- return (ctx == null) ? null : ctx.getGL();
+ final GLContext _context = context;
+ return (_context == null) ? null : _context.getGL();
}
@Override
public GL setGL(GL gl) {
- GLContext ctx = getContext();
- if (ctx != null) {
- ctx.setGL(gl);
+ final GLContext _context = context;
+ if (_context != null) {
+ _context.setGL(gl);
return gl;
}
return null;
@@ -762,8 +733,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void setContextCreationFlags(int flags) {
additionalCtxCreationFlags = flags;
- if(null != context) {
- context.setContextCreationFlags(additionalCtxCreationFlags);
+ final GLContext _context = context;
+ if(null != _context) {
+ _context.setContextCreationFlags(additionalCtxCreationFlags);
}
}
@@ -796,26 +768,30 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public NativeSurface getNativeSurface() {
- return (null != drawable) ? drawable.getNativeSurface() : null;
+ final GLDrawable _drawable = drawable;
+ return (null != _drawable) ? _drawable.getNativeSurface() : null;
}
@Override
public long getHandle() {
- return (null != drawable) ? drawable.getHandle() : 0;
+ final GLDrawable _drawable = drawable;
+ return (null != _drawable) ? _drawable.getHandle() : 0;
}
@Override
public GLDrawableFactory getFactory() {
- return (null != drawable) ? drawable.getFactory() : null;
+ final GLDrawable _drawable = drawable;
+ return (null != _drawable) ? _drawable.getFactory() : null;
}
@Override
public String toString() {
- final int dw = (null!=drawable) ? drawable.getWidth() : -1;
- final int dh = (null!=drawable) ? drawable.getHeight() : -1;
+ final GLDrawable _drawable = drawable;
+ final int dw = (null!=_drawable) ? _drawable.getWidth() : -1;
+ final int dh = (null!=_drawable) ? _drawable.getHeight() : -1;
return "AWT-GLCanvas[Realized "+isRealized()+
- ",\n\t"+((null!=drawable)?drawable.getClass().getName():"null-drawable")+
+ ",\n\t"+((null!=_drawable)?_drawable.getClass().getName():"null-drawable")+
",\n\tFactory "+getFactory()+
",\n\thandle 0x"+Long.toHexString(getHandle())+
",\n\tDrawable size "+dw+"x"+dh+
@@ -829,7 +805,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
//
private boolean disposeRegenerate;
- private final Runnable postDisposeAction = new Runnable() {
+ private final Runnable postDisposeOnEDTAction = new Runnable() {
@Override
public void run() {
context=null;
@@ -859,7 +835,47 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final Runnable disposeOnEDTAction = new Runnable() {
@Override
public void run() {
- helper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLAnimatorControl animator = getAnimator();
+
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: dispose("+disposeRegenerate+") - START, hasContext " +
+ (null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
+ Thread.dumpStack();
+ }
+
+ if(null!=drawable && null!=context) {
+ boolean animatorPaused = false;
+ if(null!=animator) {
+ // can't remove us from animator for recreational addNotify()
+ animatorPaused = animator.pause();
+ }
+
+ if(context.isCreated()) {
+ helper.disposeGL(GLCanvas.this, drawable, context, postDisposeOnEDTAction);
+ }
+
+ if(animatorPaused) {
+ animator.resume();
+ }
+ }
+
+ if(!disposeRegenerate) {
+ if(null != awtConfig) {
+ disposeAbstractGraphicsDevice();
+ }
+ awtConfig=null;
+ }
+
+ if(DEBUG) {
+ System.err.println(getThreadName()+": dispose("+disposeRegenerate+") - END, "+animator);
+ }
+
+ } finally {
+ _lock.unlock();
+ }
}
};
@@ -879,7 +895,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if(DEBUG) {
System.err.println(getThreadName()+": GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
- awtConfig=null;
}
}
};
@@ -890,7 +905,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
*
* @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
*/
- void disposeAbstractGraphicsDevice() {
+ private void disposeAbstractGraphicsDevice() {
if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
disposeAbstractGraphicsDeviceAction.run();
} else {
@@ -941,14 +956,30 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final Runnable displayOnEDTAction = new Runnable() {
@Override
public void run() {
- helper.invokeGL(drawable, context, displayAction, initAction);
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ if( validateGLDrawable() ) {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ } else if(DEBUG) {
+ System.err.println(getThreadName()+": Info: GLCanvas display - skipped GL render, drawable not valid yet");
+ }
+ } finally {
+ _lock.unlock();
+ }
}
};
private final Runnable swapBuffersOnEDTAction = new Runnable() {
@Override
public void run() {
- helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ } finally {
+ _lock.unlock();
+ }
}
};
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index 5c6d7446a..fe6d0fd76 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -46,6 +46,7 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
+import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.util.Animator;
@@ -63,11 +64,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
protected final GLDrawableHelper helper = new GLDrawableHelper();
protected final FPSCounterImpl fpsCounter = new FPSCounterImpl();
- protected GLDrawableImpl drawable;
+ protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
protected int additionalCtxCreationFlags = 0;
- protected boolean sendReshape = false;
- protected boolean sendDestroy = false;
+ protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
+ protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context) {
this.drawable = drawable;
@@ -75,31 +76,47 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
resetFPSCounter();
}
+ protected abstract RecursiveLock getLock();
+
/** Returns the delegated GLDrawable */
public final GLDrawable getDelegatedDrawable() { return drawable; }
/** Default implementation to handle repaint events from the windowing system */
- protected void defaultWindowRepaintOp() {
- if( null != drawable && drawable.isRealized() ) {
- if( !drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+ protected final void defaultWindowRepaintOp() {
+ final GLDrawable _drawable = drawable;
+ if( null != _drawable && _drawable.isRealized() ) {
+ if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
display();
}
- }
+ }
}
/** Default implementation to handle resize events from the windowing system */
- protected void defaultWindowResizedOp() {
- if( null!=drawable ) {
+ protected final void defaultWindowResizedOp() {
+ final GLDrawable _drawable = drawable;
+ if( null!=_drawable ) {
if(DEBUG) {
System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
}
- sendReshape = true;
- defaultWindowRepaintOp();
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ if( _drawable.isRealized() ) {
+ if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
+ display();
+ }
+ }
}
}
- /** Default implementation to handle destroy notifications from the windowing system */
- protected void defaultWindowDestroyNotifyOp() {
+ /**
+ * Default implementation to handle destroy notifications from the windowing system.
+ *
+ *
+ * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
+ * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
+ * {@link #defaultDestroy()} is being called.
+ *
+ */
+ protected final void defaultWindowDestroyNotifyOp() {
final NativeSurface ns = getNativeSurface();
final boolean shallClose;
if(ns instanceof WindowClosingProtocol) {
@@ -108,27 +125,66 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
shallClose = true;
}
if( shallClose ) {
- // Is an animator thread perform rendering?
- if (helper.isExternalAnimatorRunning()) {
- // Pause animations before initiating safe destroy.
- final GLAnimatorControl ctrl = helper.getAnimator();
- final boolean isPaused = ctrl.pause();
- destroy();
- if(isPaused) {
- ctrl.resume();
- }
- } else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
- // surface is locked by another thread
- // Flag that destroy should be performed on the next
- // attempt to display.
- sendDestroy = true;
- } else {
- // Without an external thread animating or locking the
- // surface, we are safe.
- destroy ();
- }
+ destroyAvoidAwareOfLocking();
}
}
+
+ /**
+ * Calls {@link #destroy()}
+ * directly if the following requirements are met:
+ *
+ * An {@link GLAnimatorControl} is bound (see {@link #getAnimator()}) and running on another thread.
+ * Here we pause the animation while issuing the destruction.
+ * Surface is not locked by another thread (considered anonymous).
+ *
+ *
+ * Otherwise destroy is being flagged to be called within the next
+ * call of display().
+ *
+ *
+ * This method is being used to avoid deadlock if
+ * destruction is desired by other threads, e.g. the window manager.
+ *
+ * @see #defaultWindowDestroyNotifyOp()
+ * @see #defaultDisplay()
+ */
+ protected final void destroyAvoidAwareOfLocking() {
+ final NativeSurface ns = getNativeSurface();
+
+ final GLAnimatorControl ctrl = helper.getAnimator();
+
+ // Is an animator thread perform rendering?
+ if ( helper.isAnimatorRunningOnOtherThread() ) {
+ // Pause animations before initiating safe destroy.
+ final boolean isPaused = ctrl.pause();
+ destroy();
+ if(isPaused) {
+ ctrl.resume();
+ }
+ } else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
+ // surface is locked by another thread
+ // Flag that destroy should be performed on the next
+ // attempt to display.
+ sendDestroy = true; // async, but avoiding deadlock
+ } else {
+ // Without an external thread animating or locking the
+ // surface, we are safe.
+ destroy();
+ }
+ }
+
+ /**
+ * Calls {@link #destroyImplInLock()} while claiming the lock.
+ */
+ protected final void defaultDestroy() {
+ final RecursiveLock lock = getLock();
+ lock.lock();
+ try {
+ destroyImplInLock();
+ } finally {
+ lock.unlock();
+ }
+ }
/**
* Default implementation to destroys the drawable and context of this GLAutoDrawable:
@@ -137,24 +193,42 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
* destroys the GLContext, if valid
* destroys the GLDrawable, if valid
*
+ * Method assumes the lock is being hold.
+ * Override it to extend it to destroy your resources, i.e. the actual window.
+ * In such case call super.destroyImplInLock
first.
*/
- protected void defaultDestroyOp() {
- if( null != drawable && drawable.isRealized() ) {
- if( null != context && context.isCreated() ) {
+ protected void destroyImplInLock() {
+ final GLContext _context = context;
+ final GLDrawable _drawable = drawable;
+ if( null != _drawable && _drawable.isRealized() ) {
+ if( null != _context && _context.isCreated() ) {
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.disposeGL(this, drawable, context, null);
+ helper.disposeGL(this, _drawable, _context, null);
} catch (GLException gle) {
gle.printStackTrace();
}
}
- drawable.setRealized(false);
+ _drawable.setRealized(false);
}
context = null;
drawable = null;
}
+ public final void defaultSwapBuffers() throws GLException {
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ if(drawable!=null && context != null) {
+ drawable.swapBuffers();
+ helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction);
+ }
+ } finally {
+ _lock.unlock();
+ }
+ }
+
//
// GLAutoDrawable
//
@@ -179,6 +253,30 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
fpsCounter.tickFPS();
} };
+ protected final void defaultDisplay() {
+ if( sendDestroy ) {
+ sendDestroy=false;
+ destroy();
+ return;
+ }
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ if( null != context ) {
+ // surface is locked/unlocked implicit by context's makeCurrent/release
+ helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction);
+ }
+ } finally {
+ _lock.unlock();
+ }
+ }
+
+ protected final Runnable defaultSwapAction = new Runnable() {
+ @Override
+ public final void run() {
+ drawable.swapBuffers();
+ } } ;
+
@Override
public final GLContext getContext() {
return context;
@@ -186,27 +284,35 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
@Override
public final GLContext setContext(GLContext newCtx) {
- final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
- context=(GLContextImpl)newCtx;
- if(newCtxCurrent) {
- context.makeCurrent();
+ final RecursiveLock lock = getLock();
+ lock.lock();
+ try {
+ final GLContext oldCtx = context;
+ final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ context=(GLContextImpl)newCtx;
+ if(newCtxCurrent) {
+ context.makeCurrent();
+ }
+ return oldCtx;
+ } finally {
+ lock.unlock();
}
- return oldCtx;
}
@Override
public final GL getGL() {
- if (context == null) {
+ final GLContext _context = context;
+ if (_context == null) {
return null;
}
- return context.getGL();
+ return _context.getGL();
}
@Override
public final GL setGL(GL gl) {
- if (context != null) {
- context.setGL(gl);
+ final GLContext _context = context;
+ if (_context != null) {
+ _context.setGL(gl);
return gl;
}
return null;
@@ -261,8 +367,9 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
@Override
public final void setContextCreationFlags(int flags) {
additionalCtxCreationFlags = flags;
- if(null != context) {
- context.setContextCreationFlags(additionalCtxCreationFlags);
+ final GLContext _context = context;
+ if(null != _context) {
+ _context.setContextCreationFlags(additionalCtxCreationFlags);
}
}
@@ -331,27 +438,36 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
@Override
public final GLContext createContext(final GLContext shareWith) {
- if(drawable != null) {
- final GLContext _ctx = drawable.createContext(shareWith);
- _ctx.setContextCreationFlags(additionalCtxCreationFlags);
- return _ctx;
+ final RecursiveLock lock = getLock();
+ lock.lock();
+ try {
+ if(drawable != null) {
+ final GLContext _ctx = drawable.createContext(shareWith);
+ _ctx.setContextCreationFlags(additionalCtxCreationFlags);
+ return _ctx;
+ }
+ return null;
+ } finally {
+ lock.unlock();
}
- return null;
}
@Override
public final boolean isRealized() {
- return null != drawable ? drawable.isRealized() : false;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.isRealized() : false;
}
@Override
public int getWidth() {
- return null != drawable ? drawable.getWidth() : 0;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getWidth() : 0;
}
@Override
public int getHeight() {
- return null != drawable ? drawable.getHeight() : 0;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getHeight() : 0;
}
/**
@@ -373,30 +489,27 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
return helper.getSkipContextReleaseThread();
}
- @Override
- public final void swapBuffers() throws GLException {
- if(drawable!=null && context != null) {
- drawable.swapBuffers();
- }
- }
-
@Override
public final GLCapabilitiesImmutable getChosenGLCapabilities() {
- return null != drawable ? drawable.getChosenGLCapabilities() : null;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getChosenGLCapabilities() : null;
}
@Override
public final GLProfile getGLProfile() {
- return null != drawable ? drawable.getGLProfile() : null;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getGLProfile() : null;
}
@Override
public final NativeSurface getNativeSurface() {
- return null != drawable ? drawable.getNativeSurface() : null;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getNativeSurface() : null;
}
@Override
public final long getHandle() {
- return null != drawable ? drawable.getHandle() : 0;
+ final GLDrawable _drawable = drawable;
+ return null != _drawable ? _drawable.getHandle() : 0;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 0c01aa676..090c5fe69 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -189,8 +189,9 @@ public class GLDrawableHelper {
*/
public final void dispose(GLAutoDrawable drawable) {
synchronized(listenersLock) {
- for (int i=0; i < listeners.size(); i++) {
- listeners.get(i).dispose(drawable);
+ final ArrayList _listeners = listeners;
+ for (int i=0; i < _listeners.size(); i++) {
+ _listeners.get(i).dispose(drawable);
}
}
}
@@ -209,8 +210,9 @@ public class GLDrawableHelper {
/** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */
public final void init(GLAutoDrawable drawable) {
synchronized(listenersLock) {
- for (int i=0; i < listeners.size(); i++) {
- final GLEventListener listener = listeners.get(i) ;
+ final ArrayList _listeners = listeners;
+ for (int i=0; i < _listeners.size(); i++) {
+ final GLEventListener listener = _listeners.get(i) ;
// If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
// This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
@@ -232,8 +234,9 @@ public class GLDrawableHelper {
}
private final void displayImpl(GLAutoDrawable drawable) {
synchronized(listenersLock) {
- for (int i=0; i < listeners.size(); i++) {
- final GLEventListener listener = listeners.get(i) ;
+ final ArrayList _listeners = listeners;
+ for (int i=0; i < _listeners.size(); i++) {
+ final GLEventListener listener = _listeners.get(i) ;
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
init( listener, drawable, true /* sendReshape */) ;
@@ -324,7 +327,7 @@ public class GLDrawableHelper {
}
}
- public final boolean isExternalAnimatorRunning() {
+ public final boolean isAnimatorRunningOnOtherThread() {
return ( null != animatorCtrl ) ? animatorCtrl.isStarted() && animatorCtrl.getThread() != Thread.currentThread() : false ;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index bbc28e283..6b64120fe 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -42,10 +42,14 @@ package jogamp.opengl;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/** Platform-independent class exposing pbuffer functionality to
applications. This class is not exposed in the public API as it
would probably add no value; however it implements the GLDrawable
@@ -101,7 +105,7 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
//
// GLDrawable delegation
//
-
+
@Override
public final void setRealized(boolean realized) {
}
@@ -109,6 +113,10 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
//
// GLAutoDrawable completion
//
+ private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
+
+ @Override
+ protected final RecursiveLock getLock() { return lock; }
@Override
public final Object getUpstreamWidget() {
@@ -117,7 +125,7 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
@Override
public void destroy() {
- defaultDestroyOp();
+ defaultDestroy();
}
@Override
@@ -126,12 +134,23 @@ public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
}
@Override
- public void display() {
- if( null != drawable && drawable.isRealized() && null != context ) {
- helper.invokeGL(drawable, context, defaultDisplayAction, initAction);
+ public final void display() {
+ final RecursiveLock _lock = lock;
+ _lock.lock(); // sync: context/drawable could been recreated/destroyed while animating
+ try {
+ if( null != context ) {
+ helper.invokeGL(drawable, context, defaultDisplayAction, initAction);
+ }
+ } finally {
+ _lock.unlock();
}
}
+ @Override
+ public final void swapBuffers() throws GLException {
+ defaultSwapBuffers();
+ }
+
//----------------------------------------------------------------------
// Internals only below this point
//
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 32d44502f..2205aec8e 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -53,6 +53,7 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import jogamp.newt.WindowImpl;
@@ -62,6 +63,7 @@ import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
+import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
@@ -87,13 +89,6 @@ import com.jogamp.opengl.JoglVersion;
* you can inject {@link javax.media.opengl.GLRunnable} objects
* via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.
*
- *
- * NOTE: [MT-0] Methods utilizing [volatile] drawable/context are not synchronized.
- In case any of the methods are called outside of a locked state
- extra care should be added. Maybe we shall expose locking facilities to the user.
- However, since the user shall stick to the GLEventListener model while utilizing
- GLAutoDrawable implementations, she is safe due to the implicit locked state.
- *
*/
public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter {
private final WindowImpl window;
@@ -437,7 +432,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
//e1.printStackTrace();
}
- defaultDestroyOp();
+ destroyImplInLock();
if(Window.DEBUG_IMPLEMENTATION) {
System.err.println("GLWindow.destroy() "+WindowImpl.getThreadName()+", fin");
@@ -515,6 +510,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
private GLContext sharedContext = null;
+ @Override
+ protected final RecursiveLock getLock() {
+ return window.getLock();
+ }
+
/**
* Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.
* At native creation, {@link #setVisible(boolean) setVisible(true)},
@@ -537,19 +537,18 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
return;
}
- window.lockWindow(); // sync: context/drawable could have been recreated/destroyed while animating
+ final RecursiveLock lock = window.getLock();
+ lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating
try {
- if( null == context && 0 display
+ setVisible(true);
}
} finally {
- window.unlockWindow();
+ lock.unlock();
}
}
@@ -559,7 +558,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
private GLDrawableFactory factory;
@Override
- public GLDrawableFactory getFactory() {
+ public final GLDrawableFactory getFactory() {
return factory;
}
@@ -567,6 +566,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
public final void setRealized(boolean realized) {
}
+ @Override
+ public final void swapBuffers() throws GLException {
+ defaultSwapBuffers();
+ }
+
//----------------------------------------------------------------------
// NEWTEventConsumer
//
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 002144b2f..b12e42680 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -564,9 +564,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final int lockSurface() throws NativeWindowException, RuntimeException {
- windowLock.lock();
- surfaceLock.lock();
- int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+ final RecursiveLock _wlock = windowLock;
+ final RecursiveLock _slock = surfaceLock;
+ _wlock.lock();
+ _slock.lock();
+ int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
@@ -583,8 +585,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
- surfaceLock.unlock();
- windowLock.unlock();
+ _slock.unlock();
+ _wlock.unlock();
}
}
}
@@ -593,10 +595,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void unlockSurface() {
- surfaceLock.validateLocked();
- windowLock.validateLocked();
+ final RecursiveLock _slock = surfaceLock;
+ final RecursiveLock _wlock = windowLock;
+ _slock.validateLocked();
+ _wlock.validateLocked();
- if (surfaceLock.getHoldCount() == 1) {
+ if (_slock.getHoldCount() == 1) {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
@@ -604,8 +608,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
adevice.unlock();
}
}
- surfaceLock.unlock();
- windowLock.unlock();
+ _slock.unlock();
+ _wlock.unlock();
}
@Override
@@ -618,21 +622,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return surfaceLock.getOwner();
}
- public final void lockWindow() {
- windowLock.lock();
- }
- public final void unlockWindow() {
- windowLock.unlock();
+ public final RecursiveLock getLock() {
+ return windowLock;
}
- public final boolean isWindowLockedByOtherThread() {
- return windowLock.isLockedByOtherThread();
- }
-
- public final Thread getWindowLockOwner() {
- return windowLock.getOwner();
- }
-
public long getSurfaceHandle() {
return windowHandle; // default: return window handle
}
@@ -670,11 +663,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public Point getLocationOnScreen(Point storage) {
if(isNativeValid()) {
Point d;
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
d = getLocationOnScreenImpl(0, 0);
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
if(null!=d) {
if(null!=storage) {
@@ -717,7 +711,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
boolean nativeWindowCreated = false;
boolean madeVisible = false;
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(null!=lifecycleHook) {
lifecycleHook.resetCounter();
@@ -739,7 +734,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
madeVisible = nativeWindowCreated;
}
// always flag visible, allowing a retry ..
- WindowImpl.this.visible = true;
+ WindowImpl.this.visible = true;
} else if(WindowImpl.this.visible != visible) {
if(isNativeValid()) {
setVisibleImpl(visible, getX(), getY(), getWidth(), getHeight());
@@ -766,7 +761,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
System.err.println("Window setVisible: END ("+getThreadName()+") "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible);
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
if( nativeWindowCreated || madeVisible ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
@@ -801,7 +796,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final void run() {
boolean recreate = false;
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) {
recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
@@ -842,7 +838,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(recreate) {
screen.removeReference(); // bring back ref-count
}
- windowLock.unlock();
+ _lock.unlock();
}
}
}
@@ -863,7 +859,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(null!=lifecycleHook) {
lifecycleHook.destroyActionPreLock();
}
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window DestroyAction() "+getThreadName());
@@ -917,7 +914,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
hasFocus = false;
parentWindowHandle = 0;
- windowLock.unlock();
+ _lock.unlock();
}
if(animatorPaused) {
lifecycleHook.resumeRenderingAction();
@@ -1002,8 +999,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
int width = getWidth();
int height = getHeight();
boolean wasVisible;
-
- windowLock.lock();
+
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(isNativeValid()) {
// force recreation if offscreen, since it may become onscreen
@@ -1220,7 +1218,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
System.err.println("Window.reparentWindow: END-1 ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
if(wasVisible) {
switch (operation) {
@@ -1245,7 +1243,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private class ReparentActionRecreate implements Runnable {
public final void run() {
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
visible = true;
if(DEBUG_IMPLEMENTATION) {
@@ -1253,7 +1252,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
setVisible(true); // native creation
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
}
}
@@ -1291,7 +1290,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final void run() {
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(WindowImpl.this.undecorated != undecorated) {
// set current state
@@ -1311,7 +1311,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
@@ -1333,7 +1333,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final void run() {
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(WindowImpl.this.alwaysOnTop != alwaysOnTop) {
// set current state
@@ -1353,7 +1354,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
@@ -1545,7 +1546,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
"\n, ParentWindow "+parentWindow+
"\n, ParentWindowHandle "+toHexString(parentWindowHandle)+" ("+(0!=getParentWindowHandle())+")"+
"\n, WindowHandle "+toHexString(getWindowHandle())+
- "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+ " (lockedExt window "+isWindowLockedByOtherThread()+", surface "+isSurfaceLockedByOtherThread()+")"+
+ "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+ " (lockedExt window "+windowLock.isLockedByOtherThread()+", surface "+isSurfaceLockedByOtherThread()+")"+
"\n, Pos "+getX()+"/"+getY()+" (auto "+autoPosition()+"), size "+getWidth()+"x"+getHeight()+
"\n, Visible "+isVisible()+", focus "+hasFocus()+
"\n, Undecorated "+undecorated+" ("+isUndecorated()+")"+
@@ -1675,7 +1676,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final void run() {
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setPosition: "+getX()+"/"+getY()+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
@@ -1689,7 +1691,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
}
}
@@ -1718,7 +1720,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public boolean fsOn() { return fullscreen; }
public final void run() {
- windowLock.lock();
+ final RecursiveLock _lock = windowLock;
+ _lock.lock();
try {
// set current state
WindowImpl.this.fullscreen = fullscreen;
@@ -1795,7 +1798,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
} finally {
- windowLock.unlock();
+ _lock.unlock();
}
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
@@ -1917,7 +1920,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// special repaint treatment
case WindowEvent.EVENT_WINDOW_REPAINT:
// queue repaint event in case window is locked, ie in operation
- if( null != getWindowLockOwner() ) {
+ if( null != windowLock.getOwner() ) {
// make sure only one repaint event is queued
if(!repaintQueued) {
repaintQueued=true;
@@ -1936,7 +1939,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// common treatment
case WindowEvent.EVENT_WINDOW_RESIZED:
// queue event in case window is locked, ie in operation
- if( null != getWindowLockOwner() ) {
+ if( null != windowLock.getOwner() ) {
final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen();
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.consumeEvent: "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
index eb716677d..426b7734f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
@@ -87,8 +87,8 @@ public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window) {
@Override
- public void destroy() {
- super.destroy(); // destroys drawable/context
+ protected void destroyImplInLock() {
+ super.destroyImplInLock(); // destroys drawable/context
window.destroy(); // destroys the actual window
}
};
@@ -97,15 +97,15 @@ public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
- glad.defaultWindowRepaintOp();
+ glad.windowRepaintOp();
}
@Override
public void windowResized(WindowEvent e) {
- glad.defaultWindowResizedOp();
+ glad.windowResizedOp();
}
@Override
public void windowDestroyNotify(WindowEvent e) {
- glad.defaultWindowDestroyNotifyOp();
+ glad.windowDestroyNotifyOp();
}
});
window.addWindowListener(wl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
index 06aa29b4f..92b4c5238 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
@@ -90,8 +90,8 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window) {
@Override
- public void destroy() {
- super.destroy(); // destroys drawable/context
+ protected void destroyImplInLock() {
+ super.destroyImplInLock();
window.destroy(); // destroys the actual window
}
};
@@ -100,15 +100,15 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
window.addWindowListener(new WindowAdapter() {
@Override
public void windowRepaint(WindowUpdateEvent e) {
- glad.defaultWindowRepaintOp();
+ glad.windowRepaintOp();
}
@Override
public void windowResized(WindowEvent e) {
- glad.defaultWindowResizedOp();
+ glad.windowResizedOp();
}
@Override
public void windowDestroyNotify(WindowEvent e) {
- glad.defaultWindowDestroyNotifyOp();
+ glad.windowDestroyNotifyOp();
}
});
window.addWindowListener(wl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
index 78988c0e5..b3516d6b4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextSurfaceLockNEWT.java
@@ -33,9 +33,9 @@ import java.io.IOException;
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
-import org.junit.Assert;
import org.junit.Test;
import com.jogamp.newt.opengl.GLWindow;
@@ -69,7 +69,7 @@ public class TestGLContextSurfaceLockNEWT extends UITestCase {
}
public void run() {
- System.err.println("Animatr "+id+": PRE: "+Thread.currentThread().getName());
+ System.err.println("Animatr "+id+", count "+frameCount+": PRE: "+Thread.currentThread().getName());
for(int c=0; c
Date: Tue, 24 Jul 2012 00:14:02 +0200
Subject: Fix GraphicsConfigurationFactory: Map factory to device-type _and_
capabilities-type; Add a pre-set nativeVisualID to
chooseGraphicsConfiguration(..)
Map factory to device-type _and_ capabilities-type:
- Allows using different GraphicsConfigurationFactory implementations for different capabilities-types.
Previous impl. failed to use an OpenGL agnostic CapabilitiesImmutable for 'chooseGraphicsConfiguration(..)'
since only the GL aware factory was mapped. The latter failed since it expected a GLCapabilitiesImmutable.
- The passed capabilities-type as well as device-type given at getFactory(..)
is traversed top-to-down to find a most suitable factory:
For-All devT := getTopDownDeviceTypes(deviceType)
For-All capsT := getTopDownCapabilitiesTypes(capabilitiesType)
f = factory.get(devT, capsT);
if(f) { return f; }
end
end
Add a pre-set nativeVisualID to chooseGraphicsConfiguration(..)
- In situations where a native visualID is already chosen [by external means for example],
but we still need to query a matching GraphicsConfiguration - we require to pass
a non VisualIDHolder.VID_UNDEFINED nativeVisualID.
We had a hack implemented before within some implementations and their static calls,
however an agnostic mechanism is required to implement new NativeSurface/Window's
platform agnostic.
- X11GLXGraphicsConfigurationFactory: respect a pre-set xvisualID
- X11GLXDrawableFactory.createProxySurfaceImpl(..) queries the given windowHandle's
visualID and 'chooses' the configuration accordingly. If the visualID is undefined
an exception is thrown, since window is invalid.
These mechanics are implicit for Windows and OSX.
Fix X11GLXGraphicsConfiguration.updateGraphicsConfiguration():
- Skip any action if a valid X11GLCapabilities is already chosen, i.e. w/ visualID.
Otherwise choose a suitable configuration incl. visualID.
The latter is quite impossible and invalid, since visualID must be defined at window creation time
and the update method is issued with a valid window.
X11 - Misc:
- Added 'int jogamp.nativewindow.x11.X11Lib.GetVisualIDFromWindow(..)'
- All returned visualID's are of type 'int'
---
make/config/nativewindow/x11-CustomJavaCode.java | 4 +-
.../javax/media/opengl/GLDrawableFactory.java | 3 +-
.../classes/javax/media/opengl/awt/GLCanvas.java | 9 +-
.../jogamp/opengl/GLDrawableFactoryImpl.java | 3 +
.../opengl/egl/EGLGraphicsConfiguration.java | 6 +-
.../egl/EGLGraphicsConfigurationFactory.java | 16 +-
.../cgl/MacOSXCGLGraphicsConfigurationFactory.java | 4 +-
.../MacOSXAWTCGLGraphicsConfigurationFactory.java | 8 +-
.../WindowsWGLGraphicsConfigurationFactory.java | 4 +-
.../WindowsAWTWGLGraphicsConfigurationFactory.java | 8 +-
.../opengl/x11/glx/X11ExternalGLXContext.java | 5 +-
.../opengl/x11/glx/X11GLXDrawableFactory.java | 15 +-
.../x11/glx/X11GLXGraphicsConfiguration.java | 29 ++-
.../glx/X11GLXGraphicsConfigurationFactory.java | 113 ++++++++---
.../nativewindow/awt/AWTGraphicsConfiguration.java | 4 +-
.../jogamp/nativewindow/x11/X11GraphicsDevice.java | 2 +-
.../jogamp/nativewindow/x11/X11GraphicsScreen.java | 2 +-
.../nativewindow/GraphicsConfigurationFactory.java | 226 +++++++++++++++++----
.../DefaultGraphicsConfigurationFactoryImpl.java | 2 +-
.../x11/X11GraphicsConfigurationFactory.java | 18 +-
.../awt/X11AWTGraphicsConfigurationFactory.java | 16 +-
src/nativewindow/native/x11/Xmisc.c | 30 ++-
src/newt/classes/jogamp/newt/OffscreenWindow.java | 5 +-
.../classes/jogamp/newt/driver/awt/AWTCanvas.java | 6 +-
.../jogamp/newt/driver/broadcom/egl/Window.java | 5 +-
.../jogamp/newt/driver/intel/gdl/Window.java | 4 +-
.../classes/jogamp/newt/driver/kd/KDWindow.java | 5 +-
.../jogamp/newt/driver/macosx/MacWindow.java | 5 +-
.../jogamp/newt/driver/windows/WindowsWindow.java | 5 +-
.../classes/jogamp/newt/driver/x11/X11Window.java | 4 +-
30 files changed, 422 insertions(+), 144 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/config/nativewindow/x11-CustomJavaCode.java b/make/config/nativewindow/x11-CustomJavaCode.java
index 73439fcc7..56aec4725 100644
--- a/make/config/nativewindow/x11-CustomJavaCode.java
+++ b/make/config/nativewindow/x11-CustomJavaCode.java
@@ -24,7 +24,9 @@
/** Entry point to C language function: XVisualInfo * XGetVisualInfo(Display * , long, XVisualInfo * , int * );
*/
private static native java.nio.ByteBuffer XGetVisualInfo1(long arg0, long arg1, java.nio.ByteBuffer arg2, Object arg3, int arg3_byte_offset);
- public static native long DefaultVisualID(long display, int screen);
+ public static native int GetVisualIDFromWindow(long display, long window);
+
+ public static native int DefaultVisualID(long display, int screen);
public static native long CreateDummyWindow(long display, int screen_index, int visualID, int width, int height);
public static native void DestroyDummyWindow(long display, long window);
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 612a02f14..9a0d2cb99 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -434,7 +434,8 @@ public abstract class GLDrawableFactory {
/**
* Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
*
- * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}.
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given
+ * windowHandle
's native visualID if set or the given {@link GLCapabilitiesImmutable}.
*
*
* Lifecycle (destruction) of the given surface handle shall be handled by the caller.
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 694a081b8..03fd78ac7 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -60,6 +60,7 @@ import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -1062,9 +1063,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
config = (AWTGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class, GLCapabilitiesImmutable.class).chooseGraphicsConfiguration(capsChosen,
capsRequested,
- chooser, aScreen);
+ chooser, aScreen, VisualIDHolder.VID_UNDEFINED);
} else {
try {
final ArrayList bucket = new ArrayList(1);
@@ -1072,9 +1073,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void run() {
AWTGraphicsConfiguration c = (AWTGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class, GLCapabilitiesImmutable.class).chooseGraphicsConfiguration(capsChosen,
capsRequested,
- chooser, aScreen);
+ chooser, aScreen, VisualIDHolder.VID_UNDEFINED);
bucket.add(c);
}
});
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 34bb8704a..f092288fb 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -381,6 +381,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
+ if(0 == windowHandle) {
+ throw new IllegalArgumentException("Null windowHandle");
+ }
device.lock();
try {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 73867fb40..716a6e6f1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -42,6 +42,7 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
@@ -96,9 +97,10 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
void updateGraphicsConfiguration() {
+ CapabilitiesImmutable capsChosen = getChosenCapabilities();
EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(
- getChosenCapabilities(), getRequestedCapabilities(), chooser, getScreen());
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), capsChosen).chooseGraphicsConfiguration(
+ capsChosen, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED);
if(null!=newConfig) {
// FIXME: setScreen( ... );
setChosenCapabilities(newConfig.getChosenCapabilities());
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index d79c351a0..0b21d2054 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -81,27 +81,27 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
// become the pre-selector for X11/.. to match the native visual id w/ EGL, if native ES is selected
final String nwType = NativeWindowFactory.getNativeWindowType(false);
if(NativeWindowFactory.TYPE_X11 == nwType) {
- nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, eglFactory);
+ nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
} /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, eglFactory);
} else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
// become the selector for KD/EGL ..
- kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, eglFactory);
+ kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
}
static void unregisterFactory() {
final String nwType = NativeWindowFactory.getNativeWindowType(false);
if(NativeWindowFactory.TYPE_X11 == nwType) {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, nativeGraphicsConfigurationFactory);
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, nativeGraphicsConfigurationFactory);
} /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, nativeGraphicsConfigurationFactory);
} else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
nativeGraphicsConfigurationFactory = null;
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, kdeglGraphicsConfigurationFactory);
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, kdeglGraphicsConfigurationFactory);
kdeglGraphicsConfigurationFactory = null;
}
@@ -110,7 +110,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl (
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
if (absScreen == null) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects");
}
@@ -140,7 +140,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
cfg = chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable) capsChosen,
(GLCapabilitiesImmutable) capsRequested,
(GLCapabilitiesChooser) chooser,
- absScreen, VisualIDHolder.VID_UNDEFINED, false);
+ absScreen, nativeVisualID, false);
} else {
// handle non native cases (X11, ..)
if(null == nativeGraphicsConfigurationFactory) {
@@ -154,7 +154,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
cfg = chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable) capsChosen,
(GLCapabilitiesImmutable) capsRequested,
(GLCapabilitiesChooser) chooser,
- absScreen, VisualIDHolder.VID_UNDEFINED, false);
+ absScreen, nativeVisualID, false);
if(null == cfg || VisualIDHolder.VID_UNDEFINED == cfg.getVisualID(VIDType.NATIVE)) {
cfg = null;
if(DEBUG) {
@@ -167,7 +167,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+nativeGraphicsConfigurationFactory.getClass().getSimpleName());
}
- cfg = nativeGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen);
+ cfg = nativeGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
}
}
return cfg;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index 1a9070aef..f138e7557 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -50,14 +50,14 @@ import javax.media.opengl.GLCapabilitiesImmutable;
public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice.class, new MacOSXCGLGraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice.class, GLCapabilitiesImmutable.class, new MacOSXCGLGraphicsConfigurationFactory());
}
private MacOSXCGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, absScreen, false);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
index a6fa01bad..edf9b7c84 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
@@ -58,14 +58,14 @@ import jogamp.opengl.macosx.cgl.MacOSXCGLGraphicsConfiguration;
public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
public static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, new MacOSXAWTCGLGraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, GLCapabilitiesImmutable.class, new MacOSXAWTCGLGraphicsConfigurationFactory());
}
private MacOSXAWTCGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
GraphicsDevice device = null;
if (absScreen != null &&
!(absScreen instanceof AWTGraphicsScreen)) {
@@ -103,9 +103,9 @@ public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigur
GraphicsConfiguration gc = device.getDefaultConfiguration();
MacOSXCGLGraphicsConfiguration macConfig = (MacOSXCGLGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(macDevice).chooseGraphicsConfiguration(capsChosen,
+ GraphicsConfigurationFactory.getFactory(macDevice, capsChosen).chooseGraphicsConfiguration(capsChosen,
capsRequested,
- chooser, macScreen);
+ chooser, macScreen, nativeVisualID);
if (macConfig == null) {
throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+macScreen);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 943c7fec4..00ed91bb4 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -69,13 +69,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
static VisualIDHolder.VIDComparator PfdIDComparator = new VisualIDHolder.VIDComparator(VisualIDHolder.VIDType.WIN32_PFD);
static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.windows.WindowsGraphicsDevice.class, new WindowsWGLGraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.windows.WindowsGraphicsDevice.class, GLCapabilitiesImmutable.class, new WindowsWGLGraphicsConfigurationFactory());
}
private WindowsWGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
if (! (capsChosen instanceof GLCapabilitiesImmutable) ) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen");
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
index bd64b58a4..3b2ff133a 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -63,14 +63,14 @@ import javax.media.opengl.GLDrawableFactory;
public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
public static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, new WindowsAWTWGLGraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, GLCapabilitiesImmutable.class, new WindowsAWTWGLGraphicsConfigurationFactory());
}
private WindowsAWTWGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
GraphicsDevice device = null;
if (absScreen != null &&
!(absScreen instanceof AWTGraphicsScreen)) {
@@ -105,11 +105,11 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu
WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex());
- GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice);
+ GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice, capsChosen);
WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration)
configFactory.chooseGraphicsConfiguration(capsChosen,
capsRequested,
- chooser, winScreen);
+ chooser, winScreen, nativeVisualID);
if (winConfig == null) {
throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index b847363e0..1f3edbd8a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -41,6 +41,7 @@
package jogamp.opengl.x11.glx;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
@@ -94,9 +95,9 @@ public class X11ExternalGLXContext extends X11GLXContext {
// of 0, which doesn't work in a subsequent call to glXChooseFBConfig; if this happens,
// create and use a default config (this has been observed when running on CentOS 5.5 inside
// of VMWare Server 2.0 with the Mesa 6.5.1 drivers)
- if( X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val[0]) ) {
+ if( VisualIDHolder.VID_UNDEFINED == val[0] || !X11GLXGraphicsConfiguration.GLXFBConfigIDValid(display, x11Screen.getIndex(), val[0]) ) {
GLCapabilities glcapsDefault = new GLCapabilities(GLProfile.getDefault());
- cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(glcapsDefault, glcapsDefault, null, x11Screen);
+ cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(glcapsDefault, glcapsDefault, null, x11Screen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG) {
System.err.println("X11ExternalGLXContext invalid FBCONFIG_ID "+val[0]+", using default cfg: " + cfg);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 8ffbf3951..b2e74f9d4 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -50,6 +50,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -514,7 +515,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
device = (X11GraphicsDevice)deviceReq;
}
final X11GraphicsScreen screen = new X11GraphicsScreen(device, 0);
- final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen);
+ final X11GLXGraphicsConfiguration config = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
@@ -582,7 +583,17 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
protected final ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(deviceReq.getConnection()), deviceReq.getUnitID(), NativeWindowFactory.getNullToolkitLock(), true);
final X11GraphicsScreen screen = new X11GraphicsScreen(device, screenIdx);
- final X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen);
+ final int xvisualID = X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
+ if(VisualIDHolder.VID_UNDEFINED == xvisualID) {
+ throw new GLException("Undefined VisualID of window 0x"+Long.toHexString(windowHandle)+", window probably invalid");
+ }
+ if(DEBUG) {
+ System.err.println("X11GLXDrawableFactory.createProxySurfaceImpl 0x"+Long.toHexString(windowHandle)+": visualID 0x"+Integer.toHexString(xvisualID));
+ }
+ final X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, xvisualID);
+ if(DEBUG) {
+ System.err.println("X11GLXDrawableFactory.createProxySurfaceImpl 0x"+Long.toHexString(windowHandle)+": "+cfg);
+ }
return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index 95b1cc457..b458fffe1 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -37,7 +37,9 @@ import java.util.ArrayList;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
@@ -102,16 +104,25 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
void updateGraphicsConfiguration() {
- X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(
- getChosenCapabilities(), getRequestedCapabilities(), chooser, getScreen());
- if(null!=newConfig) {
- // FIXME: setScreen( ... );
- setXVisualInfo(newConfig.getXVisualInfo());
- setChosenCapabilities(newConfig.getChosenCapabilities());
- if(DEBUG) {
- System.err.println("updateGraphicsConfiguration: "+this);
+ final CapabilitiesImmutable aChosenCaps = getChosenCapabilities();
+ if( !(aChosenCaps instanceof X11GLCapabilities) || VisualIDHolder.VID_UNDEFINED == aChosenCaps.getVisualID(VIDType.X11_XVISUAL) ) {
+ // This case is actually quite impossible, since on X11 the visualID and hence GraphicsConfiguration
+ // must be determined _before_ window creation!
+ final X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), aChosenCaps).chooseGraphicsConfiguration(
+ aChosenCaps, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED);
+ if(null!=newConfig) {
+ // FIXME: setScreen( ... );
+ setXVisualInfo(newConfig.getXVisualInfo());
+ setChosenCapabilities(newConfig.getChosenCapabilities());
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.updateGraphicsConfiguration updated:"+this);
+ }
+ } else {
+ throw new GLException("No native VisualID pre-chosen and update failed: "+this);
}
+ } else if (DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.updateGraphicsConfiguration kept:"+this);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 331401c06..234b06bdb 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -40,6 +40,7 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
@@ -74,20 +75,24 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
static GraphicsConfigurationFactory fallbackX11GraphicsConfigurationFactory = null;
static void registerFactory() {
final GraphicsConfigurationFactory newFactory = new X11GLXGraphicsConfigurationFactory();
- final GraphicsConfigurationFactory oldFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, newFactory);
+ final GraphicsConfigurationFactory oldFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, newFactory);
if(oldFactory == newFactory) {
throw new InternalError("GraphicsConfigurationFactory lifecycle impl. error");
}
- if(null == oldFactory) {
- throw new InternalError("Missing fallback GraphicsConfigurationFactory");
+ if(null != oldFactory) {
+ fallbackX11GraphicsConfigurationFactory = oldFactory;
+ } else {
+ fallbackX11GraphicsConfigurationFactory = GraphicsConfigurationFactory.getFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, CapabilitiesImmutable.class);
+ if( null == fallbackX11GraphicsConfigurationFactory ) {
+ throw new InternalError("Missing fallback GraphicsConfigurationFactory");
+ }
}
- fallbackX11GraphicsConfigurationFactory = oldFactory;
}
private X11GLXGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
if (!(absScreen instanceof X11GraphicsScreen)) {
throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here");
}
@@ -109,12 +114,12 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
if(DEBUG) {
System.err.println("No GLX available, fallback to "+fallbackX11GraphicsConfigurationFactory.getClass().getSimpleName()+" for: "+absScreen);
}
- return fallbackX11GraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen);
+ return fallbackX11GraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, VisualIDHolder.VID_UNDEFINED);
}
throw new InternalError("No GLX and no fallback GraphicsConfigurationFactory available for: "+absScreen);
}
return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested,
- (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen);
+ (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen, nativeVisualID);
}
protected static List getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) {
@@ -199,7 +204,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
- X11GraphicsScreen x11Screen) {
+ X11GraphicsScreen x11Screen, int xvisualID) {
if (x11Screen == null) {
throw new IllegalArgumentException("AbstractGraphicsScreen is null");
}
@@ -215,19 +220,19 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
X11GLXGraphicsConfiguration res = null;
if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
- res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen);
+ res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen, xvisualID);
}
if(null==res) {
if(usePBuffer) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen);
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for visualID "+toHexString(xvisualID)+", "+capsChosen);
}
- res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen);
+ res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen, xvisualID);
}
if(null==res) {
- throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+capsChosen);
+ throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for visualID "+toHexString(xvisualID)+", "+x11Screen+", "+capsChosen);
}
if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+capsChosen+"): "+res);
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic(visualID "+toHexString(xvisualID)+", "+x11Screen+","+capsChosen+"): "+res);
}
return res;
}
@@ -253,7 +258,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
- X11GraphicsScreen x11Screen) {
+ X11GraphicsScreen x11Screen, int xvisualID) {
int recommendedIndex = -1;
PointerBuffer fbcfgsL = null;
GLProfile glProfile = capsChosen.getGLProfile();
@@ -273,8 +278,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
int[] count = { -1 };
List availableCaps = new ArrayList();
final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
- // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
- fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice,
+ // skipped if xvisualID is given
+ if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
+ fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
+ }
if (fbcfgsL != null && fbcfgsL.limit()>0) {
for (int i = 0; i < fbcfgsL.limit(); i++) {
if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
@@ -317,6 +325,33 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
}
}
+
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: got configs: "+availableCaps.size());
+ for(int i=0; i chosenIndex ) {
if (DEBUG) {
@@ -333,7 +368,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
- X11GraphicsScreen x11Screen) {
+ X11GraphicsScreen x11Screen, int xvisualID) {
if (chooser == null) {
chooser = new DefaultGLCapabilitiesChooser();
}
@@ -351,14 +386,18 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
+ XVisualInfo recommendedVis = null;
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
- XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
- if (DEBUG) {
- System.err.print("glXChooseVisual recommended ");
- if (recommendedVis == null) {
- System.err.println("null visual");
- } else {
- System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
+ // skipped if xvisualID is given
+ if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
+ recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
+ if (DEBUG) {
+ System.err.print("glXChooseVisual recommended ");
+ if (recommendedVis == null) {
+ System.err.println("null visual");
+ } else {
+ System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
+ }
}
}
@@ -384,6 +423,32 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
}
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: got configs: "+availableCaps.size());
+ for(int i=0; i chosenIndex ) {
if (DEBUG) {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
index 61d5e5c0d..2a152ff35 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -95,8 +95,8 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc);
}
- final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice);
- final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen);
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice, capsChosen);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen, VisualIDHolder.VID_UNDEFINED);
if(config instanceof AWTGraphicsConfiguration) {
return (AWTGraphicsConfiguration) config;
}
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
index 7a98e3c25..5e4d6f41a 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java
@@ -88,7 +88,7 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
// It still could be an AWT hold handle ..
final long display = getHandle();
final int scrnIdx = X11Lib.DefaultScreen(display);
- return (int) X11Lib.DefaultVisualID(display, scrnIdx);
+ return X11Lib.DefaultVisualID(display, scrnIdx);
}
@Override
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
index 014f4f688..5f3c220ca 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsScreen.java
@@ -58,7 +58,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
public int getVisualID() {
// It still could be an AWT hold handle ..
- return (int) X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
+ return X11Lib.DefaultVisualID(getDevice().getHandle(), getIndex());
}
private static int fetchScreen(X11GraphicsDevice device, int screen) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index 2610f2cfa..c3fdc6798 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -36,9 +36,15 @@ package javax.media.nativewindow;
import com.jogamp.common.util.ReflectionUtil;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.DefaultGraphicsConfigurationFactoryImpl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Provides the mechanism by which the graphics configuration for a
@@ -59,8 +65,43 @@ import java.util.Map;
public abstract class GraphicsConfigurationFactory {
protected static final boolean DEBUG;
- private static Map, GraphicsConfigurationFactory> registeredFactories;
- private static Class> abstractGraphicsDeviceClass;
+ private static class DeviceCapsType {
+ public final Class> deviceType;
+ public final Class> capsType;
+ private final int hash32;
+
+ public DeviceCapsType(Class> deviceType, Class> capsType) {
+ this.deviceType = deviceType;
+ this.capsType = capsType;
+
+ // 31 * x == (x << 5) - x
+ int hash32 = 31 + deviceType.hashCode();
+ hash32 = ((hash32 << 5) - hash32) + capsType.hashCode();
+ this.hash32 = hash32;
+ }
+
+ public final int hashCode() {
+ return hash32;
+ }
+
+ public final boolean equals(Object obj) {
+ if(this == obj) { return true; }
+ if (obj instanceof DeviceCapsType) {
+ DeviceCapsType dct = (DeviceCapsType)obj;
+ return deviceType == dct.deviceType && capsType == dct.capsType;
+ }
+ return false;
+ }
+
+ @Override
+ public final String toString() {
+ return "DeviceCapsType["+deviceType.getName()+", "+capsType.getName()+"]";
+ }
+
+ }
+
+ private static final Map registeredFactories;
+ private static final DeviceCapsType defaultDeviceCapsType;
static boolean initialized = false;
static {
@@ -69,7 +110,8 @@ public abstract class GraphicsConfigurationFactory {
System.err.println(Thread.currentThread().getName()+" - Info: GraphicsConfigurationFactory.");
// Thread.dumpStack();
}
- abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class;
+ registeredFactories = Collections.synchronizedMap(new HashMap());
+ defaultDeviceCapsType = new DeviceCapsType(AbstractGraphicsDevice.class, CapabilitiesImmutable.class);
}
public static synchronized void initSingleton() {
@@ -79,14 +121,13 @@ public abstract class GraphicsConfigurationFactory {
if(DEBUG) {
System.err.println(Thread.currentThread().getName()+" - GraphicsConfigurationFactory.initSingleton()");
}
- registeredFactories = Collections.synchronizedMap(new HashMap, GraphicsConfigurationFactory>());
// Register the default no-op factory for arbitrary
// AbstractGraphicsDevice implementations, including
// AWTGraphicsDevice instances -- the OpenGL binding will take
// care of handling AWTGraphicsDevices on X11 platforms (as
// well as X11GraphicsDevices in non-AWT situations)
- registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl());
+ registerFactory(defaultDeviceCapsType.deviceType, defaultDeviceCapsType.capsType, new DefaultGraphicsConfigurationFactoryImpl());
if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
try {
@@ -112,7 +153,6 @@ public abstract class GraphicsConfigurationFactory {
System.err.println(Thread.currentThread().getName()+" - GraphicsConfigurationFactory.shutdown()");
}
registeredFactories.clear();
- registeredFactories = null;
}
}
@@ -133,74 +173,175 @@ public abstract class GraphicsConfigurationFactory {
protected GraphicsConfigurationFactory() {
}
- /** Returns the factory for use with the given type of
- AbstractGraphicsDevice. */
- public static GraphicsConfigurationFactory getFactory(AbstractGraphicsDevice device) {
+ /**
+ * Returns the graphics configuration factory for use with the
+ * given device and capability.
+ *
+ * @see #getFactory(Class, Class)
+ */
+ public static GraphicsConfigurationFactory getFactory(AbstractGraphicsDevice device, CapabilitiesImmutable caps) {
if (device == null) {
- return getFactory(AbstractGraphicsDevice.class);
+ throw new IllegalArgumentException("null device");
+ }
+ if (caps == null) {
+ throw new IllegalArgumentException("null caps");
}
- return getFactory(device.getClass());
+ return getFactory(device.getClass(), caps.getClass());
}
/**
* Returns the graphics configuration factory for use with the
- * given class, which must implement the {@link
- * AbstractGraphicsDevice} interface.
+ * given device and capability class.
+ *
+ * Note: Registered device types maybe classes or interfaces, where capabilities types are interfaces only.
+ *
+ *
+ *
+ * Pseudo code for finding a suitable factory is:
+ *
+ For-All devT := getTopDownDeviceTypes(deviceType)
+ For-All capsT := getTopDownCapabilitiesTypes(capabilitiesType)
+ f = factory.get(devT, capsT);
+ if(f) { return f; }
+ end
+ end
+ *
+ *
*
- * @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
+ * @param deviceType the minimum capabilities class type accepted, must implement or extend {@link AbstractGraphicsDevice}
+ * @param capabilitiesType the minimum capabilities class type accepted, must implement or extend {@link CapabilitiesImmutable}
+ *
+ * @throws IllegalArgumentException if the deviceType does not implement {@link AbstractGraphicsDevice} or
+ * capabilitiesType does not implement {@link CapabilitiesImmutable}
*/
- public static GraphicsConfigurationFactory getFactory(Class> abstractGraphicsDeviceImplementor)
+ public static GraphicsConfigurationFactory getFactory(Class> deviceType, Class> capabilitiesType)
throws IllegalArgumentException, NativeWindowException
{
- if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
+ if (!(defaultDeviceCapsType.deviceType.isAssignableFrom(deviceType))) {
throw new IllegalArgumentException("Given class must implement AbstractGraphicsDevice");
}
-
- GraphicsConfigurationFactory factory = null;
- Class> clazz = abstractGraphicsDeviceImplementor;
- while (clazz != null) {
- factory = registeredFactories.get(clazz);
- if (factory != null) {
- if(DEBUG) {
- System.err.println("GraphicsConfigurationFactory.getFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory);
+ if (!(defaultDeviceCapsType.capsType.isAssignableFrom(capabilitiesType))) {
+ throw new IllegalArgumentException("Given capabilities class must implement CapabilitiesImmutable");
+ }
+ if(DEBUG) {
+ Thread.dumpStack();
+ System.err.println("GraphicsConfigurationFactory.getFactory: "+deviceType.getName()+", "+capabilitiesType.getName());
+ dumpFactories();
+ }
+
+ final List> deviceTypes = getAllAssignableClassesFrom(defaultDeviceCapsType.deviceType, deviceType, false);
+ if(DEBUG) {
+ System.err.println("GraphicsConfigurationFactory.getFactory() deviceTypes: " + deviceTypes);
+ }
+ final List> capabilitiesTypes = getAllAssignableClassesFrom(defaultDeviceCapsType.capsType, capabilitiesType, true);
+ if(DEBUG) {
+ System.err.println("GraphicsConfigurationFactory.getFactory() capabilitiesTypes: " + capabilitiesTypes);
+ }
+ for(int j=0; j interfaceDevice = deviceTypes.get(j);
+ for(int i=0; i interfaceCaps = capabilitiesTypes.get(i);
+ final DeviceCapsType dct = new DeviceCapsType(interfaceDevice, interfaceCaps);
+ final GraphicsConfigurationFactory factory = registeredFactories.get(dct);
+ if (factory != null) {
+ if(DEBUG) {
+ System.err.println("GraphicsConfigurationFactory.getFactory() found "+dct+" -> "+factory);
+ }
+ return factory;
}
- return factory;
}
- clazz = clazz.getSuperclass();
}
// Return the default
- factory = registeredFactories.get(abstractGraphicsDeviceClass);
+ final GraphicsConfigurationFactory factory = registeredFactories.get(defaultDeviceCapsType);
if(DEBUG) {
- System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+abstractGraphicsDeviceClass+" -> "+factory);
+ System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+defaultDeviceCapsType+" -> "+factory);
}
return factory;
}
+ private static ArrayList> getAllAssignableClassesFrom(Class> superClassOrInterface, Class> fromClass, boolean interfacesOnly) {
+ // Using a todo list avoiding a recursive loop!
+ final ArrayList> inspectClasses = new ArrayList>();
+ final ArrayList> resolvedInterfaces = new ArrayList>();
+ inspectClasses.add(fromClass);
+ for(int j=0; j clazz = inspectClasses.get(j);
+ getAllAssignableClassesFrom(superClassOrInterface, clazz, interfacesOnly, resolvedInterfaces, inspectClasses);
+ }
+ return resolvedInterfaces;
+ }
+ private static void getAllAssignableClassesFrom(Class> superClassOrInterface, Class> fromClass, boolean interfacesOnly, List> resolvedInterfaces, List> inspectClasses) {
+ final ArrayList> types = new ArrayList>();
+ if( superClassOrInterface.isAssignableFrom(fromClass) && !resolvedInterfaces.contains(fromClass)) {
+ if( !interfacesOnly || fromClass.isInterface() ) {
+ types.add(fromClass);
+ }
+ }
+ types.addAll(Arrays.asList(fromClass.getInterfaces()));
+
+ for(int i=0; i iface = types.get(i);
+ if( superClassOrInterface.isAssignableFrom(iface) && !resolvedInterfaces.contains(iface) ) {
+ resolvedInterfaces.add(iface);
+ if( !superClassOrInterface.equals(iface) && !inspectClasses.contains(iface) ) {
+ inspectClasses.add(iface); // safe add to todo list, avoiding a recursive nature
+ }
+ }
+ }
+ final Class> parentClass = fromClass.getSuperclass();
+ if( null != parentClass && superClassOrInterface.isAssignableFrom(parentClass) && !inspectClasses.contains(parentClass) ) {
+ inspectClasses.add(parentClass); // safe add to todo list, avoiding a recursive nature
+ }
+ }
+ private static void dumpFactories() {
+ Set dcts = registeredFactories.keySet();
+ int i=0;
+ for(Iterator iter = dcts.iterator(); iter.hasNext(); ) {
+ DeviceCapsType dct = iter.next();
+ System.err.println("Factory #"+i+": "+dct+" -> "+registeredFactories.get(dct));
+ i++;
+ }
+ }
- /** Registers a GraphicsConfigurationFactory handling graphics
- * device objects of the given class. This does not need to be
- * called by end users, only implementors of new
+ /**
+ * Registers a GraphicsConfigurationFactory handling
+ * the given graphics device and capability class.
+ *
+ * This does not need to be called by end users, only implementors of new
* GraphicsConfigurationFactory subclasses.
- *
+ *
+ *
+ *
+ * Note: Registered device types maybe classes or interfaces, where capabilities types are interfaces only.
+ *
+ *
+ * See {@link #getFactory(Class, Class)} for a description of the find algorithm.
+ *
+ * @param deviceType the minimum capabilities class type accepted, must implement or extend interface {@link AbstractGraphicsDevice}
+ * @param capabilitiesType the minimum capabilities class type accepted, must extend interface {@link CapabilitiesImmutable}
* @return the previous registered factory, or null if none
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- protected static GraphicsConfigurationFactory registerFactory(Class> abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
+ protected static GraphicsConfigurationFactory registerFactory(Class> abstractGraphicsDeviceImplementor, Class> capabilitiesType, GraphicsConfigurationFactory factory)
throws IllegalArgumentException
{
- if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
- throw new IllegalArgumentException("Given class must implement AbstractGraphicsDevice");
+ if (!(defaultDeviceCapsType.deviceType.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
+ throw new IllegalArgumentException("Given device class must implement AbstractGraphicsDevice");
}
+ if (!(defaultDeviceCapsType.capsType.isAssignableFrom(capabilitiesType))) {
+ throw new IllegalArgumentException("Given capabilities class must implement CapabilitiesImmutable");
+ }
+ final DeviceCapsType dct = new DeviceCapsType(abstractGraphicsDeviceImplementor, capabilitiesType);
final GraphicsConfigurationFactory prevFactory;
if(null == factory) {
- prevFactory = registeredFactories.remove(abstractGraphicsDeviceImplementor);
+ prevFactory = registeredFactories.remove(dct);
if(DEBUG) {
- System.err.println("GraphicsConfigurationFactory.registerFactory() remove "+abstractGraphicsDeviceImplementor+
+ System.err.println("GraphicsConfigurationFactory.registerFactory() remove "+dct+
", deleting: "+prevFactory);
}
} else {
- prevFactory = registeredFactories.put(abstractGraphicsDeviceImplementor, factory);
+ prevFactory = registeredFactories.put(dct, factory);
if(DEBUG) {
- System.err.println("GraphicsConfigurationFactory.registerFactory() put "+abstractGraphicsDeviceImplementor+" -> "+factory+
+ System.err.println("GraphicsConfigurationFactory.registerFactory() put "+dct+" -> "+factory+
", overridding: "+prevFactory);
}
}
@@ -244,6 +385,7 @@ public abstract class GraphicsConfigurationFactory {
* @param capsRequested the original requested capabilities
* @param chooser the choosing implementation
* @param screen the referring Screen
+ * @param nativeVisualID if not {@link VisualIDHolder#VID_UNDEFINED} it reflects a pre-chosen visualID of the native platform's windowing system.
* @return the complete GraphicsConfiguration
*
* @throws IllegalArgumentException if the data type of the passed
@@ -258,7 +400,7 @@ public abstract class GraphicsConfigurationFactory {
public final AbstractGraphicsConfiguration
chooseGraphicsConfiguration(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser,
- AbstractGraphicsScreen screen)
+ AbstractGraphicsScreen screen, int nativeVisualID)
throws IllegalArgumentException, NativeWindowException {
if(null==capsChosen) {
throw new NativeWindowException("Chosen Capabilities are null");
@@ -275,7 +417,7 @@ public abstract class GraphicsConfigurationFactory {
}
device.lock();
try {
- return chooseGraphicsConfigurationImpl(capsChosen, capsRequested, chooser, screen);
+ return chooseGraphicsConfigurationImpl(capsChosen, capsRequested, chooser, screen, nativeVisualID);
} finally {
device.unlock();
}
@@ -283,7 +425,7 @@ public abstract class GraphicsConfigurationFactory {
protected abstract AbstractGraphicsConfiguration
chooseGraphicsConfigurationImpl(CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
+ CapabilitiesChooser chooser, AbstractGraphicsScreen screen, int nativeVisualID)
throws IllegalArgumentException, NativeWindowException;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java
index f34b740d4..52e9c8308 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/DefaultGraphicsConfigurationFactoryImpl.java
@@ -37,7 +37,7 @@ import javax.media.nativewindow.*;
public class DefaultGraphicsConfigurationFactoryImpl extends GraphicsConfigurationFactory {
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen) {
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen, int nativeVisualID) {
return new DefaultGraphicsConfiguration(screen, capsChosen, capsRequested);
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index 070f87216..b11dd1df1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -39,33 +39,39 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.VisualIDHolder;
import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
public static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, new X11GraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, CapabilitiesImmutable.class, new X11GraphicsConfigurationFactory());
}
private X11GraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
- CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen, int nativeVisualID)
throws IllegalArgumentException, NativeWindowException {
if(!(screen instanceof X11GraphicsScreen)) {
throw new NativeWindowException("Only valid X11GraphicsScreen are allowed");
}
- final X11Capabilities x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, capsChosen));
- AbstractGraphicsConfiguration res = new X11GraphicsConfiguration((X11GraphicsScreen)screen, x11CapsChosen, capsRequested, x11CapsChosen.getXVisualInfo());
+ final X11Capabilities x11CapsChosen;
+ if(VisualIDHolder.VID_UNDEFINED == nativeVisualID) {
+ x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, capsChosen));
+ } else {
+ x11CapsChosen = new X11Capabilities(getXVisualInfo(screen, nativeVisualID));
+ }
+ final AbstractGraphicsConfiguration res = new X11GraphicsConfiguration((X11GraphicsScreen)screen, x11CapsChosen, capsRequested, x11CapsChosen.getXVisualInfo());
if(DEBUG) {
- System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl("+screen+","+capsChosen+"): "+res);
+ System.err.println("X11GraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(visualID 0x"+Integer.toHexString(nativeVisualID)+", "+screen+","+capsChosen+"): "+res);
}
return res;
}
- public static XVisualInfo getXVisualInfo(AbstractGraphicsScreen screen, long visualID)
+ public static XVisualInfo getXVisualInfo(AbstractGraphicsScreen screen, int visualID)
{
XVisualInfo xvi_temp = XVisualInfo.create();
xvi_temp.setVisualid(visualID);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
index b6bf63d44..1de03e8be 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -61,14 +61,14 @@ import jogamp.nativewindow.x11.X11Util;
public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
public static void registerFactory() {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, new X11AWTGraphicsConfigurationFactory());
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.awt.AWTGraphicsDevice.class, CapabilitiesImmutable.class, new X11AWTGraphicsConfigurationFactory());
}
private X11AWTGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
if (absScreen != null &&
!(absScreen instanceof AWTGraphicsScreen)) {
throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
@@ -77,18 +77,18 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
absScreen = AWTGraphicsScreen.createDefault();
}
- return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, (AWTGraphicsScreen)absScreen);
+ return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, (AWTGraphicsScreen)absScreen, nativeVisualID);
}
public static AWTGraphicsConfiguration chooseGraphicsConfigurationStatic(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AWTGraphicsScreen awtScreen) {
+ CapabilitiesChooser chooser, AWTGraphicsScreen awtScreen, int nativeVisualID) {
if(DEBUG) {
System.err.println("X11AWTGraphicsConfigurationFactory: got "+awtScreen);
}
final GraphicsDevice device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
-
+
final long displayHandleAWT = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
final long displayHandle;
boolean owner = false;
@@ -121,8 +121,8 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
System.err.println("X11AWTGraphicsConfigurationFactory: made "+x11Screen);
}
- final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device);
- AbstractGraphicsConfiguration aConfig = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device, capsChosen);
+ AbstractGraphicsConfiguration aConfig = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen, nativeVisualID);
if (aConfig == null) {
throw new NativeWindowException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
}
@@ -160,7 +160,7 @@ public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFac
// try again using an AWT Colormodel compatible configuration
GraphicsConfiguration gc = device.getDefaultConfiguration();
capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsChosen, gc);
- aConfig = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ aConfig = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen, nativeVisualID);
if (aConfig == null) {
throw new NativeWindowException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
}
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index 21771c9aa..fcba8580c 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -362,14 +362,40 @@ Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Lja
return jbyteCopy;
}
-JNIEXPORT jlong JNICALL
+JNIEXPORT jint JNICALL
+Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _unused, jlong display, jlong window) {
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+ XWindowAttributes xwa;
+ jlong r = 0; // undefinded
+
+ if(NULL==dpy) {
+ NativewindowCommon_throwNewRuntimeException(env, "invalid display connection..");
+ return;
+ }
+
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 1, 0, 1);
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(NULL != xwa.visual) {
+ r = (jint) XVisualIDFromVisual( xwa.visual );
+ } else {
+ r = 0;
+ }
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1);
+
+ return r;
+}
+
+
+JNIEXPORT jint JNICALL
Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
jlong r;
if(0==display) {
NativewindowCommon_FatalError(env, "invalid display connection..");
}
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 1, 0, 0);
- r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
+ r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, 0);
return r;
}
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index be543aba9..ba98ca3af 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -40,6 +40,7 @@ import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
@@ -72,8 +73,8 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
dummySurface.createNotify();
}
} */
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice(), capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 5a49dd57c..a7950048a 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -46,6 +46,7 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.VisualIDHolder;
import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
@@ -53,6 +54,7 @@ import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
import com.jogamp.newt.Window;
+@SuppressWarnings("serial")
public class AWTCanvas extends Canvas {
private GraphicsDevice device;
private GraphicsConfiguration chosen;
@@ -252,9 +254,9 @@ public class AWTCanvas extends Canvas {
AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT):
AWTGraphicsScreen.createDefault();
AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class, capsChosen.getClass()).chooseGraphicsConfiguration(capsChosen,
capsRequested,
- chooser, aScreen);
+ chooser, aScreen, VisualIDHolder.VID_UNDEFINED);
if (config == null) {
throw new NativeWindowException("Error: Couldn't fetch AWTGraphicsConfiguration");
}
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
index ed1d0511a..223ad6484 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
@@ -37,6 +37,7 @@ package jogamp.newt.driver.broadcom.egl;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -57,8 +58,8 @@ public class Window extends jogamp.newt.WindowImpl {
}
// query a good configuration, however chose the final one by the native queried egl-cfg-id
// after creation at {@link #windowCreated(int, int, int)}.
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
index 09e0e3016..d5c75abd4 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
@@ -54,8 +54,8 @@ public class Window extends jogamp.newt.WindowImpl {
final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
final AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice, capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen, VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
index bb76d21ff..9f9d6948e 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
@@ -37,6 +37,7 @@ package jogamp.newt.driver.kd;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
@@ -59,8 +60,8 @@ public class KDWindow extends WindowImpl {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index fcca5c843..720d4ee4c 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -39,6 +39,7 @@ import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
@@ -61,8 +62,8 @@ public class MacWindow extends WindowImpl implements MutableSurface, DriverClear
@Override
protected void createNativeImpl() {
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
index 5e636d982..34d76a148 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
@@ -41,6 +41,7 @@ import jogamp.newt.WindowImpl;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
@@ -119,8 +120,8 @@ public class WindowsWindow extends WindowImpl {
protected void createNativeImpl() {
final WindowsScreen screen = (WindowsScreen) getScreen();
final WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
- final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
index 9a5074c29..5501f5a3c 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
@@ -63,9 +63,9 @@ public class X11Window extends WindowImpl {
protected void createNativeImpl() {
final X11Screen screen = (X11Screen) getScreen();
final X11Display display = (X11Display) screen.getDisplay();
- final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice());
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
+ capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
--
cgit v1.2.3
From 93ab5e38ed59d6df101886ac8a2207955b0cea7f Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Wed, 25 Jul 2012 04:25:32 +0200
Subject: Add property: 'jogl.disable.opengles' to disable querying and using
OpenGL ES
This might be required by a few older buggy ES implementations.
Also assists to discable ANGLE is not properly detected (?)
on Windows 32bit - the latter causes SEGV within FF and Chrome.
TODO: Fix ANGLE detection and usage within broser
NOTE: ANGLE works fine standalone ..
---
src/jogl/classes/javax/media/opengl/GLProfile.java | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 73d13a387..1e10dc9a6 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -86,7 +86,14 @@ public class GLProfile {
*
*/
private static final boolean enableANGLE = Debug.isPropertyDefined("jogl.enable.ANGLE", true);
-
+
+ /**
+ * In case no OpenGL ES implementation is required
+ * and if the running platform may have a buggy implementation,
+ * setting the property jogl.disable.opengles
disables querying a possible existing OpenGL ES implementation.
+ */
+ private static final boolean disableOpenGLES = Debug.isPropertyDefined("jogl.disable.opengles", true);
+
static {
// Also initializes TempJarCache if shall be used.
Platform.initSingleton();
@@ -1475,7 +1482,7 @@ public class GLProfile {
}
}
- if ( ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
+ if ( !disableOpenGLES && ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
t=null;
try {
eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
--
cgit v1.2.3
From 9e87acd921bcb357f1ec88d166bde672b54b02c8 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 3 Aug 2012 01:38:37 +0300
Subject: Fix X11 Display Connection leak w/ new GLAutoDrawableBase code when
used w/ offscreen drawables, reported by Mark Raynsford
New common GLAutoDrawableBase missed to close the AbstractGraphicsDevice
in case it has been created and dedicated for the passed GLDrawable.
This detailed knowledge is only known to the creator, hence it is passed
in the constructor and is being passed through all specializations.
Further more the new X11/GLX impl. of GLDrawableFactory's
'createMutableSurfaceImpl' always creates it's own private X11 display connection
to avoid locking / threading issues. Since the old implementation reused the
shared display connection which is prone to threading issues, this bug was not visible before.
Also fixed the unit test TestNEWTCloseX11DisplayBug565,
now correctly validating that no display connection is left over
after a new cycle of create/destroy of onscreen and offscreen drawables.
---
make/scripts/tests.sh | 6 ++--
.../com/jogamp/opengl/OffscreenAutoDrawable.java | 13 ++++++--
.../javax/media/opengl/GLAutoDrawableDelegate.java | 14 +++++---
.../classes/jogamp/opengl/GLAutoDrawableBase.java | 39 ++++++++++++++++------
.../jogamp/opengl/GLDrawableFactoryImpl.java | 2 +-
src/jogl/classes/jogamp/opengl/GLPbufferImpl.java | 4 +--
.../classes/jogamp/nativewindow/x11/X11Util.java | 2 +-
.../classes/com/jogamp/newt/opengl/GLWindow.java | 2 +-
.../test/junit/jogl/acore/TestFBODrawableNEWT.java | 2 +-
.../jogl/acore/TestGLAutoDrawableDelegateNEWT.java | 2 +-
.../acore/TestGLContextDrawableSwitchNEWT.java | 2 +-
.../jogl/acore/TestNEWTCloseX11DisplayBug565.java | 8 ++---
12 files changed, 64 insertions(+), 32 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index af6218968..43d04c6bd 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -61,7 +61,7 @@ function jrun() {
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all"
- D_ARGS="-Dnewt.debug.Window"
+ #D_ARGS="-Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
@@ -217,7 +217,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFloatUtil01MatrixMatrixMultNOUI $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
@@ -328,7 +328,7 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
-testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
index 1ea8595c6..8450ffdb0 100644
--- a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
@@ -28,6 +28,7 @@
package com.jogamp.opengl;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -45,8 +46,16 @@ import jogamp.opengl.GLFBODrawableImpl;
*/
public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
- public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, Object upstreamWidget) {
- super(drawable, context, upstreamWidget);
+ /**
+ * @param drawable a valid {@link GLDrawable}, may not be realized yet.
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
+ */
+ public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, boolean ownDevice) {
+ super(drawable, context, null, ownDevice);
}
/**
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
index 76959f3f4..67e81270d 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
@@ -28,6 +28,8 @@
package javax.media.opengl;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
@@ -57,12 +59,16 @@ public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
/**
- * @param drawable
- * @param context
+ * @param drawable a valid {@link GLDrawable}, may not be realized yet.
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
* @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
*/
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget) {
- super((GLDrawableImpl)drawable, (GLContextImpl)context);
+ public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
+ super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
this.upstreamWidget = null;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index fe6d0fd76..cc4e1b434 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -30,6 +30,8 @@ package jogamp.opengl;
import java.io.PrintStream;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
@@ -66,13 +68,23 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
+ protected final boolean ownDevice;
protected int additionalCtxCreationFlags = 0;
protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
- public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context) {
+ /**
+ * @param drawable a valid {@link GLDrawableImpl}, may not be realized yet.
+ * @param context a valid {@link GLContextImpl}, may not be made current (created) yet.
+ * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
+ */
+ public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
this.drawable = drawable;
this.context = context;
+ this.ownDevice = ownDevice;
resetFPSCounter();
}
@@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
/**
- * Calls {@link #destroyImplInLock()} while claiming the lock.
+ * Calls {@link #destroyImplInLock()} while claiming the lock.
*/
protected final void defaultDestroy() {
final RecursiveLock lock = getLock();
@@ -200,17 +212,22 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
protected void destroyImplInLock() {
final GLContext _context = context;
final GLDrawable _drawable = drawable;
- if( null != _drawable && _drawable.isRealized() ) {
- if( null != _context && _context.isCreated() ) {
- // Catch dispose GLExceptions by GLEventListener, just 'print' them
- // so we can continue with the destruction.
- try {
- helper.disposeGL(this, _drawable, _context, null);
- } catch (GLException gle) {
- gle.printStackTrace();
+ if( null != _drawable ) {
+ if( _drawable.isRealized() ) {
+ if( null != _context && _context.isCreated() ) {
+ // Catch dispose GLExceptions by GLEventListener, just 'print' them
+ // so we can continue with the destruction.
+ try {
+ helper.disposeGL(this, _drawable, _context, null);
+ } catch (GLException gle) {
+ gle.printStackTrace();
+ }
}
+ _drawable.setRealized(false);
+ }
+ if( ownDevice ) {
+ _drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close();
}
- _drawable.setRealized(false);
}
context = null;
drawable = null;
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index f092288fb..f7808294b 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -245,7 +245,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
if(null==drawable) {
throw new GLException("Could not create Pbuffer drawable for: "+device+", "+capsChosen+", "+width+"x"+height);
}
- return new GLPbufferImpl( drawable, shareWith);
+ return new GLPbufferImpl( drawable, shareWith, true);
}
//---------------------------------------------------------------------------
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index 6b64120fe..32f4cb696 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -58,8 +58,8 @@ import com.jogamp.common.util.locks.RecursiveLock;
public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
private int floatMode;
- public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext) {
- super(pbufferDrawable, null); // drawable := pbufferDrawable
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext, boolean ownDevice) {
+ super(pbufferDrawable, null, ownDevice); // drawable := pbufferDrawable
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index fcc374751..7b46a1df0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -255,7 +255,7 @@ public class X11Util {
*/
public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
- if(DEBUG||verbose||pendingDisplayList.size() > 0) {
+ if(DEBUG || verbose || openDisplayMap.size() > 0 || pendingDisplayList.size() > 0) {
System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index d662a743a..0fc1b4e89 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -97,7 +97,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
* Constructor. Do not call this directly -- use {@link #create()} instead.
*/
protected GLWindow(Window window) {
- super(null, null);
+ super(null, null, false);
this.window = (WindowImpl) window;
this.window.setHandleDestroyNotify(false);
window.addWindowListener(new WindowAdapter() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
index 1a33845b3..7977347a7 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
@@ -167,7 +167,7 @@ public class TestFBODrawableNEWT extends UITestCase {
final FBObject.RenderAttachment depthA = fbo.getDepthAttachment();
Assert.assertNotNull(depthA);
- final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, null);
+ final OffscreenAutoDrawable glad = new OffscreenAutoDrawable(fboDrawable, context, true);
glad.addGLEventListener(demo);
glad.addGLEventListener(new GLEventListener() {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
index 426b7734f..96d9b2e28 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
@@ -85,7 +85,7 @@ public class TestGLAutoDrawableDelegateNEWT extends UITestCase {
Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
context.release();
- final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window) {
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, context, window, false) {
@Override
protected void destroyImplInLock() {
super.destroyImplInLock(); // destroys drawable/context
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
index 92b4c5238..cece4c6d5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitchNEWT.java
@@ -88,7 +88,7 @@ public class TestGLContextDrawableSwitchNEWT extends UITestCase {
drawable.setRealized(true);
Assert.assertTrue(drawable.isRealized());
- final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window) {
+ final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false) {
@Override
protected void destroyImplInLock() {
super.destroyImplInLock();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
index e14d5b800..33a9b7799 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNEWTCloseX11DisplayBug565.java
@@ -43,10 +43,10 @@ public class TestNEWTCloseX11DisplayBug565 {
if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {
final int openD = X11Util.getOpenDisplayConnectionNumber() - open0;
- if(openD>1) {
+ if( openD > 0) {
X11Util.dumpOpenDisplayConnections();
X11Util.dumpPendingDisplayConnections();
- Assert.assertTrue("More than 1 new open display connections", false);
+ Assert.assertEquals("New display connection didn't close", 0, openD);
}
}
}
@@ -86,10 +86,10 @@ public class TestNEWTCloseX11DisplayBug565 {
if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false)) {
final int openD = X11Util.getOpenDisplayConnectionNumber() - open0;
- if(openD>1) {
+ if(openD > 0) {
X11Util.dumpOpenDisplayConnections();
X11Util.dumpPendingDisplayConnections();
- Assert.assertTrue("More than 1 new open display connections", false);
+ Assert.assertEquals("New display connection didn't close", 0, openD);
}
}
}
--
cgit v1.2.3
From 5a5c2bc7a113906453e0de6f0403f394acdb9a4f Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sat, 18 Aug 2012 00:45:13 +0200
Subject: Fix GLCanvas's JAWTWindow reference ; Add ES2 test in TestAWT01GLn ;
Ubuntu 12.04/Pandaboard(Omap4, PowerVR SGX 540) 103/108 tests passed (before
freeze) of 124 total
Fix GLCanvas's JAWTWindow reference
- drawable.getNativeSurface() may not be a JAWTWindow
due to our EGL WrappedSurface. Hence store the created JAWTWindow reference locally.
Add ES2 test in TestAWT01GLn
- test EGL/ES2 w/ AWT GLCanvas
Ubuntu 12.04/Pandaboard(Omap4, PowerVR SGX 540): 103/108 tests passed (before freeze) of 124 total
- machine freezes around test 108 ..
- new passed unit test high for ES2 incl. AWT tests
---
make/scripts/targetcommand-awt.sh | 2 +-
make/scripts/tests.sh | 4 +-
.../classes/javax/media/opengl/awt/GLCanvas.java | 11 ++--
.../opengl/test/junit/jogl/awt/TestAWT01GLn.java | 60 +++++++++++-----------
4 files changed, 37 insertions(+), 40 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/scripts/targetcommand-awt.sh b/make/scripts/targetcommand-awt.sh
index d776abd16..6bd4dd22c 100755
--- a/make/scripts/targetcommand-awt.sh
+++ b/make/scripts/targetcommand-awt.sh
@@ -18,7 +18,7 @@ XTRA_FLAGS="-Dnewt.test.Screen.disableScreenMode -Djogl.debug.EGL -Dnativewindow
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT
#TSTCLASS=com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT
-TSTCLASS=com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01AWT
+TSTCLASS=com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
mkdir -p $THISDIR/projects-cross
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 6aa69fa34..5a8d596df 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -274,7 +274,7 @@ function testawtswt() {
#testawt javax.media.opengl.awt.GLCanvas $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug551AWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $*
+testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestAWTCloseX11DisplayBug565 $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 $*
@@ -411,8 +411,6 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
#linux:
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01NEWT $*
# osx:
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 03fd78ac7..033591fe3 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -146,6 +146,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final GLDrawableHelper helper = new GLDrawableHelper();
private AWTGraphicsConfiguration awtConfig;
private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
+ private volatile JAWTWindow jawtWindow; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private GLContextImpl context;
private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
@@ -268,9 +269,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public final boolean isOffscreenLayerSurfaceEnabled() {
- final GLDrawable _drawable = drawable;
- if(null != _drawable) {
- return ((JAWTWindow)_drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+ final JAWTWindow _jawtWindow = jawtWindow;
+ if(null != _jawtWindow) {
+ return _jawtWindow.isOffscreenLayerSurfaceEnabled();
}
return false;
}
@@ -539,7 +540,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private void createDrawableAndContext() {
// no lock required, since this resource ain't available yet
- final JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
jawtWindow.lockSurface();
try {
@@ -811,11 +812,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
public void run() {
context=null;
if(null!=drawable) {
- final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
drawable.setRealized(false);
drawable=null;
if(null!=jawtWindow) {
jawtWindow.destroy();
+ jawtWindow=null;
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
index 64a1a0138..e1048c2f8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWT01GLn.java
@@ -40,49 +40,23 @@ import java.awt.Frame;
import org.junit.Assert;
import org.junit.Assume;
-import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.After;
import org.junit.Test;
public class TestAWT01GLn extends UITestCase {
- Frame frame=null;
- GLCanvas glCanvas=null;
-
@BeforeClass
public static void startup() {
System.out.println("GLProfile "+GLProfile.glAvailabilityToString());
}
- @Before
- public void init() {
- frame = new Frame("Texture Test");
- Assert.assertNotNull(frame);
- }
-
- @After
- public void release() {
- Assert.assertNotNull(frame);
- Assert.assertNotNull(glCanvas);
- try {
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.setVisible(false);
- frame.remove(glCanvas);
- frame.dispose();
- }});
- } catch (Throwable t) {
- t.printStackTrace();
- Assume.assumeNoException(t);
- }
- frame=null;
- glCanvas=null;
- }
-
protected void runTestGL(GLCapabilities caps) throws InterruptedException {
- glCanvas = new GLCanvas(caps);
+ final Frame frame = new Frame("Texture Test");
+ Assert.assertNotNull(frame);
+
+ final GLCanvas glCanvas = new GLCanvas(caps);
Assert.assertNotNull(glCanvas);
+
glCanvas.addGLEventListener(new GearsES2());
frame.add(glCanvas);
@@ -110,6 +84,18 @@ public class TestAWT01GLn extends UITestCase {
Thread.sleep(500); // 500 ms
animator.stop();
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ Assume.assumeNoException(t);
+ }
}
@Test
@@ -136,6 +122,18 @@ public class TestAWT01GLn extends UITestCase {
}
}
+ @Test
+ public void test02ES2() throws InterruptedException {
+ if(GLProfile.isAvailable(GLProfile.GLES2)) {
+ GLProfile glprofile = GLProfile.get(GLProfile.GLES2);
+ System.out.println( "GLProfile GLES2: " + glprofile );
+ GLCapabilities caps = new GLCapabilities(glprofile);
+ runTestGL(caps);
+ } else {
+ System.out.println("GLES2 n/a");
+ }
+ }
+
public static void main(String args[]) {
org.junit.runner.JUnitCore.main(TestAWT01GLn.class.getName());
}
--
cgit v1.2.3
From 3ab518e90eb4cf82bcb8b990d337a5e4a531136b Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sat, 18 Aug 2012 11:46:01 +0200
Subject: GLProfile/NativeWindowFactory: Remove deprecated argument
'firstUIActionOnProcess' of initSingleton() method
The notion of changing the threading behavior of native initialization was deprecated for over a year.
The code still contained the bits and pieces, i.e. whether X11Util.initSingletion() is invoked
before or after optional AWT initialization.
This condition has been removed now and behavior is uniform, i.e.
X11Util.initSingletion() is invoked after optional AWT initialization.
- Removed GLProfile.initSingleton(boolean firstUIActionOnProcess), use remaining GLProfile.initSingleton()
- Removed NativeWindowFactory.isFirstUIActionOnProcess()
- Changed NativeWindowFactory.initSingleton(boolean firstUIActionOnProcess) to
NativeWindowFactory.initSingleton()
---
src/jogl/classes/javax/media/opengl/GLProfile.java | 54 +++++++++-------------
.../media/nativewindow/NativeWindowFactory.java | 46 +++++-------------
.../nativewindow/NativeWindowFactoryImpl.java | 2 +-
.../jogamp/nativewindow/macosx/OSXUtil.java | 12 ++---
.../jogamp/nativewindow/windows/GDIUtil.java | 15 +++---
.../classes/jogamp/nativewindow/x11/X11Util.java | 13 +++---
src/newt/classes/com/jogamp/newt/NewtFactory.java | 2 +-
.../classes/com/jogamp/newt/util/MainThread.java | 2 +-
.../test/junit/newt/TestRemoteWindow01NEWT.java | 2 +-
.../test/junit/newt/TestScreenMode00NEWT.java | 2 +-
.../test/junit/newt/TestScreenMode00bNEWT.java | 2 +-
.../opengl/test/junit/newt/TestWindows01NEWT.java | 2 +-
12 files changed, 57 insertions(+), 97 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 1e10dc9a6..513ccd101 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -101,29 +101,29 @@ public class GLProfile {
/**
* Static initialization of JOGL.
+ *
*
- * The parameter firstUIActionOnProcess
has an impact on concurrent locking,
- * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
+ * This method shall not need to be called for other reasons than having a defined initialization sequence.
*
- *
- * Applications using this method may place it's call before any other UI invocation
- * in the main class
's static block or within the main function
.
- * In such case, applications may pass firstUIActionOnProcess=true
to use native toolkit locking.
- *
- * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL are not be able to initialize JOGL
- * before the first UI action.
- * In such case you shall pass firstUIActionOnProcess=false
.
+ *
*
* In case this method is not invoked, GLProfile is initialized implicit by
- * the first call to {@link #getDefault()}, {@link #get(java.lang.String)} passing firstUIActionOnProcess=false
.
+ * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}.
*
- *
- * @param firstUIActionOnProcess Should be true
if called before the first UI action of the running program,
- * otherwise false
.
*
- * @deprecated Use {@link #initSingleton()}. This method is subject to be removed in future versions of JOGL.
+ *
+ * To initialize JOGL at startup ASAP, this method may be invoked in the main class 's
+ * static initializer block, in the static main() method or in the Applet init() method .
+ *
+ *
+ *
+ * Since JOGL's initialization is complex and involves multi threading, it is not recommended
+ * to be have it invoked on the AWT EDT thread. In case all JOGL usage is performed
+ * on the AWT EDT, invoke this method outside the AWT EDT - see above.
+ *
+ *
*/
- public static void initSingleton(final boolean firstUIActionOnProcess) {
+ public static void initSingleton() {
final boolean justInitialized;
initLock.lock();
try {
@@ -131,7 +131,7 @@ public class GLProfile {
initialized = true;
justInitialized = true;
if(DEBUG) {
- System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
+ System.err.println("GLProfile.initSingleton() - thread "+Thread.currentThread().getName());
Thread.dumpStack();
}
@@ -171,7 +171,7 @@ public class GLProfile {
}
JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core" } );
}
- initProfilesForDefaultDevices(firstUIActionOnProcess);
+ initProfilesForDefaultDevices();
return null;
}
});
@@ -188,17 +188,6 @@ public class GLProfile {
}
}
- /**
- * Static initialization of JOGL.
- *
- *
- * This method shall not need to be called for other reasons than having a defined initialization sequence.
- *
- */
- public static void initSingleton() {
- GLProfile.initSingleton(false);
- }
-
/**
* Trigger eager initialization of GLProfiles for the given device,
* in case it isn't done yet.
@@ -1411,11 +1400,10 @@ public class GLProfile {
/**
* Tries the profiles implementation and native libraries.
*/
- private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
- NativeWindowFactory.initSingleton(firstUIActionOnProcess);
+ private static void initProfilesForDefaultDevices() {
+ NativeWindowFactory.initSingleton();
if(DEBUG) {
- System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess
- + ", thread: " + Thread.currentThread().getName());
+ System.err.println("GLProfile.init - thread: " + Thread.currentThread().getName());
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
System.err.println(NativeWindowVersion.getInstance());
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 6faa9890c..94f5d753c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -99,7 +99,6 @@ public abstract class NativeWindowFactory {
private static Constructor> x11JAWTToolkitLockConstructor;
private static Class> x11ToolkitLockClass;
private static Constructor> x11ToolkitLockConstructor;
- private static boolean isFirstUIActionOnProcess;
private static boolean requiresToolkitLock;
/** Creates a new NativeWindowFactory instance. End users do not
@@ -138,9 +137,7 @@ public abstract class NativeWindowFactory {
static boolean initialized = false;
- private static void initSingletonNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) {
- isFirstUIActionOnProcess = firstUIActionOnProcess;
-
+ private static void initSingletonNativeImpl(final ClassLoader cl) {
final String clazzName;
if( TYPE_X11.equals(nativeWindowingTypePure) ) {
clazzName = X11UtilClassName;
@@ -152,9 +149,7 @@ public abstract class NativeWindowFactory {
clazzName = null;
}
if( null != clazzName ) {
- ReflectionUtil.callStaticMethod(clazzName, "initSingleton",
- new Class[] { boolean.class },
- new Object[] { new Boolean(firstUIActionOnProcess) }, cl );
+ ReflectionUtil.callStaticMethod(clazzName, "initSingleton", null, null, cl );
final Boolean res = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
requiresToolkitLock = res.booleanValue();
@@ -166,24 +161,13 @@ public abstract class NativeWindowFactory {
/**
* Static one time initialization of this factory.
* This initialization method must be called once by the program or utilizing modules!
- *
- * The parameter firstUIActionOnProcess
has an impact on concurrent locking:
- *
- * {@link #getDefaultToolkitLock() getDefaultToolkitLock() }
- * {@link #getDefaultToolkitLock(java.lang.String) getDefaultToolkitLock(type) }
- * {@link #createDefaultToolkitLock(java.lang.String, long) createDefaultToolkitLock(type, dpyHandle) }
- * {@link #createDefaultToolkitLockNoAWT(java.lang.String, long) createDefaultToolkitLockNoAWT(type, dpyHandle) }
- *
- *
- * @param firstUIActionOnProcess Should be true
if called before the first UI action of the running program,
- * otherwise false
.
*/
- public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
+ public static synchronized void initSingleton() {
if(!initialized) {
initialized = true;
if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")");
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton()");
}
final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
@@ -197,10 +181,6 @@ public abstract class NativeWindowFactory {
nativeWindowingTypeCustom = tmp;
}
- if(firstUIActionOnProcess) {
- // X11 initialization before possible AWT initialization
- initSingletonNativeImpl(true, cl);
- }
isAWTAvailable = false; // may be set to true below
if( Platform.AWT_AVAILABLE &&
@@ -248,10 +228,13 @@ public abstract class NativeWindowFactory {
}
}
}
- if(!firstUIActionOnProcess) {
- // X11 initialization after possible AWT initialization
- initSingletonNativeImpl(false, cl);
- }
+
+ // X11 initialization after possible AWT initialization
+ // This is performed post AWT initialization, allowing AWT to complete the same,
+ // which may have been triggered before NativeWindow initialization.
+ // This way behavior is more uniforms across configurations (Applet/RCP, applications, ..).
+ initSingletonNativeImpl(cl);
+
registeredFactories = Collections.synchronizedMap(new HashMap, NativeWindowFactory>());
// register our default factory -> NativeWindow
@@ -276,7 +259,6 @@ public abstract class NativeWindowFactory {
}
if(DEBUG) {
- System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess);
System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock);
System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
}
@@ -301,12 +283,6 @@ public abstract class NativeWindowFactory {
}
}
- /** @return true if initialized with {@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)} ,
- otherwise false. */
- public static boolean isFirstUIActionOnProcess() {
- return isFirstUIActionOnProcess;
- }
-
/** @return true if the underlying toolkit requires locking, otherwise false. */
public static boolean requiresToolkitLock() {
return requiresToolkitLock;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 9e18439db..2c2a627a4 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -90,7 +90,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
// Assume Linux, Solaris, etc. Should probably test for these explicitly.
windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow";
} else {
- throw new IllegalArgumentException("OS " + Platform.getOSName() + " not yet supported");
+ throw new IllegalArgumentException("Native windowing type " + windowingType + " (custom) not yet supported, platform reported native windowing type: "+getNativeWindowType(false));
}
nativeWindowConstructor = ReflectionUtil.getConstructor(
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 894084fce..f5f735051 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -38,20 +38,18 @@ public class OSXUtil {
private static boolean isInit = false;
private static final boolean DEBUG = Debug.debug("OSXUtil");
- public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ public static synchronized void initSingleton() {
if(!isInit) {
+ if(DEBUG) {
+ System.out.println("OSXUtil.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("macosx")) {
throw new NativeWindowException("NativeWindow MacOSX native library load error.");
}
if( !initIDs0() ) {
throw new NativeWindowException("MacOSX: Could not initialized native stub");
- }
-
- if(DEBUG) {
- System.out.println("OSX.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
- }
-
+ }
isInit = true;
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index d17a1898c..fda1649b6 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -41,24 +41,21 @@ public class GDIUtil {
private static RegisteredClassFactory dummyWindowClassFactory;
private static boolean isInit = false;
- public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ public static synchronized void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
if(!isInit) {
- isInit = true;
+ if(DEBUG) {
+ System.out.println("GDI.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("win32")) {
throw new NativeWindowException("NativeWindow Windows native library load error.");
}
-
if( !initIDs0() ) {
throw new NativeWindowException("GDI: Could not initialized native stub");
}
-
- if(DEBUG) {
- System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
- }
-
- dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ isInit = true;
}
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 7b46a1df0..860238649 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -95,18 +95,20 @@ public class X11Util {
private static Object setX11ErrorHandlerLock = new Object();
- @SuppressWarnings("unused")
- public static void initSingleton(final boolean firstX11ActionOnProcess) {
+ public static void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
if(!isInit) {
isInit = true;
+ if(DEBUG) {
+ System.out.println("X11UtilUtil.initSingleton()");
+ }
if(!NWJNILibLoader.loadNativeWindow("x11")) {
throw new NativeWindowException("NativeWindow X11 native library load error.");
}
- final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
- final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess, XERROR_STACKDUMP);
+ final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED ;
+ final boolean isXInitThreadsOK = initialize0( callXInitThreads, XERROR_STACKDUMP);
isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
final long dpy = X11Lib.XOpenDisplay(null);
@@ -124,8 +126,7 @@ public class X11Util {
}
if(DEBUG) {
- System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", requiresX11Lock "+requiresX11Lock+
+ System.err.println("X11Util requiresX11Lock "+requiresX11Lock+
", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
", isX11LockAvailable "+isX11LockAvailable+
", X11 Display(NULL) <"+nullDisplayName+">"+
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 61dbfb34c..0644c9164 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -52,7 +52,7 @@ public class NewtFactory {
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
- NativeWindowFactory.initSingleton(false); // last resort ..
+ NativeWindowFactory.initSingleton(); // last resort ..
WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index bbe415b2f..a6e2ae02b 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -101,7 +101,7 @@ public class MainThread {
public static final boolean HINT_USE_MAIN_THREAD;
static {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
NEWTJNILibLoader.loadNEWT();
HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
Debug.getBooleanProperty("newt.MainThread.force", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
index eb652584c..53995e8f7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
@@ -47,7 +47,7 @@ public class TestRemoteWindow01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
index a5b7a76e7..577119bcd 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
@@ -59,7 +59,7 @@ public class TestScreenMode00NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
index e9e66da2c..75a312686 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
@@ -57,7 +57,7 @@ public class TestScreenMode00bNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 640;
height = 480;
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
index a99edfadb..bf72348f9 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
@@ -45,7 +45,7 @@ public class TestWindows01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- NativeWindowFactory.initSingleton(true);
+ NativeWindowFactory.initSingleton();
width = 256;
height = 256;
}
--
cgit v1.2.3
From c5835a2e19a84cb08957d6c742e4334d578c3c66 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sat, 18 Aug 2012 14:52:32 +0200
Subject: NativeWindowFactory.getNativeWindowType(..): Return canonical string
representation allowing proper use of ref. comparison '==', instead of
'String.equals()'
Also make NativeWindowFactory's instances of nativeWindowingTypePure and nativeWindowingTypeCustom static final.
---
.../com/jogamp/opengl/util/texture/Texture.java | 2 +-
.../javax/media/opengl/GLDrawableFactory.java | 14 ++---
src/jogl/classes/jogamp/opengl/ThreadingImpl.java | 3 +-
.../classes/jogamp/opengl/egl/EGLDisplayUtil.java | 2 +-
.../jogamp/opengl/egl/EGLDrawableFactory.java | 2 +-
.../com/jogamp/nativewindow/swt/SWTAccessor.java | 36 ++++++-----
.../nativewindow/GraphicsConfigurationFactory.java | 2 +-
.../media/nativewindow/NativeWindowFactory.java | 72 +++++++++++-----------
.../nativewindow/NativeWindowFactoryImpl.java | 11 ++--
.../jogamp/nativewindow/jawt/JAWTJNILibLoader.java | 2 +-
10 files changed, 76 insertions(+), 70 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index e7bf87a36..15dd19ea9 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -1089,7 +1089,7 @@ public class Texture {
// Prefer GL_ARB_texture_rectangle on ATI hardware on Mac OS X
// due to software fallbacks
- if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+ if (NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
String vendor = gl.glGetString(GL.GL_VENDOR);
if (vendor != null && vendor.startsWith("ATI")) {
return true;
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 9a0d2cb99..fbdc51022 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -123,16 +123,16 @@ public abstract class GLDrawableFactory {
private static final void initSingletonImpl() {
registerFactoryShutdownHook();
- final String nativeOSType = NativeWindowFactory.getNativeWindowType(true);
+ final String nwt = NativeWindowFactory.getNativeWindowType(true);
GLDrawableFactory tmp = null;
String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true);
ClassLoader cl = GLDrawableFactory.class.getClassLoader();
if (null == factoryClassName) {
- if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) {
+ if ( nwt == NativeWindowFactory.TYPE_X11 ) {
factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory";
- } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_WINDOWS) ) {
+ } else if ( nwt == NativeWindowFactory.TYPE_WINDOWS ) {
factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
- } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_MACOSX) ) {
+ } else if ( nwt == NativeWindowFactory.TYPE_MACOSX ) {
if(ReflectionUtil.isClassAvailable(macosxFactoryClassNameAWTCGL, cl)) {
factoryClassName = macosxFactoryClassNameAWTCGL;
} else {
@@ -141,19 +141,19 @@ public abstract class GLDrawableFactory {
} else {
// may use egl*Factory ..
if (GLProfile.DEBUG) {
- System.err.println("GLDrawableFactory.static - No native OS Factory for: "+nativeOSType+"; May use EGLDrawableFactory, if available." );
+ System.err.println("GLDrawableFactory.static - No native Windowing Factory for: "+nwt+"; May use EGLDrawableFactory, if available." );
}
}
}
if (null != factoryClassName) {
if (GLProfile.DEBUG) {
- System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nativeOSType+": "+factoryClassName);
+ System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nwt+": "+factoryClassName);
}
try {
tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl);
} catch (JogampRuntimeException jre) {
if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName);
+ System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nwt+" - not available: "+factoryClassName);
jre.printStackTrace();
}
}
diff --git a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
index 61a47675f..d55a2c976 100644
--- a/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
+++ b/src/jogl/classes/jogamp/opengl/ThreadingImpl.java
@@ -89,8 +89,7 @@ public class ThreadingImpl {
// problems.
hasAWT = GLProfile.isAWTAvailable();
- String osType = NativeWindowFactory.getNativeWindowType(false);
- _isX11 = NativeWindowFactory.TYPE_X11.equals(osType);
+ _isX11 = NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false);
// default setting
singleThreaded = true;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index dbf35d68c..18d2f830d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -228,7 +228,7 @@ public class EGLDisplayUtil {
*/
public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface) {
final long nativeDisplayID;
- if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) {
+ if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
nativeDisplayID = surface.getSurfaceHandle(); // don't even ask ..
} else {
nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 50b480210..f2e836e3c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -103,7 +103,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
EGLGraphicsConfigurationFactory.registerFactory();
// Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
} catch (JogampRuntimeException jre) { /* n/a .. */ }
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
index ba07d97dc..1cc796086 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java
@@ -83,7 +83,9 @@ public class SWTAccessor {
static {
Field f = null;
- if(NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+
+ if(NativeWindowFactory.TYPE_MACOSX != nwt ) {
try {
f = Control.class.getField(str_handle);
} catch (Exception ex) {
@@ -124,7 +126,7 @@ public class SWTAccessor {
Class> c=null;
Method m1=null, m2=null, m3=null, m4=null, m5=null;
Class> handleType = swt_uses_long_handles ? long.class : int.class ;
- if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( NativeWindowFactory.TYPE_X11 == nwt ) {
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
m1 = c.getDeclaredMethod(str_gtk_widget_realize, handleType);
@@ -210,33 +212,36 @@ public class SWTAccessor {
long displayHandle = callStaticMethodL2L(OS_gdk_x11_drawable_get_xdisplay, widgedHandle);
return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static AbstractGraphicsScreen getScreen(AbstractGraphicsDevice device, int screen) {
if( null != OS_gtk_class ) {
return new X11GraphicsScreen((X11GraphicsDevice)device, screen);
- }
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ }
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return new DefaultGraphicsScreen(device, screen);
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static int getNativeVisualID(AbstractGraphicsDevice device, long windowHandle) {
if( null != OS_gtk_class ) {
return X11Lib.GetVisualIDFromWindow(device.getHandle(), windowHandle);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return VisualIDHolder.VID_UNDEFINED;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static long getWindowHandle(Control swtControl) {
@@ -245,11 +250,12 @@ public class SWTAccessor {
long widgedHandle = callStaticMethodL2L(OS_GTK_WIDGET_WINDOW, handle);
return callStaticMethodL2L(OS_gdk_x11_drawable_get_xid, widgedHandle);
}
- if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ||
- NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false) ) {
+ final String nwt = NativeWindowFactory.getNativeWindowType(false);
+ if( NativeWindowFactory.TYPE_WINDOWS == nwt ||
+ NativeWindowFactory.TYPE_MACOSX == nwt ) {
return handle;
}
- throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
+ throw new UnsupportedOperationException("n/a for this windowing system: "+nwt);
}
public static long newGC(final Control swtControl, final GCData gcData) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index c3fdc6798..9694f2491 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -129,7 +129,7 @@ public abstract class GraphicsConfigurationFactory {
// well as X11GraphicsDevices in non-AWT situations)
registerFactory(defaultDeviceCapsType.deviceType, defaultDeviceCapsType.capsType, new DefaultGraphicsConfigurationFactoryImpl());
- if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ if (NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
try {
ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
"registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 867d0733b..afcd0a008 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -56,33 +56,34 @@ import com.jogamp.common.util.ReflectionUtil;
public abstract class NativeWindowFactory {
protected static final boolean DEBUG;
- /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
- public static final String TYPE_EGL = "jogamp.newt.driver.kd";
+ /** OpenKODE/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+ public static final String TYPE_EGL = "jogamp.newt.driver.kd".intern();
- /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_WINDOWS = "jogamp.newt.driver.windows";
+ /** Microsoft Windows type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_WINDOWS = "jogamp.newt.driver.windows".intern();
- /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_X11 = "jogamp.newt.driver.x11";
+ /** X11 type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_X11 = "jogamp.newt.driver.x11".intern();
- /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}*/
- public static final String TYPE_ANDROID = "jogamp.newt.driver.android";
+ /** Android/EGL type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}.*/
+ public static final String TYPE_ANDROID = "jogamp.newt.driver.android".intern();
- /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_MACOSX = "jogamp.newt.driver.macosx";
+ /** Mac OS X type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_MACOSX = "jogamp.newt.driver.macosx".intern();
- /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_AWT = "jogamp.newt.driver.awt";
+ /** Generic AWT type, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_AWT = "jogamp.newt.driver.awt".intern();
- /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)} */
- public static final String TYPE_DEFAULT = "default";
+ /** Generic DEFAULT type, where platform implementation don't care, as retrieved with {@link #getNativeWindowType(boolean)}. String is canonical via {@link String#intern()}. */
+ public static final String TYPE_DEFAULT = "default".intern();
+ private static final String nativeWindowingTypePure; // canonical String via String.intern()
+ private static final String nativeWindowingTypeCustom; // canonical String via String.intern()
+
private static NativeWindowFactory defaultFactory;
private static Map, NativeWindowFactory> registeredFactories;
private static Class> nativeWindowClass;
- private static String nativeWindowingTypePure;
- private static String nativeWindowingTypeCustom;
private static boolean isAWTAvailable;
private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
@@ -133,17 +134,26 @@ public abstract class NativeWindowFactory {
System.err.println(Thread.currentThread().getName()+" - Info: NativeWindowFactory.");
// Thread.dumpStack();
}
+
+ // Gather the windowing TK first
+ nativeWindowingTypePure = _getNativeWindowingType();
+ final String tmp = Debug.getProperty("nativewindow.ws.name", true);
+ if(null==tmp || tmp.length()==0) {
+ nativeWindowingTypeCustom = nativeWindowingTypePure;
+ } else {
+ nativeWindowingTypeCustom = tmp.intern(); // canonical representation
+ }
}
static boolean initialized = false;
private static void initSingletonNativeImpl(final ClassLoader cl) {
final String clazzName;
- if( TYPE_X11.equals(nativeWindowingTypePure) ) {
+ if( TYPE_X11 == nativeWindowingTypePure ) {
clazzName = X11UtilClassName;
- } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) {
+ } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
clazzName = GDIClassName;
- } else if( TYPE_MACOSX.equals(nativeWindowingTypePure) ) {
+ } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
clazzName = OSXUtilClassName;
} else {
clazzName = null;
@@ -172,15 +182,6 @@ public abstract class NativeWindowFactory {
final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
- // Gather the windowing OS first
- nativeWindowingTypePure = _getNativeWindowingType();
- String tmp = Debug.getProperty("nativewindow.ws.name", true);
- if(null==tmp || tmp.length()==0) {
- nativeWindowingTypeCustom = nativeWindowingTypePure;
- } else {
- nativeWindowingTypeCustom = tmp;
- }
-
isAWTAvailable = false; // may be set to true below
if( Platform.AWT_AVAILABLE &&
@@ -293,7 +294,8 @@ public abstract class NativeWindowFactory {
/**
* @param useCustom if false return the native value, if true return a custom value if set, otherwise fallback to the native value.
- * @return a define native window type, like {@link #TYPE_X11}, ..
+ * @return the native window type, e.g. {@link #TYPE_X11}, which is canonical via {@link String#intern()}.
+ * Hence {@link String#equals(Object)} and ==
produce the same result.
*/
public static String getNativeWindowType(boolean useCustom) {
return useCustom?nativeWindowingTypeCustom:nativeWindowingTypePure;
@@ -301,13 +303,13 @@ public abstract class NativeWindowFactory {
/** Don't know if we shall add this factory here ..
public static AbstractGraphicsDevice createGraphicsDevice(String type, String connection, int unitID, long handle, ToolkitLock locker) {
- if(type.equals(TYPE_EGL)) {
+ if(TYPE_EGL == type) {
return new
- } else if(type.equals(TYPE_X11)) {
- } else if(type.equals(TYPE_WINDOWS)) {
- } else if(type.equals(TYPE_MACOSX)) {
- } else if(type.equals(TYPE_AWT)) {
- } else if(type.equals(TYPE_DEFAULT)) {
+ } else if(TYPE_X11 == type) {
+ } else if(TYPE_WINDOWS == type) {
+ } else if(TYPE_MACOSX == type)) {
+ } else if(TYPE_AWT == type) {
+ } else if(TYPE_DEFAULT == type) {
}
} */
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 2c2a627a4..29564da3b 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -39,7 +39,6 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
-import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.ReflectionUtil.AWTNames;
@@ -76,17 +75,17 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
try {
- String windowingType = getNativeWindowType(true);
- String windowClassName = null;
+ final String windowingType = getNativeWindowType(true);
+ final String windowClassName;
// We break compile-time dependencies on the AWT here to
// make it easier to run this code on mobile devices
- if (windowingType.equals(TYPE_WINDOWS)) {
+ if (TYPE_WINDOWS == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.windows.WindowsJAWTWindow";
- } else if (windowingType.equals(TYPE_MACOSX)) {
+ } else if (TYPE_MACOSX == windowingType) {
windowClassName = "jogamp.nativewindow.jawt.macosx.MacOSXJAWTWindow";
- } else if (windowingType.equals(TYPE_X11)) {
+ } else if (TYPE_X11 == windowingType) {
// Assume Linux, Solaris, etc. Should probably test for these explicitly.
windowClassName = "jogamp.nativewindow.jawt.x11.X11JAWTWindow";
} else {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2377c2be6..f579da217 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -60,7 +60,7 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
// ensure references from jogl_awt shared object
// will succeed since JAWT shared object isn't in
// default library path
- if ( ! NativeWindowFactory.TYPE_MACOSX.equals( NativeWindowFactory.getNativeWindowType(false) ) ) {
+ if ( NativeWindowFactory.TYPE_MACOSX != NativeWindowFactory.getNativeWindowType(false) ) {
try {
loadLibrary("jawt", null, true, JAWTJNILibLoader.class.getClassLoader());
} catch (Throwable t) {
--
cgit v1.2.3
From 27e81bf4d851ce2b81763920b4d1981c6a44b42a Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Tue, 21 Aug 2012 15:51:55 +0200
Subject: Fix EGLDrawableFactory ES1/ES2 detection for !pbuffer ; Misc
robustness changes for GLDrawableFactory ..
- EGLDrawableFactory ES1/ES2 detection for !pbuffer
- isEGLContextAvailable(..) -> mapAvailableEGLESConfig(..)
- handle case where no pbuffer configuration is available (nokia n9 meego ..).
in such case, assume availability if onscreen profile is avail.
- EGLDrawableFactory.getOrCreateEGLSharedResource(..)
- avoid double creation attempt (similar to SharedResourceRunner)
- EGLGraphicsConfiguration.EGLConfig2Capabilities(..) respect EGL.EGL_CONFIG_CAVEAT's EGL.EGL_SLOW_CONFIG
- if EGL.EGL_SLOW_CONFIG -> no hw accel.
- Fix GLContext.getRequestMajorAndCompat(..): Proper handling of ES1 and ES2
- Add abstract GLDrawableFactory.isComplete(): Only if true use the factory for 'getFactory(..)' avoid using incomplete ones.
---
src/jogl/classes/javax/media/opengl/GLContext.java | 6 +-
.../javax/media/opengl/GLDrawableFactory.java | 11 +-
src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 14 +-
.../jogamp/opengl/egl/EGLDrawableFactory.java | 174 +++++++++++++++------
.../opengl/egl/EGLGraphicsConfiguration.java | 5 +
.../macosx/cgl/MacOSXCGLDrawableFactory.java | 5 +
.../windows/wgl/WindowsWGLDrawableFactory.java | 6 +
.../opengl/x11/glx/X11GLXDrawableFactory.java | 5 +
8 files changed, 173 insertions(+), 53 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 63a02ad9c..a2ce619e7 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -1141,7 +1141,7 @@ public abstract class GLContext {
}
/**
- * Returns the GLProfile's major version number and it's context property (CTP) for availability mapping request.
+ * Returns the GLProfile's major version number at reqMajorCTP[0] and it's context property (CTP) at reqMajorCTP[1] for availability mapping request.
*/
protected static final void getRequestMajorAndCompat(final GLProfile glp, int[/*2*/] reqMajorCTP) {
final GLProfile glpImpl = glp.getImpl();
@@ -1149,7 +1149,9 @@ public abstract class GLContext {
reqMajorCTP[0]=4;
} else if (glpImpl.isGL3()) {
reqMajorCTP[0]=3;
- } else /* if (glpImpl.isGL2()) */ {
+ } else if (glpImpl.isGLES1()) {
+ reqMajorCTP[0]=1;
+ } else /* if (glpImpl.isGL2() || glpImpl.isGLES2()) */ {
reqMajorCTP[0]=2;
}
if( glpImpl.isGLES() ) {
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index fbdc51022..acda45bff 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -158,7 +158,9 @@ public abstract class GLDrawableFactory {
}
}
}
- nativeOSFactory = tmp;
+ if(null != tmp && tmp.isComplete()) {
+ nativeOSFactory = tmp;
+ }
tmp = null;
try {
@@ -169,7 +171,9 @@ public abstract class GLDrawableFactory {
jre.printStackTrace();
}
}
- eglFactory = tmp;
+ if(null != tmp && tmp.isComplete()) {
+ eglFactory = tmp;
+ }
}
protected static void shutdown(ShutdownType shutdownType) {
@@ -233,6 +237,9 @@ public abstract class GLDrawableFactory {
glDrawableFactories.add(this);
}
}
+
+ /** Returns true if this factory is complete, i.e. ready to be used. Otherwise return false. */
+ protected abstract boolean isComplete();
protected void enterThreadCriticalZone() {};
protected void leaveThreadCriticalZone() {};
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 919f92c02..03d0d650f 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -42,6 +42,7 @@ import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -303,8 +304,19 @@ public abstract class EGLContext extends GLContextImpl {
*/
protected void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
mapCurrentAvailableGLVersionImpl(device, ctxMajorVersion, ctxMinorVersion, ctxOptions);
+ }
+ protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps) {
+ final GLProfile glp = caps.getGLProfile();
+ final int[] reqMajorCTP = new int[2];
+ GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
+ if(glp.isGLES() && reqMajorCTP[0] >= 2) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
+ }
+ if(!caps.getHardwareAccelerated()) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+ }
+ mapCurrentAvailableGLVersionImpl(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
}
-
protected static void mapStaticGLESVersion(AbstractGraphicsDevice device, int major) {
int ctp = ( 2 == major ) ? ( GLContext.CTX_PROFILE_ES | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ) : ( GLContext.CTX_PROFILE_ES );
mapCurrentAvailableGLVersionImpl(device, major, 0, ctp);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index f2e836e3c..a9e339bea 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -36,9 +36,11 @@
package jogamp.opengl.egl;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -71,6 +73,8 @@ import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.WrappedSurface;
@@ -183,9 +187,19 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE");
}
}
+ if(null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper) {
+ sharedMap = new HashMap();
+ sharedMapCreateAttempt = new HashSet();
+ }
}
}
+ @Override
+ protected final boolean isComplete() {
+ return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+ }
+
+
@Override
protected final void destroy(ShutdownType shutdownType) {
if(null != sharedMap) {
@@ -198,7 +212,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
sr.device.close();
}
sharedMap.clear();
+ sharedMapCreateAttempt.clear();
sharedMap = null;
+ sharedMapCreateAttempt = null;
}
defaultDevice = null;
/**
@@ -217,7 +233,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
EGLGraphicsConfigurationFactory.unregisterFactory();
}
- private HashMap sharedMap = new HashMap();
+ private HashMap sharedMap = null;
+ private HashSet sharedMapCreateAttempt = null;
+
private EGLGraphicsDevice defaultDevice;
static class SharedResource {
@@ -227,8 +245,12 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// private final EGLContext contextES2;
private final boolean wasES1ContextCreated;
private final boolean wasES2ContextCreated;
+ private final boolean hasPBufferES1;
+ private final boolean hasPBufferES2;
- SharedResource(EGLGraphicsDevice dev, boolean wasContextES1Created, boolean wasContextES2Created
+ SharedResource(EGLGraphicsDevice dev,
+ boolean wasContextES1Created, boolean hasPBufferES1,
+ boolean wasContextES2Created, boolean hasPBufferES2
/*EGLDrawable draw, EGLContext ctxES1, EGLContext ctxES2 */) {
this.device = dev;
// this.drawable = draw;
@@ -236,13 +258,17 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// this.contextES2 = ctxES2;
this.wasES1ContextCreated = wasContextES1Created;
this.wasES2ContextCreated = wasContextES2Created;
+ this.hasPBufferES1= hasPBufferES1;
+ this.hasPBufferES2= hasPBufferES2;
}
final EGLGraphicsDevice getDevice() { return device; }
// final EGLDrawable getDrawable() { return drawable; }
// final EGLContext getContextES1() { return contextES1; }
// final EGLContext getContextES2() { return contextES2; }
final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
- final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ final boolean hasES1PBuffer() { return hasPBufferES1; }
+ final boolean hasES2PBuffer() { return hasPBufferES2; }
}
@Override
@@ -253,10 +279,26 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
// via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
}
- private boolean isEGLContextAvailable(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString) {
+ private static List getAvailableEGLConfigs(EGLGraphicsDevice eglDisplay, GLCapabilitiesImmutable caps) {
+ final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
+ if(!EGL.eglGetConfigs(eglDisplay.getHandle(), null, 0, numConfigs)) {
+ throw new GLException("EGLDrawableFactory.getAvailableEGLConfigs: Get maxConfigs (eglGetConfigs) call failed, error "+EGLContext.toHexString(EGL.eglGetError()));
+ }
+ if(0 < numConfigs.get(0)) {
+ final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(caps));
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(true, true, true);
+ if( EGL.eglChooseConfig(eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) {
+ return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(caps.getGLProfile(), eglDisplay.getHandle(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */);
+ }
+ }
+ return new ArrayList(0);
+ }
+
+ private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, EGLGraphicsDevice sharedEGLDevice, String profileString, boolean[] hasPBuffer) {
if( !GLProfile.isAvailable(adevice, profileString) ) {
return false;
}
@@ -268,57 +310,78 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
boolean success = false;
boolean deviceFromUpstreamSurface = false;
try {
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
+ final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+ reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List availablePBufferCapsL = getAvailableEGLConfigs(sharedEGLDevice, reqCapsPBuffer);
+ hasPBuffer[0] = availablePBufferCapsL.size() > 0;
+
if(adevice instanceof EGLGraphicsDevice || null == desktopFactory || !QUERY_EGL_ES_NATIVE_TK) {
eglDevice = sharedEGLDevice; // reuse
- surface = createDummySurfaceImpl(eglDevice, false, caps, null, 64, 64); // egl pbuffer offscreen
- upstreamSurface = (ProxySurface)surface;
- upstreamSurface.createNotify();
- deviceFromUpstreamSurface = false;
+ if( hasPBuffer[0] ) {
+ surface = createDummySurfaceImpl(eglDevice, false, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
+ upstreamSurface = (ProxySurface)surface;
+ upstreamSurface.createNotify();
+ deviceFromUpstreamSurface = false;
+ } else {
+ final List capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
+ if(capsAnyL.size() > 0) {
+ final GLCapabilitiesImmutable caps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(eglDevice, caps);
+ if(eglDevice != adevice) {
+ EGLContext.mapStaticGLESVersion(adevice, caps);
+ }
+ success = true;
+ }
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.isEGLContextAvailable() no pbuffer config available, detected !pbuffer config: "+success);
+ EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
+ }
+ }
} else {
- surface = desktopFactory.createDummySurface(adevice, caps, null, 64, 64); // X11, WGL, .. dummy window
+ surface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
if(null != upstreamSurface) {
upstreamSurface.createNotify();
}
eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
deviceFromUpstreamSurface = true;
+ hasPBuffer[0] = true;
}
-
- final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
- drawable.setRealized(true);
- final EGLContext context = (EGLContext) drawable.createContext(null);
- if (null != context) {
- try {
- context.makeCurrent(); // could cause exception
- success = context.isCurrent();
- if(success) {
- final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
- if(null == glVersion) {
- // Oops .. something is wrong
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+
+ if(null != surface) {
+ final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface ); // works w/ implicit pbuffer surface via proxy-hook
+ drawable.setRealized(true);
+ final EGLContext context = (EGLContext) drawable.createContext(null);
+ if (null != context) {
+ try {
+ context.makeCurrent(); // could cause exception
+ if(context.isCurrent()) {
+ final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+ if(null != glVersion) {
+ context.mapCurrentAvailableGLVersion(eglDevice);
+ if(eglDevice != adevice) {
+ context.mapCurrentAvailableGLVersion(adevice);
+ }
+ success = true;
+ } else {
+ // Oops .. something is wrong
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.isEGLContextAvailable: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+ }
}
- success = false;
}
- }
- if(success) {
- context.mapCurrentAvailableGLVersion(eglDevice);
- if(eglDevice != adevice) {
- context.mapCurrentAvailableGLVersion(adevice);
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
+ gle.printStackTrace();
}
+ } finally {
+ context.destroy();
}
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: INFO: context create/makeCurrent failed");
- gle.printStackTrace();
- }
- } finally {
- context.destroy();
}
+ drawable.setRealized(false);
}
- drawable.setRealized(false);
} catch (Throwable t) {
if(DEBUG) {
System.err.println("Catched Exception:");
@@ -350,25 +413,38 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
/* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
return null;
}
final String connection = adevice.getConnection();
SharedResource sr;
+ boolean createAttempted;
synchronized(sharedMap) {
sr = sharedMap.get(connection);
+ if( null == sr ) {
+ createAttempted = sharedMapCreateAttempt.contains(connection);
+ if(!createAttempted) {
+ sharedMapCreateAttempt.add(connection);
+ }
+ } else {
+ createAttempted = true;
+ }
}
- if(null==sr) {
+ if(null==sr && !createAttempted) {
final boolean madeCurrentES1;
final boolean madeCurrentES2;
final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ boolean[] hasPBufferES1 = new boolean[1];
+ boolean[] hasPBufferES2 = new boolean[1];
if(QUERY_EGL_ES) {
- madeCurrentES1 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES1);
- madeCurrentES2 = isEGLContextAvailable(adevice, sharedDevice, GLProfile.GLES2);
+ madeCurrentES1 = mapAvailableEGLESConfig(adevice, sharedDevice, GLProfile.GLES1, hasPBufferES1);
+ madeCurrentES2 = mapAvailableEGLESConfig(adevice, sharedDevice, GLProfile.GLES2, hasPBufferES2);
} else {
madeCurrentES1 = true;
madeCurrentES2 = true;
+ hasPBufferES1[0] = true;
+ hasPBufferES2[0] = true;
EGLContext.mapStaticGLESVersion(sharedDevice, 1);
if(sharedDevice != adevice) {
EGLContext.mapStaticGLESVersion(adevice, 1);
@@ -384,7 +460,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// avoid exception due to double 'set' - carefull exception of the rule.
EGLContext.setAvailableGLVersionsSet(adevice);
}
- sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
+ sr = new SharedResource(sharedDevice, madeCurrentES1, hasPBufferES1[0], madeCurrentES2, hasPBufferES2[0]);
synchronized(sharedMap) {
sharedMap.put(connection, sr);
@@ -394,8 +470,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
if (DEBUG) {
System.err.println("EGLDrawableFactory.createShared: devices: queried " + QUERY_EGL_ES + "[nativeTK "+QUERY_EGL_ES_NATIVE_TK+"], " + adevice + ", " + sharedDevice);
- System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
- System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
+ System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", hasPBuffer "+hasPBufferES1[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", hasPBuffer "+hasPBufferES2[0]);
}
}
return sr;
@@ -453,7 +529,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected List getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
return new ArrayList(); // null
}
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
@@ -546,6 +622,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ // SharedResource sr = getOrCreateEGLSharedResource(device);
+ // return sr.hasES1PBuffer() || sr.hasES2PBuffer();
return true;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 716a6e6f1..20102547d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -211,6 +211,11 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return false;
}
+ if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_CAVEAT, val)) {
+ if( EGL.EGL_SLOW_CONFIG == val.get(0) ) {
+ caps.setHardwareAccelerated(false);
+ }
+ }
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val)) {
caps.setSampleBuffers(val.get(0)>0?true:false);
caps.setNumSamples(val.get(0));
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 9689d9f64..c1b15cac5 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -118,6 +118,11 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ @Override
+ protected final boolean isComplete() {
+ return null != macOSXCGLDynamicLookupHelper;
+ }
+
@Override
protected final void destroy(ShutdownType shutdownType) {
if(null != sharedMap) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 09e97ff79..c414083c4 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -129,6 +129,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ @Override
+ protected final boolean isComplete() {
+ return null != windowsWGLDynamicLookupHelper;
+ }
+
+
@Override
protected final void destroy(ShutdownType shutdownType) {
if(null != sharedResourceRunner) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index b2e74f9d4..293ac96f7 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -123,6 +123,11 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ @Override
+ protected final boolean isComplete() {
+ return null != x11GLXDynamicLookupHelper;
+ }
+
@Override
protected final void destroy(ShutdownType shutdownType) {
if(null != sharedResourceRunner) {
--
cgit v1.2.3
From 6d241fc2a46413ee478985d676d2481c5a7ed119 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Thu, 23 Aug 2012 14:01:08 +0200
Subject: GLContext: Remove integer-key based attach/detach object - use String
based (minor API change)
The integer based attachement is currently not used
and since it has no benefit over the String based hash map - remove it.
---
src/jogl/classes/javax/media/opengl/GLContext.java | 32 ++++------------------
1 file changed, 5 insertions(+), 27 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index a2ce619e7..c2f94b9af 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -52,7 +52,6 @@ import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.IntObjectHashMap;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.opengl.GLExtensions;
@@ -140,8 +139,7 @@ public abstract class GLContext {
private static final ThreadLocal currentContext = new ThreadLocal();
- private final HashMap attachedObjectsByString = new HashMap();
- private final IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+ private final HashMap attachedObjects = new HashMap();
// RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock.
protected final RecursiveLock lock = LockFactory.createRecursiveLock();
@@ -168,8 +166,7 @@ public abstract class GLContext {
ctxMinorVersion=-1;
ctxOptions=0;
ctxVersionString=null;
- attachedObjectsByString.clear();
- attachedObjectsByInt.clear();
+ attachedObjects.clear();
contextHandle=0;
currentSwapInterval = -1;
}
@@ -422,30 +419,11 @@ public abstract class GLContext {
return 0 != contextHandle;
}
- /**
- * Returns the attached user object for the given name to this GLContext.
- */
- public final Object getAttachedObject(int name) {
- return attachedObjectsByInt.get(name);
- }
-
/**
* Returns the attached user object for the given name to this GLContext.
*/
public final Object getAttachedObject(String name) {
- return attachedObjectsByString.get(name);
- }
-
- /**
- * Sets the attached user object for the given name to this GLContext.
- * Returns the previously set object or null.
- */
- public final Object attachObject(int name, Object obj) {
- return attachedObjectsByInt.put(name, obj);
- }
-
- public final Object detachObject(int name) {
- return attachedObjectsByInt.remove(name);
+ return attachedObjects.get(name);
}
/**
@@ -453,11 +431,11 @@ public abstract class GLContext {
* Returns the previously set object or null.
*/
public final Object attachObject(String name, Object obj) {
- return attachedObjectsByString.put(name, obj);
+ return attachedObjects.put(name, obj);
}
public final Object detachObject(String name) {
- return attachedObjectsByString.remove(name);
+ return attachedObjects.remove(name);
}
/**
--
cgit v1.2.3
From 90d45928186f2be99999461cfe45f76a783cc961 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Fri, 7 Sep 2012 05:46:22 +0200
Subject: Fix Capabilities ambiguity and explosion of queried available-list;
Add FBO availability detection for EGL, WGL and OSX.
Introducing Capabilities 'bitmap' boolean, complementing the offscreen modes FBO and PBuffer.
This allows:
1 - deterministic setting of the offscreen mode
2 - utilizing auto configuration of offscreen mode, if !onscreen !FBO !PBuffer and !Bitmap
3 - adding 'availability' semantic of 'onscreen' boolean,
i.e. if onscree:=1 for a queried instance, the offscreen modes still indicate offscreen
availability - see [4]
4 - avoiding explosion of the availability list due to [3],
one Capability entry reflect on- and offscreen settings.
Add FBO availability detection for EGL, WGL and OSX.
Tested manually w/ 'TestGLCapabilities01NEWT' on X11 [NV, ATI], WGL[NV], OSX[NV].
---
make/scripts/tests-x64.bat | 3 +-
make/scripts/tests.sh | 51 +++--
.../media/opengl/DefaultGLCapabilitiesChooser.java | 39 ++--
.../classes/javax/media/opengl/GLCapabilities.java | 96 +++++----
.../media/opengl/GLCapabilitiesImmutable.java | 79 +++++--
.../jogamp/opengl/GLDrawableFactoryImpl.java | 6 +-
.../jogamp/opengl/GLGraphicsConfigurationUtil.java | 151 +++++++------
.../jogamp/opengl/egl/EGLDrawableFactory.java | 9 +-
.../jogamp/opengl/egl/EGLGLCapabilities.java | 18 +-
.../opengl/egl/EGLGraphicsConfiguration.java | 68 +++---
.../egl/EGLGraphicsConfigurationFactory.java | 36 ++--
.../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 9 +-
.../macosx/cgl/MacOSXCGLGraphicsConfiguration.java | 6 +-
.../windows/wgl/WindowsPbufferWGLDrawable.java | 15 +-
.../wgl/WindowsWGLGraphicsConfiguration.java | 94 ++++-----
.../WindowsWGLGraphicsConfigurationFactory.java | 80 +++----
.../x11/glx/X11GLXGraphicsConfiguration.java | 59 ++----
.../glx/X11GLXGraphicsConfigurationFactory.java | 81 +++----
.../javax/media/nativewindow/Capabilities.java | 160 +++++++-------
.../media/nativewindow/CapabilitiesImmutable.java | 35 +++-
.../nativewindow/DefaultCapabilitiesChooser.java | 9 +-
.../junit/jogl/acore/TestGLCapabilities01NEWT.java | 233 +++++++++++++++++++++
.../opengl/test/junit/util/AWTRobotUtil.java | 13 ++
23 files changed, 881 insertions(+), 469 deletions(-)
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 6d3e46af6..669e0212e 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -1,6 +1,7 @@
REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet
REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas
+scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -39,7 +40,7 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
-scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index cccc825ee..1314094cf 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -60,10 +60,9 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
#D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Djogl.fbo.force.none"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug=all"
- #D_ARGS="-Dnewt.debug.Window"
- #D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.DontQuery -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.EGLDrawableFactory.QueryNativeTK -Djogl.debug.GLDrawable"
#D_ARGS="-Djogl.debug.GLDebugMessageHandler"
@@ -76,7 +75,8 @@ function jrun() {
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
#D_ARGS="-Djogamp.debug.IOUtil -Djogl.debug.GLSLCode -Djogl.debug.GLMediaPlayer"
#D_ARGS="-Djogl.debug.GLArrayData"
- #D_ARGS="-Djogl.debug.EGL -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable"
+ #D_ARGS="-Djogl.debug.EGLDisplayUtil -Dnativewindow.debug.X11Util"
#D_ARGS="-Djogl.debug.GLDrawable"
#D_ARGS="-Dnewt.test.Screen.disableScreenMode -Dnewt.debug.Screen"
#D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true"
@@ -107,7 +107,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.Animator -Dnewt.debug=all"
#D_ARGS="-Dnewt.debug.EDT -Dnewt.debug.Display -Dnativewindow.debug.X11Util -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas"
#D_ARGS="-Djogl.debug.GLContext"
- #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser"
+ #D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.CapabilitiesChooser -Djogl.debug.GLDrawable -Djogl.debug.GLProfile"
#D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.EDT -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.GraphicsConfiguration"
#D_ARGS="-Dnewt.debug.EDT"
@@ -247,7 +247,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
-testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestRedSquareES1NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestRedSquareES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestWindows01NEWT $*
@@ -278,6 +278,7 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestAWTCloseX11DisplayBug565 $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextNewtAWTBug523 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestPBufferDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
@@ -291,7 +292,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWTAnalyzeBug455 $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsGLJPanelAWTBug450 $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461PBufferSupersamplingSwingAWT
#testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWTCardLayoutAnimatorStartStopBug532 $*
@@ -315,8 +317,8 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#
# newt.awt (testawt)
#
-#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411
-#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper
+#testawt com.jogamp.opengl.test.junit.jogl.newt.TestSwingAWTRobotUsageBeforeJOGLInitBug411 $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper $*
#testawt com.jogamp.opengl.test.junit.newt.TestEventSourceNotAWTBug
#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
@@ -366,16 +368,32 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube $*
#
-# GLSL / FBO / ..
+# GLSL
#
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestTransformFeedbackVaryingsBug407NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLSimple01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+
+#
+# FBO / ..
+#
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
+
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable00NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01bNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableMix2DemosES2NEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#
# Graph
@@ -411,13 +429,20 @@ testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
#linux:
+# EARMARK removal of shutdown mode!
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $*
# osx:
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
+
$spath/count-edt-start.sh java-run.log
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 5fa8ce32d..b052769ca 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -87,20 +87,20 @@ import jogamp.opengl.Debug;
public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
private static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.CapabilitiesChooser", true);
- final static int NO_SCORE = -9999999;
- final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
- final static int OPAQUE_MISMATCH_PENALTY = 750;
- final static int STENCIL_MISMATCH_PENALTY = 500;
- final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
- final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
+ private final static int NO_SCORE = -9999999;
+ private final static int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
+ private final static int OPAQUE_MISMATCH_PENALTY = 750;
+ private final static int STENCIL_MISMATCH_PENALTY = 500;
+ private final static int MULTISAMPLE_MISMATCH_PENALTY = 500;
+ private final static int MULTISAMPLE_EXTENSION_MISMATCH_PENALTY = 250; // just a little drop, no scale
// Pseudo attempt to keep equal rank penalties scale-equivalent
// (e.g., stencil mismatch is 3 * accum because there are 3 accum
// components)
- final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
- final static int DEPTH_MISMATCH_PENALTY_SCALE = 6;
- final static int ACCUM_MISMATCH_PENALTY_SCALE = 1;
- final static int STENCIL_MISMATCH_PENALTY_SCALE = 3;
- final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE = 3;
+ private final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
+ private final static int DEPTH_MISMATCH_PENALTY_SCALE = 6;
+ private final static int ACCUM_MISMATCH_PENALTY_SCALE = 1;
+ private final static int STENCIL_MISMATCH_PENALTY_SCALE = 3;
+ private final static int MULTISAMPLE_MISMATCH_PENALTY_SCALE = 3;
@Override
public int chooseCapabilities(final CapabilitiesImmutable desired,
@@ -150,11 +150,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (cur == null) {
continue;
}
- if (gldes.isOnscreen() != cur.isOnscreen()) {
- continue;
+ if (gldes.isOnscreen() && !cur.isOnscreen()) {
+ continue; // requested onscreen, but n/a
}
- if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) {
- continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available
+ if (!gldes.isOnscreen()) {
+ /** FBO is generic ..
+ if (gldes.isFBO() && !cur.isFBO()) {
+ continue; // requested FBO, but n/a
+ } */
+ if (gldes.isPBuffer() && !cur.isPBuffer()) {
+ continue; // requested pBuffer, but n/a
+ }
+ if (gldes.isBitmap() && !cur.isBitmap()) {
+ continue; // requested pBuffer, but n/a
+ }
}
if (gldes.getStereo() != cur.getStereo()) {
continue;
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 8845ec665..30a6215e7 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -105,20 +105,21 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
- int hash = 31 + this.glProfile.hashCode() ;
+ int hash = super.hashCode();
+ hash = ((hash << 5) - hash) + this.glProfile.hashCode() ;
+ hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.isFBO ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.isPBuffer ? 1 : 0 );
- hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
- hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
+ hash = ((hash << 5) - hash) + this.getNumSamples();
+ hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
hash = ((hash << 5) - hash) + this.depthBits;
hash = ((hash << 5) - hash) + this.stencilBits;
hash = ((hash << 5) - hash) + this.accumRedBits;
hash = ((hash << 5) - hash) + this.accumGreenBits;
hash = ((hash << 5) - hash) + this.accumBlueBits;
hash = ((hash << 5) - hash) + this.accumAlphaBits;
- hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
- hash = ((hash << 5) - hash) + this.numSamples;
- hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
hash = ((hash << 5) - hash) + ( this.pbufferFloatingPointBuffers ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.pbufferRenderToTexture ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.pbufferRenderToTextureRectangle ? 1 : 0 );
@@ -148,9 +149,8 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
other.getPbufferFloatingPointBuffers()==pbufferFloatingPointBuffers &&
other.getPbufferRenderToTexture()==pbufferRenderToTexture &&
other.getPbufferRenderToTextureRectangle()==pbufferRenderToTextureRectangle;
- if(sampleBuffers) {
- res = res &&
- other.getNumSamples()==numSamples &&
+ if(res && sampleBuffers) {
+ res = other.getNumSamples()==getNumSamples() &&
other.getSampleExtension().equals(sampleExtension) ;
}
return res;
@@ -222,19 +222,24 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
public void setGLProfile(GLProfile profile) {
glProfile=profile;
}
-
+
@Override
public final boolean isPBuffer() {
return isPBuffer;
}
/**
- * Enables or disables pbuffer usage.
+ * Requesting offscreen pbuffer mode.
*
* If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
+ *
* Defaults to false.
- */
+ *
+ *
+ * Requesting offscreen pbuffer mode disables the offscreen auto selection.
+ *
+ */
public void setPBuffer(boolean enable) {
if(enable) {
setOnscreen(false);
@@ -248,11 +253,16 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
}
/**
- * Enables or disables FBO usage.
+ * Requesting offscreen FBO mode.
*
* If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
+ *
* Defaults to false.
+ *
+ *
+ * Requesting offscreen FBO mode disables the offscreen auto selection.
+ *
*/
public void setFBO(boolean enable) {
if(enable) {
@@ -261,21 +271,6 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
isFBO = enable;
}
- /**
- * Sets whether the drawable surface supports onscreen.
- * If enabled this method also invokes {@link #setPBuffer(int) setPBuffer(false)}
- * and {@link #setFBO(int) setFBO(false)}
- * Defaults to true.
- */
- @Override
- public void setOnscreen(boolean onscreen) {
- if(onscreen) {
- setPBuffer(false);
- setFBO(false);
- }
- super.setOnscreen(onscreen);
- }
-
@Override
public final boolean getDoubleBuffered() {
return doubleBuffered;
@@ -465,9 +460,9 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
sink = new StringBuilder();
}
- int samples = sampleBuffers ? numSamples : 0 ;
+ final int samples = sampleBuffers ? numSamples : 0 ;
- super.toString(sink);
+ super.toString(sink, false);
sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits);
sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples);
@@ -490,20 +485,37 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
sink.append(", sw, ");
}
sink.append(glProfile);
- if(!isOnscreen()) {
- if(isFBO) {
- sink.append(", fbo");
- }
- if(isPBuffer) {
- sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
- .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
- .append(", float ").append(pbufferFloatingPointBuffers?1:0)
- .append("]");
- }
- if(!isFBO && !isPBuffer) {
- sink.append(", pixmap");
+ if(isOnscreen()) {
+ sink.append(", on-scr[");
+ } else {
+ sink.append(", offscr[");
+ }
+ boolean ns=false;
+ if(isFBO()) {
+ sink.append("fbo");
+ ns = true;
+ }
+ if(isPBuffer()) {
+ if(ns) { sink.append(", "); }
+ sink.append("pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
+ .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
+ .append(", float ").append(pbufferFloatingPointBuffers?1:0)
+ .append("]");
+ ns = true;
+ }
+ if(isBitmap()) {
+ if(ns) { sink.append(", "); }
+ sink.append("bitmap");
+ ns = true;
+ }
+ if(!ns) { // !FBO !PBuffer !Bitmap
+ if(isOnscreen()) {
+ sink.append("."); // no additional off-screen modes besides on-screen
+ } else {
+ sink.append("auto-cfg"); // auto-config off-screen mode
}
}
+ sink.append("]");
return sink;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
index 7e0459b2d..ee261ca01 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -50,7 +50,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
GLProfile getGLProfile();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's alpha component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -58,7 +58,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumAlphaBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's blue component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -66,7 +66,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumBlueBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's green component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -74,7 +74,7 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumGreenBits();
/**
- * Returns the number of bits requested for the accumulation
+ * Returns the number of bits for the accumulation
* buffer's red component. On some systems only the accumulation
* buffer depth, which is the sum of the red, green, and blue bits,
* is considered.
@@ -82,74 +82,115 @@ public interface GLCapabilitiesImmutable extends CapabilitiesImmutable {
int getAccumRedBits();
/**
- * Returns the number of bits requested for the depth buffer.
+ * Returns the number of depth buffer bits.
*/
int getDepthBits();
/**
- * Indicates whether double-buffering is enabled.
+ * Returns whether double-buffering is requested, available or chosen.
+ *
+ * Default is true.
+ *
*/
boolean getDoubleBuffered();
/**
- * Indicates whether hardware acceleration is enabled.
+ * Returns whether hardware acceleration is requested, available or chosen.
+ *
+ * Default is true.
+ *
*/
boolean getHardwareAccelerated();
/**
- * Returns the used extension for full-scene antialiasing
- * (FSAA), default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+ * Returns the extension for full-scene antialiasing
+ * (FSAA).
+ *
+ * Default is {@link #DEFAULT_SAMPLE_EXTENSION}.
+ *
*/
String getSampleExtension();
/**
* Returns whether sample buffers for full-scene antialiasing
- * (FSAA) should be allocated for this drawable. Defaults to
- * false.
+ * (FSAA) should be allocated for this drawable.
+ *
+ * Default is false.
+ *
*/
boolean getSampleBuffers();
/**
* Returns the number of sample buffers to be allocated if sample
- * buffers are enabled, otherwise returns 0. Defaults to 2.
+ * buffers are enabled, otherwise returns 0.
+ *
+ * Default is 0 due to disable sample buffers per default.
+ *
*/
int getNumSamples();
/**
* For pbuffers only, returns whether floating-point buffers should
- * be used if available. Defaults to false.
+ * be used if available.
+ *
+ * Default is false.
+ *
*/
boolean getPbufferFloatingPointBuffers();
/**
* For pbuffers only, returns whether the render-to-texture
- * extension should be used if available. Defaults to false.
+ * extension should be used if available.
+ *
+ * Default is false.
+ *
*/
boolean getPbufferRenderToTexture();
/**
* For pbuffers only, returns whether the render-to-texture
- * extension should be used. Defaults to false.
+ * extension should be used.
+ *
+ * Default is false.
+ *
*/
boolean getPbufferRenderToTextureRectangle();
/**
- * Returns the number of bits requested for the stencil buffer.
+ * Returns the number of stencil buffer bits.
+ *
+ * Default is 0.
+ *
*/
int getStencilBits();
/**
- * Indicates whether stereo is enabled.
+ * Returns whether stereo is requested, available or chosen.
+ *
+ * Default is false.
+ *
*/
boolean getStereo();
/**
- * Indicates whether pbuffer offscreen is used/requested.
+ * Returns whether pbuffer offscreen mode is requested, available or chosen.
+ *
+ * Default is false.
+ *
+ *
+ * For chosen capabilities, only the selected offscreen surface is set to true
.
+ *
*/
boolean isPBuffer();
/**
- * Indicates whether FBO offscreen is used/requested.
+ * Returns whether FBO offscreen mode is requested, available or chosen.
+ *
+ * Default is false.
+ *
+ *
+ * For chosen capabilities, only the selected offscreen surface is set to true
.
+ *
*/
boolean isFBO();
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 2f2bf5961..e1e253d35 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -271,7 +271,10 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
throw new GLException("No shared device for requested: "+deviceReq);
}
- if( capsRequested.isFBO() && GLContext.isFBOAvailable(device, capsRequested.getGLProfile()) ) {
+ final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested,
+ GLContext.isFBOAvailable(device, capsRequested.getGLProfile()),
+ canCreateGLPbuffer(device));
+ if( capsChosen.isFBO() ) {
device.lock();
try {
return createFBODrawableImpl(device, capsRequested, chooser, width, height);
@@ -280,7 +283,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
}
}
- final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested, false, canCreateGLPbuffer(device));
device.lock();
try {
return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 3f38f33bc..d8e5ba31a 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,7 +28,6 @@
package jogamp.opengl;
-import java.util.List;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -74,56 +73,60 @@ public class GLGraphicsConfigurationUtil {
}
/**
- * @param isFBO TODO
- * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
+ public static final int getWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
+ int winattrbits = 0;
+ if(isOnscreen) {
+ winattrbits |= WINDOW_BIT;
+ }
+ if(isFBO) {
+ winattrbits |= FBO_BIT;
+ }
+ if(isPBuffer ){
+ winattrbits |= PBUFFER_BIT;
+ }
+ if(isBitmap) {
+ winattrbits |= BITMAP_BIT;
+ }
+ return winattrbits;
+ }
+ public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
+ } */
+
+ /**
+ * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set.
*/
- public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer, boolean isFBO) {
+ public static final int getExclusiveWinAttributeBits(boolean isOnscreen, boolean isFBO, boolean isPBuffer, boolean isBitmap) {
int winattrbits = 0;
if(isOnscreen) {
winattrbits |= WINDOW_BIT;
- } else {
- if(isFBO) {
- winattrbits |= FBO_BIT;
- }
- if (!isPBuffer) {
- winattrbits |= BITMAP_BIT;
- } else {
- winattrbits |= PBUFFER_BIT;
- }
+ } else if(isFBO) {
+ winattrbits |= FBO_BIT;
+ } else if(isPBuffer ){
+ winattrbits |= PBUFFER_BIT;
+ } else if(isBitmap) {
+ winattrbits |= BITMAP_BIT;
+ }
+ if(0 == winattrbits) {
+ throw new InternalError("Empty bitmask");
}
return winattrbits;
}
/**
- * @see #getWinAttributeBits(boolean, boolean, boolean)
+ * @see #getExclusiveWinAttributeBits(boolean, boolean, boolean, boolean)
*/
- public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
- return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer(), false);
+ public static final int getExclusiveWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
}
- public static final boolean addGLCapabilitiesPermutations(List capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
- int preSize = capsBucket.size();
- if( 0 != ( WINDOW_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(true);
- cpy.setPBuffer(false);
- cpy.setFBO(false);
- capsBucket.add(cpy);
- }
- if( 0 != ( PBUFFER_BIT & winattrbits ) || 0 != ( FBO_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setFBO(0 != ( FBO_BIT & winattrbits ));
- cpy.setPBuffer(0 != ( PBUFFER_BIT & winattrbits ));
- capsBucket.add(cpy);
- }
- if( 0 != ( BITMAP_BIT & winattrbits ) ) {
- GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
- cpy.setOnscreen(false);
- cpy.setPBuffer(false);
- cpy.setFBO(false);
- capsBucket.add(cpy);
- }
- return capsBucket.size() > preSize;
+ public static final GLCapabilities setWinAttributeBits(GLCapabilities caps, int winattrbits) {
+ caps.setBitmap ( 0 != ( BITMAP_BIT & winattrbits ) );
+ caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
+ caps.setFBO ( 0 != ( FBO_BIT & winattrbits ) );
+ // we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
+ caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
+ return caps;
}
public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
@@ -131,33 +134,46 @@ public class GLGraphicsConfigurationUtil {
if( !capsRequested.isOnscreen() ) {
return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
}
- return fixOnscreenGLCapabilities(capsRequested);
+ return capsRequested;
}
public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
if( !capsRequested.isOnscreen() ) {
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setBitmap (false);
+ caps2.setPBuffer (false);
+ caps2.setFBO (false);
caps2.setOnscreen(true);
return caps2;
}
return capsRequested;
}
-
- public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
- {
- if( capsRequested.getDoubleBuffered() ||
- capsRequested.isOnscreen() ||
- ( fboAvailable != capsRequested.isFBO() ) ||
- ( pbufferAvailable != capsRequested.isPBuffer() ) )
+
+ public static boolean isGLCapabilitiesOffscreenAutoSelection(GLCapabilitiesImmutable capsRequested) {
+ return !capsRequested.isOnscreen() &&
+ !capsRequested.isFBO() && !capsRequested.isPBuffer() && !capsRequested.isBitmap() ;
+ }
+
+ public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable) {
+ final boolean auto = !capsRequested.isFBO() && !capsRequested.isPBuffer() && !capsRequested.isBitmap() ;
+
+ final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
+ final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+ final boolean useBitmap = !usePbuffer && ( auto || capsRequested.isBitmap() ) ;
+
+ if( capsRequested.isOnscreen() ||
+ useFBO != capsRequested.isFBO() ||
+ usePbuffer != capsRequested.isPBuffer() ||
+ useBitmap != capsRequested.isBitmap() )
{
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
- caps2.setFBO( fboAvailable );
- caps2.setPBuffer( pbufferAvailable );
+ caps2.setFBO( useFBO );
+ caps2.setPBuffer( usePbuffer );
+ caps2.setBitmap( useBitmap );
return caps2;
}
return capsRequested;
@@ -165,31 +181,40 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixGLPBufferGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer() || capsRequested.isFBO() ) {
+ if( capsRequested.isOnscreen() ||
+ !capsRequested.isPBuffer() ||
+ capsRequested.isFBO() )
+ {
// fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setOnscreen(false);
- caps2.setPBuffer(true);
caps2.setFBO(false);
+ caps2.setPBuffer(true);
+ caps2.setBitmap(false);
return caps2;
}
return capsRequested;
}
/** Fix opaque setting while preserve alpha bits */
- public static GLCapabilitiesImmutable fixOpaqueGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean isOpaque)
+ public static GLCapabilities fixOpaqueGLCapabilities(GLCapabilities capsRequested, boolean isOpaque)
{
- GLCapabilities caps2 = null;
-
if( capsRequested.isBackgroundOpaque() != isOpaque) {
final int alphaBits = capsRequested.getAlphaBits();
- caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setBackgroundOpaque(isOpaque);
- caps2.setAlphaBits(alphaBits);
- return caps2;
+ capsRequested.setBackgroundOpaque(isOpaque);
+ capsRequested.setAlphaBits(alphaBits);
}
return capsRequested;
}
+ /** Fix double buffered setting */
+ public static GLCapabilitiesImmutable fixDoubleBufferedGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean doubleBuffered)
+ {
+ if( capsRequested.getDoubleBuffered() != doubleBuffered) {
+ final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setDoubleBuffered(doubleBuffered);
+ return caps2;
+ }
+ return capsRequested;
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index a9e339bea..986b110be 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -290,9 +290,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(0 < numConfigs.get(0)) {
final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(caps));
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(true, true, true);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(caps);
if( EGL.eglChooseConfig(eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) {
- return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(caps.getGLProfile(), eglDisplay.getHandle(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */);
+ return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(eglDisplay, caps.getGLProfile(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */);
}
}
return new ArrayList(0);
@@ -649,7 +649,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
- final GLCapabilitiesImmutable chosenCaps = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq));
+ final GLCapabilitiesImmutable chosenCaps =
+ GLGraphicsConfigurationUtil.fixDoubleBufferedGLCapabilities(
+ GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)),
+ false);
return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
}
private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index 70a570174..e513a86cf 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -33,6 +33,8 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
public class EGLGLCapabilities extends GLCapabilities {
private long eglcfg;
@@ -45,13 +47,13 @@ public class EGLGLCapabilities extends GLCapabilities {
* @param eglcfg
* @param eglcfgid
* @param visualID native visualID if valid, otherwise VisualIDHolder.VID_UNDEFINED
- * @param glp desired GLProfile, or null if determined by renderableType
+ * @param glp desired GLProfile
* @param renderableType actual EGL renderableType
*
* May throw GLException if given GLProfile is not compatible w/ renderableType
*/
public EGLGLCapabilities(long eglcfg, int eglcfgid, int visualID, GLProfile glp, int renderableType) {
- super( ( null != glp ) ? glp : getCompatible(renderableType) );
+ super( glp );
this.eglcfg = eglcfg;
this.eglcfgid = eglcfgid;
if(!isCompatible(glp, renderableType)) {
@@ -111,15 +113,15 @@ public class EGLGLCapabilities extends GLCapabilities {
return false;
}
- public static GLProfile getCompatible(int renderableType) {
- if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(GLProfile.GLES2)) {
- return GLProfile.get(GLProfile.GLES2);
+ public static GLProfile getCompatible(EGLGraphicsDevice device, int renderableType) {
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(device, GLProfile.GLES2)) {
+ return GLProfile.get(device, GLProfile.GLES2);
}
- if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(GLProfile.GLES1)) {
- return GLProfile.get(GLProfile.GLES1);
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(device, GLProfile.GLES1)) {
+ return GLProfile.get(device, GLProfile.GLES1);
}
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
- return GLProfile.getDefault();
+ return GLProfile.getDefault(device);
}
return null;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 20102547d..135101ff2 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -37,8 +37,6 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -48,6 +46,7 @@ import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -85,7 +84,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
final long cfg = EGLConfigId2EGLConfig(dpy, cfgID);
if(0 < cfg) {
- final EGLGLCapabilities caps = EGLConfig2Capabilities(capsRequested.getGLProfile(), dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer(), false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
+ final EGLGLCapabilities caps = EGLConfig2Capabilities((EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
}
return null;
@@ -129,9 +129,10 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return configs.get(0);
}
- static int EGLConfigDrawableTypeBits(final long display, final long config) {
+ static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final GLProfile glp, final long config) {
int val = 0;
+ final long display = device.getHandle();
int[] stype = new int[1];
if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
throw new GLException("Could not determine EGL_SURFACE_TYPE");
@@ -146,32 +147,24 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
}
+ if ( GLContext.isFBOAvailable(device, glp) ) {
+ val |= GLGraphicsConfigurationUtil.FBO_BIT;
+ }
return val;
}
- public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
- boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
- List bucket = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- }
- return null;
- }
-
- public static boolean EGLConfig2Capabilities(List capsBucket,
- GLProfile glp, long display, long config,
- int winattrmask, boolean forceTransparentFlag) {
- final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config);
- final int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
- if( 0 == drawableTypeBits ) {
- return false;
- }
-
+ /**
+ * @param device
+ * @param glp desired GLProfile, may be null
+ * @param config
+ * @param winattrmask
+ * @param forceTransparentFlag
+ * @return
+ */
+ public static EGLGLCapabilities EGLConfig2Capabilities(EGLGraphicsDevice device, GLProfile glp, long config,
+ int winattrmask, boolean forceTransparentFlag) {
+ final long display = device.getHandle();
final IntBuffer val = Buffers.newDirectIntBuffer(1);
final int cfgID;
final int rType;
@@ -183,7 +176,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
cfgID = val.get(0);
@@ -191,10 +184,10 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(DEBUG) {
System.err.println("EGL couldn't retrieve EGL_RENDERABLE_TYPE for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
rType = val.get(0);
-
+
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_NATIVE_VISUAL_ID, val)) {
visualID = val.get(0);
} else {
@@ -203,12 +196,15 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
EGLGLCapabilities caps = null;
try {
+ if(null == glp) {
+ glp = EGLGLCapabilities.getCompatible(device, rType);
+ }
caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
} catch (GLException gle) {
if(DEBUG) {
System.err.println("config "+toHexString(config)+": "+gle);
}
- return false;
+ return null;
}
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_CAVEAT, val)) {
@@ -270,7 +266,17 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
caps.setDepthBits(val.get(0));
}
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
+
+ // Since the passed GLProfile may be null,
+ // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
+ final int allDrawableTypeBits = EGLConfigDrawableTypeBits(device, caps.getGLProfile(), config);
+ final int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return null;
+ }
+
+ return (EGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(caps, drawableTypeBits);
}
public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 72dea9ead..d08685dcb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -207,7 +207,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(null, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
+ availableCaps = eglConfigs2GLCaps(eglDevice, null, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
if( null != availableCaps && availableCaps.size() > 1) {
Collections.sort(availableCaps, EglCfgIDComparator);
}
@@ -250,7 +250,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
final EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(absDevice, glp), factory.canCreateGLPbuffer(absDevice) );
- EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
+ EGLGraphicsConfiguration res = eglChooseConfig(eglDevice, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
if(null==res) {
if(DEBUG) {
System.err.println("eglChooseConfig failed with given capabilities "+capsChosen);
@@ -274,7 +274,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (1): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
@@ -292,7 +292,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (2): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
@@ -312,7 +312,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
System.err.println("trying fixed caps (3): "+fixedCaps);
}
- res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]");
@@ -324,15 +324,14 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return res;
}
- static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
+ static EGLGraphicsConfiguration eglChooseConfig(EGLGraphicsDevice device,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen,
int nativeVisualID, boolean forceTransparentFlag) {
+ final long eglDisplay = device.getHandle();
final GLProfile glp = capsChosen.getGLProfile();
- final boolean onscreen = capsChosen.isOnscreen();
- final boolean usePBuffer = capsChosen.isPBuffer();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
List availableCaps = null;
int recommendedIndex = -1;
long recommendedEGLConfig = -1;
@@ -345,7 +344,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
}
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", onscreen "+onscreen+", usePBuffer "+usePBuffer+", "+capsChosen+", numConfigs "+numConfigs.get(0));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", "+capsChosen+", numConfigs "+numConfigs.get(0));
}
final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
@@ -359,7 +358,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: false");
}
} else if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
if(availableCaps.size() > 0) {
recommendedEGLConfig = configs.get(0);
recommendedIndex = 0;
@@ -384,7 +383,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
}
}
@@ -392,7 +391,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag);
printCaps("AllCaps", availableCaps, System.err);
}
return null;
@@ -439,12 +438,15 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
}
- static List eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
- List caps = new ArrayList(num);
+ static List eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
+ List bucket = new ArrayList(num);
for(int i=0; i caps, PrintStream out) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 82525cfde..55aea3a98 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -49,6 +49,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
@@ -495,8 +496,14 @@ public abstract class MacOSXCGLContext extends GLContextImpl
CGL.setContextOpacity(ctx, 0);
}
- GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+ GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ if(!fixedCaps.isPBuffer()) {
+ // not handled, so copy them
+ fixedCaps.setFBO(chosenCaps.isFBO());
+ fixedCaps.setBitmap(chosenCaps.isBitmap());
+ fixedCaps.setOnscreen(chosenCaps.isOnscreen());
+ }
config.setChosenCapabilities(fixedCaps);
if(DEBUG) {
System.err.println("NS create fixedCaps: "+fixedCaps);
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 202644bb3..10e8193e2 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -176,7 +176,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
return CGL.createPixelFormat(cglInternalAttributeToken, off, len, ivalues, 0);
}
- static GLCapabilitiesImmutable NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
+ static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) {
return PixelFormat2GLCapabilities(glp, pixelFormat, true);
}
@@ -233,11 +233,11 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
return fmt.get(0);
}
- static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) {
+ static GLCapabilities CGLPixelFormat2GLCapabilities(long pixelFormat) {
return PixelFormat2GLCapabilities(null, pixelFormat, false);
}
- private static GLCapabilitiesImmutable PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
+ private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) {
int len = cglInternalAttributeToken.length;
int off = 0;
if ( !MacOSXCGLContext.isLionOrLater ) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 175622343..75c1c4441 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -40,6 +40,7 @@
package jogamp.opengl.windows.wgl;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
@@ -52,6 +53,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource;
// import javax.media.opengl.GLPbuffer;
@@ -127,13 +129,16 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
System.out.println("Pbuffer config: " + config);
}
+ final int winattrPbuffer = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(false /* onscreen */, false /* fbo */, true /* pbuffer */, false /* bitmap */);
+
int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
float[] fattributes = new float[1];
int[] floatModeTmp = new int[1];
int niattribs = 0;
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GLProfile glProfile = chosenCaps.getGLProfile();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ final GLProfile glProfile = chosenCaps.getGLProfile();
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
if (DEBUG) {
System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc));
@@ -175,7 +180,8 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
if (DEBUG) {
System.err.println("" + nformats + " suitable pixel formats found");
for (int i = 0; i < nformats; i++) {
- WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pformats[i], glProfile, false, true);
+ WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile,
+ sharedHdc, pformats[i], winattrPbuffer);
System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
}
}
@@ -239,7 +245,8 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
// Re-query chosen pixel format
{
- WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pfdid, glProfile, false, true);
+ WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile,
+ sharedHdc, pfdid, winattrPbuffer);
if(null == newCaps) {
throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc));
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 209589b29..5b21353c3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -42,6 +42,7 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
@@ -104,9 +105,9 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
WGLGLCapabilities caps = null;
if(hasARB) {
- caps = wglARBPFID2GLCapabilities(sharedResource, hdc, pfdID, glp, onscreen, true /* pbuffer */);
+ caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
} else {
- caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen);
+ caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
}
if(null==caps) {
throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+
@@ -304,8 +305,8 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int pfdID,
- GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ AbstractGraphicsDevice device, GLProfile glp,
+ long hdc, int pfdID, int winattrbits) {
if (!sharedResource.hasARBPixelFormat()) {
return null;
}
@@ -319,17 +320,12 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID +
" of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
}
- List bucket = new ArrayList(1);
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
- return (WGLGLCapabilities) bucket.get(0);
- }
- return null;
+ return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
}
- static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource,
+ static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device,
GLCapabilitiesImmutable capabilities,
- int[] iattributes, int accelerationMode, float[] fattributes)
+ long hdc, int[] iattributes, int accelerationMode, float[] fattributes)
{
if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
@@ -366,27 +362,20 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
+ Integer.toHexString(accelerationMode) + ": " + numFormats);
for (int i = 0; i < numFormats; i++) {
WGLGLCapabilities dbgCaps0 = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(
- sharedResource, hdc, pformats[i],
- capabilities.getGLProfile(), capabilities.isOnscreen(), capabilities.isPBuffer());
+ sharedResource, device, capabilities.getGLProfile(), hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps0);
}
}
return pformats;
}
- static List wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp, boolean onscreen, boolean usePBuffer) {
- final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, winattrbits);
- }
-
static List wglARBPFIDs2AllGLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp) {
- return wglARBPFIDs2GLCapabilitiesImpl(sharedResource, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS);
+ AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs) {
+ return wglARBPFIDs2GLCapabilities(sharedResource, device, glp, hdc, pfdIDs, GLGraphicsConfigurationUtil.ALL_BITS);
}
- private static List wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLDrawableFactory.SharedResource sharedResource,
- long hdc, int[] pfdIDs, GLProfile glp, int winattrbits) {
+ static List wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
+ AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits) {
if (!sharedResource.hasARBPixelFormat()) {
return null;
}
@@ -401,7 +390,10 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
for(int i = 0; i= 1 &&
((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
- AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ if(null != caps) {
+ bucket.add(caps);
+ }
} else if (DEBUG) {
System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
@@ -582,7 +574,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return true;
}
- static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) {
+ static int AttribList2DrawableTypeBits(AbstractGraphicsDevice device, GLProfile glp, final int[] iattribs, final int niattribs, final int[] iresults) {
int val = 0;
for (int i = 0; i < niattribs; i++) {
@@ -599,18 +591,20 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
break;
}
}
+ if ( GLContext.isFBOAvailable(device, glp) ) {
+ val |= GLGraphicsConfigurationUtil.FBO_BIT;
+ }
return val;
}
- static boolean AttribList2GLCapabilities( List capsBucket,
- final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs,
- final int niattribs,
- final int[] iresults, final int winattrmask) {
- final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
+ static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device,
+ final GLProfile glp, final long hdc, final int pfdID,
+ final int[] iattribs, final int niattribs, final int[] iresults, final int winattrmask) {
+ final int allDrawableTypeBits = AttribList2DrawableTypeBits(device, glp, iattribs, niattribs, iresults);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
@@ -618,14 +612,13 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
// remove displayable bits, since pfdID is non displayable
drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
// non displayable requested (pbuffer)
}
- WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByARB(iattribs, niattribs, iresults);
-
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
}
//
@@ -645,7 +638,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return pfdIDs;
}
- static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) {
+ static int PFD2DrawableTypeBits(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd) {
int val = 0;
int dwFlags = pfd.getDwFlags();
@@ -656,37 +649,30 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
}
+ if ( GLContext.isFBOAvailable(device, glp) ) {
+ val |= GLGraphicsConfigurationUtil.FBO_BIT;
+ }
return val;
}
- static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
- List capsBucket = new ArrayList(1);
- if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
- return (WGLGLCapabilities) capsBucket.get(0);
- }
- return null;
- }
-
- static boolean PFD2GLCapabilities(List capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
if(null == pfd) {
- return false;
+ return null;
}
if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
- return false;
+ return null;
}
- final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
+ final int allDrawableTypeBits = PFD2DrawableTypeBits(device, glp, pfd);
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
- WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByGDI();
-
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits );
}
static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 00ed91bb4..66a5821d3 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -131,10 +131,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
throw new GLException("Error: HDC is null");
}
if (sharedResource.hasARBPixelFormat()) {
- availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedResource, capsChosen.getGLProfile());
+ availableCaps = WindowsWGLGraphicsConfigurationFactory.getAvailableGLCapabilitiesARB(sharedResource, sharedResource.getDevice(), capsChosen.getGLProfile(), hdc);
}
if( null == availableCaps || availableCaps.isEmpty() ) {
- availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen.getGLProfile());
+ availableCaps = getAvailableGLCapabilitiesGDI(device, capsChosen.getGLProfile(), hdc);
}
} finally {
if ( sharedResource.needsCurrentContext4ARBPFDQueries() ) {
@@ -150,17 +150,20 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return availableCaps;
}
- static List getAvailableGLCapabilitiesARB(long hdc, WindowsWGLDrawableFactory.SharedResource sharedResource, GLProfile glProfile) {
+ static List getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
- return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, hdc, pformats, glProfile);
+ return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, device, glProfile, hdc, pformats);
}
- static List getAvailableGLCapabilitiesGDI(long hdc, GLProfile glProfile) {
+ static List getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
int numFormats = pformats.length;
List bucket = new ArrayList(numFormats);
for (int i = 0; i < numFormats; i++) {
- WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(bucket, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ if(null != caps) {
+ bucket.add(caps);
+ }
}
return bucket;
}
@@ -274,8 +277,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
try {
- if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) {
- updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs);
+ if( !updateGraphicsConfigurationARB((WindowsWGLDrawableFactory)factory, config, chooser, hdc, extHDC, pfdIDs) ) {
+ updateGraphicsConfigurationGDI(config, chooser, hdc, extHDC, pfdIDs);
}
} finally {
if (null != sharedContext) {
@@ -284,10 +287,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
- private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) {
- AbstractGraphicsDevice device = config.getScreen().getDevice();
- WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ private static boolean updateGraphicsConfigurationARB(WindowsWGLDrawableFactory factory, WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser,
+ long hdc, boolean extHDC, int[] pformats) {
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ final WindowsWGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
if (null == sharedResource) {
if (DEBUG) {
@@ -302,11 +305,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return false;
}
- GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
- boolean onscreen = capsChosen.isOnscreen();
- boolean usePBuffer = capsChosen.isPBuffer();
- GLProfile glProfile = capsChosen.getGLProfile();
+ final GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final boolean isOpaque = capsChosen.isBackgroundOpaque() && GDI.DwmIsCompositionEnabled();
+ final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+ final GLProfile glProfile = capsChosen.getGLProfile();
if(DEBUG) {
System.err.println("translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+" -> translucency "+(!isOpaque));
@@ -325,7 +327,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + presetPFDID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, hdc, presetPFDID, glProfile, onscreen, usePBuffer);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, device, glProfile, hdc, presetPFDID, winattrbits);
pixelFormatCaps = (WGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(pixelFormatCaps, isOpaque);
} else {
int recommendedIndex = -1; // recommended index
@@ -337,17 +339,17 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
float[] fattributes = new float[1];
int accelerationMode = WGLExt.WGL_FULL_ACCELERATION_ARB;
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
if (null == pformats) {
accelerationMode = WGLExt.WGL_GENERIC_ACCELERATION_ARB;
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
}
if (null == pformats) {
accelerationMode = -1; // use what we are offered ..
- pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedResource, capsChosen,
- iattributes, accelerationMode, fattributes);
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(sharedResource, device, capsChosen,
+ hdc, iattributes, accelerationMode, fattributes);
}
if (null != pformats) {
recommendedIndex = 0;
@@ -371,13 +373,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
}
- List availableCaps =
- WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, hdc, pformats,
- glProfile, onscreen, usePBuffer);
+ List availableCaps =
+ WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, winattrbits);
+
if( null == availableCaps || 0 == availableCaps.size() ) {
if (DEBUG) {
System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
- " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer);
+ " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
Thread.dumpStack();
}
return false;
@@ -385,7 +387,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if (DEBUG) {
System.err.println("updateGraphicsConfigurationARB: " + pformats.length +
- " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps");
+ " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString() + ", " + availableCaps.size() + " glcaps");
if(0 <= recommendedIndex) {
System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " +
pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex));
@@ -420,8 +422,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
return true;
}
- private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, int[] pformats) {
+ private static boolean updateGraphicsConfigurationGDI(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser, long hdc,
+ boolean extHDC, int[] pformats) {
GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(capsChosen.isPBuffer()) {
if (DEBUG) {
@@ -429,9 +431,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
return false;
}
- boolean onscreen = capsChosen.isOnscreen();
- GLProfile glProfile = capsChosen.getGLProfile();
-
+ // final boolean onscreen = capsChosen.isOnscreen();
+ // final boolean useFBO = capsChosen.isFBO();
+ final GLProfile glProfile = capsChosen.getGLProfile();
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+
List availableCaps = new ArrayList();
int pfdID; // chosen or preset PFD ID
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
@@ -447,15 +451,17 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + pfdID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(config.getScreen().getDevice(), glProfile, hdc, pfdID, winattrmask);
} else {
if(null == pformats) {
pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
}
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false, false);
for (int i = 0; i < pformats.length; i++) {
- WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(config.getScreen().getDevice(), glProfile, hdc, pformats[i], winattrmask);
+ if(null != caps) {
+ availableCaps.add(caps);
+ }
}
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index b458fffe1..d169945fe 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -33,10 +33,6 @@
package jogamp.opengl.x11.glx;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
@@ -58,6 +54,7 @@ import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.x11.X11GraphicsConfiguration;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
@@ -71,7 +68,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
- final AbstractGraphicsDevice device = x11Screen.getDevice();
+ final X11GraphicsDevice device = (X11GraphicsDevice) x11Screen.getDevice();
final long display = device.getHandle();
if(0==display) {
throw new GLException("Display null of "+x11Screen);
@@ -85,7 +82,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
glp = GLProfile.getDefault(x11Screen.getDevice());
}
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, device, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(device));
+ final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(device));
if(null==caps) {
throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
}
@@ -247,7 +244,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return true;
}
- static int FBCfgDrawableTypeBits(final AbstractGraphicsDevice device, GLProfile glp, final long fbcfg) {
+ static int FBCfgDrawableTypeBits(final X11GraphicsDevice device, GLProfile glp, final long fbcfg) {
int val = 0;
int[] tmp = new int[1];
@@ -268,19 +265,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return val;
}
- static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
- boolean relaxed, boolean onscreen, boolean usePBuffer,
- boolean isMultisampleAvailable) {
- ArrayList bucket = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, false);
- if( GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, winattrmask, isMultisampleAvailable) ) {
- return (X11GLCapabilities) bucket.get(0);
- } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, device, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- return (X11GLCapabilities) bucket.get(0);
- }
- return null;
- }
-
static XRenderDirectFormat XVisual2XRenderMask(long dpy, long visual) {
XRenderPictFormat renderPictFmt = X11Lib.XRenderFindVisualFormat(dpy, visual);
if(null == renderPictFmt) {
@@ -289,9 +273,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return renderPictFmt.getDirect();
}
- static boolean GLXFBConfig2GLCapabilities(List capsBucket,
- GLProfile glp, AbstractGraphicsDevice device, long fbcfg,
- int winattrmask, boolean isMultisampleAvailable) {
+ static X11GLCapabilities GLXFBConfig2GLCapabilities(X11GraphicsDevice device, GLProfile glp, long fbcfg,
+ int winattrmask, boolean isMultisampleAvailable) {
final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp, fbcfg);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
@@ -307,18 +290,18 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
int[] tmp = new int[1];
if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
- return false;
+ return null;
}
if( 0 == ( GLX.GLX_RGBA_BIT & tmp[0] ) ) {
- return false; // no RGBA -> color index not supported
+ return null; // no RGBA -> color index not supported
}
- GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
+ X11GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
if (isMultisampleAvailable) {
res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
@@ -353,7 +336,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
} catch (Exception e) {}
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
}
private static String glXGetFBConfigErrorCode(int err) {
@@ -408,30 +391,34 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return res;
}
- static boolean XVisualInfo2GLCapabilities(List capsBucket,
- GLProfile glp, long display, XVisualInfo info,
- final int winattrmask, boolean isMultisampleEnabled) {
- final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ;
+ static X11GLCapabilities XVisualInfo2GLCapabilities(final X11GraphicsDevice device, GLProfile glp, XVisualInfo info,
+ final int winattrmask, boolean isMultisampleEnabled) {
+ final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.BITMAP_BIT |
+ ( GLContext.isFBOAvailable(device, glp) ? GLGraphicsConfigurationUtil.FBO_BIT : 0 )
+ ;
+
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
- return false;
+ return null;
}
+ final long display = device.getHandle();
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
}
- return false;
+ return null;
}
val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
}
- return false;
+ return null;
}
GLCapabilities res = new X11GLCapabilities(info, glp);
@@ -470,7 +457,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits);
+ return (X11GLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits);
}
private static String glXGetConfigErrorCode(int err) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 234b06bdb..3189f933f 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -152,12 +152,12 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
// Utilizing FBConfig
//
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = absDevice.getHandle();
- int screen = x11Screen.getIndex();
- int[] count = { -1 };
- ArrayList availableCaps = new ArrayList();
+ final int screen = x11Screen.getIndex();
+ final int[] count = { -1 };
+ final ArrayList availableCaps = new ArrayList();
fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<=0) {
@@ -167,18 +167,19 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
return null;
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(absDevice, glProfile, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+ if(null != caps) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
return availableCaps;
}
static List getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) {
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ final X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
@@ -191,10 +192,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
ArrayList availableCaps = new ArrayList();
for (int i = 0; i < infos.length; i++) {
- if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable);
+ if(null != caps) {
+ availableCaps.add(caps);
+ } if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
}
}
return availableCaps;
@@ -238,8 +240,8 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(X11GraphicsScreen x11Screen, int fbID, GLProfile glp) {
- final AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- final long display = absDevice.getHandle();
+ final X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = x11Device.getHandle();
final int screen = x11Screen.getIndex();
final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
@@ -251,7 +253,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, absDevice, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
+ final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(x11Device));
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
@@ -262,22 +264,19 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
int recommendedIndex = -1;
PointerBuffer fbcfgsL = null;
GLProfile glProfile = capsChosen.getGLProfile();
- boolean onscreen = capsChosen.isOnscreen();
- boolean usePBuffer = capsChosen.isPBuffer();
- boolean useFBO = capsChosen.isFBO();
// Utilizing FBConfig
//
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
+ X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+ long display = x11Device.getHandle();
int screen = x11Screen.getIndex();
final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
+ final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(x11Device);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
List availableCaps = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer, useFBO);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice,
// skipped if xvisualID is given
if( VisualIDHolder.VID_UNDEFINED == xvisualID ) {
@@ -285,10 +284,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
if (fbcfgsL != null && fbcfgsL.limit()>0) {
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
if(availableCaps.size() > 0) {
@@ -318,10 +318,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, absDevice, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
- }
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(x11Device, glProfile, fbcfgsL.get(i), winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
}
}
@@ -374,11 +375,11 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
GLProfile glProfile = capsChosen.getGLProfile();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */, false);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen.isOnscreen(), capsChosen.isFBO(), false /* pbuffer */, capsChosen.isBitmap());
List availableCaps = new ArrayList();
int recommendedIndex = -1;
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ X11GraphicsDevice absDevice = (X11GraphicsDevice) x11Screen.getDevice();
long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
@@ -411,15 +412,15 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
for (int i = 0; i < infos.length; i++) {
- if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
- }
- } else {
+ final GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(absDevice, glProfile, infos[i], winattrmask, isMultisampleAvailable);
+ if( null != caps ) {
+ availableCaps.add(caps);
// Attempt to find the visual chosenIndex by glXChooseVisual, if not translucent
if (capsChosen.isBackgroundOpaque() && recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
recommendedIndex = availableCaps.size() - 1;
}
+ } else if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
index cb33aec5e..50e6ed46c 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
@@ -61,6 +61,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
// Switch for on- or offscreen
private boolean onscreen = true;
+
+ // offscreen bitmap mode
+ private boolean isBitmap = false;
/** Creates a Capabilities object. All attributes are in a default
state.
@@ -85,6 +88,8 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + this.redBits;
+ hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.isBitmap ? 1 : 0 );
hash = ((hash << 5) - hash) + this.greenBits;
hash = ((hash << 5) - hash) + this.blueBits;
hash = ((hash << 5) - hash) + this.alphaBits;
@@ -93,7 +98,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
hash = ((hash << 5) - hash) + this.transparentValueGreen;
hash = ((hash << 5) - hash) + this.transparentValueBlue;
hash = ((hash << 5) - hash) + this.transparentValueAlpha;
- hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
return hash;
}
@@ -109,12 +113,13 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
other.getBlueBits()==blueBits &&
other.getAlphaBits()==alphaBits &&
other.isBackgroundOpaque()==backgroundOpaque &&
- other.isOnscreen()==onscreen;
- if(!backgroundOpaque) {
- res = res && other.getTransparentRedValue()==transparentValueRed &&
- other.getTransparentGreenValue()==transparentValueGreen &&
- other.getTransparentBlueValue()==transparentValueBlue &&
- other.getTransparentAlphaValue()==transparentValueAlpha;
+ other.isOnscreen()==onscreen &&
+ other.isBitmap()==isBitmap;
+ if(res && !backgroundOpaque) {
+ res = other.getTransparentRedValue()==transparentValueRed &&
+ other.getTransparentGreenValue()==transparentValueGreen &&
+ other.getTransparentBlueValue()==transparentValueBlue &&
+ other.getTransparentAlphaValue()==transparentValueAlpha;
}
return res;
@@ -158,9 +163,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
- /** Returns the number of bits requested for the color buffer's red
- component. On some systems only the color depth, which is the
- sum of the red, green, and blue bits, is considered. */
@Override
public final int getRedBits() {
return redBits;
@@ -173,9 +175,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.redBits = redBits;
}
- /** Returns the number of bits requested for the color buffer's
- green component. On some systems only the color depth, which is
- the sum of the red, green, and blue bits, is considered. */
@Override
public final int getGreenBits() {
return greenBits;
@@ -188,9 +187,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.greenBits = greenBits;
}
- /** Returns the number of bits requested for the color buffer's blue
- component. On some systems only the color depth, which is the
- sum of the red, green, and blue bits, is considered. */
@Override
public final int getBlueBits() {
return blueBits;
@@ -203,9 +199,6 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
this.blueBits = blueBits;
}
- /** Returns the number of bits requested for the color buffer's
- alpha component. On some systems only the color depth, which is
- the sum of the red, green, and blue bits, is considered. */
@Override
public final int getAlphaBits() {
return alphaBits;
@@ -228,10 +221,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
/**
- * Defaults to true, ie. opaque surface.
- *
- * On supported platforms, setting opaque to false may result in a translucent surface.
- *
+ * Sets whether the surface shall be opaque or translucent.
*
* Platform implementations may need an alpha component in the surface (eg. Windows),
* or expect pre-multiplied alpha values (eg. X11/XRender).
@@ -240,16 +230,9 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
* Please note that in case alpha is required on the platform the
* clear color shall have an alpha lower than 1.0 to allow anything shining through.
*
- *
*
* Mind that translucency may cause a performance penalty
- * due to the composite work required by the window manager.
- *
- *
- * The platform implementation may utilize the transparency RGBA values.
- * This is true for the original GLX transparency specification, which is no more used today.
- * Actually these values are currently not used by any implementation,
- * so we may mark them deprecated soon, if this doesn't change.
+ * due to the composite work required by the window manager.
*
*/
public void setBackgroundOpaque(boolean opaque) {
@@ -259,56 +242,65 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
- /** Indicates whether the background of this OpenGL context should
- be considered opaque. Defaults to true.
-
- @see #setBackgroundOpaque
- */
@Override
public final boolean isBackgroundOpaque() {
return backgroundOpaque;
}
- /** Sets whether the drawable surface supports onscreen.
- Defaults to true.
- */
+ /**
+ * Sets whether the surface shall be on- or offscreen.
+ *
+ * Defaults to true.
+ *
+ *
+ * If requesting an offscreen surface without further selection of it's mode,
+ * e.g. FBO, Pbuffer or {@link #setBitmap(boolean) bitmap},
+ * the implementation will choose the best available offscreen mode.
+ *
+ * @param onscreen
+ */
public void setOnscreen(boolean onscreen) {
this.onscreen=onscreen;
}
- /** Indicates whether the drawable surface is onscreen.
- Defaults to true.
- */
@Override
public final boolean isOnscreen() {
return onscreen;
}
- /** Gets the transparent red value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentRedValue
- */
+ /**
+ * Requesting offscreen bitmap mode.
+ *
+ * If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
+ *
+ *
+ * Defaults to false.
+ *
+ *
+ * Requesting offscreen bitmap mode disables the offscreen auto selection.
+ *
+ */
+ public void setBitmap(boolean enable) {
+ if(enable) {
+ setOnscreen(false);
+ }
+ isBitmap = enable;
+ }
+
+ @Override
+ public boolean isBitmap() {
+ return isBitmap;
+ }
+
@Override
public final int getTransparentRedValue() { return transparentValueRed; }
- /** Gets the transparent green value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentGreenValue
- */
@Override
public final int getTransparentGreenValue() { return transparentValueGreen; }
- /** Gets the transparent blue value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentBlueValue
- */
@Override
public final int getTransparentBlueValue() { return transparentValueBlue; }
- /** Gets the transparent alpha value for the frame buffer configuration.
- * This value is undefined if {@link #isBackgroundOpaque()} equals true.
- * @see #setTransparentAlphaValue
- */
@Override
public final int getTransparentAlphaValue() { return transparentValueAlpha; }
@@ -342,32 +334,58 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
@Override
public StringBuilder toString(StringBuilder sink) {
+ return toString(sink, true);
+ }
+
+ /** Returns a textual representation of this Capabilities
+ object. */
+ @Override
+ public String toString() {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Caps[");
+ toString(msg);
+ msg.append("]");
+ return msg.toString();
+ }
+
+ /** Return a textual representation of this object's on/off screen state. Use the given StringBuffer [optional]. */
+ protected StringBuilder onoffScreenToString(StringBuilder sink) {
if(null == sink) {
sink = new StringBuilder();
}
if(onscreen) {
sink.append("on-scr");
} else {
- sink.append("offscr");
+ sink.append("offscr[");
+ }
+ if(isBitmap) {
+ sink.append("bitmap");
+ } else if(onscreen) {
+ sink.append("."); // no additional off-screen modes besides on-screen
+ } else {
+ sink.append("auto-cfg"); // auto-config off-screen mode
+ }
+ sink.append("]");
+
+ return sink;
+ }
+
+ protected StringBuilder toString(StringBuilder sink, boolean withOnOffScreen) {
+ if(null == sink) {
+ sink = new StringBuilder();
}
- sink.append(", rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
+ sink.append("rgba 0x").append(toHexString(redBits)).append("/").append(toHexString(greenBits)).append("/").append(toHexString(blueBits)).append("/").append(toHexString(alphaBits));
if(backgroundOpaque) {
sink.append(", opaque");
} else {
sink.append(", trans-rgba 0x").append(toHexString(transparentValueRed)).append("/").append(toHexString(transparentValueGreen)).append("/").append(toHexString(transparentValueBlue)).append("/").append(toHexString(transparentValueAlpha));
}
+ if(withOnOffScreen) {
+ sink.append(", ");
+ onoffScreenToString(sink);
+ }
return sink;
}
+
protected final String toHexString(int val) { return Integer.toHexString(val); }
-
- /** Returns a textual representation of this Capabilities
- object. */
- @Override
- public String toString() {
- StringBuilder msg = new StringBuilder();
- msg.append("Caps[");
- toString(msg);
- msg.append("]");
- return msg.toString();
- }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
index b984a4626..b801ab457 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/CapabilitiesImmutable.java
@@ -39,44 +39,65 @@ import com.jogamp.common.type.WriteCloneable;
public interface CapabilitiesImmutable extends VisualIDHolder, WriteCloneable, Comparable {
/**
- * Returns the number of bits requested for the color buffer's red
+ * Returns the number of bits for the color buffer's red
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getRedBits();
/**
- * Returns the number of bits requested for the color buffer's green
+ * Returns the number of bits for the color buffer's green
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getGreenBits();
/**
- * Returns the number of bits requested for the color buffer's blue
+ * Returns the number of bits for the color buffer's blue
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getBlueBits();
/**
- * Returns the number of bits requested for the color buffer's alpha
+ * Returns the number of bits for the color buffer's alpha
* component. On some systems only the color depth, which is the sum of the
* red, green, and blue bits, is considered.
*/
int getAlphaBits();
/**
- * Indicates whether the background of this OpenGL context should be
- * considered opaque. Defaults to true.
+ * Returns whether an opaque or translucent surface is requested, supported or chosen.
+ *
+ * Default is true, i.e. opaque.
+ *
*/
boolean isBackgroundOpaque();
/**
- * Indicates whether the drawable surface is onscreen. Defaults to true.
+ * Returns whether an on- or offscreen surface is requested, available or chosen.
+ *
+ * Default is true, i.e. onscreen.
+ *
+ *
+ * Mind that an capabilities intance w/ available semantics
+ * may show onscreen, but also the offscreen modes FBO, Pbuffer or {@link #setBitmap(boolean) bitmap}.
+ * This is valid, since one native configuration maybe used for either functionality.
+ *
*/
boolean isOnscreen();
+ /**
+ * Returns whether bitmap offscreen mode is requested, available or chosen.
+ *
+ * Default is false.
+ *
+ *
+ * For chosen capabilities, only the selected offscreen surface is set to true
.
+ *
+ */
+ boolean isBitmap();
+
/**
* Gets the transparent red value for the frame buffer configuration. This
* value is undefined if; equals true.
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
index 9d4b112b1..744c7e6d5 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultCapabilitiesChooser.java
@@ -68,6 +68,9 @@ import jogamp.nativewindow.Debug;
public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
private static final boolean DEBUG = Debug.isPropertyDefined("nativewindow.debug.CapabilitiesChooser", true);
+ private final static int NO_SCORE = -9999999;
+ private final static int COLOR_MISMATCH_PENALTY_SCALE = 36;
+
public int chooseCapabilities(final CapabilitiesImmutable desired,
final List extends CapabilitiesImmutable> available,
final int windowSystemRecommendedChoice) {
@@ -92,8 +95,6 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
// Create score array
int[] scores = new int[availnum];
- int NO_SCORE = -9999999;
- int COLOR_MISMATCH_PENALTY_SCALE = 36;
for (int i = 0; i < availnum; i++) {
scores[i] = NO_SCORE;
}
@@ -103,6 +104,10 @@ public class DefaultCapabilitiesChooser implements CapabilitiesChooser {
if (cur == null) {
continue;
}
+ if (desired.isOnscreen() && !cur.isOnscreen()) {
+ continue; // requested onscreen, but n/a
+ }
+
int score = 0;
// Compute difference in color depth
score += (COLOR_MISMATCH_PENALTY_SCALE *
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
new file mode 100644
index 000000000..0782e8915
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
@@ -0,0 +1,233 @@
+/**
+ * Copyright 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Window;
+import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestGLCapabilities01NEWT extends UITestCase {
+ static final int width = 100;
+ static final int height = 100;
+
+ boolean checkProfile(String profile) {
+ if( !GLProfile.isAvailable(profile) ) {
+ System.err.println("Profile "+profile+" n/a");
+ return false;
+ }
+ return true;
+ }
+
+ void doTest(GLCapabilities reqGLCaps, GLEventListener demo) throws InterruptedException {
+ System.out.println("Requested GL Caps: "+reqGLCaps);
+
+ //
+ // Create native windowing resources .. X11/Win/OSX
+ //
+ final Window window = NewtFactory.createWindow(reqGLCaps);
+ Assert.assertNotNull(window);
+ window.setSize(width, height);
+ window.setVisible(true);
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(window, true));
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(window, true));
+ System.out.println("Window: "+window.getClass().getName());
+
+ // Check caps of NativeWindow config w/o GL
+ final CapabilitiesImmutable chosenCaps = window.getGraphicsConfiguration().getChosenCapabilities();
+ System.out.println("Window Caps Pre_GL: "+chosenCaps);
+ Assert.assertNotNull(chosenCaps);
+ Assert.assertTrue(chosenCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenCaps.getRedBits()>5);
+
+ //
+ // Create native OpenGL resources .. XGL/WGL/CGL ..
+ // equivalent to GLAutoDrawable methods: setVisible(true)
+ //
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+
+ final GLDrawable drawable = factory.createGLDrawable(window);
+ Assert.assertNotNull(drawable);
+ System.out.println("Drawable Pre-GL(0): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+ //
+ drawable.setRealized(true);
+ Assert.assertTrue(drawable.isRealized());
+
+ System.out.println("Window Caps PostGL : "+window.getGraphicsConfiguration().getChosenCapabilities());
+ System.out.println("Drawable Post-GL(1): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+ // Check caps of GLDrawable after realization
+ final GLCapabilitiesImmutable chosenGLCaps = drawable.getChosenGLCapabilities();
+ System.out.println("Chosen GL Caps(1): "+chosenGLCaps);
+ Assert.assertNotNull(chosenGLCaps);
+ Assert.assertTrue(chosenGLCaps.getGreenBits()>5);
+ Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
+ Assert.assertTrue(chosenGLCaps.getRedBits()>5);
+ Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
+ Assert.assertEquals(reqGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(reqGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(reqGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(reqGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
+ // dbl buffer may be disabled w/ offscreen pbuffer and bitmap
+ Assert.assertEquals(reqGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ }
+
+ GLContext context = drawable.createContext(null);
+ Assert.assertNotNull(context);
+ int res = context.makeCurrent();
+ Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res);
+ context.release();
+
+ System.out.println("Chosen GL Caps(2): "+drawable.getChosenGLCapabilities());
+ System.out.println("Drawable Post-GL(2): "+drawable.getClass().getName()+", "+drawable.getNativeSurface().getClass().getName());
+
+ drawable.setRealized(false);
+ window.destroy();
+ }
+
+ @Test
+ public void testAvailableInfo() {
+ GLDrawableFactory f = GLDrawableFactory.getDesktopFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ f = GLDrawableFactory.getEGLFactory();
+ if(null != f) {
+ System.err.println(JoglVersion.getDefaultOpenGLInfo(f.getDefaultDevice(), null, true).toString());
+ }
+ }
+
+ //@Test
+ public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GL2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ // @Test
+ public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GL2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OnScreenDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GL2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenPbufferDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GL2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testGL2OffScreenBitmapDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GL2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OnScreenDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setPBuffer(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ /** Not implemented !
+ @Test
+ public void testES2OffScreenBitmapDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setBitmap(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ } */
+
+ public static void main(String args[]) throws IOException {
+ org.junit.runner.JUnitCore.main(TestGLCapabilities01NEWT.class.getName());
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
index 35a2d9669..9e96db5e1 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -38,6 +38,7 @@ import java.awt.Robot;
import java.awt.Toolkit;
import javax.media.nativewindow.NativeWindow;
+import javax.media.opengl.GLDrawable;
import javax.media.opengl.awt.GLCanvas;
import org.junit.Assert;
@@ -494,6 +495,18 @@ public class AWTRobotUtil {
return wait
Date: Fri, 7 Sep 2012 08:13:06 +0200
Subject: Cleanup shutdown mechanism ; Fix X11/ATI SIGV at shutdown ;
EGLDisplayUtil: Check for leaked display handles
GLProfile / all shutdown methods: Remove ShutdownType to remove complexity (not required)
Proper shutdown sequence:
GLProfile - GLDrawableFactory+ - GLContext - NativeWindowFactory - [X11Util, OSXUtil, ..]
GLDrawableFactory: Always keep shutdown-hook alive, required for X11Util shutdown (@ JVMShutdown only)
X11Util: Shutdown
- @ JVMShutdown only
- If GL vendor ATI: close pending X11 display connections in proper order of creation.
This finally removes the SIGV when shutting down the JVM on X11 w/ ATI driver.
EGLDisplayUtil: Add shutdown, allowing to validate whether leaked EGL display handles remain.
---
make/scripts/tests-x64.bat | 4 +-
make/scripts/tests.sh | 12 +-
.../javax/media/opengl/GLDrawableFactory.java | 36 +++---
src/jogl/classes/javax/media/opengl/GLProfile.java | 29 +----
.../classes/jogamp/opengl/egl/EGLDisplayUtil.java | 38 +++++-
.../jogamp/opengl/egl/EGLDrawableFactory.java | 22 ++--
.../macosx/cgl/MacOSXCGLDrawableFactory.java | 10 +-
.../windows/wgl/WindowsWGLDrawableFactory.java | 10 +-
.../opengl/x11/glx/X11GLXDrawableFactory.java | 14 +--
.../media/nativewindow/NativeWindowFactory.java | 42 +++++--
.../classes/jogamp/nativewindow/jawt/JAWTUtil.java | 11 +-
.../jogamp/nativewindow/macosx/OSXUtil.java | 10 ++
.../jogamp/nativewindow/windows/GDIUtil.java | 10 ++
.../classes/jogamp/nativewindow/x11/X11Util.java | 127 +++++++++++++--------
.../junit/jogl/acore/TestShutdownCompleteAWT.java | 4 +-
.../junit/jogl/acore/TestShutdownCompleteNEWT.java | 14 ++-
.../junit/jogl/acore/TestShutdownSharedAWT.java | 124 --------------------
.../junit/jogl/acore/TestShutdownSharedNEWT.java | 127 ---------------------
.../jogl/demos/es2/newt/TestGearsES2NEWT.java | 13 +--
.../jogl/demos/es2/newt/TestRedSquareES2NEWT.java | 13 +--
.../test/junit/newt/TestScreenMode01NEWT.java | 2 +-
21 files changed, 243 insertions(+), 429 deletions(-)
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
(limited to 'src/jogl/classes/javax/media')
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 669e0212e..22cce49aa 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -1,7 +1,9 @@
REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet
REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas
-scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
+scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 1314094cf..5668893f7 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -53,6 +53,7 @@ function jrun() {
swton=$1
shift
+ #D_ARGS="-Djogl.disable.opengles"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Dnewt.debug.Window.MouseEvent"
#D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
#D_ARGS="-Djogl.debug.FBObject"
@@ -217,12 +218,12 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen02BitmapNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFloatUtil01MatrixMatrixMultNOUI $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestNEWTCloseX11DisplayBug565 $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLProfile01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestInitConcurrentNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextSurfaceLockNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
@@ -260,7 +261,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode00bNEWT
-#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT
+testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01bNEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT
@@ -281,7 +282,6 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestPBufferDeadlockAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.x11.TestGLXCallsOnAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestSwingAWT01GLn
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestAWT03GLCanvasRecreate01 $*
@@ -379,7 +379,6 @@ function testawtswt() {
#
# FBO / ..
#
-testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable00NEWT $*
@@ -429,11 +428,6 @@ testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $*
#linux:
-# EARMARK removal of shutdown mode!
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedAWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestShutdownSharedNEWT $*
# osx:
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index acda45bff..9fd895c1f 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -55,7 +55,6 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.opengl.Debug;
@@ -106,6 +105,7 @@ public abstract class GLDrawableFactory {
// Shutdown hook mechanism for the factory
private static boolean factoryShutdownHookRegistered = false;
private static Thread factoryShutdownHook = null;
+ private static volatile boolean isJVMShuttingDown = false;
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
@@ -176,21 +176,24 @@ public abstract class GLDrawableFactory {
}
}
- protected static void shutdown(ShutdownType shutdownType) {
+ protected static void shutdown() {
if (isInit) { // volatile: ok
synchronized (GLDrawableFactory.class) {
if (isInit) {
isInit=false;
- unregisterFactoryShutdownHook();
- shutdownImpl(shutdownType);
+ shutdownImpl();
}
}
}
}
- private static void shutdownImpl(ShutdownType shutdownType) {
+
+ private static void shutdownImpl() {
+ // Following code will _always_ remain in shutdown hook
+ // due to special semantics of native utils, i.e. X11Utils.
+ // The latter requires shutdown at JVM-Shutdown only.
synchronized(glDrawableFactories) {
for(int i=0; i() {
@@ -218,20 +224,6 @@ public abstract class GLDrawableFactory {
factoryShutdownHookRegistered = true;
}
- private static synchronized void unregisterFactoryShutdownHook() {
- if (!factoryShutdownHookRegistered) {
- return;
- }
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
- return null;
- }
- });
- factoryShutdownHookRegistered = false;
- }
-
-
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
glDrawableFactories.add(this);
@@ -244,7 +236,7 @@ public abstract class GLDrawableFactory {
protected void enterThreadCriticalZone() {};
protected void leaveThreadCriticalZone() {};
- protected abstract void destroy(ShutdownType shutdownType);
+ protected abstract void destroy();
/**
* Retrieve the default device
{@link AbstractGraphicsDevice#getConnection() connection},
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 513ccd101..23d789afd 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -198,44 +198,25 @@ public class GLProfile {
getProfileMap(device, true);
}
- /**
- * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}.
- *
- * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.
- * {@link #COMPLETE} Everything.
- *
- */
- public enum ShutdownType {
- /* Shared thread based resources only, eg. for Applets */
- SHARED_ONLY,
- /* Everything */
- COMPLETE;
- }
-
/**
* Manual shutdown method, may be called after your last JOGL use
* within the running JVM.
* It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.
* The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.
*
- * This method shall not need to be called for other reasons than issuing a proper shutdown of resources.
+ * This method shall not need to be called for other reasons than issuing a proper shutdown of resources at a defined time.
*
- * @param type the shutdown type, see {@link ShutdownType}.
*/
- public static void shutdown(ShutdownType type) {
+ public static void shutdown() {
initLock.lock();
try {
if(initialized) { // volatile: ok
initialized = false;
if(DEBUG) {
- System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName());
+ System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName());
Thread.dumpStack();
}
- GLDrawableFactory.shutdown(type);
- if(ShutdownType.COMPLETE == type) {
- GLContext.shutdown();
- }
- NativeWindowFactory.shutdown();
+ GLDrawableFactory.shutdown();
}
} finally {
initLock.unlock();
@@ -1480,7 +1461,7 @@ public class GLProfile {
if(DEBUG) {
System.err.println("Info: GLProfile.init - EGL/ES2 ANGLE disabled");
}
- eglFactory.destroy(ShutdownType.COMPLETE);
+ eglFactory.destroy();
eglFactory = null;
hasEGLFactory = false;
} else {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 18d2f830d..ce2e824f5 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -29,6 +29,7 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
+import java.util.Iterator;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -51,7 +52,7 @@ import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
*
*/
public class EGLDisplayUtil {
- protected static final boolean DEBUG = Debug.debug("EGL");
+ protected static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
static LongIntHashMap eglDisplayCounter;
@@ -60,6 +61,32 @@ public class EGLDisplayUtil {
eglDisplayCounter.setKeyNotFoundValue(0);
}
+ /**
+ * @return number of unclosed EGL Displays.
+ */
+ public static int shutdown(boolean verbose) {
+ if(DEBUG || verbose || eglDisplayCounter.size() > 0 ) {
+ System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+eglDisplayCounter.size()+")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( eglDisplayCounter.size() > 0) {
+ EGLDisplayUtil.dumpOpenDisplayConnections();
+ }
+ }
+
+ return eglDisplayCounter.size();
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+eglDisplayCounter.size());
+ int i=0;
+ for(Iterator iter = eglDisplayCounter.iterator(); iter.hasNext(); i++) {
+ final LongIntHashMap.Entry e = iter.next();
+ System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": refCnt "+e.value);
+ }
+ }
+
public static long eglGetDisplay(long nativeDisplay_id) {
final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
if(DEBUG) {
@@ -89,6 +116,7 @@ public class EGLDisplayUtil {
eglDisplayCounter.put(eglDisplay, refCnt);
if(DEBUG) {
System.err.println("EGLDisplayUtil.eglInitialize1("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ // Thread.dumpStack();
}
return res;
}
@@ -117,6 +145,7 @@ public class EGLDisplayUtil {
}
if(DEBUG) {
System.err.println("EGLDisplayUtil.eglInitialize2("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ // Thread.dumpStack();
}
return res;
}
@@ -185,12 +214,13 @@ public class EGLDisplayUtil {
final int refCnt = eglDisplayCounter.get(eglDisplay) - 1; // 1 - 1 = 0 -> final terminate
if(0==refCnt) { // no terminate if still in use or already terminated
res = EGL.eglTerminate(eglDisplay);
+ eglDisplayCounter.remove(eglDisplay);
} else {
+ if(0 < refCnt) { // no negative refCount
+ eglDisplayCounter.put(eglDisplay, refCnt);
+ }
res = true;
}
- if(0<=refCnt) { // no negative refCount
- eglDisplayCounter.put(eglDisplay, refCnt);
- }
if(DEBUG) {
System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
// Thread.dumpStack();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 986b110be..292eb17c8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -64,7 +64,6 @@ import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -201,13 +200,13 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final void destroy() {
if(null != sharedMap) {
Collection srl = sharedMap.values();
for(Iterator sri = srl.iterator(); sri.hasNext(); ) {
SharedResource sr = sri.next();
if(DEBUG) {
- System.err.println("EGLDrawableFactory.destroy("+shutdownType+"): "+sr.device.toString());
+ System.err.println("EGLDrawableFactory.destroy(): "+sr.device.toString());
}
sr.device.close();
}
@@ -220,17 +219,16 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*/
- if(ShutdownType.COMPLETE == shutdownType) {
- if(null != eglES1DynamicLookupHelper) {
- // eglES1DynamicLookupHelper.destroy();
- eglES1DynamicLookupHelper = null;
- }
- if(null != eglES2DynamicLookupHelper) {
- // eglES2DynamicLookupHelper.destroy();
- eglES2DynamicLookupHelper = null;
- }
+ if(null != eglES1DynamicLookupHelper) {
+ // eglES1DynamicLookupHelper.destroy();
+ eglES1DynamicLookupHelper = null;
+ }
+ if(null != eglES2DynamicLookupHelper) {
+ // eglES2DynamicLookupHelper.destroy();
+ eglES2DynamicLookupHelper = null;
}
EGLGraphicsConfigurationFactory.unregisterFactory();
+ EGLDisplayUtil.shutdown(DEBUG);
}
private HashMap sharedMap = null;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index c1b15cac5..591fafc68 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -60,7 +60,6 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -124,7 +123,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final void destroy() {
if(null != sharedMap) {
sharedMap.clear();
sharedMap = null;
@@ -133,10 +132,9 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) {
- macOSXCGLDynamicLookupHelper.destroy();
- macOSXCGLDynamicLookupHelper = null;
- } */
+ macOSXCGLDynamicLookupHelper.destroy();
+ */
+ macOSXCGLDynamicLookupHelper = null;
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index c414083c4..7ea487523 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -61,7 +61,6 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.GDISurface;
@@ -136,7 +135,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final void destroy() {
if(null != sharedResourceRunner) {
sharedResourceRunner.stop();
sharedResourceRunner = null;
@@ -149,10 +148,9 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) {
- windowsWGLDynamicLookupHelper.destroy();
- windowsWGLDynamicLookupHelper = null;
- } */
+ windowsWGLDynamicLookupHelper.destroy();
+ */
+ windowsWGLDynamicLookupHelper = null;
RegisteredClassFactory.shutdownSharedClasses();
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 293ac96f7..bc3e5b793 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -58,7 +58,6 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
@@ -129,7 +128,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void destroy(ShutdownType shutdownType) {
+ protected final void destroy() {
if(null != sharedResourceRunner) {
sharedResourceRunner.stop();
sharedResourceRunner = null;
@@ -142,14 +141,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
/**
* Pulling away the native library may cause havoc ..
*
- if(ShutdownType.COMPLETE == shutdownType && null != x11GLXDynamicLookupHelper) {
- x11GLXDynamicLookupHelper.destroy();
- x11GLXDynamicLookupHelper = null;
- } */
-
- // Don't really close pending Display connections,
- // since this may trigger a JVM exception
- X11Util.shutdown( false, DEBUG );
+ x11GLXDynamicLookupHelper.destroy();
+ */
+ x11GLXDynamicLookupHelper = null;
}
@Override
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index afcd0a008..89d476a3b 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -102,6 +102,8 @@ public abstract class NativeWindowFactory {
private static Constructor> x11ToolkitLockConstructor;
private static boolean requiresToolkitLock;
+ private static volatile boolean isJVMShuttingDown = false;
+
/** Creates a new NativeWindowFactory instance. End users do not
need to call this method. */
protected NativeWindowFactory() {
@@ -168,6 +170,22 @@ public abstract class NativeWindowFactory {
}
}
+ private static void shutdownNativeImpl(final ClassLoader cl) {
+ final String clazzName;
+ if( TYPE_X11 == nativeWindowingTypePure ) {
+ clazzName = X11UtilClassName;
+ } else if( TYPE_WINDOWS == nativeWindowingTypePure ) {
+ clazzName = GDIClassName;
+ } else if( TYPE_MACOSX == nativeWindowingTypePure ) {
+ clazzName = OSXUtilClassName;
+ } else {
+ clazzName = null;
+ }
+ if( null != clazzName ) {
+ ReflectionUtil.callStaticMethod(clazzName, "shutdown", null, null, cl );
+ }
+ }
+
/**
* Static one time initialization of this factory.
* This initialization method must be called once by the program or utilizing modules!
@@ -268,22 +286,28 @@ public abstract class NativeWindowFactory {
}
}
- public static synchronized void shutdown() {
+ public static synchronized void shutdown(boolean _isJVMShuttingDown) {
+ isJVMShuttingDown = _isJVMShuttingDown;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown);
+ }
if(initialized) {
initialized = false;
- if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START");
+ if(null != registeredFactories) {
+ registeredFactories.clear();
+ registeredFactories = null;
}
- registeredFactories.clear();
- registeredFactories = null;
GraphicsConfigurationFactory.shutdown();
- // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() ..
- if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END");
- }
+ }
+ shutdownNativeImpl(NativeWindowFactory.class.getClassLoader()); // always re-shutdown
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
}
}
+ /** Returns true if the JVM is shutting down, otherwise false. */
+ public static final boolean isJVMShuttingDown() { return isJVMShuttingDown; }
+
/** @return true if the underlying toolkit requires locking, otherwise false. */
public static boolean requiresToolkitLock() {
return requiresToolkitLock;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index 36d7c3727..f1e8a786a 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -48,6 +48,7 @@ import java.util.ArrayList;
import java.util.Map;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ToolkitLock;
import jogamp.nativewindow.Debug;
@@ -271,10 +272,18 @@ public class JAWTUtil {
}
}
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
public static void initSingleton() {
// just exist to ensure static init has been run
}
-
+
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ */
+ public static void shutdown() {
+ }
public static boolean hasJava2D() {
return j2dExist;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index f5f735051..149ebdf4a 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -28,6 +28,7 @@
package jogamp.nativewindow.macosx;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
@@ -38,6 +39,9 @@ public class OSXUtil {
private static boolean isInit = false;
private static final boolean DEBUG = Debug.debug("OSXUtil");
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
public static synchronized void initSingleton() {
if(!isInit) {
if(DEBUG) {
@@ -54,6 +58,12 @@ public class OSXUtil {
}
}
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ */
+ public static void shutdown() {
+ }
+
public static boolean requiresToolkitLock() {
return false;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index fda1649b6..613c76032 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -29,6 +29,7 @@ package jogamp.nativewindow.windows;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.NWJNILibLoader;
import jogamp.nativewindow.Debug;
@@ -41,6 +42,9 @@ public class GDIUtil {
private static RegisteredClassFactory dummyWindowClassFactory;
private static boolean isInit = false;
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
public static synchronized void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
@@ -61,6 +65,12 @@ public class GDIUtil {
}
}
+ /**
+ * Called by {@link NativeWindowFactory#shutdown()}
+ */
+ public static void shutdown() {
+ }
+
public static boolean requiresToolkitLock() { return false; }
private static RegisteredClass dummyWindowClass = null;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 860238649..93b7f3487 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -67,13 +67,13 @@ public class X11Util {
*
*
* You may test this, ie just reverse the destroy order below.
- * See also native test: jogl/test/native/displayMultiple02.c
+ * See also native test: jogl/test-native/displayMultiple02.c
*
*
* Workaround is to not close them at all if driver vendor is ATI.
*
*/
- public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
+ public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = !Debug.isPropertyDefined("nativewindow.debug.X11Util.ATI_HAS_NO_XCLOSEDISPLAY_BUG", true);
/** Value is true
, best 'stable' results if always using XInitThreads(). */
public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
@@ -95,6 +95,9 @@ public class X11Util {
private static Object setX11ErrorHandlerLock = new Object();
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
public static void initSingleton() {
if(!isInit) {
synchronized(X11Util.class) {
@@ -138,6 +141,52 @@ public class X11Util {
}
}
+ /**
+ * Cleanup resources.
+ *
+ * Called by {@link NativeWindowFactory#shutdown()}
+ *
+ */
+ public static void shutdown() {
+ if(isInit) {
+ synchronized(X11Util.class) {
+ if(isInit) {
+ final boolean isJVMShuttingDown = NativeWindowFactory.isJVMShuttingDown() ;
+ if(DEBUG || openDisplayMap.size() > 0 || reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0) {
+ System.err.println("X11Util.Display: Shutdown (JVM shutdown: "+isJVMShuttingDown+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", reusable (open, marked uncloseable): "+reusableDisplayList.size()+
+ ", pending (post closing): "+pendingDisplayList.size()+
+ ")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( openDisplayList.size() > 0) {
+ X11Util.dumpOpenDisplayConnections();
+ }
+ if( reusableDisplayList.size() > 0 || pendingDisplayList.size() > 0 ) {
+ X11Util.dumpPendingDisplayConnections();
+ }
+ }
+
+ synchronized(globalLock) {
+ // Only at JVM shutdown time, since AWT impl. seems to
+ // dislike closing of X11 Display's (w/ ATI driver).
+ if( isJVMShuttingDown ) {
+ isInit = false;
+ closePendingDisplayConnections();
+ openDisplayList.clear();
+ reusableDisplayList.clear();
+ pendingDisplayList.clear();
+ openDisplayMap.clear();
+ shutdown0();
+ }
+ }
+ }
+ }
+ }
+ }
+
public static synchronized boolean isNativeLockAvailable() {
return isX11LockAvailable;
}
@@ -183,6 +232,7 @@ public class X11Util {
private static Object globalLock = new Object();
private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name
private static List openDisplayList = new ArrayList();
+ private static List reusableDisplayList = new ArrayList();
private static List pendingDisplayList = new ArrayList();
public static class NamedDisplay {
@@ -218,8 +268,7 @@ public class X11Util {
public final boolean equals(Object obj) {
if(this == obj) { return true; }
if(obj instanceof NamedDisplay) {
- NamedDisplay n = (NamedDisplay) obj;
- return handle == n.handle;
+ return handle == ((NamedDisplay) obj).handle;
}
return false;
}
@@ -246,43 +295,6 @@ public class X11Util {
}
}
- /**
- * Cleanup resources.
- * If realXCloseOpenAndPendingDisplays
is false
,
- * keep alive all references (open display connection) for restart on same ClassLoader.
- *
- * @return number of unclosed X11 Displays.
- * @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
- */
- public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
- int num=0;
- if(DEBUG || verbose || openDisplayMap.size() > 0 || pendingDisplayList.size() > 0) {
- System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
- if(DEBUG) {
- Thread.dumpStack();
- }
- if( openDisplayList.size() > 0) {
- X11Util.dumpOpenDisplayConnections();
- }
- if( pendingDisplayList.size() > 0 ) {
- X11Util.dumpPendingDisplayConnections();
- }
- }
-
- synchronized(globalLock) {
- if(realXCloseOpenAndPendingDisplays) {
- closePendingDisplayConnections();
- openDisplayList.clear();
- pendingDisplayList.clear();
- openDisplayMap.clear();
- shutdown0();
- }
- }
- return num;
- }
-
/**
* Closing pending Display connections in reverse order.
*
@@ -292,9 +304,9 @@ public class X11Util {
int num=0;
synchronized(globalLock) {
if(DEBUG) {
- System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size());
+ System.err.println("X11Util: Closing Pending X11 Display Connections in order of their creation: "+pendingDisplayList.size());
}
- for(int i=pendingDisplayList.size()-1; i>=0; i--) {
+ for(int i=0; i
Date: Sat, 8 Sep 2012 19:45:11 +0200
Subject: Fix window mode attribute bit FBO_BIT usage in platform dependent
code (map it to native type) ; OSX Caps selection ; WGL/GDI BITMAP fix
Fix window mode attribute bit FBO_BIT usage in platform dependent code (map it to native type)
All platform dependent winAttrBit mapping: 'nativeType -> winAttrBit' and 'GLCapabilities -> winAttrBits'
shall replace FBO_BIT w/ the native type of the wrapper surface, i.e. WINDOW_BIT (X11, WGL, CGL) or PBUFFER_BIT (EGL).
This condenses to changes in
- EGLGraphicsConfiguration: EGLConfigDrawableTypeBits / GLCapabilities2AttribList
- X11GLXGraphicsConfiguration: FBCfgDrawableTypeBits, XVisualInfo2GLCapabilities / GLCapabilities2AttribList
- WindowsWGLGraphicsConfiguration: AttribList2DrawableTypeBits, PFD2DrawableTypeBits / GLCapabilities2AttribList
- OSX CGL/NS requires changes in MacOSXCGLContext, i.e. fix the surface mode of
NSPixelFormat2GLCapabilities, CGLPixelFormat2GLCapabilities results.
This change is included in the upcoming commit (class is heavily edited).
OSX chooseGraphicsConfigurationStatic: Add missing 'GLGraphicsConfigurationUtil.fixGLCapabilities(..)' call
- all platform impl. require to fix the given user caps due to the new offscreen auto selection mode
WindowsWGLGraphicsConfiguration*: ARB / GDI updateGraphicsConfiguration*()
- ARB method detects early whether it's suitable for given HDC, i.e. in case of BITMAP (it's not here)
- GDI methods detect failure while choosing PFD and doesn't care of DOUBLEBUFFER in case of bitmap (fixes BITMAP usage)
Capabilities/GLCapabilities:
- Fix missing double-buffer check in GLCapabilities.equals()
- add 'copyFrom(..)' method copy all data from give caps
---
.../classes/javax/media/opengl/GLCapabilities.java | 29 ++
.../jogamp/opengl/GLGraphicsConfigurationUtil.java | 5 +-
.../opengl/egl/EGLGraphicsConfiguration.java | 48 +++-
.../egl/EGLGraphicsConfigurationFactory.java | 13 +-
.../macosx/cgl/MacOSXCGLGraphicsConfiguration.java | 4 +-
.../cgl/MacOSXCGLGraphicsConfigurationFactory.java | 32 ++-
.../wgl/WindowsWGLGraphicsConfiguration.java | 299 ++++++++++++---------
.../WindowsWGLGraphicsConfigurationFactory.java | 71 +++--
.../x11/glx/X11GLXGraphicsConfiguration.java | 89 +++---
.../glx/X11GLXGraphicsConfigurationFactory.java | 1 -
.../javax/media/nativewindow/Capabilities.java | 22 +-
.../junit/jogl/acore/TestGLCapabilities01NEWT.java | 65 +++--
12 files changed, 442 insertions(+), 236 deletions(-)
(limited to 'src/jogl/classes/javax/media')
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 30a6215e7..9b004a0af 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -102,6 +102,34 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
}
}
+ /**
+ * Copies all {@link GLCapabilities} and {@link Capabilities} values
+ * from source
into this instance.
+ * @return this instance
+ */
+ public GLCapabilities copyFrom(GLCapabilitiesImmutable source) {
+ super.copyFrom(source);
+ glProfile = source.getGLProfile();
+ isPBuffer = source.isPBuffer();
+ isFBO = source.isFBO();
+ doubleBuffered = source.getDoubleBuffered();
+ stereo = source.getStereo();
+ hardwareAccelerated = source.getHardwareAccelerated();
+ depthBits = source.getDepthBits();
+ stencilBits = source.getStencilBits();
+ accumRedBits = source.getAccumRedBits();
+ accumGreenBits = source.getAccumGreenBits();
+ accumBlueBits = source.getAccumBlueBits();
+ accumAlphaBits = source.getAccumAlphaBits();
+ sampleBuffers = source.getSampleBuffers();
+ pbufferFloatingPointBuffers = source.getPbufferFloatingPointBuffers();
+ pbufferRenderToTexture = source.getPbufferRenderToTexture();
+ pbufferRenderToTextureRectangle = source.getPbufferRenderToTextureRectangle();
+ numSamples = source.getNumSamples();
+ sampleExtension = source.getSampleExtension();
+ return this;
+ }
+
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
@@ -137,6 +165,7 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
other.getGLProfile()==glProfile &&
other.isPBuffer()==isPBuffer &&
other.isFBO()==isFBO &&
+ other.getDoubleBuffered() == doubleBuffered &&
other.getStereo()==stereo &&
other.getHardwareAccelerated()==hardwareAccelerated &&
other.getDepthBits()==depthBits &&
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index d8e5ba31a..768fc6892 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,7 +28,6 @@
package jogamp.opengl;
-
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -37,7 +36,7 @@ public class GLGraphicsConfigurationUtil {
public static final int WINDOW_BIT = 1 << 0;
public static final int BITMAP_BIT = 1 << 1;
public static final int PBUFFER_BIT = 1 << 2;
- public static final int FBO_BIT = 1 << 3;
+ public static final int FBO_BIT = 1 << 3; // generic bit must be mapped to native one at impl. level
public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT | FBO_BIT ;
public static final StringBuilder winAttributeBits2String(StringBuilder sb, int winattrbits) {
@@ -161,7 +160,7 @@ public class GLGraphicsConfigurationUtil {
final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
- final boolean useBitmap = !usePbuffer && ( auto || capsRequested.isBitmap() ) ;
+ final boolean useBitmap = !useFBO && !usePbuffer && ( auto || capsRequested.isBitmap() ) ;
if( capsRequested.isOnscreen() ||
useFBO != capsRequested.isFBO() ||
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 135101ff2..8ee98072f 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -46,7 +46,6 @@ import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -129,12 +128,28 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return configs.get(0);
}
- static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final GLProfile glp, final long config) {
+ public static boolean isEGLConfigValid(long display, long config) {
+ if(0 == config) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+
+ // get the configID
+ if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val)) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println("Info: Couldn't retrieve EGL ConfigID for config "+toHexString(config)+", error "+toHexString(eglErr));
+ }
+ return false;
+ }
+ return true;
+ }
+
+ static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final long config) {
int val = 0;
- final long display = device.getHandle();
int[] stype = new int[1];
- if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
+ if(! EGL.eglGetConfigAttrib(device.getHandle(), config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
throw new GLException("Could not determine EGL_SURFACE_TYPE");
}
@@ -145,12 +160,9 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
}
if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
- val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
- }
- if ( GLContext.isFBOAvailable(device, glp) ) {
- val |= GLGraphicsConfigurationUtil.FBO_BIT;
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
-
return val;
}
@@ -269,8 +281,8 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
// Since the passed GLProfile may be null,
// we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
- final int allDrawableTypeBits = EGLConfigDrawableTypeBits(device, caps.getGLProfile(), config);
- final int drawableTypeBits = winattrmask & allDrawableTypeBits;
+ final int availableTypeBits = EGLConfigDrawableTypeBits(device, config);
+ final int drawableTypeBits = winattrmask & availableTypeBits;
if( 0 == drawableTypeBits ) {
return null;
@@ -284,7 +296,19 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
int idx=0;
attrs[idx++] = EGL.EGL_SURFACE_TYPE;
- attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = EGL.EGL_WINDOW_BIT;
+ } else if( caps.isFBO() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT;
+ } else if( caps.isBitmap() ) {
+ surfaceType = EGL.EGL_PIXMAP_BIT;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ attrs[idx++] = surfaceType;
attrs[idx++] = EGL.EGL_RED_SIZE;
attrs[idx++] = caps.getRedBits();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index d08685dcb..e72255108 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -324,6 +324,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return res;
}
+
static EGLGraphicsConfiguration eglChooseConfig(EGLGraphicsDevice device,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
@@ -344,7 +345,12 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
}
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+", nativeVisualID "+toHexString(nativeVisualID)+", "+capsChosen+", numConfigs "+numConfigs.get(0));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+
+ ", nativeVisualID "+toHexString(nativeVisualID)+
+ ", capsChosen "+capsChosen+", winbits "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()+
+ ", fboAvail "+GLContext.isFBOAvailable(device, glp)+
+ ", device "+device+", "+device.getUniqueID()+
+ ", numConfigs "+numConfigs.get(0));
}
final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
@@ -432,10 +438,11 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return null;
}
final EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex);
+ final EGLGraphicsConfiguration res = new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+", "+chosenCaps);
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+": "+res);
}
- return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
+ return res;
}
static List eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index 10e8193e2..149927160 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -280,7 +280,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
if(null == glp) {
glp = GLProfile.get(GLProfile.GL2);
}
- GLCapabilities caps = new GLCapabilities(glp);
+ final GLCapabilities caps = new GLCapabilities(glp);
int alphaBits = 0;
for (int i = 0; i < len; i++) {
int attr = cglInternalAttributeToken[i+off];
@@ -353,7 +353,7 @@ public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration
}
}
caps.setAlphaBits(alphaBits);
-
+
return caps;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index f138e7557..13faf7090 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -34,13 +34,19 @@
package jogamp.opengl.macosx.cgl;
import jogamp.opengl.GLGraphicsConfigurationFactory;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+import jogamp.opengl.x11.glx.X11GLXDrawableFactory;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
@@ -58,13 +64,7 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
- return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, absScreen, false);
- }
-
- static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(CapabilitiesImmutable capsChosen,
- CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser,
- AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+
if (absScreen == null) {
throw new IllegalArgumentException("AbstractGraphicsScreen is null");
}
@@ -77,11 +77,25 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurati
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
}
- if (chooser != null &&
- !(chooser instanceof GLCapabilitiesChooser)) {
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
}
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen, false);
+ }
+
+ static MacOSXCGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser,
+ AbstractGraphicsScreen absScreen, boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ final MacOSXCGLDrawableFactory factory = (MacOSXCGLDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final AbstractGraphicsDevice device = absScreen.getDevice();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLContext.isFBOAvailable(device, capsChosen.getGLProfile()), factory.canCreateGLPbuffer(device) );
+
return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, 0);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 5b21353c3..4d1069e6b 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -42,7 +42,6 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
@@ -58,6 +57,7 @@ import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
+@SuppressWarnings("deprecation")
public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
protected static final int MAX_PFORMATS = 256;
protected static final int MAX_ATTRIBS = 256;
@@ -107,7 +107,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if(hasARB) {
caps = wglARBPFID2GLCapabilities(sharedResource, device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
} else {
- caps = PFD2GLCapabilities(device, glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
+ caps = PFD2GLCapabilities(glp, hdc, pfdID, GLGraphicsConfigurationUtil.ALL_BITS);
}
if(null==caps) {
throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+
@@ -186,7 +186,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
}
}
if (DEBUG) {
- System.err.println("setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+caps);
+ System.err.println("setPixelFormat: hdc "+toHexString(hdc) +", "+caps);
}
setCapsPFD(caps);
}
@@ -274,36 +274,41 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return true;
}
- static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) {
+ static int wglARBPFDIDCount(WindowsWGLContext sharedCtx, long hdc) {
int[] iattributes = new int[1];
int[] iresults = new int[1];
WGLExt wglExt = sharedCtx.getWGLExt();
- iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
- if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ // pfdID shall be ignored here (spec), however, pass a valid pdf index '1' below (possible driver bug)
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 1 /* pfdID */, 0, 1, iattributes, 0, iresults, 0)) {
if(DEBUG) {
System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) +
+ ", value "+iresults[0]+
", LastError: " + GDI.GetLastError());
Thread.dumpStack();
}
- return null;
+ return 0;
}
- int numFormats = iresults[0];
- if(0 == numFormats) {
+ final int pfdIDCount = iresults[0];
+ if(0 == pfdIDCount) {
if(DEBUG) {
System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) +
", LastError: " + GDI.GetLastError());
Thread.dumpStack();
}
- return null;
}
- int[] pfdIDs = new int[numFormats];
- for (int i = 0; i < numFormats; i++) {
+ return pfdIDCount;
+ }
+
+ static int[] wglAllARBPFDIDs(int pfdIDCount) {
+ int[] pfdIDs = new int[pfdIDCount];
+ for (int i = 0; i < pfdIDCount; i++) {
pfdIDs[i] = 1 + i;
}
return pfdIDs;
}
-
+
static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
AbstractGraphicsDevice device, GLProfile glp,
long hdc, int pfdID, int winattrbits) {
@@ -320,7 +325,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID +
" of device context " + toHexString(hdc) + ", werr " + GDI.GetLastError());
}
- return AttribList2GLCapabilities(device, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
+ return AttribList2GLCapabilities(glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits);
}
static int[] wglChoosePixelFormatARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device,
@@ -369,11 +374,6 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return pformats;
}
- static List wglARBPFIDs2AllGLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
- AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs) {
- return wglARBPFIDs2GLCapabilities(sharedResource, device, glp, hdc, pfdIDs, GLGraphicsConfigurationUtil.ALL_BITS);
- }
-
static List wglARBPFIDs2GLCapabilities(WindowsWGLDrawableFactory.SharedResource sharedResource,
AbstractGraphicsDevice device, GLProfile glp, long hdc, int[] pfdIDs, int winattrbits) {
if (!sharedResource.hasARBPixelFormat()) {
@@ -390,14 +390,24 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
for(int i = 0; i= 1 &&
((WindowsWGLContext)sharedResource.getContext()).getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
- final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(device, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ final GLCapabilitiesImmutable caps = AttribList2GLCapabilities(glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
if(null != caps) {
bucket.add(caps);
+ if(DEBUG) {
+ final int j = bucket.size() - 1;
+ System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> "+j+"]: "+caps);
+ }
+ } else if(DEBUG) {
+ GLCapabilitiesImmutable skipped = AttribList2GLCapabilities(glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, GLGraphicsConfigurationUtil.ALL_BITS);
+ System.err.println("wglARBPFIDs2GLCapabilities: bucket["+i+" -> skip]: pfdID "+pfdIDs[i]+", "+skipped+", winattr "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
}
} else if (DEBUG) {
- System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
- i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
- GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ if( 1 > pfdIDs[i] ) {
+ System.err.println("wglARBPFIDs2GLCapabilities: Invalid pfdID " + i + "/" + numFormats + ": " + pfdIDs[i]);
+ } else {
+ System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
+ i + "/" + numFormats + ": " + pfdIDs[i] + ", hdc " + toHexString(hdc));
+ }
}
}
return bucket;
@@ -412,9 +422,6 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return false;
}
- boolean onscreen = caps.isOnscreen();
- boolean pbuffer = caps.isPBuffer();
-
int niattribs = 0;
iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
@@ -423,17 +430,24 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
iattributes[niattribs++] = accelerationValue;
}
- if (onscreen) {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
- } else if (pbuffer && sharedResource.hasARBPBuffer()) {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
+
+ final boolean usePBuffer = caps.isPBuffer() && sharedResource.hasARBPBuffer() ;
+
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ } else if( caps.isFBO() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_WINDOW_ARB; // native replacement!
+ } else if( usePBuffer ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ } else if( caps.isBitmap() ) {
+ surfaceType = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
} else {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
- iattributes[niattribs++] = GL.GL_TRUE;
+ throw new GLException("no surface type set in caps: "+caps);
}
-
+ iattributes[niattribs++] = surfaceType;
+ iattributes[niattribs++] = GL.GL_TRUE;
+
iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
if (caps.getDoubleBuffered()) {
iattributes[niattribs++] = GL.GL_TRUE;
@@ -495,7 +509,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
boolean useFloat = caps.getPbufferFloatingPointBuffers();
boolean ati = false;
boolean nvidia = false;
- if (pbuffer && sharedResource.hasARBPBuffer()) {
+ if ( usePBuffer ) {
// Check some invariants and set up some state
if (rect && !rtt) {
throw new GLException("Render-to-texture-rectangle requires render-to-texture to be specified");
@@ -574,33 +588,38 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return true;
}
- static int AttribList2DrawableTypeBits(AbstractGraphicsDevice device, GLProfile glp, final int[] iattribs, final int niattribs, final int[] iresults) {
+ static int AttribList2DrawableTypeBits(final int[] iattribs,
+ final int niattribs, final int[] iresults) {
int val = 0;
for (int i = 0; i < niattribs; i++) {
int attr = iattribs[i];
switch (attr) {
case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ if(iresults[i] == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
+ }
break;
case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ if(iresults[i] == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
break;
case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ if(iresults[i] == GL.GL_TRUE) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ }
break;
}
}
- if ( GLContext.isFBOAvailable(device, glp) ) {
- val |= GLGraphicsConfigurationUtil.FBO_BIT;
- }
return val;
}
- static WGLGLCapabilities AttribList2GLCapabilities(final AbstractGraphicsDevice device,
- final GLProfile glp, final long hdc, final int pfdID,
- final int[] iattribs, final int niattribs, final int[] iresults, final int winattrmask) {
- final int allDrawableTypeBits = AttribList2DrawableTypeBits(device, glp, iattribs, niattribs, iresults);
+ static WGLGLCapabilities AttribList2GLCapabilities(final GLProfile glp,
+ final long hdc, final int pfdID, final int[] iattribs,
+ final int niattribs, final int[] iresults, final int winattrmask) {
+ final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
@@ -610,7 +629,7 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
// remove displayable bits, since pfdID is non displayable
- drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
+ drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT | GLGraphicsConfigurationUtil.FBO_BIT );
if( 0 == drawableTypeBits ) {
return null;
}
@@ -638,32 +657,30 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
return pfdIDs;
}
- static int PFD2DrawableTypeBits(AbstractGraphicsDevice device, GLProfile glp, PIXELFORMATDESCRIPTOR pfd) {
+ static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) {
int val = 0;
int dwFlags = pfd.getDwFlags();
if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) {
- val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
}
- if ( GLContext.isFBOAvailable(device, glp) ) {
- val |= GLGraphicsConfigurationUtil.FBO_BIT;
- }
return val;
}
- static WGLGLCapabilities PFD2GLCapabilities(AbstractGraphicsDevice device, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ static WGLGLCapabilities PFD2GLCapabilities(final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
if(null == pfd) {
return null;
}
if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
- return null;
+ return null;
}
- final int allDrawableTypeBits = PFD2DrawableTypeBits(device, glp, pfd);
+ final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
@@ -673,79 +690,105 @@ public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguratio
final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
res.setValuesByGDI();
return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, drawableTypeBits );
- }
-
- static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
- int colorDepth = (caps.getRedBits() +
- caps.getGreenBits() +
- caps.getBlueBits());
- if (colorDepth < 15) {
- throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
- }
- int pfdFlags = (GDI.PFD_SUPPORT_OPENGL |
- GDI.PFD_GENERIC_ACCELERATED);
- if (caps.getDoubleBuffered()) {
- pfdFlags |= GDI.PFD_DOUBLEBUFFER;
- }
- if (caps.isOnscreen()) {
- pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
- } else {
- pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
- }
- if (caps.getStereo()) {
- pfdFlags |= GDI.PFD_STEREO;
- }
- pfd.setDwFlags(pfdFlags);
- pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
- pfd.setCColorBits((byte) colorDepth);
- pfd.setCRedBits ((byte) caps.getRedBits());
- pfd.setCGreenBits((byte) caps.getGreenBits());
- pfd.setCBlueBits ((byte) caps.getBlueBits());
- pfd.setCAlphaBits((byte) caps.getAlphaBits());
- int accumDepth = (caps.getAccumRedBits() +
- caps.getAccumGreenBits() +
- caps.getAccumBlueBits());
- pfd.setCAccumBits ((byte) accumDepth);
- pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
- pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
- pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
- pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
- pfd.setCDepthBits((byte) caps.getDepthBits());
- pfd.setCStencilBits((byte) caps.getStencilBits());
- pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
-
- // n/a with non ARB/GDI method:
- // multisample
- // opaque
- // pbuffer
- return pfd;
- }
-
- static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
- PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
- pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
- pfd.setNVersion((short) 1);
- if(0 != hdc && 1 <= pfdID) {
- if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
- // Accelerated pixel formats that are non displayable
- if(DEBUG) {
- System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
- }
+ }
+
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(final GLProfile glp, final long hdc, final int pfdID) {
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
+ return PFD2GLCapabilitiesNoCheck(glp, pfd, pfdID);
+ }
+
+ static WGLGLCapabilities PFD2GLCapabilitiesNoCheck(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, int pfdID) {
+ if(null == pfd) {
return null;
}
- }
- return pfd;
- }
-
- static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
- return createPixelFormatDescriptor(0, 0);
- }
-
- public String toString() {
- return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
- ",\n\trequested " + getRequestedCapabilities() +
- ",\n\tchosen " + getChosenCapabilities() +
- "]";
- }
+ final WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByGDI();
+ return (WGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(res, PFD2DrawableTypeBits(pfd));
+ }
+
+ static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int pfdFlags = ( GDI.PFD_SUPPORT_OPENGL | GDI.PFD_GENERIC_ACCELERATED );
+
+ if( caps.isOnscreen() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_WINDOW;
+ } else if( caps.isFBO() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_WINDOW; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_BITMAP; // pbuffer n/a, use bitmap
+ } else if( caps.isBitmap() ) {
+ pfdFlags |= GDI.PFD_DRAW_TO_BITMAP;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+
+ if ( caps.getDoubleBuffered() ) {
+ if( caps.isBitmap() || caps.isPBuffer() ) {
+ pfdFlags |= GDI.PFD_DOUBLEBUFFER_DONTCARE; // bitmaps probably don't have dbl buffering
+ } else {
+ pfdFlags |= GDI.PFD_DOUBLEBUFFER;
+ }
+ }
+
+ if (caps.getStereo()) {
+ pfdFlags |= GDI.PFD_STEREO;
+ }
+ pfd.setDwFlags(pfdFlags);
+ pfd.setIPixelType((byte) GDI.PFD_TYPE_RGBA);
+ pfd.setCColorBits((byte) colorDepth);
+ pfd.setCRedBits ((byte) caps.getRedBits());
+ pfd.setCGreenBits((byte) caps.getGreenBits());
+ pfd.setCBlueBits ((byte) caps.getBlueBits());
+ pfd.setCAlphaBits((byte) caps.getAlphaBits());
+ int accumDepth = (caps.getAccumRedBits() +
+ caps.getAccumGreenBits() +
+ caps.getAccumBlueBits());
+ pfd.setCAccumBits ((byte) accumDepth);
+ pfd.setCAccumRedBits ((byte) caps.getAccumRedBits());
+ pfd.setCAccumGreenBits((byte) caps.getAccumGreenBits());
+ pfd.setCAccumBlueBits ((byte) caps.getAccumBlueBits());
+ pfd.setCAccumAlphaBits((byte) caps.getAccumAlphaBits());
+ pfd.setCDepthBits((byte) caps.getDepthBits());
+ pfd.setCStencilBits((byte) caps.getStencilBits());
+ pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
+
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
+ PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
+ pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
+ pfd.setNVersion((short) 1);
+ if(0 != hdc && 1 <= pfdID) {
+ if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
+ // Accelerated pixel formats that are non displayable
+ if(DEBUG) {
+ System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
+ }
+ return null;
+ }
+ }
+ return pfd;
+ }
+
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ return createPixelFormatDescriptor(0, 0);
+ }
+
+ public String toString() {
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
+ ",\n\trequested " + getRequestedCapabilities() +
+ ",\n\tchosen " + getChosenCapabilities() +
+ "]";
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 66a5821d3..41c9bba02 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -85,7 +85,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
}
- return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, chooser, absScreen);
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen);
}
static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps,
@@ -95,7 +99,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
- CapabilitiesChooser chooser,
+ GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen) {
if(null==absScreen) {
absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
@@ -151,8 +155,9 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
static List getAvailableGLCapabilitiesARB(WindowsWGLDrawableFactory.SharedResource sharedResource, AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
- int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
- return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedResource, device, glProfile, hdc, pformats);
+ final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
+ final int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
+ return WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedResource, device, glProfile, hdc, pformats, GLGraphicsConfigurationUtil.ALL_BITS);
}
static List getAvailableGLCapabilitiesGDI(AbstractGraphicsDevice device, GLProfile glProfile, long hdc) {
@@ -160,7 +165,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
int numFormats = pformats.length;
List bucket = new ArrayList(numFormats);
for (int i = 0; i < numFormats; i++) {
- final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(device, glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], GLGraphicsConfigurationUtil.ALL_BITS);
if(null != caps) {
bucket.add(caps);
}
@@ -310,10 +315,20 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
final int winattrbits = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
final GLProfile glProfile = capsChosen.getGLProfile();
+ final int pfdIDCount = WindowsWGLGraphicsConfiguration.wglARBPFDIDCount((WindowsWGLContext)sharedResource.getContext(), hdc);
+
if(DEBUG) {
- System.err.println("translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+" -> translucency "+(!isOpaque));
+ System.err.println("updateGraphicsConfigurationARB: hdc "+toHexString(hdc)+", pfdIDCount(hdc) "+pfdIDCount+", capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ System.err.println("isOpaque "+isOpaque+" (translucency requested: "+(!capsChosen.isBackgroundOpaque())+", compositioning enabled: "+GDI.DwmIsCompositionEnabled()+")");
}
+ if(0 >= pfdIDCount) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: failed due to 0 pfdIDs for hdc "+toHexString(hdc)+" - hdc incompatible w/ ARB ext.");
+ }
+ return false;
+ }
+
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ;
@@ -358,7 +373,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
}
// 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
- pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs((WindowsWGLContext)sharedResource.getContext(), hdc);
+ pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFDIDs(pfdIDCount);
if (DEBUG) {
final int len = ( null != pformats ) ? pformats.length : 0;
System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + len);
@@ -378,8 +393,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if( null == availableCaps || 0 == availableCaps.size() ) {
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
- " pfd ids, " + GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
+ System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length + " pfd ids");
Thread.dumpStack();
}
return false;
@@ -436,7 +450,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
final GLProfile glProfile = capsChosen.getGLProfile();
final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
- List availableCaps = new ArrayList();
+ if(DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: capsChosen "+capsChosen+", "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString());
+ }
+
int pfdID; // chosen or preset PFD ID
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
@@ -451,17 +468,29 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
+ ", pixelformat " + pfdID);
}
pixelFormatSet = true;
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(config.getScreen().getDevice(), glProfile, hdc, pfdID, winattrmask);
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, winattrmask);
+ if(null == pixelFormatCaps) {
+ throw new GLException("Could not map PFD2GLCaps w/ already chosen pfdID "+pfdID);
+ }
} else {
- if(null == pformats) {
+ final boolean givenPFormats = null != pformats;
+ if( !givenPFormats ) {
pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
}
+ List availableCaps = new ArrayList();
for (int i = 0; i < pformats.length; i++) {
- final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(config.getScreen().getDevice(), glProfile, hdc, pformats[i], winattrmask);
+ final GLCapabilitiesImmutable caps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], winattrmask);
if(null != caps) {
availableCaps.add(caps);
- }
+ if(DEBUG) {
+ final int j = availableCaps.size() - 1;
+ System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> "+j+"]: "+caps);
+ }
+ } else if(DEBUG) {
+ GLCapabilitiesImmutable skipped = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(glProfile, hdc, pformats[i]);
+ System.err.println("updateGraphicsConfigurationGDI: availableCaps["+i+" -> skip]: pfdID "+pformats[i]+", "+skipped);
+ }
}
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
@@ -470,16 +499,21 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
pfdID = WGLUtil.ChoosePixelFormat(hdc, pfd);
int recommendedIndex = -1 ;
if( 1 <= pfdID ) {
- // seek index ..
+ // seek index .. in all formats _or_ in given formats!
for (recommendedIndex = availableCaps.size() - 1 ;
0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID();
recommendedIndex--)
{ /* nop */ }
+ if(DEBUG && 0 > recommendedIndex) {
+ final GLCapabilitiesImmutable reqPFDCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilitiesNoCheck(glProfile, pfd, pfdID);
+ final GLCapabilitiesImmutable chosenCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, winattrmask);
+ System.err.println("Chosen PFDID "+pfdID+", but not found in available caps (use given pfdIDs "+givenPFormats+", reqPFDCaps "+reqPFDCaps+", chosenCaps: "+chosenCaps);
+ }
}
- // 2nd choice: if no preferred recommendedIndex available
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
+ System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = pfdID " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
}
+ // 2nd choice: if no preferred recommendedIndex available
int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
if ( 0 > chosenIndex ) {
if (DEBUG) {
@@ -490,8 +524,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
if (DEBUG) {
- System.err.println("chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) +
- ", caps " + pixelFormatCaps);
+ System.err.println("chosen pfdID (GDI): chosenIndex "+ chosenIndex + ", caps " + pixelFormatCaps);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index d169945fe..866fcbbe4 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -41,7 +41,6 @@ import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -67,28 +66,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
this.chooser=chooser;
}
- static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
- final X11GraphicsDevice device = (X11GraphicsDevice) x11Screen.getDevice();
- final long display = device.getHandle();
- if(0==display) {
- throw new GLException("Display null of "+x11Screen);
- }
- final int screen = x11Screen.getIndex();
- final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
- if(0==fbcfg) {
- throw new GLException("FBConfig null of "+toHexString(fbcfgID));
- }
- if(null==glp) {
- glp = GLProfile.getDefault(x11Screen.getDevice());
- }
- final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(device));
- if(null==caps) {
- throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
- }
- return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
- }
-
public Object clone() {
return super.clone();
}
@@ -123,11 +100,31 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
+ static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
+ final X11GraphicsDevice device = (X11GraphicsDevice) x11Screen.getDevice();
+ final long display = device.getHandle();
+ if(0==display) {
+ throw new GLException("Display null of "+x11Screen);
+ }
+ final int screen = x11Screen.getIndex();
+ final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+ if(0==fbcfg) {
+ throw new GLException("FBConfig null of "+toHexString(fbcfgID));
+ }
+ if(null==glp) {
+ glp = GLProfile.getDefault(x11Screen.getDevice());
+ }
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(device, glp, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, factory.isGLXMultisampleAvailable(device));
+ if(null==caps) {
+ throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
+ }
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
+ }
+
static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
- boolean forFBAttr,
- boolean isMultisampleAvailable,
- long display,
- int screen)
+ boolean forFBAttr, boolean isMultisampleAvailable,
+ long display, int screen)
{
int colorDepth = (caps.getRedBits() +
caps.getGreenBits() +
@@ -140,10 +137,21 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if (forFBAttr) {
res[idx++] = GLX.GLX_DRAWABLE_TYPE;
- res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ;
- }
-
- if (forFBAttr) {
+
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = GLX.GLX_WINDOW_BIT;
+ } else if( caps.isFBO() ) {
+ surfaceType = GLX.GLX_WINDOW_BIT; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ surfaceType = GLX.GLX_PBUFFER_BIT;
+ } else if( caps.isBitmap() ) {
+ surfaceType = GLX.GLX_PIXMAP_BIT;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ res[idx++] = surfaceType;
+
res[idx++] = GLX.GLX_RENDER_TYPE;
res[idx++] = GLX.GLX_RGBA_BIT;
} else {
@@ -244,14 +252,15 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return true;
}
- static int FBCfgDrawableTypeBits(final X11GraphicsDevice device, GLProfile glp, final long fbcfg) {
+ static int FBCfgDrawableTypeBits(final X11GraphicsDevice device, final long fbcfg) {
int val = 0;
int[] tmp = new int[1];
int fbtype = glXGetFBConfig(device.getHandle(), fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
- val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
@@ -259,9 +268,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
}
- if ( GLContext.isFBOAvailable(device, glp) ) {
- val |= GLGraphicsConfigurationUtil.FBO_BIT;
- }
return val;
}
@@ -275,7 +281,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
static X11GLCapabilities GLXFBConfig2GLCapabilities(X11GraphicsDevice device, GLProfile glp, long fbcfg,
int winattrmask, boolean isMultisampleAvailable) {
- final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, glp, fbcfg);
+ final int allDrawableTypeBits = FBCfgDrawableTypeBits(device, fbcfg);
int drawableTypeBits = winattrmask & allDrawableTypeBits;
final long display = device.getHandle();
@@ -286,7 +292,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid));
}
// onscreen must have an XVisualInfo
- drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT;
+ drawableTypeBits &= ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.FBO_BIT);
}
if( 0 == drawableTypeBits ) {
@@ -394,10 +400,9 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
static X11GLCapabilities XVisualInfo2GLCapabilities(final X11GraphicsDevice device, GLProfile glp, XVisualInfo info,
final int winattrmask, boolean isMultisampleEnabled) {
final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT |
- GLGraphicsConfigurationUtil.BITMAP_BIT |
- ( GLContext.isFBOAvailable(device, glp) ? GLGraphicsConfigurationUtil.FBO_BIT : 0 )
- ;
-
+ GLGraphicsConfigurationUtil.BITMAP_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT ;
+
final int drawableTypeBits = winattrmask & allDrawableTypeBits;
if( 0 == drawableTypeBits ) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 3189f933f..8086cd26a 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -210,7 +210,6 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
if (x11Screen == null) {
throw new IllegalArgumentException("AbstractGraphicsScreen is null");
}
-
if (capsChosen == null) {
capsChosen = new GLCapabilities(null);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
index 50e6ed46c..5795e8cfe 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/Capabilities.java
@@ -74,7 +74,7 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
public Object cloneMutable() {
return clone();
}
-
+
@Override
public Object clone() {
try {
@@ -84,6 +84,26 @@ public class Capabilities implements CapabilitiesImmutable, Cloneable {
}
}
+ /**
+ * Copies all {@link Capabilities} values
+ * from source
into this instance.
+ * @return this instance
+ */
+ public Capabilities copyFrom(CapabilitiesImmutable other) {
+ redBits = other.getRedBits();
+ greenBits = other.getGreenBits();
+ blueBits = other.getBlueBits();
+ alphaBits = other.getAlphaBits();
+ backgroundOpaque = other.isBackgroundOpaque();
+ onscreen = other.isOnscreen();
+ isBitmap = other.isBitmap();
+ transparentValueRed = other.getTransparentRedValue();
+ transparentValueGreen = other.getTransparentGreenValue();
+ transparentValueBlue = other.getTransparentBlueValue();
+ transparentValueAlpha = other.getTransparentAlphaValue();
+ return this;
+ }
+
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
index 0782e8915..cd1107e25 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
@@ -39,6 +39,8 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
import org.junit.Assert;
import org.junit.Test;
@@ -61,9 +63,19 @@ public class TestGLCapabilities01NEWT extends UITestCase {
return true;
}
- void doTest(GLCapabilities reqGLCaps, GLEventListener demo) throws InterruptedException {
+ void doTest(GLCapabilitiesImmutable reqGLCaps, GLEventListener demo) throws InterruptedException {
System.out.println("Requested GL Caps: "+reqGLCaps);
-
+
+ final GLCapabilitiesImmutable expGLCaps;
+ if( GLGraphicsConfigurationUtil.isGLCapabilitiesOffscreenAutoSelection(reqGLCaps) ) {
+ final GLDrawableFactory f = GLDrawableFactory.getFactory(reqGLCaps.getGLProfile());
+ final boolean fboAvailable = true ; // f.canCreateFBO(null, reqGLCaps.getGLProfile());
+ final boolean pbufferAvailable = f.canCreateGLPbuffer(null);
+ expGLCaps = GLGraphicsConfigurationUtil.fixGLCapabilities(reqGLCaps, fboAvailable, pbufferAvailable);
+ } else {
+ expGLCaps = reqGLCaps;
+ }
+ System.out.println("Expected GL Caps: "+expGLCaps);
//
// Create native windowing resources .. X11/Win/OSX
//
@@ -108,13 +120,13 @@ public class TestGLCapabilities01NEWT extends UITestCase {
Assert.assertTrue(chosenGLCaps.getBlueBits()>5);
Assert.assertTrue(chosenGLCaps.getRedBits()>5);
Assert.assertTrue(chosenGLCaps.getDepthBits()>4);
- Assert.assertEquals(reqGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
- Assert.assertEquals(reqGLCaps.isFBO(), chosenGLCaps.isFBO());
- Assert.assertEquals(reqGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
- Assert.assertEquals(reqGLCaps.isBitmap(), chosenGLCaps.isBitmap());
+ Assert.assertEquals(expGLCaps.isOnscreen(), chosenGLCaps.isOnscreen());
+ Assert.assertEquals(expGLCaps.isFBO(), chosenGLCaps.isFBO());
+ Assert.assertEquals(expGLCaps.isPBuffer(), chosenGLCaps.isPBuffer());
+ Assert.assertEquals(expGLCaps.isBitmap(), chosenGLCaps.isBitmap());
if(chosenGLCaps.isOnscreen() || chosenGLCaps.isFBO()) {
// dbl buffer may be disabled w/ offscreen pbuffer and bitmap
- Assert.assertEquals(reqGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
+ Assert.assertEquals(expGLCaps.getDoubleBuffered(), chosenGLCaps.getDoubleBuffered());
}
GLContext context = drawable.createContext(null);
@@ -142,33 +154,33 @@ public class TestGLCapabilities01NEWT extends UITestCase {
}
}
- //@Test
- public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
+ @Test
+ public void testGL2OnScreenDblBuf() throws InterruptedException {
if(!checkProfile(GLProfile.GL2)) {
return;
}
final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
- reqGLCaps.setOnscreen(false);
doTest(reqGLCaps, new GearsES2(1));
}
-
- // @Test
- public void testGL2OffScreenFBODblBuf() throws InterruptedException {
+
+ @Test
+ public void testGL2OffScreenAutoDblBuf() throws InterruptedException {
if(!checkProfile(GLProfile.GL2)) {
return;
}
final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
reqGLCaps.setOnscreen(false);
- reqGLCaps.setFBO(true);
doTest(reqGLCaps, new GearsES2(1));
}
-
+
@Test
- public void testGL2OnScreenDblBuf() throws InterruptedException {
+ public void testGL2OffScreenFBODblBuf() throws InterruptedException {
if(!checkProfile(GLProfile.GL2)) {
return;
}
final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
doTest(reqGLCaps, new GearsES2(1));
}
@@ -203,6 +215,27 @@ public class TestGLCapabilities01NEWT extends UITestCase {
doTest(reqGLCaps, new GearsES2(1));
}
+ @Test
+ public void testES2OffScreenAutoDblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
+ @Test
+ public void testES2OffScreenFBODblBuf() throws InterruptedException {
+ if(!checkProfile(GLProfile.GLES2)) {
+ return;
+ }
+ final GLCapabilities reqGLCaps = new GLCapabilities(GLProfile.get(GLProfile.GLES2));
+ reqGLCaps.setOnscreen(false);
+ reqGLCaps.setFBO(true);
+ doTest(reqGLCaps, new GearsES2(1));
+ }
+
@Test
public void testES2OffScreenPbufferDblBuf() throws InterruptedException {
if(!checkProfile(GLProfile.GLES2)) {
--
cgit v1.2.3
From 4dd44b985fe0541be3a3bcd9045d201ed3ca2cc5 Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Sat, 15 Sep 2012 16:54:52 +0200
Subject: Seamless Integration of an FBObject based GLFBODrawable as
GLOffscreenAutoDrawable.FBO and as an OffscreenLayerSurface's drawable (OSX)
- Fix Bugs 569 and 599
Summary:
=========
The new FBObject based GLFBODrawable implementation allows the seamless utilization of
FBO offscreen rendering in single buffer, double buffer and MSAA mode.
The GLFBODrawable uses a parent drawable based on a
dummy surface to allow a GLOffscreenAutoDrawable.FBO creation
or a mutable surface supporting an existing offscreen layer surface (OSX CALayer).
Offscreen GLDrawable's and GLOffscreenAutoDrawable's can be selected via the
GLCapabilities. If simply !onscreen is selected in the caps instance w/o enabling FBO, PBuffer or Bitmap,
the factory will automatically choose regarding availability:
FBO > PBuffer > Bitmap
Double buffering is supported in MSAA more (intrinsic) and explicit in non MSAA.
It is preferred when delivering resources (texture id's or framebuffer names)
to a shared GLContext.
This is demonstrated in (emulates our OSX CALayer implementation):
TestFBOOffThreadSharedContextMix2DemosES2NEWT,
TestFBOOnThreadSharedContext1DemoES2NEWT
and with the OSX JAWT OffscreenLayerSurface itself. FBO is the preferred choice.
+++
Offscreen drawables can be resized while maintaining a bound GLContext (e.g. w/ GLAutoDrawable).
Previously both, drawable and context, needed to be destroyed and recreated at offscreen resize.
Common implementation in GLDrawableHelper is used in the implementations
(NEWT's GLWindow, AWT GLCanvas, SWT GLCanvas).
+++
Tested:
=======
Manually run all unit tests on:
- Linux x86_64 NVidia/AMD/Mesa3d(ES)
- OSX x86_64 NVidia
- Windows x86_64 NVidia
- Android arm Mali-400/Tegra-2
No regressions.
Disclaimer:
===========
This feature is committed almost in one patch.
Both previous commits were introducing / fixing the capabilities behavior:
90d45928186f2be99999461cfe45f76a783cc961
9036376b7806a5fc61590bf49404eb71830de92f
I have to appologize for the huge size and impact (files and platforms) of this commit
however, I could not find a better way to inject this feature in one sane piece.
NativeWindow Details:
=====================
Complete decoupling of platform impl. detail of surfaces
implementing ProxySurface. Used to generalize dummy surfaces and EGL surfaces
on top of a native platform surface.
- ProxySurface.UpstreamSurfaceHook -> UpstreamSurfaceHook
- abstract class ProxySurface -> interface ProxySurface + ProxySurfaceImpl
- Misc. implementations
JOGL Details:
=====================
FBOObject: API Change / Simplification & Usability
- Removed reference counter to remove complexity, allow user to choose.
- Add 'dispose' flag for detachColorbuffer(..), allowing to keep attachment alive
- Fix equals operation of Attachment
- Check pre-exising GL errors
- Interface Colobuffer gets lifecycle methods
- Add static factory methods to create Attachments w/o FBObject instance
- Reset:
- Clip min size to 1
- Keep alive samplingSink, i.e. don't issue resetMSAATexture2DSink(..).
It gets called at syncFramebuffer()/use(..) later on before actual usage.
This allows the consumer to utilize the GL_FRONT buffer until (e.g.) swap.
- misc bugfixes
GLOffscreenAutoDrawable: API Change
- Reloc and interfacing
- class com.jogamp.opengl.OffscreenAutoDrawable -> javax.media.opengl.*
interfaces GLOffscreenAutoDrawable extends GLAutoDrawable
GLOffscreenAutoDrawable.FBO extends GLOffscreenAutoDrawable, GLFBODrawable
- Added general implementation and FBO specialization
- Replacing GLPBuffer (deprecated) .. usable for any offscreen GLDrawable via factory
GLAutoDrawable:
- Add 'GLDrawable getDelegatedDrawable()'
- Refine documentation of setContext(..), remove disclaimer and fixme tags
GLDrawableFactory:
- Refine API doc and it's selection mechanism for offscreen.
- Add createOffscreenDrawable(..)
- Add createOffscreenAutoDrawable(..)
- Add canCreateFBO(..)
- Mark createGLPbuffer(..) deprectated
Mark GLPBuffer deprecated
New: GLFBODrawable extends GLDrawable
GLCanvas (AWT and SWT): Add offscreen resize support w/o GLContext recreation
GLAutoDrawableBase .. GLWindow:
- Add offscreen resize support w/o GLContext recreation
- Remove double swapBuffer call
-
GLBase/GLContext:
- Add:
- boolean hasBasicFBOSupport()
- boolean hasFullFBOSupport()
- int getMaxRenderbufferSamples()
- boolean isTextureFormatBGRA8888Available()
GLContext: Fix version detection and hasGLSL()
- Version detection in setGLFunctionAvailability(..)
- Query GL_VERSION ASAP and parse it and compare w/ given major/minor
- Use parsed version if valid and lower than given _or_ given is invalid.
- Use validated version for caching (procaddr, ..), version number, etc.
- Fix hasGLSL()
Since 'isGL2ES2()' is true if 'isGL2()'
and the latter simply alows GL 1.*, we confine the result to a GL >= 2.0
on desktops. FIXME: May consider GL 1.5 w/ extensions.
- return isGL2ES2();
+ return isGLES2() ||
+ isGL3() ||
+ isGL2() && ctxMajorVersion>1 ;
GLDrawableImpl:
- Add 'associateContext(GLContext, boolean)' allowing impl.
to have a (weak) reference list of bound context.
This is was pulled up from the OSX specific drawable impl.
- swapBuffersImpl() -> swapBuffersImpl(boolean doubleBuffered)
and call it regardless of single buffering.
This is required to propagate this event to impl. properly,
i.e. FBODrawable requires a swap notification.
- Clarify 'contextMadeCurrent(..)' protocol
GLDrawableHelper:
- Add resize and recreate offscreen drawable util method
- Simplify required init/reshape calls for GLEventListener
-
GLGraphicsConfigurationUtil:
- fixWinAttribBitsAndHwAccel: Reflect sharede context hw-accel bits
- OSX has no offscreen bitmap, use pbuffer
- use proper offscreen auto selection if offscreen and no modes are set
EGL Context/Drawable/DrawableFactory: Abstract native platform code out of base classes
- Use EGLWrappedSurface w/ UpstreamSurfaceHook to handle upstream (X11, WGL, ..)
lifecycle - in case the EGL resource is hooked up on it.
Invisible dummy surfaces: All platforms
- size is now reduced to 64x64 and decoupled of actual generic mutable size
- fix device lifecycle, no more leaks
+++
OSX
====
Enable support for GLFBODrawableImpl in offscreen CALayer mode
- NSOpenGLImpl: hooks to calayer native code
- calayer code:
- allows pbuffer and texures (FBO)
- decouple size and draw calls avoiding flickering
- enable auto resize of calayer tree
MacOSXCGLContext:
- NSOpenGLImpl:
- Fix false pbuffer 'usage', validate the pointer
- If !pbuffer, copy other window mode bits of caps
-
MacOSXCGLGraphicsConfiguration:
- Only assume pbuffer if !onscreen
- Remove reference of native pixelformat pointer
Native code:
- use 'respondsToSelector:' query before calling 'new' methods
avoiding an error message where unsuported (prev. OSX versions)
- if monitor refresh-rate is queried 0, set to default 60hz
- add missing NSAutoreleasePool decoration
+++
Android / NEWT:
===============
Issue setVisible(..) w/o wait, i.e. queue on EDT,
@Android surfaceChanged() callback. Otherwise we could deadlock:
setVisible(..) -> EDT -> setVisibleImpl(..) -> 'GL-display'.
the latter may may cause havoc while Android-EDT is blocked [until it's return].
---
doc/TODO.txt | 12 -
make/build-jogl.xml | 2 +-
.../config/jogl/gl-impl-CustomJavaCode-common.java | 20 +
make/scripts/java-win64-dbg.bat | 4 +-
make/scripts/tests-x64.bat | 45 +-
make/scripts/tests.sh | 50 +-
make/stub_includes/opengl/macosx-window-system.h | 11 +-
src/jogl/classes/com/jogamp/opengl/FBObject.java | 882 +++++++++++++--------
.../com/jogamp/opengl/GLAutoDrawableDelegate.java | 189 +++++
.../classes/com/jogamp/opengl/GLExtensions.java | 3 +
.../com/jogamp/opengl/OffscreenAutoDrawable.java | 112 ---
.../classes/com/jogamp/opengl/swt/GLCanvas.java | 41 +-
.../classes/javax/media/opengl/GLAutoDrawable.java | 38 +-
.../javax/media/opengl/GLAutoDrawableDelegate.java | 144 ----
src/jogl/classes/javax/media/opengl/GLBase.java | 38 +
src/jogl/classes/javax/media/opengl/GLContext.java | 97 ++-
.../javax/media/opengl/GLDrawableFactory.java | 128 ++-
.../classes/javax/media/opengl/GLFBODrawable.java | 173 ++++
.../media/opengl/GLOffscreenAutoDrawable.java | 63 ++
src/jogl/classes/javax/media/opengl/GLPbuffer.java | 6 +-
.../classes/javax/media/opengl/awt/GLCanvas.java | 119 +--
.../classes/javax/media/opengl/awt/GLJPanel.java | 13 +-
.../classes/jogamp/opengl/GLAutoDrawableBase.java | 76 +-
src/jogl/classes/jogamp/opengl/GLContextImpl.java | 175 ++--
.../jogamp/opengl/GLDrawableFactoryImpl.java | 127 +--
.../classes/jogamp/opengl/GLDrawableHelper.java | 185 ++++-
src/jogl/classes/jogamp/opengl/GLDrawableImpl.java | 80 +-
.../classes/jogamp/opengl/GLFBODrawableImpl.java | 496 ++++++++++--
.../jogamp/opengl/GLGraphicsConfigurationUtil.java | 28 +-
.../jogamp/opengl/GLOffscreenAutoDrawableImpl.java | 123 +++
src/jogl/classes/jogamp/opengl/GLPbufferImpl.java | 31 +-
src/jogl/classes/jogamp/opengl/egl/EGLContext.java | 6 -
.../classes/jogamp/opengl/egl/EGLDrawable.java | 135 ++--
.../jogamp/opengl/egl/EGLDrawableFactory.java | 163 +---
.../opengl/egl/EGLDummyUpstreamSurfaceHook.java | 49 ++
.../jogamp/opengl/egl/EGLExternalContext.java | 11 -
.../jogamp/opengl/egl/EGLGLCapabilities.java | 5 +-
.../opengl/egl/EGLGraphicsConfiguration.java | 9 +-
.../jogamp/opengl/egl/EGLOnscreenContext.java | 11 -
.../jogamp/opengl/egl/EGLOnscreenDrawable.java | 4 +-
.../jogamp/opengl/egl/EGLPbufferContext.java | 10 -
.../jogamp/opengl/egl/EGLPbufferDrawable.java | 8 +-
.../jogamp/opengl/egl/EGLUpstreamSurfaceHook.java | 145 +++-
.../jogamp/opengl/egl/EGLWrappedSurface.java | 26 +
.../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 716 ++++++++++-------
.../opengl/macosx/cgl/MacOSXCGLDrawable.java | 48 +-
.../macosx/cgl/MacOSXCGLDrawableFactory.java | 71 +-
.../macosx/cgl/MacOSXCGLGraphicsConfiguration.java | 21 +-
.../cgl/MacOSXCGLGraphicsConfigurationFactory.java | 2 +-
.../macosx/cgl/MacOSXExternalCGLContext.java | 7 +-
.../macosx/cgl/MacOSXOnscreenCGLDrawable.java | 4 +-
.../opengl/macosx/cgl/MacOSXPbufferCGLContext.java | 1 +
.../macosx/cgl/MacOSXPbufferCGLDrawable.java | 42 +-
.../windows/wgl/WindowsExternalWGLContext.java | 4 +-
.../windows/wgl/WindowsExternalWGLDrawable.java | 4 +-
.../opengl/windows/wgl/WindowsWGLDrawable.java | 43 +-
.../windows/wgl/WindowsWGLDrawableFactory.java | 58 +-
.../wgl/WindowsWGLGraphicsConfiguration.java | 29 +-
.../WindowsWGLGraphicsConfigurationFactory.java | 28 +-
.../opengl/x11/glx/X11ExternalGLXContext.java | 4 +-
.../opengl/x11/glx/X11ExternalGLXDrawable.java | 5 +-
.../jogamp/opengl/x11/glx/X11GLXDrawable.java | 7 +-
.../opengl/x11/glx/X11GLXDrawableFactory.java | 63 +-
.../x11/glx/X11GLXGraphicsConfiguration.java | 6 +-
.../glx/X11GLXGraphicsConfigurationFactory.java | 6 +-
.../opengl/x11/glx/X11PbufferGLXDrawable.java | 17 +-
.../macosx/MacOSXWindowSystemInterface-calayer.m | 665 ++++++++++++++++
.../macosx/MacOSXWindowSystemInterface-pbuffer.m | 494 ------------
.../native/macosx/MacOSXWindowSystemInterface.m | 40 +-
.../DelegatedUpstreamSurfaceHookMutableSize.java | 39 +
...elegatedUpstreamSurfaceHookWithSurfaceSize.java | 54 ++
.../UpstreamSurfaceHookMutableSize.java | 45 ++
.../com/jogamp/nativewindow/WrappedSurface.java | 78 --
.../com/jogamp/nativewindow/awt/JAWTWindow.java | 99 ++-
.../jogamp/nativewindow/egl/EGLGraphicsDevice.java | 4 +-
.../javax/media/nativewindow/NativeSurface.java | 5 +-
.../media/nativewindow/OffscreenLayerSurface.java | 3 +
.../javax/media/nativewindow/ProxySurface.java | 266 ++-----
.../media/nativewindow/UpstreamSurfaceHook.java | 52 ++
.../jogamp/nativewindow/ProxySurfaceImpl.java | 326 ++++++++
.../jogamp/nativewindow/WrappedSurface.java | 95 +++
.../nativewindow/jawt/macosx/MacOSXJAWTWindow.java | 84 +-
.../macosx/OSXDummyUpstreamSurfaceHook.java | 56 ++
.../jogamp/nativewindow/macosx/OSXUtil.java | 15 +
.../windows/GDIDummyUpstreamSurfaceHook.java | 50 ++
.../jogamp/nativewindow/windows/GDISurface.java | 34 +-
.../x11/X11DummyUpstreamSurfaceHook.java | 60 ++
src/nativewindow/native/macosx/OSXmisc.m | 189 +++--
.../classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 9 +
.../classes/com/jogamp/newt/opengl/GLWindow.java | 25 +-
.../classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 3 +
src/newt/classes/jogamp/newt/OffscreenWindow.java | 31 +-
src/newt/classes/jogamp/newt/WindowImpl.java | 34 +-
.../jogamp/newt/driver/android/WindowDriver.java | 2 +-
.../jogamp/newt/driver/macosx/WindowDriver.java | 24 +-
src/newt/native/MacWindow.m | 49 +-
.../test/android/MovieCubeActivityLauncher0.java | 2 +
.../android/NEWTGraphUI1pActivityLauncher.java | 22 +-
.../jogl/acore/TestFBOAutoDrawableDeadlockAWT.java | 128 +++
.../jogl/acore/TestFBOAutoDrawableFactoryNEWT.java | 375 +++++++++
.../test/junit/jogl/acore/TestFBODrawableNEWT.java | 272 -------
.../test/junit/jogl/acore/TestFBOMRTNEWT01.java | 2 +-
.../junit/jogl/acore/TestFBOMix2DemosES2NEWT.java | 2 +-
...tFBOOffThreadSharedContextMix2DemosES2NEWT.java | 298 +++++++
.../TestFBOOnThreadSharedContext1DemoES2NEWT.java | 273 +++++++
.../jogl/acore/TestGLAutoDrawableDelegateNEWT.java | 152 ----
...estGLAutoDrawableDelegateOnOffscrnCapsNEWT.java | 384 +++++++++
.../TestGLAutoDrawableFactoryOffscrnCapsNEWT.java | 317 ++++++++
...TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java | 328 ++++++++
...estGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java | 351 ++++++++
...LAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java | 300 +++++++
.../junit/jogl/acore/TestGLCapabilities01NEWT.java | 266 -------
.../acore/TestGLContextDrawableSwitchNEWT.java | 22 +-
.../junit/jogl/acore/TestGLDrawable01NEWT.java | 171 ----
.../jogl/acore/TestGLExtensionQueryOffscreen.java | 19 +-
.../jogl/acore/TestNEWTCloseX11DisplayBug565.java | 46 +-
.../acore/TestOffscreenLayer01GLCanvasAWT.java | 236 ++++++
.../acore/TestOffscreenLayer02NewtCanvasAWT.java | 233 ++++++
.../junit/jogl/acore/TestPBufferDeadlockAWT.java | 2 +
.../junit/jogl/acore/TestSharedContextListAWT.java | 20 +-
.../jogl/acore/TestSharedContextListNEWT.java | 20 +-
.../jogl/acore/TestSharedContextListNEWT2.java | 14 +-
.../jogl/acore/TestSharedContextNewtAWTBug523.java | 17 +-
.../jogl/acore/TestSharedContextVBOES1NEWT.java | 20 +-
.../jogl/acore/TestSharedContextVBOES2NEWT.java | 20 +-
.../jogl/acore/TestSharedContextVBOES2NEWT2.java | 14 +-
.../awt/TestBug461FBOSupersamplingSwingAWT.java | 159 ++++
.../TestBug461OffscreenSupersamplingSwingAWT.java | 157 ----
.../TestBug461PBufferSupersamplingSwingAWT.java | 159 ++++
.../junit/jogl/caps/TestMultisampleES1AWT.java | 2 +-
.../junit/jogl/caps/TestMultisampleES1NEWT.java | 2 +-
.../junit/jogl/caps/TestMultisampleES2NEWT.java | 2 +-
.../opengl/test/junit/jogl/demos/es1/GearsES1.java | 6 +
.../test/junit/jogl/demos/es1/RedSquareES1.java | 19 +-
.../test/junit/jogl/demos/es2/FBOMix2DemosES2.java | 5 +-
.../opengl/test/junit/jogl/demos/es2/GearsES2.java | 17 +-
.../test/junit/jogl/demos/es2/Mix2TexturesES2.java | 216 +++++
.../test/junit/jogl/demos/es2/RedSquareES2.java | 21 +-
.../junit/jogl/demos/es2/awt/TestGearsES2AWT.java | 27 +-
.../opengl/test/junit/jogl/demos/gl2/Gears.java | 13 +-
.../jogl/demos/gl2/awt/TestGLJPanelAWTBug450.java | 2 +-
.../test/junit/jogl/offscreen/ReadBufferBase.java | 2 +-
.../test/junit/jogl/swt/TestNewtCanvasSWTGLn.java | 2 +-
.../junit/jogl/swt/TestSWTJOGLGLCanvas01GLn.java | 2 +-
.../TestGLReadBufferUtilTextureIOWrite01AWT.java | 4 +-
.../TestGLReadBufferUtilTextureIOWrite01NEWT.java | 16 +-
.../TestGLReadBufferUtilTextureIOWrite02AWT.java | 2 +-
.../TestGLReadBufferUtilTextureIOWrite02NEWT.java | 2 +-
.../util/texture/TestPNGTextureFromFileAWT.java | 2 +-
.../util/texture/TestPNGTextureFromFileNEWT.java | 2 +-
.../test/junit/newt/TestFocus01SwingAWTRobot.java | 21 +-
.../test/junit/newt/TestFocus02SwingAWTRobot.java | 16 +-
.../opengl/test/junit/newt/TestWindows01NEWT.java | 1 -
.../parenting/NewtAWTReparentingKeyAdapter.java | 2 +-
.../TestParentingOffscreenLayer01GLCanvasAWT.java | 211 -----
...TestParentingOffscreenLayer02NewtCanvasAWT.java | 221 ------
.../opengl/test/junit/util/AWTRobotUtil.java | 39 +-
.../opengl/test/junit/util/NEWTGLContext.java | 4 +-
.../jogamp/opengl/test/junit/util/UITestCase.java | 109 ++-
159 files changed, 9357 insertions(+), 4643 deletions(-)
create mode 100644 src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
delete mode 100644 src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
delete mode 100644 src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
create mode 100644 src/jogl/classes/javax/media/opengl/GLFBODrawable.java
create mode 100644 src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
create mode 100644 src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
create mode 100644 src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
create mode 100644 src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
create mode 100644 src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
delete mode 100644 src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookMutableSize.java
create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/DelegatedUpstreamSurfaceHookWithSurfaceSize.java
create mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/UpstreamSurfaceHookMutableSize.java
delete mode 100644 src/nativewindow/classes/com/jogamp/nativewindow/WrappedSurface.java
create mode 100644 src/nativewindow/classes/javax/media/nativewindow/UpstreamSurfaceHook.java
create mode 100644 src/nativewindow/classes/jogamp/nativewindow/ProxySurfaceImpl.java
create mode 100644 src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
create mode 100644 src/nativewindow/classes/jogamp/nativewindow/macosx/OSXDummyUpstreamSurfaceHook.java
create mode 100644 src/nativewindow/classes/jogamp/nativewindow/windows/GDIDummyUpstreamSurfaceHook.java
create mode 100644 src/nativewindow/classes/jogamp/nativewindow/x11/X11DummyUpstreamSurfaceHook.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableDeadlockAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBODrawableNEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOffThreadSharedContextMix2DemosES2NEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOOnThreadSharedContext1DemoES2NEWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableFactoryOffscrnCapsNEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLCapabilities01NEWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDrawable01NEWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer01GLCanvasAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/acore/TestOffscreenLayer02NewtCanvasAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461FBOSupersamplingSwingAWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461PBufferSupersamplingSwingAWT.java
create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/Mix2TexturesES2.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
delete mode 100644 src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
(limited to 'src/jogl/classes/javax/media')
diff --git a/doc/TODO.txt b/doc/TODO.txt
index 20a7a9071..0ce1fd3ac 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -1,13 +1,6 @@
Version 2.0:
-- Fix ES2 detection if it fails (no egl pbuffer on nokia es2) ?
- SIGG slides / video
-- FBO Drawable w/ given NativeSurface - and OSX w/ JAWT
- - Bug 569
- - Bug 599
-
-- cleanup jocl build/jar/demos
-- clean up . in jar names in all docs and tutorials
- ES3 / GL 4.3
@@ -15,11 +8,6 @@ Version 2.0:
WIP:
-- GLPbuffer -> GLOffscreenAutoDrawable
- - GLPbuffer GLDrawableFactory.createPbuffer() ->
- GLOffscreenAutoDrawable GLDrawableFactory.createOffsceenAutoDrawable()
- - Mark both deprecated!
-
- Optimize/Fix NIO caching of glMapBuffer/glUnmapBuffer
- optimize the NIO caching, i.e. memory range, incr. reference count
- _remove_ the cached object w/ decr. ref count, remove object
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 40859845c..a72d6c77c 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -1375,7 +1375,7 @@
-
+
diff --git a/make/config/jogl/gl-impl-CustomJavaCode-common.java b/make/config/jogl/gl-impl-CustomJavaCode-common.java
index b05ba2643..283a4e623 100644
--- a/make/config/jogl/gl-impl-CustomJavaCode-common.java
+++ b/make/config/jogl/gl-impl-CustomJavaCode-common.java
@@ -50,6 +50,26 @@
return null;
}
+ @Override
+ public final boolean hasBasicFBOSupport() {
+ return _context.hasBasicFBOSupport();
+ }
+
+ @Override
+ public final boolean hasFullFBOSupport() {
+ return _context.hasFullFBOSupport();
+ }
+
+ @Override
+ public final int getMaxRenderbufferSamples() {
+ return _context.getMaxRenderbufferSamples();
+ }
+
+ @Override
+ public final boolean isTextureFormatBGRA8888Available() {
+ return _context.isTextureFormatBGRA8888Available();
+ }
+
@Override
public final GLContext getContext() {
return _context;
diff --git a/make/scripts/java-win64-dbg.bat b/make/scripts/java-win64-dbg.bat
index 510ebf4dc..b63438534 100755
--- a/make/scripts/java-win64-dbg.bat
+++ b/make/scripts/java-win64-dbg.bat
@@ -30,13 +30,15 @@ REM set D_ARGS="-Djogl.debug.ExtensionAvailabilityCache" "-Djogl.debug=all" "-Dn
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.NativeLibrary=true"
REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.ExtensionAvailabilityCache" "-Djogamp.debug.ProcAddressHelper=true"
REM set D_ARGS="-Djogl.debug.GraphicsConfiguration"
+REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLDrawable" "-Dnativewindow.debug.GraphicsConfiguration"
REM set D_ARGS="-Djogamp.debug.JNILibLoader=true" "-Djogamp.debug.NativeLibrary=true" "-Djogamp.debug.NativeLibrary.Lookup=true" "-Djogl.debug.GLProfile=true"
REM set D_ARGS="-Djogl.debug=all" "-Dnewt.debug=all" "-Dnativewindow.debug=all" "-Djogamp.debug.Lock" "-Djogamp.debug.Lock.TraceLock"
-set D_ARGS="-Djogl.debug=all" "-Dnativewindow.debug=all"
+REM set D_ARGS="-Djogl.debug=all" "-Dnativewindow.debug=all"
REM set D_ARGS="-Djogl.debug=all"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch" "-Djogl.windows.useWGLVersionOf5WGLGDIFuncSet"
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.Animator" "-Djogl.debug.GLContext" "-Djogl.debug.GLContext.TraceSwitch"
+set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display"
REM set D_ARGS="-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.DebugGL" "-Djogl.debug.TraceGL"
REM set D_ARGS="-Djogl.debug.DebugGL" "-Djogl.debug.GLDebugMessageHandler" "-Djogl.debug.GLSLCode"
diff --git a/make/scripts/tests-x64.bat b/make/scripts/tests-x64.bat
index 22cce49aa..a4207b696 100755
--- a/make/scripts/tests-x64.bat
+++ b/make/scripts/tests-x64.bat
@@ -1,9 +1,9 @@
REM scripts\java-win64-dbg.bat jogamp.newt.awt.opengl.VersionApplet
REM scripts\java-win64-dbg.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win64-dbg.bat javax.media.opengl.awt.GLCanvas
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT $*
-scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLCapabilities01NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteNEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestShutdownCompleteAWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.offscreen.TestOffscreen01GLPBufferNEWT -time 5000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestAWT01GLn
@@ -40,13 +40,13 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting03bAWT -time 100000
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01AWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
@@ -73,9 +73,9 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.caps.TestMultis
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461OffscreenSupersamplingSwingAWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestShaderCompilationBug459AWT
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol01AWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT %*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol03NewtAWT %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn %*
@@ -96,16 +96,25 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtD
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo01
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo02
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug01NEWT %*
-REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
+REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT
+scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableOffThreadSharedContextES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT %*
-REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT %*
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index ce04ae4dc..d2e2db375 100755
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -32,7 +32,7 @@ MOSX=0
MOSX_MT=0
uname -a | grep -i Darwin && MOSX=1
if [ $MOSX -eq 1 ] ; then
- #export NSZombieEnabled=YES
+ export NSZombieEnabled=YES
MOSX_MT=1
fi
@@ -56,11 +56,13 @@ function jrun() {
#D_ARGS="-Djogl.disable.opengles"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.GLSLCode -Dnewt.debug.Window.MouseEvent"
#D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
+ #D_ARGS="-Djogl.debug.FBObject -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.FBObject"
#D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
#D_ARGS="-Djogl.debug.GLContext.NoProfileAliasing"
#D_ARGS="-Djogamp.debug=all -Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
- #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all"
+ #D_ARGS="-Djogl.debug.GLContext -Djogl.debug.GLDrawable -Dnativewindow.debug.GraphicsConfiguration"
#D_ARGS="-Djogl.fbo.force.none"
#D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all -Dnewt.debug=all -Djogamp.debug.Lock"
#D_ARGS="-Djogl.debug=all"
@@ -208,7 +210,7 @@ function testawtswt() {
}
#
-# newt (testnoawt and testawt)
+# core/newt (testnoawt and testawt)
#
#testnoawt com.jogamp.nativewindow.NativeWindowVersion $*
#testnoawt com.jogamp.opengl.JoglVersion $*
@@ -237,6 +239,26 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableNewtCanvasAWTOnOffscrnCapsAWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
+
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer01GLCanvasAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestOffscreenLayer02NewtCanvasAWT $*
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableFactoryNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOffThreadSharedContextMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOOnThreadSharedContext1DemoES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
+
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $*
+
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting02NEWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01cSwingAWT $*
@@ -331,10 +353,8 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting03AWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04AWT $*
#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting01aSWT $*
-testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
+#testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingFocusTraversal01AWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer01GLCanvasAWT $*
-#testawt com.jogamp.opengl.test.junit.newt.parenting.TestParentingOffscreenLayer02NewtCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT $*
#testawt com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT
#testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT $*
@@ -376,24 +396,6 @@ testawtswt com.jogamp.opengl.test.junit.newt.parenting.TestParenting04SWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $*
-#
-# FBO / ..
-#
-
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable00NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable01bNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLDrawable02NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMix2DemosES2NEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBODrawableMix2DemosES2NEWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOAutoDrawableDeadlockAWT $*
-#testawt com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestFBOMRTNEWT01 $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestGLContextDrawableSwitchNEWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
-
#
# Graph
#
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index 47b51a509..c627f67de 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
typedef int Bool;
@@ -51,12 +52,13 @@ NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int wid
Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer);
void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer);
void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer);
+Bool isNSOpenGLPixelBuffer(uint64_t object);
-// NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque);
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* pbuffer, Bool opaque, int texWidth, int texHeight);
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight);
void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval);
void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros);
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* glLayer);
+void flushNSOpenGLLayerPBuffer(NSOpenGLLayer* layer);
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p, uint32_t texID, int texWidth, int texHeight);
void releaseNSOpenGLLayer(NSOpenGLLayer *glLayer);
void* getProcAddress(const char *procName);
@@ -67,6 +69,3 @@ void setSwapInterval(NSOpenGLContext* ctx, int interval);
Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp);
void resetGammaRamp();
-/* returns the screen refresh rate in Hz */
-int getScreenRefreshRate(int scrn_idx);
-
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 8a6495e6b..cc0af29a9 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -35,6 +35,7 @@ import javax.media.opengl.GL;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GL3;
import javax.media.opengl.GLBase;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -61,55 +62,33 @@ public class FBObject {
protected static final boolean DEBUG = Debug.debug("FBObject");
private static final boolean forceMinimumFBOSupport = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+ private static enum DetachAction { NONE, DISPOSE, RECREATE };
+
/**
- * Returns true
if basic FBO support is available, otherwise false
.
- *
- * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
- * ARB_ES2_compatibility
, ARB_framebuffer_object
, EXT_framebuffer_object
or OES_framebuffer_object
.
- *
- *
- * Basic FBO support may only include one color attachment and no multisampling,
- * as well as limited internal formats for renderbuffer.
- *
- * @see GLContext#hasFBO()
- */
- public static final boolean supportsBasicFBO(GL gl) {
- return gl.getContext().hasFBO();
- }
-
- /**
- * Returns true
if full FBO support is available, otherwise false
.
- *
- * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
- * ARB_framebuffer_object
, or all of
- * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
- * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
- *
- *
- * Full FBO support includes multiple color attachments and multisampling.
- *
+ * Marker interface, denotes a color buffer attachment.
+ * Always an instance of {@link Attachment}.
+ * Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
*/
- public static final boolean supportsFullFBO(GL gl) {
- return !forceMinimumFBOSupport &&
- ( gl.isGL3() || // GL >= 3.0
- gl.isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
-
- ( gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
- gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
- gl.isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
- gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil)
- )
- ) ;
- }
-
- public static final int getMaxSamples(GL gl) {
- if( supportsFullFBO(gl) ) {
- int[] val = new int[] { 0 } ;
- gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
- return val[0];
- } else {
- return 0;
- }
+ public static interface Colorbuffer {
+ /**
+ * Initializes the color buffer and set it's parameter, if uninitialized, i.e. name is zero
.
+ * @return true
if newly initialized, otherwise false
.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public boolean initialize(GL gl) throws GLException;
+
+ /**
+ * Releases the color buffer if initialized, i.e. name is not zero
.
+ * @throws GLException if buffer release fails.
+ */
+ public void free(GL gl) throws GLException;
+
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
}
/** Common super class of all attachments */
@@ -155,21 +134,89 @@ public class FBObject {
private int name;
- /** true
if resource is initialized by {@link #initialize(GL)}, hence {@link #free(GL)} is allowed to free the GL resources. */
- protected boolean resourceOwner;
-
- private int initCounter;
-
protected Attachment(Type type, int iFormat, int width, int height, int name) {
this.type = type;
this.format = iFormat;
this.width = width;
this.height = height;
this.name = name;
- this.resourceOwner = false;
- this.initCounter = 0;
}
+ /**
+ * Writes the internal format to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ * @param rgba8Avail whether rgba8 is available
+ */
+ public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {
+ final int _format;
+ switch(format) {
+ case GL.GL_RGBA:
+ _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
+ break;
+ case GL.GL_RGB:
+ _format = rgba8Avail ? GL.GL_RGB8 : GL.GL_RGB565;
+ break;
+ default:
+ _format = format;
+ }
+ switch(_format) {
+ case GL.GL_RGBA4:
+ caps.setRedBits(4);
+ caps.setGreenBits(4);
+ caps.setBlueBits(4);
+ caps.setAlphaBits(4);
+ break;
+ case GL.GL_RGB5_A1:
+ caps.setRedBits(5);
+ caps.setGreenBits(5);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(1);
+ break;
+ case GL.GL_RGB565:
+ caps.setRedBits(5);
+ caps.setGreenBits(6);
+ caps.setBlueBits(5);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGB8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(0);
+ break;
+ case GL.GL_RGBA8:
+ caps.setRedBits(8);
+ caps.setGreenBits(8);
+ caps.setBlueBits(8);
+ caps.setAlphaBits(8);
+ break;
+ case GL.GL_DEPTH_COMPONENT16:
+ caps.setDepthBits(16);
+ break;
+ case GL.GL_DEPTH_COMPONENT24:
+ caps.setDepthBits(24);
+ break;
+ case GL.GL_DEPTH_COMPONENT32:
+ caps.setDepthBits(32);
+ break;
+ case GL.GL_STENCIL_INDEX1:
+ caps.setStencilBits(1);
+ break;
+ case GL.GL_STENCIL_INDEX4:
+ caps.setStencilBits(4);
+ break;
+ case GL.GL_STENCIL_INDEX8:
+ caps.setStencilBits(8);
+ break;
+ case GL.GL_DEPTH24_STENCIL8:
+ caps.setDepthBits(24);
+ caps.setStencilBits(8);
+ break;
+ default:
+ throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ }
+ }
+
/** width of attachment */
public final int getWidth() { return width; }
/** height of attachment */
@@ -180,45 +227,31 @@ public class FBObject {
public final int getName() { return name; }
/* pp */ final void setName(int n) { name = n; }
- public final int getInitCounter() { return initCounter; }
-
/**
- * Initializes the attachment buffer and set it's parameter, if uninitialized, i.e. name is zero
.
- *
Implementation employs an initialization counter, hence it can be paired recursively with {@link #free(GL)}.
- * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
- */
- public void initialize(GL gl) throws GLException {
- initCounter++;
- /*
- super.initialize(gl);
- if(1 == getInitCounter() && 0 == getName() ) {
+ * Initializes the attachment and set it's parameter, if uninitialized, i.e. name is zero
.
+ *
+ final boolean init = 0 == name;
+ if( init ) {
do init ..
- freeResources = true; // if all OK
}
- */
- }
+ return init;
+ *
+ * @return true
if newly initialized, otherwise false
.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ */
+ public abstract boolean initialize(GL gl) throws GLException;
/**
- * Releases the attachment buffer if initialized, i.e. name is zero
.
- * Implementation employs an initialization counter, hence it can be paired recursively with {@link #initialize(GL)}.
- * @throws GLException if buffer release fails.
- */
- public void free(GL gl) throws GLException {
- /*
- if(1 == getInitCounter() && freeResources && .. ) {
+ * Releases the attachment if initialized, i.e. name is not zero
.
+ *
+ if(0 != name) {
do free ..
- }
- super.free(gl);
- */
- initCounter--;
- if(0 == initCounter) {
- resourceOwner = false;
name = 0;
}
- if(DEBUG) {
- System.err.println("Attachment.free: "+this);
- }
- }
+ *
+ * @throws GLException if buffer release fails.
+ */
+ public abstract void free(GL gl) throws GLException;
/**
*
@@ -232,9 +265,9 @@ public class FBObject {
if( ! ( o instanceof Attachment ) ) return false;
final Attachment a = (Attachment)o;
return type == a.type &&
- format == a.format ||
- width == a.width ||
- height== a.height ||
+ format == a.format &&
+ width == a.width &&
+ height== a.height &&
name == a.name ;
}
@@ -259,8 +292,7 @@ public class FBObject {
public String toString() {
return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
- ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+
- ", resOwner "+resourceOwner+", initCount "+initCounter+"]";
+ ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
}
public static Type getType(int attachmentPoint, int maxColorAttachments) {
@@ -277,7 +309,7 @@ public class FBObject {
}
}
}
-
+
/** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
public static class RenderAttachment extends Attachment {
private int samples;
@@ -339,14 +371,13 @@ public class FBObject {
}
@Override
- public void initialize(GL gl) throws GLException {
- super.initialize(gl);
- if( 1 == getInitCounter() && 0 == getName() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ int glerr = checkPreGLError(gl);
+
final int[] name = new int[] { -1 };
gl.glGenRenderbuffers(1, name, 0);
- if( 0 == name[0] ) {
- throw new GLException("null renderbuffer, "+this);
- }
setName(name[0]);
gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
@@ -355,43 +386,37 @@ public class FBObject {
} else {
gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
}
- int glerr = gl.glGetError();
+ glerr = gl.glGetError();
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteRenderbuffers(1, name, 0);
setName(0);
throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
}
- resourceOwner = true;
if(DEBUG) {
System.err.println("Attachment.init: "+this);
}
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
gl.glDeleteRenderbuffers(1, name, 0);
+ setName(0);
+ if(DEBUG) {
+ System.err.println("Attachment.free: "+this);
+ }
}
- super.free(gl);
}
public String toString() {
return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
- ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+
- ", resOwner "+resourceOwner+", initCount "+getInitCounter()+"]";
+ ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
}
}
- /**
- * Marker interface, denotes a color buffer attachment.
- *
Always an instance of {@link Attachment}.
- * Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
- */
- public static interface Colorbuffer {
- }
-
/** Color render buffer attachment */
public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
@@ -444,9 +469,11 @@ public class FBObject {
* @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
*/
@Override
- public void initialize(GL gl) throws GLException {
- super.initialize(gl);
- if( 1 == getInitCounter() && 0 == getName() ) {
+ public boolean initialize(GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ int glerr = checkPreGLError(gl);
+
final int[] name = new int[] { -1 };
gl.glGenTextures(1, name, 0);
if(0 == name[0]) {
@@ -468,31 +495,111 @@ public class FBObject {
if( 0 < wrapT ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
}
- int glerr = gl.glGetError();
+ glerr = gl.glGetError();
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteTextures(1, name, 0);
setName(0);
throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
}
- resourceOwner = true;
- }
- if(DEBUG) {
- System.err.println("Attachment.init: "+this);
+ if(DEBUG) {
+ System.err.println("Attachment.init: "+this);
+ }
}
+ return init;
}
@Override
public void free(GL gl) {
- if(1 == getInitCounter() && resourceOwner && 0 != getName() ) {
- final int[] name = new int[] { getName() };
+ final int[] name = new int[] { getName() };
+ if( 0 != name[0] ) {
gl.glDeleteTextures(1, name, 0);
+ setName(0);
+ if(DEBUG) {
+ System.err.println("Attachment.free: "+this);
+ }
}
- super.free(gl);
+ }
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * selecting the texture data type and format automatically.
+ *
+ *
Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.
+ *
+ * @param glp the chosen {@link GLProfile}
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @param width texture width
+ * @param height texture height
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height) {
+ return createColorTextureAttachment(glp, alpha, width, height, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * selecting the texture data type and format automatically.
+ *
+ * @param glp the chosen {@link GLProfile}
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @param width texture width
+ * @param height texture height
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ final int textureInternalFormat, textureDataFormat, textureDataType;
+ if(glp.isGLES()) {
+ textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataType = GL.GL_UNSIGNED_BYTE;
+ } else {
+ textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
+ textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
+ }
+ return createColorTextureAttachment(textureInternalFormat, width, height, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ }
+
+ /**
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}.
+ *
+ * @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param width texture width
+ * @param height texture height
+ * @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
+ * @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
+ * @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
+ * @return the created and uninitialized color {@link TextureAttachment}
+ */
+ public static final TextureAttachment createColorTextureAttachment(int internalFormat, int width, int height, int dataFormat, int dataType,
+ int magFilter, int minFilter, int wrapS, int wrapT) {
+ return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
+ magFilter, minFilter, wrapS, wrapT, 0 /* name */);
+ }
+
+ private static boolean hasAlpha(int format) {
+ switch(format) {
+ case GL.GL_RGBA8:
+ case GL.GL_RGBA4:
+ case GL.GL_RGBA:
+ case GL.GL_BGRA:
+ case 4:
+ return true;
+ default:
+ return false;
}
}
private boolean initialized;
- private boolean basicFBOSupport;
private boolean fullFBOSupport;
private boolean rgba8Avail;
private boolean depth24Avail;
@@ -523,6 +630,9 @@ public class FBObject {
//
private final void validateColorAttachmentPointRange(int point) {
+ if(!initialized) {
+ throw new GLException("FBO not initialized");
+ }
if(maxColorAttachments != colorAttachmentPoints.length) {
throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
}
@@ -621,7 +731,6 @@ public class FBObject {
this.initialized = false;
// TBD @ init
- this.basicFBOSupport = false;
this.fullFBOSupport = false;
this.rgba8Avail = false;
this.depth24Avail = false;
@@ -657,14 +766,11 @@ public class FBObject {
private void init(GL gl, int width, int height, int samples) throws GLException {
if(initialized) {
throw new GLException("FBO already initialized");
- }
- fullFBOSupport = supportsFullFBO(gl);
-
- if( !fullFBOSupport && !supportsBasicFBO(gl) ) {
+ }
+ if( !gl.hasBasicFBOSupport() ) {
throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
}
-
- basicFBOSupport = true;
+ fullFBOSupport = gl.hasFullFBOSupport();
rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
@@ -680,10 +786,7 @@ public class FBObject {
int val[] = new int[1];
- int glerr = gl.glGetError();
- if(DEBUG && GL.GL_NO_ERROR != glerr) {
- System.err.println("FBObject.init-preexisting.0 GL Error 0x"+Integer.toHexString(glerr));
- }
+ int glerr = checkPreGLError(gl);
int realMaxColorAttachments = 1;
maxColorAttachments = 1;
@@ -703,16 +806,7 @@ public class FBObject {
colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
colorAttachmentCount = 0;
- maxSamples = 0;
- if(fullFBOSupport) {
- gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
- glerr = gl.glGetError();
- if(GL.GL_NO_ERROR == glerr) {
- maxSamples = val[0];
- } else if(DEBUG) {
- System.err.println("FBObject.init-GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
- }
- }
+ maxSamples = gl.getMaxRenderbufferSamples();
if(!forceMinimumFBOSupport) {
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
maxTextureSize = val[0];
@@ -733,10 +827,9 @@ public class FBObject {
this.samples = samples <= maxSamples ? samples : maxSamples;
if(DEBUG) {
- System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+samples+" samples");
- System.err.println("basicFBOSupport: "+basicFBOSupport);
+ System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+this.samples+" samples");
System.err.println("fullFBOSupport: "+fullFBOSupport);
- System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments);
+ System.err.println("maxColorAttachments: "+maxColorAttachments+"/"+realMaxColorAttachments+" [capped/real]");
System.err.println("maxSamples: "+maxSamples);
System.err.println("maxTextureSize: "+maxTextureSize);
System.err.println("maxRenderbufferSize: "+maxRenderbufferSize);
@@ -761,12 +854,8 @@ public class FBObject {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
- if(null != samplesSink) {
- // init sampling sink
- samplesSink.reset(gl, width, height);
- resetMSAATexture2DSink(gl);
- }
-
+ resetMSAATexture2DSink(gl);
+
// generate fbo ..
gl.glGenFramebuffers(1, val, 0);
fbName = val[0];
@@ -780,7 +869,8 @@ public class FBObject {
if(!gl.glIsFramebuffer(fbName)) {
checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
}
- bound = true;
+ bound = true;
+ samplesSinkDirty = true;
initialized = true;
updateStatus(gl);
@@ -797,7 +887,7 @@ public class FBObject {
* to match the new given parameters.
*
*
- * Currently incompatibility and hence recreation is given if
+ * Incompatibility and hence recreation is forced if
* the size or sample count doesn't match for subsequent calls.
*
*
@@ -820,17 +910,17 @@ public class FBObject {
* to match the new given parameters.
*
*
- * Currently incompatibility and hence recreation is given if
- * the size or sample count doesn't match for subsequent calls.
+ * Currently incompatibility and hence recreation of the attachments will be performed
+ * if the size or sample count doesn't match for subsequent calls.
*
*
* Leaves the FBO bound state untouched
*
* @param gl the current GL context
- * @param newWidth
- * @param newHeight
+ * @param newWidth the new width, it's minimum is capped to 1
+ * @param newHeight the new height, it's minimum is capped to 1
* @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
- * @throws GLException in case of an error
+ * @throws GLException in case of an error, i.e. size too big, etc ..
*/
public final void reset(GL gl, int newWidth, int newHeight, int newSamples) {
if(!initialized) {
@@ -841,13 +931,15 @@ public class FBObject {
newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
if( newWidth != width || newHeight != height || newSamples != samples ) {
+ if(0>=newWidth) { newWidth = 1; }
+ if(0>=newHeight) { newHeight = 1; }
if(newWidth > 2 + maxTextureSize || newHeight> 2 + maxTextureSize ||
newWidth > maxRenderbufferSize || newHeight> maxRenderbufferSize ) {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
if(DEBUG) {
- System.err.println("FBObject.reset - START - "+this);
+ System.err.println("FBObject.reset - START - "+width+"x"+height+", "+samples+" -> "+newWidth+"x"+newHeight+", "+newSamples+"; "+this);
}
final boolean wasBound = isBound();
@@ -856,11 +948,18 @@ public class FBObject {
height = newHeight;
samples = newSamples;
detachAllImpl(gl, true , true);
- resetMSAATexture2DSink(gl);
- if(wasBound) {
- bind(gl);
- } else {
+ /**
+ * Postpone reset of samplesSink until syncFramebuffer,
+ * issued at use(..) method (swapBuffer usually initiates it).
+ * This allows another thread to still use the 'samplesSinkTexture'
+ * until swapBuffer happens and does not invalidate the GL_FRONT
+ * FBO (framebuffer & texture).
+ resetMSAATexture2DSink(gl);
+ */
+ samplesSinkDirty = true;
+
+ if(!wasBound) {
unbind(gl);
}
@@ -870,6 +969,28 @@ public class FBObject {
}
}
+ /**
+ * Writes the internal format of the attachments to the given GLCapabilities object.
+ * @param caps the destination for format bits
+ */
+ public final void formatToGLCapabilities(GLCapabilities caps) {
+ caps.setSampleBuffers(samples > 0);
+ caps.setNumSamples(samples);
+ caps.setDepthBits(0);
+ caps.setStencilBits(0);
+
+ final Colorbuffer cb = samples > 0 ? getSamplingSink() : getColorbuffer(0);
+ if(null != cb) {
+ cb.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ if(null != depth) {
+ depth.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ if(null != stencil && stencil != depth) {
+ stencil.formatToGLCapabilities(caps, rgba8Avail);
+ }
+ }
+
/**
* Note that the status may reflect an incomplete state during transition of attachments.
* @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
@@ -954,6 +1075,15 @@ public class FBObject {
}
}
+ private static int checkPreGLError(GL gl) {
+ int glerr = gl.glGetError();
+ if(DEBUG && GL.GL_NO_ERROR != glerr) {
+ System.err.println("Pre-existing GL error: 0x"+Integer.toHexString(glerr));
+ Thread.dumpStack();
+ }
+ return glerr;
+ }
+
private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
if(GL.GL_NO_ERROR != err) {
if(null != gl) {
@@ -974,7 +1104,7 @@ public class FBObject {
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
*
* Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.
@@ -986,13 +1116,15 @@ public class FBObject {
* @param alpha set to true
if you request alpha channel, otherwise false
;
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(GLProfile, boolean, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
- return attachTexture2D(gl, attachmentPoint, alpha, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
*
* Leaves the FBO bound.
@@ -1006,23 +1138,15 @@ public class FBObject {
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- final int textureInternalFormat, textureDataFormat, textureDataType;
- if(gl.isGLES()) {
- textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
- textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
- textureDataType = GL.GL_UNSIGNED_BYTE;
- } else {
- textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
- textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
- textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
- }
- return attachTexture2D(gl, attachmentPoint, textureInternalFormat, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point.
*
* Leaves the FBO bound.
*
@@ -1037,66 +1161,33 @@ public class FBObject {
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @see #createColorTextureAttachment(int, int, int, int, int, int, int, int, int)
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint,
int internalFormat, int dataFormat, int dataType,
int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
- return attachTexture2D(gl, attachmentPoint,
- new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
- magFilter, minFilter, wrapS, wrapT, 0 /* name */));
+ return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
+ createColorTextureAttachment(internalFormat, width, height, dataFormat, dataType, magFilter, minFilter, wrapS, wrapT));
}
/**
- * Attaches a Texture2D Color Buffer to this FBO's instance at the given attachment point.
+ * Creates a {@link ColorAttachment}, selecting the format automatically.
*
- *
- * In case the passed TextureAttachment texA
is uninitialized, i.e. it's texture name is zero
,
- * a new texture name is generated and setup w/ the texture parameter.
- * Otherwise, i.e. texture name is not zero
, the passed TextureAttachment texA
is
- * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
- *
- *
- * Leaves the FBO bound.
- *
- * @param gl the current GL context
- * @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param texA the to be attached {@link TextureAttachment}. Maybe complete or uninitialized, see above.
- * @return the passed TextureAttachment texA
instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
- * @throws GLException in case the texture colorbuffer couldn't be allocated or MSAA has been chosen
+ * @param alpha set to true
if you request alpha channel, otherwise false
;
+ * @return uninitialized ColorAttachment instance describing the new attached colorbuffer
*/
- public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, TextureAttachment texA) throws GLException {
- validateAddColorAttachment(attachmentPoint, texA);
-
- if(samples>0) {
- removeColorAttachment(attachmentPoint, texA);
- throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
- }
-
- texA.initialize(gl);
- addColorAttachment(attachmentPoint, texA);
-
- bind(gl);
-
- // Set up the color buffer for use as a renderable texture:
- gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
- GL.GL_TEXTURE_2D, texA.getName(), 0);
-
- if(!ignoreStatus) {
- updateStatus(gl);
- if(!isStatusValid()) {
- detachColorbuffer(gl, attachmentPoint);
- throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
- }
- }
- if(DEBUG) {
- System.err.println("FBObject.attachTexture2D: "+this);
+ public final ColorAttachment createColorAttachment(boolean alpha) {
+ final int internalFormat;
+ if( rgba8Avail ) {
+ internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
+ } else {
+ internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
}
- return texA;
+ return new ColorAttachment(internalFormat, samples, width, height, 0);
}
-
+
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point,
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point,
* selecting the format automatically.
*
* Leaves the FBO bound.
@@ -1106,19 +1197,14 @@ public class FBObject {
* @param alpha set to true
if you request alpha channel, otherwise false
;
* @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the colorbuffer couldn't be allocated
+ * @see #createColorAttachment(boolean)
*/
public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
- final int internalFormat;
- if( rgba8Avail ) {
- internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
- } else {
- internalFormat = alpha ? GL.GL_RGBA4 : GL.GL_RGB565;
- }
- return attachColorbuffer(gl, attachmentPoint, internalFormat);
+ return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
}
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point.
*
* Leaves the FBO bound.
*
@@ -1135,46 +1221,80 @@ public class FBObject {
throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
}
- return attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+ return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
}
/**
- * Attaches a Color Buffer to this FBO's instance at the given attachment point.
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment},
+ * to this FBO's instance at the given attachment point.
*
+ *
+ * If {@link Colorbuffer} is a {@link TextureAttachment} and is uninitialized, i.e. it's texture name is zero
,
+ * a new texture name is generated and setup w/ the texture parameter.
+ * Otherwise, i.e. texture name is not zero
, the passed TextureAttachment texA
is
+ * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
+ *
+ *
* Leaves the FBO bound.
*
* @param gl
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param colA the template for the new {@link ColorAttachment}
- * @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
- * @throws GLException in case the colorbuffer couldn't be allocated
+ * @param colbuf the to be attached {@link Colorbuffer}
+ * @return newly attached {@link Colorbuffer} instance if bound and configured successfully, otherwise GLException is thrown
+ * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment}
*/
- public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, ColorAttachment colA) throws GLException {
- validateAddColorAttachment(attachmentPoint, colA);
-
- colA.initialize(gl);
- addColorAttachment(attachmentPoint, colA);
+ public final Colorbuffer attachColorbuffer(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
+ validateAddColorAttachment(attachmentPoint, colbuf);
- bind(gl);
+ final boolean initializedColorbuf = colbuf.initialize(gl);
+ addColorAttachment(attachmentPoint, colbuf);
- // Attach the color buffer
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
- GL.GL_RENDERBUFFER, colA.getName());
+ bind(gl);
- if(!ignoreStatus) {
- updateStatus(gl);
- if(!isStatusValid()) {
- detachColorbuffer(gl, attachmentPoint);
- throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ if(colbuf instanceof TextureAttachment) {
+ final TextureAttachment texA = (TextureAttachment) colbuf;
+
+ if(samples>0) {
+ removeColorAttachment(attachmentPoint, texA);
+ if(initializedColorbuf) {
+ texA.free(gl);
+ }
+ throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
+ }
+
+ // Set up the color buffer for use as a renderable texture:
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, texA.getName(), 0);
+
+ if(!ignoreStatus) {
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint, true);
+ throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
+ }
+ } else if(colbuf instanceof ColorAttachment) {
+ final ColorAttachment colA = (ColorAttachment) colbuf;
+
+ // Attach the color buffer
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_RENDERBUFFER, colA.getName());
+
+ if(!ignoreStatus) {
+ updateStatus(gl);
+ if(!isStatusValid()) {
+ detachColorbuffer(gl, attachmentPoint, true);
+ throw new GLException("attachColorbuffer "+colA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
+ }
}
}
if(DEBUG) {
- System.err.println("FBObject.attachColorbuffer: "+this);
+ System.err.println("FBObject.attachColorbuffer: [attachmentPoint "+attachmentPoint+", colbuf "+colbuf+"]: "+this);
}
- return colA;
+ return colbuf;
}
-
/**
* Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
@@ -1355,33 +1475,39 @@ public class FBObject {
if(!ignoreStatus) {
updateStatus(gl);
if( !isStatusValid() ) {
- detachRenderbuffer(gl, atype);
+ detachRenderbuffer(gl, atype, true);
throw new GLException("renderbuffer attachment failed: "+this.getStatusString());
}
}
if(DEBUG) {
- System.err.println("FBObject.attachRenderbuffer: "+this);
- }
+ System.err.println("FBObject.attachRenderbuffer: [attachmentType "+atype+"]: "+this);
+ }
}
/**
+ * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}.
* Leaves the FBO bound!
+ *
* @param gl
- * @param ca
+ * @param attachmentPoint
+ * @param dispose true if the Colorbuffer shall be disposed
+ * @return the detached Colorbuffer
* @throws IllegalArgumentException
*/
- public final void detachColorbuffer(GL gl, int attachmentPoint) throws IllegalArgumentException {
- if(null == detachColorbufferImpl(gl, attachmentPoint, false)) {
+ public final Colorbuffer detachColorbuffer(GL gl, int attachmentPoint, boolean dispose) throws IllegalArgumentException {
+ final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+ if(null == res) {
throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
}
if(DEBUG) {
- System.err.println("FBObject.detachColorbuffer: [attachmentPoint "+attachmentPoint+"]: "+this);
+ System.err.println("FBObject.detachColorbuffer: [attachmentPoint "+attachmentPoint+", dispose "+dispose+"]: "+res+", "+this);
}
+ return res;
}
- private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, boolean recreate) {
- final Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+ private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, DetachAction detachAction) {
+ Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
if(null == colbuf) {
return null;
@@ -1389,6 +1515,8 @@ public class FBObject {
bind(gl);
+ removeColorAttachment(attachmentPoint, colbuf);
+
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
if( 0 != texA.getName() ) {
@@ -1397,11 +1525,22 @@ public class FBObject {
GL.GL_TEXTURE_2D, 0, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
}
- texA.free(gl);
- removeColorAttachment(attachmentPoint, texA);
- if(recreate) {
- texA.setSize(width, height);
- attachTexture2D(gl, attachmentPoint, texA);
+ switch(detachAction) {
+ case DISPOSE:
+ texA.free(gl);
+ break;
+ case RECREATE:
+ texA.free(gl);
+ if(samples == 0) {
+ // stay non MSAA
+ texA.setSize(width, height);
+ } else {
+ // switch to MSAA
+ colbuf = createColorAttachment(hasAlpha(texA.format));
+ }
+ attachColorbuffer(gl, attachmentPoint, colbuf);
+ break;
+ default:
}
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
@@ -1410,12 +1549,30 @@ public class FBObject {
GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
GL.GL_RENDERBUFFER, 0);
}
- colA.free(gl);
- removeColorAttachment(attachmentPoint, colbuf);
- if(recreate) {
- colA.setSize(width, height);
- colA.setSamples(samples);
- attachColorbuffer(gl, attachmentPoint, colA);
+ switch(detachAction) {
+ case DISPOSE:
+ colA.free(gl);
+ break;
+ case RECREATE:
+ colA.free(gl);
+ if(samples > 0) {
+ // stay MSAA
+ colA.setSize(width, height);
+ colA.setSamples(samples);
+ } else {
+ // switch to non MSAA
+ if(null != samplesSinkTexture) {
+ colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height,
+ samplesSinkTexture.dataFormat, samplesSinkTexture.dataType,
+ samplesSinkTexture.magFilter, samplesSinkTexture.minFilter,
+ samplesSinkTexture.wrapS, samplesSinkTexture.wrapT);
+ } else {
+ colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
+ }
+ }
+ attachColorbuffer(gl, attachmentPoint, colbuf);
+ break;
+ default:
}
}
return colbuf;
@@ -1424,10 +1581,14 @@ public class FBObject {
/**
*
* @param gl
+ * @param dispose true if the Colorbuffer shall be disposed
* @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL}
*/
- public final void detachRenderbuffer(GL gl, Attachment.Type atype) throws IllegalArgumentException {
- detachRenderbufferImpl(gl, atype, false);
+ public final void detachRenderbuffer(GL gl, Attachment.Type atype, boolean dispose) throws IllegalArgumentException {
+ detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+ if(DEBUG) {
+ System.err.println("FBObject.detachRenderbuffer: [attachmentType "+atype+", dispose "+dispose+"]: "+this);
+ }
}
public final boolean isDepthStencilPackedFormat() {
@@ -1439,7 +1600,7 @@ public class FBObject {
return res;
}
- private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, boolean recreate) throws IllegalArgumentException {
+ private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, DetachAction detachAction) throws IllegalArgumentException {
switch ( atype ) {
case DEPTH:
case STENCIL:
@@ -1485,8 +1646,14 @@ public class FBObject {
if( 0 != depth.getName() ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
}
- depth.free(gl);
- if(!recreate) {
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ break;
+ default:
+ }
+ if(DetachAction.RECREATE != detachAction) {
depth = null;
}
break;
@@ -1495,8 +1662,14 @@ public class FBObject {
if(0 != stencil.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
}
- stencil.free(gl);
- if(!recreate) {
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ stencil.free(gl);
+ break;
+ default:
+ }
+ if(DetachAction.RECREATE != detachAction) {
stencil = null;
}
break;
@@ -1506,9 +1679,15 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
}
- depth.free(gl);
- stencil.free(gl);
- if(!recreate) {
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ stencil.free(gl);
+ break;
+ default:
+ }
+ if(DetachAction.RECREATE != detachAction) {
depth = null;
stencil = null;
}
@@ -1516,14 +1695,15 @@ public class FBObject {
default:
throw new InternalError("XXX");
}
- if(recreate) {
+ if(DetachAction.RECREATE == detachAction) {
attachRenderbufferImpl2(gl, action, format);
}
}
}
/**
- * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s.
+ * Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s
+ * and disposes them.
* Leaves the FBO bound!
*
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
@@ -1538,7 +1718,8 @@ public class FBObject {
}
/**
- * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s.
+ * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s
+ * and disposes them.
*
Leaves the FBO bound!
*
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
@@ -1553,7 +1734,7 @@ public class FBObject {
}
/**
- * Detaches all {@link TextureAttachment}s
+ * Detaches all {@link TextureAttachment}s and disposes them.
*
Leaves the FBO bound!
*
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
@@ -1566,30 +1747,33 @@ public class FBObject {
}
for(int i=0; i reset
try {
for(int i=0; i0 ) {
throw new InternalError("Non zero ColorAttachments "+this);
}
if(detachNonColorbuffer) {
- detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate);
+ detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
}
if(ignoreStatus) { // post validate
updateStatus(gl);
@@ -1651,14 +1835,22 @@ public class FBObject {
}
private final void resetMSAATexture2DSink(GL gl) throws GLException {
+ if(null == samplesSink ) {
+ return; // this is the sample sink!
+ }
if(0 == samples) {
// MSAA off
- if(null != samplesSink) {
+ if(samplesSink.initialized) {
+ // cleanup
samplesSink.detachAll(gl);
}
return;
}
+ if(!samplesSink.initialized) {
+ samplesSink.init(gl, width, height, 0);
+ }
+
boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
@@ -1692,7 +1884,7 @@ public class FBObject {
samplesSinkTexture = samplesSink.attachTexture2D(gl, 0, true);
} else if( 0 == samplesSinkTexture.getName() ) {
samplesSinkTexture.setSize(width, height);
- samplesSink.attachTexture2D(gl, 0, samplesSinkTexture);
+ samplesSink.attachColorbuffer(gl, 0, samplesSinkTexture);
}
if( sampleSinkDepthStencilMismatch ) {
@@ -1768,6 +1960,17 @@ public class FBObject {
bound = false;
}
}
+
+ /**
+ * Method simply marks this FBO unbound w/o interfering w/ the bound framebuffer as perfomed by {@link #unbind(GL)}.
+ *
+ * Only use this method if a subsequent {@link #unbind(GL)}, {@link #use(GL, TextureAttachment)} or {@link #bind(GL)}
+ * follows on any FBO.
+ *
+ */
+ public final void markUnbound() {
+ bound = false;
+ }
/**
* Returns true
if framebuffer object is bound via {@link #bind(GL)}, otherwise false
.
@@ -1785,49 +1988,54 @@ public class FBObject {
public final boolean isBound() { return bound; }
/**
- * Samples the multisampling colorbuffer (msaa-buffer) to it's sink {@link #getSamplingSink()}.
- *
- * The operation is skipped, if no multisampling is used or
- * the msaa-buffer has not been flagged dirty by a previous call of {@link #bind(GL)},
- * see {@link #isSamplingBufferDirty()}
- *
- * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
- * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
- *
- * In case you intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
+ * If multisampling is being used and flagged dirty by a previous call of {@link #bind(GL)} or after initialization,
+ * the msaa-buffers are sampled to it's sink {@link #getSamplingSink()}.
+ *
+ * Method also updates the sampling sink configuration (if used). Hence it is recommended to call this
+ * method after your have initialized the FBO and attached renderbuffer etc for the 1st time.
+ * Method is called automatically by {@link #use(GL, TextureAttachment)}.
+ *
+ *
+ * Methos always resets the framebuffer binding to default in the end.
+ * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
+ * an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
+ *
+ *
+ * In case you use this FBO w/o the {@link GLFBODrawable} and intend to employ {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}
* you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
*
- *
* Leaves the FBO unbound.
*
* @param gl the current GL context
* @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
* @throws IllegalArgumentException
*/
- public final void syncSamplingBuffer(GL gl) {
- unbind(gl);
+ public final void syncFramebuffer(GL gl) {
+ markUnbound();
if(samples>0 && samplesSinkDirty) {
samplesSinkDirty = false;
resetMSAATexture2DSink(gl);
gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbName);
gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplesSink.getWriteFramebuffer());
- ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, ugly cast is OK
+ ((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2GL3 is OK
GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
- if(fullFBOSupport) {
- // default read/draw buffers, may utilize GLContext/GLDrawable override of
- // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
- gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
- gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
- } else {
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
- }
+ }
+ if(fullFBOSupport) {
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
+ } else {
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
}
}
/**
* Bind the given texture colorbuffer.
*
- * If multisampling is being used, {@link #syncSamplingBuffer(GL)} is being called.
+ * If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first!
+ *
+ * {@link #syncFramebuffer(GL)} is being called
*
* Leaves the FBO unbound!
*
@@ -1837,11 +2045,7 @@ public class FBObject {
*/
public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
if(null == ta) { throw new IllegalArgumentException("null TextureAttachment, this: "+toString()); }
- if(samples > 0 && samplesSinkTexture == ta) {
- syncSamplingBuffer(gl);
- } else {
- unbind(gl);
- }
+ syncFramebuffer(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
}
@@ -1855,14 +2059,8 @@ public class FBObject {
gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
}
- /**
- * Returns true
if basic or full FBO is supported, otherwise false
.
- * @param full true
for full FBO supported query, otherwise false
for basic FBO support query.
- * @see #supportsFullFBO(GL)
- * @see #supportsBasicFBO(GL)
- * @throws GLException if {@link #init(GL)} hasn't been called.
- */
- public final boolean supportsFBO(boolean full) throws GLException { checkInitialized(); return full ? fullFBOSupport : basicFBOSupport; }
+ /** @see GL#hasFullFBOSupport() */
+ public final boolean hasFullFBOSupport() throws GLException { checkInitialized(); return this.fullFBOSupport; }
/**
* Returns true
if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise false
.
@@ -1878,7 +2076,7 @@ public class FBObject {
public final boolean supportsDepth(int bits) throws GLException {
checkInitialized();
switch(bits) {
- case 16: return basicFBOSupport;
+ case 16: return true;
case 24: return depth24Avail;
case 32: return depth32Avail;
default: return false;
@@ -1913,11 +2111,11 @@ public class FBObject {
*/
public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
- /**
- * Returns the maximum number of samples for multisampling. Maybe zero if multisampling is not supported.
- * @throws GLException if {@link #init(GL)} hasn't been called.
- */
- public final int getMaxSamples() throws GLException { checkInitialized(); return maxSamples; }
+ public final int getMaxTextureSize() throws GLException { checkInitialized(); return this.maxTextureSize; }
+ public final int getMaxRenderbufferSize() throws GLException { checkInitialized(); return this.maxRenderbufferSize; }
+
+ /** @see GL#getMaxRenderbufferSamples() */
+ public final int getMaxSamples() throws GLException { checkInitialized(); return this.maxSamples; }
/**
* Returns true
if this instance has been initialized with {@link #reset(GL, int, int)}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
new file mode 100644
index 000000000..38a8deef8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLAutoDrawableDelegate.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+import jogamp.opengl.GLAutoDrawableBase;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableImpl;
+
+
+/**
+ * Fully functional {@link GLAutoDrawable} implementation
+ * utilizing already created created {@link GLDrawable} and {@link GLContext} instances.
+ *
+ * Since no native windowing system events are being processed, it is recommended
+ * to handle at least:
+ *
+ * {@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #windowRepaintOp()}
+ * {@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #windowResizedOp()}
+ * {@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #windowDestroyNotifyOp()}
+ *
+ *
+ *
+ * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
+ *
+ */
+public class GLAutoDrawableDelegate extends GLAutoDrawableBase implements GLAutoDrawable {
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
+ * @param lock optional custom {@link RecursiveLock}.
+ */
+ public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice, RecursiveLock lock) {
+ super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
+ if(null == drawable) {
+ throw new IllegalArgumentException("null drawable");
+ }
+ if(null == context) {
+ throw new IllegalArgumentException("null context");
+ }
+ if(!drawable.isRealized()) {
+ throw new IllegalArgumentException("drawable not realized");
+ }
+ this.upstreamWidget = upstreamWidget;
+ this.lock = ( null != lock ) ? lock : LockFactory.createRecursiveLock() ;
+ }
+
+ //
+ // expose default methods
+ //
+
+ /** Default implementation to handle repaint events from the windowing system */
+ public final void windowRepaintOp() {
+ super.defaultWindowRepaintOp();
+ }
+
+ /** Implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ public final void windowResizedOp(int newWidth, int newHeight) {
+ super.defaultWindowResizedOp(newWidth, newHeight);
+ }
+
+ /**
+ * Implementation to handle destroy notifications from the windowing system.
+ *
+ *
+ * If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
+ * or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
+ * a thread safe destruction is being induced.
+ *
+ */
+ public final void windowDestroyNotifyOp() {
+ super.defaultWindowDestroyNotifyOp();
+ }
+
+ //
+ // Complete GLAutoDrawable
+ //
+
+ private Object upstreamWidget;
+ private final RecursiveLock lock;
+
+ @Override
+ protected final RecursiveLock getLock() { return lock; }
+
+ @Override
+ public final Object getUpstreamWidget() {
+ return upstreamWidget;
+ }
+
+ /**
+ * Set the upstream UI toolkit object.
+ * @see #getUpstreamWidget()
+ */
+ public final void setUpstreamWidget(Object newUpstreamWidget) {
+ upstreamWidget = newUpstreamWidget;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation calls {@link #defaultDestroy()}.
+ *
+ *
+ * User still needs to destroy the upstream window, which details are hidden from this aspect.
+ * This can be performed by overriding {@link #destroyImplInLock()}.
+ *
+ */
+ @Override
+ public final void destroy() {
+ defaultDestroy();
+ }
+
+ @Override
+ protected void destroyImplInLock() {
+ super.destroyImplInLock();
+ }
+
+ @Override
+ public void display() {
+ defaultDisplay();
+ }
+
+ //
+ // GLDrawable delegation
+ //
+
+ @Override
+ public final GLDrawableFactory getFactory() {
+ return drawable.getFactory();
+ }
+
+ @Override
+ public final void setRealized(boolean realized) {
+ }
+
+ @Override
+ public final void swapBuffers() throws GLException {
+ defaultSwapBuffers();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + ", \n\tUpstreamWidget: "+upstreamWidget+ /** ", \n\tFactory: "+factory+ */ "]";
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
index f7e25fa01..cf81b85ee 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLExtensions.java
@@ -72,6 +72,9 @@ public class GLExtensions {
public static final String OES_EGL_image_external = "GL_OES_EGL_image_external";
+ public static final String ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64";
+ public static final String ARB_shader_objects = "GL_ARB_shader_objects";
+
//
// Aliased GLX/WGL/.. extensions
//
diff --git a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
deleted file mode 100644
index 4caea03b2..000000000
--- a/src/jogl/classes/com/jogamp/opengl/OffscreenAutoDrawable.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * Copyright 2012 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:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package com.jogamp.opengl;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.opengl.GLAutoDrawableDelegate;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
-import javax.media.opengl.GLException;
-
-import jogamp.opengl.GLFBODrawableImpl;
-
-/**
- * Platform-independent class exposing FBO offscreen functionality to
- * applications.
- *
- * This class distinguishes itself from {@link GLAutoDrawableDelegate}
- * with it's {@link #setSize(int, int)} functionality.
- *
- */
-public class OffscreenAutoDrawable extends GLAutoDrawableDelegate {
-
- /**
- * @param drawable a valid {@link GLDrawable}, may not be realized yet.
- * @param context a valid {@link GLContext}, may not be made current (created) yet.
- * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public OffscreenAutoDrawable(GLDrawable drawable, GLContext context, boolean ownDevice) {
- super(drawable, context, null, ownDevice);
- }
-
- /**
- * Attempts to resize this offscreen auto drawable, if supported
- * by the underlying {@link GLDrawable).
- * @param newWidth
- * @param newHeight
- * @return true
if resize was executed, otherwise false
.
- * @throws GLException in case of an error during the resize operation
- */
- public boolean setSize(int newWidth, int newHeight) throws GLException {
- boolean done = false;
- if(drawable instanceof GLFBODrawableImpl) {
- Throwable tFBO = null;
- Throwable tGL = null;
- context.makeCurrent();
- try {
- ((GLFBODrawableImpl)drawable).setSize(context.getGL(), newWidth, newHeight);
- done = true;
- } catch (Throwable t) {
- tFBO = t;
- } finally {
- try {
- context.release();
- } catch (Throwable t) {
- tGL = t;
- }
- }
- if(null != tFBO) {
- throw new GLException("OffscreenAutoDrawable.setSize(..) GLFBODrawableImpl.setSize(..) exception", tFBO);
- }
- if(null != tGL) {
- throw new GLException("OffscreenAutoDrawable.setSize(..) GLContext.release() exception", tGL);
- }
- }
- if(done) {
- this.defaultWindowResizedOp();
- return true;
- }
- return false;
- }
-
- /**
- * If the underlying {@link GLDrawable} is an FBO implementation
- * and contains an {#link FBObject}, the same is returned.
- * Otherwise returns null
.
- */
- public FBObject getFBObject() {
- if(drawable instanceof GLFBODrawableImpl) {
- return ((GLFBODrawableImpl)drawable).getFBObject();
- }
- return null;
- }
-}
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
index 8d237162c..02f62daec 100644
--- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
+++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java
@@ -30,6 +30,7 @@ package com.jogamp.opengl.swt;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
@@ -48,6 +49,7 @@ import javax.media.opengl.Threading;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
@@ -97,8 +99,8 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
private final GLCapabilitiesImmutable capsRequested;
private final GLCapabilitiesChooser capsChooser;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
- private GLContext context;
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
+ private GLContextImpl context;
/* Native window surface */
private AbstractGraphicsDevice device;
@@ -319,7 +321,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
}
});
}
- private final ProxySurface.UpstreamSurfaceHook swtCanvasUpStreamHook = new ProxySurface.UpstreamSurfaceHook() {
+ private final UpstreamSurfaceHook swtCanvasUpStreamHook = new UpstreamSurfaceHook() {
@Override
public final void create(ProxySurface s) { /* nop */ }
@@ -349,7 +351,27 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
( nClientArea.width != oClientArea.width || nClientArea.height != oClientArea.height )
) {
clientArea = nClientArea; // write back new value
- sendReshape = true; // Mark for OpenGL reshape next time the control is painted
+
+ GLDrawableImpl _drawable = drawable;
+ if( null != _drawable ) {
+ if(DEBUG) {
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+nClientArea.width+"x"+nClientArea.height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, nClientArea.width, nClientArea.height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
+ }
}
}
@@ -391,10 +413,10 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
if(null != proxySurface) {
/* Associate a GL surface with the proxy */
- drawable = glFactory.createGLDrawable(proxySurface);
+ drawable = (GLDrawableImpl) glFactory.createGLDrawable(proxySurface);
drawable.setRealized(true);
- context = drawable.createContext(shareWith);
+ context = (GLContextImpl) drawable.createContext(shareWith);
}
} finally {
_lock.unlock();
@@ -455,6 +477,11 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
return helper.getAutoSwapBufferMode();
}
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
@Override
public GLContext getContext() {
return null != drawable ? context : null;
@@ -502,7 +529,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable {
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
index 0b2c664fe..38f1746f9 100644
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -114,6 +114,12 @@ public interface GLAutoDrawable extends GLDrawable {
* where you drag the window to another monitor. */
public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true);
+ /**
+ * If the implementation uses delegation, return the delegated {@link GLDrawable} instance,
+ * otherwise return this
instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
/**
* Returns the context associated with this drawable. The returned
* context will be synchronized.
@@ -124,23 +130,31 @@ public interface GLAutoDrawable extends GLDrawable {
/**
* Associate a new context to this drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- * drawable
might be an inner GLDrawable instance if using such a delegation pattern,
- * or this GLAutoDrawable itself.
- *
- * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
- * is being cleared by calling
- * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
- *
+ * drawable
might be an inner GLDrawable instance if using a delegation pattern,
+ * or this GLAutoDrawable instance.
*
* If the old or new context was current on this thread, it is being released before switching the drawable.
* The new context will be made current afterwards, if it was current before.
- * However the user shall take extra care that not other thread
- * attempts to make this context current. Otherwise a race condition may happen.
+ * However the user shall take extra care that no other thread
+ * attempts to make this context current.
+ *
+ *
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only be bound to one drawable at one time!
*
*
- * Disclaimer : 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!
+ * In case you do not intend to use the old context anymore, i.e.
+ * not assigning it to another drawable, it shall be
+ * destroyed before setting the new context, i.e.:
+ *
+ GLContext oldCtx = glad.getContext();
+ if(null != oldCtx) {
+ oldCtx.destroy();
+ }
+ glad.setContext(newCtx);
+ *
+ * This is required, since a context must have a valid drawable at all times
+ * and this API shall not restrict the user in any way.
*
*
* @param newCtx the new context
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
deleted file mode 100644
index 67e81270d..000000000
--- a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Copyright 2012 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:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of JogAmp Community.
- */
-
-package javax.media.opengl;
-
-import javax.media.nativewindow.AbstractGraphicsDevice;
-
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
-
-import jogamp.opengl.Debug;
-import jogamp.opengl.GLAutoDrawableBase;
-import jogamp.opengl.GLContextImpl;
-import jogamp.opengl.GLDrawableImpl;
-
-
-/**
- * Fully functional {@link GLAutoDrawable} implementation
- * utilizing already created created {@link GLDrawable} and {@link GLContext} instances.
- *
- * Since no native windowing system events are being processed, it is recommended
- * to handle at least:
- *
- * {@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint} using {@link #defaultWindowRepaintOp()}
- * {@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize} using {@link #defaultWindowResizedOp()}
- * {@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} using {@link #defaultWindowDestroyNotifyOp()}
- *
- *
- *
- * See example {@link com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateNEWT TestGLAutoDrawableDelegateNEWT}.
- *
- */
-public class GLAutoDrawableDelegate extends GLAutoDrawableBase {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate");
-
- /**
- * @param drawable a valid {@link GLDrawable}, may not be realized yet.
- * @param context a valid {@link GLContext}, may not be made current (created) yet.
- * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
- * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
- */
- public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context, Object upstreamWidget, boolean ownDevice) {
- super((GLDrawableImpl)drawable, (GLContextImpl)context, ownDevice);
- this.upstreamWidget = null;
- }
-
- //
- // expose default methods
- //
-
- public final void windowRepaintOp() {
- super.defaultWindowRepaintOp();
- }
-
- public final void windowResizedOp() {
- super.defaultWindowResizedOp();
- }
-
- public final void windowDestroyNotifyOp() {
- super.defaultWindowDestroyNotifyOp();
- }
-
- //
- // Complete GLAutoDrawable
- //
-
- private final RecursiveLock lock = LockFactory.createRecursiveLock(); // instance wide lock
- private final Object upstreamWidget;
-
- @Override
- protected final RecursiveLock getLock() { return lock; }
-
- @Override
- public final Object getUpstreamWidget() {
- return upstreamWidget;
- }
-
- /**
- * {@inheritDoc}
- *
- * This implementation calls {@link #defaultDestroy()}.
- *
- *
- * User still needs to destroy the upstream window, which details are hidden from this aspect.
- * This can be performed by overriding {@link #destroyImplInLock()}.
- *
- */
- @Override
- public final void destroy() {
- defaultDestroy();
- }
-
- @Override
- public void display() {
- defaultDisplay();
- }
-
- //
- // GLDrawable delegation
- //
-
- @Override
- public final GLDrawableFactory getFactory() {
- return drawable.getFactory();
- }
-
- @Override
- public final void setRealized(boolean realized) {
- }
-
- @Override
- public final void swapBuffers() throws GLException {
- defaultSwapBuffers();
- }
-
-}
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f5831a72d..9bcee819a 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -273,6 +273,42 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns true
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= core 3.0 or implements the extensions
+ * GL_ARB_ES2_compatibility
, GL_ARB_framebuffer_object
, GL_EXT_framebuffer_object
or GL_OES_framebuffer_object
.
+ *
+ *
+ * Basic FBO support may only include one color attachment and no multisampling,
+ * as well as limited internal formats for renderbuffer.
+ *
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public boolean hasBasicFBOSupport();
+
+ /**
+ * Returns true
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ *
+ * Full FBO support includes multiple color attachments and multisampling.
+ *
+ * @see GLContext#hasFullFBOSupport()
+ */
+ public boolean hasFullFBOSupport();
+
+ /**
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
+ * @see GLContext#getMaxRenderbufferSamples()
+ */
+ public int getMaxRenderbufferSamples();
+
/**
* Returns true if the GL context supports non power of two (NPOT) textures,
* otherwise false.
@@ -284,6 +320,8 @@ public interface GLBase {
*/
public boolean isNPOTTextureAvailable();
+ public boolean isTextureFormatBGRA8888Available();
+
/** Provides a platform-independent way to specify the minimum swap
interval for buffer swaps. An argument of 0 disables
sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index c2f94b9af..a5e639c74 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -96,6 +96,9 @@ public abstract class GLContext {
*/
public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true);
+ protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true);
+ protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true);
+
public static final boolean DEBUG = Debug.debug("GLContext");
public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true);
@@ -127,9 +130,9 @@ public abstract class GLContext {
/** GL_ARB_ES2_compatibility
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 supports basic FBO, details see {@link #hasFBO()}.
+ /** Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
* Not a cache key.
- * @see #hasFBO()
+ * @see #hasBasicFBOSupport()
* @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
*/
protected static final int CTX_IMPL_FBO = 1 << 9;
@@ -178,11 +181,6 @@ public abstract class GLContext {
* 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.
*
- *
- * Disclaimer : 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!
- *
* @param readWrite the read/write drawable for framebuffer operations.
* @param setWriteOnly if true
and if the current read-drawable differs
* from the write-drawable ({@link #setGLReadDrawable(GLDrawable)}),
@@ -603,12 +601,23 @@ public abstract class GLContext {
/**
* @return true if impl. is a hardware rasterizer, otherwise false.
+ * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile)
* @see GLProfile#isHardwareRasterizer()
*/
public final boolean isHardwareRasterizer() {
return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ;
}
+ /**
+ * @return true if context supports GLSL, i.e. is either {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} and major-version > 1.
+ * @see GLProfile#hasGLSL()
+ */
+ public final boolean hasGLSL() {
+ return isGLES2() ||
+ isGL3() ||
+ isGL2() && ctxMajorVersion>1 ;
+ }
+
/**
* Returns true
if basic FBO support is available, otherwise false
.
*
@@ -620,21 +629,54 @@ public abstract class GLContext {
* as well as limited internal formats for renderbuffer.
*
* @see #CTX_IMPL_FBO
- * @see com.jogamp.opengl.FBObject#supportsBasicFBO(GL)
- * @see com.jogamp.opengl.FBObject#supportsFullFBO(GL)
*/
- public final boolean hasFBO() {
+ public final boolean hasBasicFBOSupport() {
return 0 != ( ctxOptions & CTX_IMPL_FBO ) ;
}
+ /**
+ * Returns true
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= core 3.0 or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ *
+ * Full FBO support includes multiple color attachments and multisampling.
+ *
+ */
+ public final boolean hasFullFBOSupport() {
+ return !FORCE_MIN_FBO_SUPPORT && hasBasicFBOSupport() &&
+ ( isGL3() || // GL >= 3.0
+ isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object
+ ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object*
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) &&
+ isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) &&
+ isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil)
+ )
+ ) ;
+ }
+
/**
- * @return true if context supports GLSL
- * @see GLProfile#hasGLSL()
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
*/
- public final boolean hasGLSL() {
- return isGL2ES2() ;
+ public final int getMaxRenderbufferSamples() {
+ if( hasFullFBOSupport() ) {
+ final GL gl = getGL();
+ final int[] val = new int[] { 0 } ;
+ gl.glGetIntegerv(GL2GL3.GL_MAX_SAMPLES, val, 0);
+ final int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ return val[0];
+ } else if(DEBUG) {
+ System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ }
+ return 0;
}
-
+
/** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns true
. */
public boolean isNPOTTextureAvailable() {
return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
@@ -1014,6 +1056,9 @@ public abstract class GLContext {
validateProfileBits(profile, "profile");
validateProfileBits(resCtp, "resCtp");
+ if(FORCE_NO_FBO_SUPPORT) {
+ resCtp &= ~CTX_IMPL_FBO ;
+ }
if(DEBUG) {
System.err.println("GLContext.mapAvailableGLVersion: "+device+": "+getGLVersion(reqMajor, 0, profile, null)+" -> "+getGLVersion(resMajor, resMinor, resCtp, null));
// Thread.dumpStack();
@@ -1197,17 +1242,35 @@ public abstract class GLContext {
* FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
*
*
- * FBO support is queried as described in {@link #hasFBO()}.
+ * FBO support is queried as described in {@link #hasBasicFBOSupport()}.
*
*
* @param device the device to request whether FBO is available for
* @param glp {@link GLProfile} to check for FBO capabilities
- * @see GLContext#hasFBO()
+ * @see GLContext#hasBasicFBOSupport()
*/
public static final boolean isFBOAvailable(AbstractGraphicsDevice device, GLProfile glp) {
return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) );
}
+ /**
+ * @return 1
if using a hardware rasterizer, 0
if using a software rasterizer and -1
if not determined yet.
+ * @see GLContext#isHardwareRasterizer()
+ * @see GLProfile#isHardwareRasterizer()
+ */
+ public static final int isHardwareRasterizer(AbstractGraphicsDevice device, GLProfile glp) {
+ final int r;
+ final int ctp = getAvailableContextProperties(device, glp);
+ if(0 == ctp) {
+ r = -1;
+ } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ return r;
+ }
+
/**
* @param device the device to request whether the profile is available for
* @param reqMajor Key Value either 1, 2, 3 or 4
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 9fd895c1f..b6e7b0576 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -48,13 +48,16 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import jogamp.opengl.Debug;
@@ -373,44 +376,63 @@ public abstract class GLDrawableFactory {
// Methods to create high-level objects
/**
- * Returns a GLDrawable according to it's chosen Capabilities,
+ * Returns a GLDrawable according to it's chosen {@link GLCapabilitiesImmutable},
* which determines pixel format, on- and offscreen incl. PBuffer type.
*
- * The native platform's chosen Capabilties are referenced within the target
- * NativeSurface's AbstractGraphicsConfiguration.
- *
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,
- * an onscreen GLDrawable will be realized.
+ * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
+ * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.
+ *
*
- * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,
- * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,
- * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.
+ * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
+ *
*
- *
+ * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ *
+ *
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ *
+ *
+ * If not onscreen and neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ *
+ *
* @throws IllegalArgumentException if the passed target is null
* @throws GLException if any window system-specific errors caused
* the creation of the GLDrawable to fail.
*
+ * @see #canCreateGLPbuffer(AbstractGraphicsDevice)
+ * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile)
+ * @see javax.media.opengl.GLCapabilities#isOnscreen()
+ * @see javax.media.opengl.GLCapabilities#isFBO()
+ * @see javax.media.opengl.GLCapabilities#isPBuffer()
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
public abstract GLDrawable createGLDrawable(NativeSurface target)
throws IllegalArgumentException, GLException;
-
+
/**
- * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * Creates an {@link GLOffscreenAutoDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
*
- * It's {@link AbstractGraphicsConfiguration} is properly set according to the given {@link GLCapabilitiesImmutable}, see below.
+ * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is realized and it's {@link GLContext} assigned but not yet made current.
*
*
- * A FBO drawable is created if both {@link javax.media.opengl.GLCapabilities#isFBO() caps.isFBO()}
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. The latter will set offscreen and also FBO or Pbuffer, whichever is available in that order.
+ *
+ *
+ * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
* and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
*
*
- * A Pbuffer drawable is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
- * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
*
*
- * If neither FBO nor Pbuffer is available, a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated.
*
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be null
for the platform's default device.
@@ -418,17 +440,55 @@ public abstract class GLDrawableFactory {
* @param chooser the custom chooser, may be null for default
* @param width the requested offscreen width
* @param height the requested offscreen height
+ * @return the created and initialized offscreen {@link GLOffscreenAutoDrawable} instance
*
- * @return the created offscreen GLDrawable
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+ */
+ public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) throws GLException;
+ /**
+ * Creates a offscreen {@link GLDrawable} incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ *
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. The latter will set offscreen and also FBO or Pbuffer, whichever is available in that order.
+ *
+ *
+ * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
+ * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
+ *
+ *
+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.
+ *
+ *
+ * If neither FBO nor Pbuffer is available,
+ * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated.
+ *
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be null
for the platform's default device.
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param width the requested offscreen width
+ * @param height the requested offscreen height
+ *
+ * @return the created offscreen {@link GLDrawable}
*
* @throws GLException if any window system-specific errors caused
* the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
*/
public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
- GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesImmutable caps,
GLCapabilitiesChooser chooser,
- int width, int height)
- throws GLException;
+ int width, int height) throws GLException;
/**
* Creates a proxy {@link NativeSurface} w/ defined surface handle, i.e. a {@link WrappedSurface} or {@link GDISurface} instance.
@@ -458,6 +518,21 @@ public abstract class GLDrawableFactory {
long windowHandle,
GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
+ /**
+ * Returns true if it is possible to create an framebuffer object (FBO).
+ *
+ * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
+ *
+ *
+ * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}.
+ *
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
for the platform's default device.
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
/**
* Returns true if it is possible to create a GLPbuffer. Some older
* graphics cards do not have this capability.
@@ -467,7 +542,10 @@ public abstract class GLDrawableFactory {
public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
/**
- * Creates a GLPbuffer with the given capabilites and dimensions.
+ * Creates a GLPbuffer {@link GLAutoDrawable} with the given capabilites and dimensions.
+ *
+ * The GLPbuffer drawable is realized and initialized eagerly.
+ *
*
* See the note in the overview documentation on
* context sharing .
@@ -479,10 +557,12 @@ public abstract class GLDrawableFactory {
* @param initialHeight initial height of pbuffer
* @param shareWith a shared GLContext this GLPbuffer shall use
*
- * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable}
+ * @return the created and initialized {@link GLPbuffer} instance
*
* @throws GLException if any window system-specific errors caused
* the creation of the GLPbuffer to fail.
+ *
+ * @deprecated {@link GLPbuffer} is deprecated, use {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)}
*/
public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device,
GLCapabilitiesImmutable capabilities,
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
new file mode 100644
index 000000000..45fd3b686
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -0,0 +1,173 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+
+/**
+ * Platform-independent {@link GLDrawable} specialization,
+ * exposing {@link FBObject} functionality.
+ *
+ *
+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound
+ * and made current the first time.
+ *
+ *
+ *
+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}.
+ *
+ *
+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}.
+ *
+ *
+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}.
+ * Hence double buffering is always the case w/ MSAA.
+ *
+ *
+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used.
+ * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection
+ * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}.
+ * This method also allows usage of both textures seperately.
+ *
+ *
+ * It would be possible to implement double buffering simply using
+ * {@link FBObject.TextureAttachment texture attachment}s with one {@link FBObject framebuffer}.
+ * This would require mode selection and hence complicate the API. Besides, it would
+ * not support differentiation of read and write framebuffer and hence not be spec compliant.
+ *
+ *
+ * Actual swapping of the {@link FBObject.TextureAttachment texture}s or {@link FBObject framebuffer}
+ * is performed either in the {@link #contextMadeCurrent(boolean) context current hook}
+ * or when {@link #swapBuffersImpl(boolean) swapping buffers}, whatever comes first.
+ *
+ */
+public interface GLFBODrawable extends GLDrawable {
+ // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * @return true
if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise false
.
+ */
+ public boolean isInitialized();
+
+ /**
+ * Notify this instance about upstream size change
+ * to reconfigure the {@link FBObject}.
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @throws GLException if resize operation failed
+ */
+ void resetSize(GL gl) throws GLException;
+
+ /**
+ * @return the used texture unit
+ */
+ int getTextureUnit();
+
+ /**
+ *
+ * @param unit the texture unit to be used
+ */
+ void setTextureUnit(int unit);
+
+ /**
+ * Set a new sample size
+ * @param gl GL context object bound to this drawable, will be made current during operation.
+ * A prev. current context will be make current after operation.
+ * @param newSamples new sample size
+ * @throws GLException if resetting the FBO failed
+ */
+ void setNumSamples(GL gl, int newSamples) throws GLException;
+
+ /**
+ * @return the number of sample buffers if using MSAA, otherwise 0
+ */
+ int getNumSamples();
+
+ /**
+ * @return the used {@link DoubleBufferMode}
+ */
+ // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+ * otherwise an exception is thrown.
+ *
+ * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}.
+ * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}
+ * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored.
+ *
+ *
+ * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect.
+ *
+ * @throws GLException if already initialized, see {@link #isInitialized()}.
+ */
+ // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * If MSAA is being used and {@link GL#GL_FRONT} is requested,
+ * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned.
+ *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link FBObject}
+ * @throws IllegalArgumentException if an illegal buffer name is being used
+ */
+ FBObject getFBObject(int bufferName) throws IllegalArgumentException;
+
+ /**
+ * Returns the named texture buffer.
+ *
+ * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible
+ * and an exception is being thrown if {@link GL#GL_BACK} is being requested.
+ *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names
+ * @return the named {@link TextureAttachment}
+ * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used
+ */
+ FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException;
+
+ /** Resizeable {@link GLFBODrawable} specialization */
+ public interface Resizeable extends GLFBODrawable {
+ /**
+ * Resize this drawable.
+ *
+ * This drawable is being locked during operation.
+ *
+ * @param context the {@link GLContext} bound to this drawable, will be made current during operation
+ * A prev. current context will be make current after operation.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case an error during the resize operation occurred
+ */
+ void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException;
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
new file mode 100644
index 000000000..6fe76a3f4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLOffscreenAutoDrawable.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package javax.media.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.opengl.FBObject;
+
+/**
+ * Platform-independent {@link GLAutoDrawable} specialization,
+ * exposing offscreen functionality.
+ *
+ * This class distinguishes itself from {@link GLAutoDrawable}
+ * with it's {@link #setSize(int, int)} functionality.
+ *
+ */
+public interface GLOffscreenAutoDrawable extends GLAutoDrawable {
+
+ /**
+ * Resize this auto drawable.
+ * @param newWidth
+ * @param newHeight
+ * @throws NativeWindowException in case the surface could no be locked
+ * @throws GLException in case of an error during the resize operation
+ */
+ void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException;
+
+ /**
+ * Set the upstream UI toolkit object.
+ * @see #getUpstreamWidget()
+ */
+ void setUpstreamWidget(Object newUpstreamWidget);
+
+ /** {@link FBObject} based {@link GLOffscreenAutoDrawable} specialization */
+ public interface FBO extends GLOffscreenAutoDrawable, GLFBODrawable {
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
index 273a992cf..de7731a3b 100644
--- a/src/jogl/classes/javax/media/opengl/GLPbuffer.java
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -45,7 +45,11 @@ package javax.media.opengl;
contains experimental methods for accessing the pbuffer's contents
as a texture map and enabling rendering to floating-point frame
buffers. These methods are not guaranteed to be supported on all
- platforms and may be deprecated in a future release. */
+ platforms and may be deprecated in a future release.
+
+ @deprecated Use {@link GLOffscreenAutoDrawable} w/ {@link GLCapabilities#setFBO(boolean)}
+ via {@link GLDrawableFactory#createOffscreenAutoDrawable(javax.media.nativewindow.AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext) GLDrawableFactory.createOffscreenAutoDrawable(..)}.
+ */
public interface GLPbuffer extends GLAutoDrawable {
/** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 033591fe3..329cf9e3f 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -98,6 +98,7 @@ import jogamp.common.awt.AWTEDTExecutor;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on our
@@ -109,6 +110,16 @@ import jogamp.opengl.GLDrawableHelper;
interfaces when adding a heavyweight doesn't work either because
of Z-ordering or LayoutManager problems.
*
+ *
+ *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * maybe called to use an offscreen drawable (FBO or PBuffer) allowing
+ * the underlying JAWT mechanism to composite the image, if supported.
+ *
+ * {@link OffscreenLayerOption#setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * is being called if {@link GLCapabilitiesImmutable#isOnscreen()} is false
.
+ *
+ *
*
*
* To avoid any conflicts with a potential Java2D OpenGL context,
@@ -145,7 +156,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private final RecursiveLock lock = LockFactory.createRecursiveLock();
private final GLDrawableHelper helper = new GLDrawableHelper();
private AWTGraphicsConfiguration awtConfig;
- private volatile GLDrawable drawable; // volatile: avoid locking for read-only access
+ private volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
private volatile JAWTWindow jawtWindow; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private GLContextImpl context;
private volatile boolean sendReshape = false; // volatile: maybe written by EDT w/o locking
@@ -237,6 +248,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// don't allow the user to change data
capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
}
+ if(!capsReqUser.isOnscreen()) {
+ setShallUseOffscreenLayer(true); // trigger offscreen layer - if supported
+ }
if(null==device) {
GraphicsConfiguration gc = super.getGraphicsConfiguration();
@@ -451,11 +465,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
/** Overridden to cause OpenGL rendering to be performed during
repaint cycles. Subclasses which override this method must call
super.paint() in their paint() method in order to function
- properly.
-
- Overrides:
-
paint
in class java.awt.Component
*/
- @Override
+ properly.
+ */
+ @Override
public void paint(Graphics g) {
if (Beans.isDesignTime()) {
// Make GLCanvas behave better in NetBeans GUI builder
@@ -544,7 +556,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
jawtWindow.lockSurface();
try {
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ drawable = (GLDrawableImpl) GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
context = (GLContextImpl) drawable.createContext(shareWith);
context.setContextCreationFlags(additionalCtxCreationFlags);
} finally {
@@ -561,13 +573,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if (!Beans.isDesignTime() &&
0 < _drawable.getWidth() * _drawable.getHeight() ) {
// make sure drawable realization happens on AWT EDT, due to AWTTree lock
- AWTEDTExecutor.singleton.invoke(true, setRealizedOnEDTAction);
- sendReshape=true; // ensure a reshape is being send ..
- if(DEBUG) {
- System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
- Thread.dumpStack();
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, setRealizedOnEDTAction);
+ if( _drawable.isRealized() ) {
+ sendReshape=true; // ensure a reshape is being send ..
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Realized Drawable: "+_drawable.toString());
+ Thread.dumpStack();
+ }
+ return true;
}
- return true;
}
}
return false;
@@ -575,7 +589,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private Runnable setRealizedOnEDTAction = new Runnable() {
@Override
public void run() {
- drawable.setRealized(true);
+ final GLDrawable _drawable = drawable;
+ if ( null != _drawable && 0 < _drawable.getWidth() * _drawable.getHeight() ) {
+ _drawable.setRealized(true);
+ }
} };
/** Overridden to track when this component is removed from a
@@ -620,22 +637,37 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
- super.reshape(x, y, width, height);
- final GLDrawable _drawable = drawable;
- if(null != _drawable && _drawable.isRealized() && !_drawable.getChosenGLCapabilities().isOnscreen()) {
- dispose(true);
- } else {
- sendReshape = true;
+ synchronized (getTreeLock()) { // super.reshape(..) claims tree lock, so we do extend it's lock over reshape
+ super.reshape(x, y, width, height);
+
+ GLDrawableImpl _drawable = drawable;
+ if( null != _drawable ) {
+ if(DEBUG) {
+ System.err.println("GLCanvas.sizeChanged: ("+Thread.currentThread().getName()+"): "+width+"x"+height+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = lock;
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, width, height);
+ if(_drawable != _drawableNew) {
+ // write back
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
+ }
+ sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
+ }
}
}
- /** Overrides:
-
update
in class java.awt.Component
*/
/**
* Overridden from Canvas to prevent the AWT's clearing of the
* canvas from interfering with the OpenGL rendering.
*/
- @Override
+ @Override
public void update(Graphics g) {
paint(g);
}
@@ -681,7 +713,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
_lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -692,6 +724,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
@Override
public GLContext getContext() {
return context;
@@ -866,7 +903,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
if(!disposeRegenerate) {
if(null != awtConfig) {
- disposeAbstractGraphicsDevice();
+ AWTEDTExecutor.singleton.invoke(getTreeLock(), true, disposeAbstractGraphicsDeviceActionOnEDT);
}
awtConfig=null;
}
@@ -881,7 +918,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
};
- private final Runnable disposeAbstractGraphicsDeviceAction = new Runnable() {
+ /**
+ * Disposes the AbstractGraphicsDevice within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+ */
+ private final Runnable disposeAbstractGraphicsDeviceActionOnEDT = new Runnable() {
@Override
public void run() {
if(null != awtConfig) {
@@ -900,27 +943,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
};
-
- /**
- * Disposes the AbstractGraphicsDevice within EDT,
- * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
- *
- * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
- */
- private void disposeAbstractGraphicsDevice() {
- if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
- disposeAbstractGraphicsDeviceAction.run();
- } else {
- try {
- EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
- } catch (InvocationTargetException e) {
- throw new GLException(e.getTargetException());
- } catch (InterruptedException e) {
- throw new GLException(e);
- }
- }
- }
-
+
private final Runnable initAction = new Runnable() {
@Override
public void run() {
@@ -1046,7 +1069,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* @param device
* @return the chosen AWTGraphicsConfiguration
*
- * @see #disposeAbstractGraphicsDevice()
+ * @see #disposeAbstractGraphicsDeviceActionOnEDT
*/
private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
final GLCapabilitiesImmutable capsRequested,
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index acb8f2183..6d4a5861f 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -121,7 +121,7 @@ import com.jogamp.opengl.util.GLBuffers;
*
*/
-@SuppressWarnings("serial")
+@SuppressWarnings({ "serial", "deprecation" })
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
@@ -396,7 +396,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
their reshape() method in order to function properly.
reshape
in class java.awt.Component
*/
- @SuppressWarnings("deprecation")
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
@@ -471,7 +470,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return null;
}
final GLContext oldCtx = backend.getContext();
- final boolean newCtxCurrent = helper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags);
backend.setContext(newCtx);
if(newCtxCurrent) {
newCtx.makeCurrent();
@@ -480,6 +479,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ if (backend == null) {
+ return null;
+ }
+ return backend.getDrawable();
+ }
+
@Override
public GLContext getContext() {
if (backend == null) {
diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
index cc4e1b434..07029f143 100644
--- a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
+++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java
@@ -30,16 +30,15 @@ package jogamp.opengl;
import java.io.PrintStream;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
import javax.media.opengl.FPSCounter;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLAutoDrawableDelegate;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -49,6 +48,7 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.util.Animator;
@@ -61,38 +61,36 @@ import com.jogamp.opengl.util.Animator;
* @see GLWindow
*/
public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
- public static final boolean DEBUG = Debug.debug("GLAutoDrawable");
+ public static final boolean DEBUG = GLDrawableImpl.DEBUG;
protected final GLDrawableHelper helper = new GLDrawableHelper();
protected final FPSCounterImpl fpsCounter = new FPSCounterImpl();
protected volatile GLDrawableImpl drawable; // volatile: avoid locking for read-only access
protected GLContextImpl context;
- protected final boolean ownDevice;
+ protected final boolean ownsDevice;
protected int additionalCtxCreationFlags = 0;
protected volatile boolean sendReshape = false; // volatile: maybe written by WindowManager thread w/o locking
protected volatile boolean sendDestroy = false; // volatile: maybe written by WindowManager thread w/o locking
/**
- * @param drawable a valid {@link GLDrawableImpl}, may not be realized yet.
- * @param context a valid {@link GLContextImpl}, may not be made current (created) yet.
- * @param ownDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
- * otherwise pass false
. Closing the device is required in case
- * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
- * and no further lifecycle handling is applied.
+ * @param drawable upstream {@link GLDrawableImpl} instance, may be null for lazy initialization
+ * @param context upstream {@link GLContextImpl} instance, may be null for lazy initialization
+ * @param ownsDevice pass true
if {@link AbstractGraphicsDevice#close()} shall be issued,
+ * otherwise pass false
. Closing the device is required in case
+ * the drawable is created w/ it's own new instance, e.g. offscreen drawables,
+ * and no further lifecycle handling is applied.
*/
- public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownDevice) {
+ public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context, boolean ownsDevice) {
this.drawable = drawable;
this.context = context;
- this.ownDevice = ownDevice;
+ this.ownsDevice = ownsDevice;
resetFPSCounter();
}
+ /** Returns the recursive lock object of the upstream implementation, which synchronizes multithreaded access. */
protected abstract RecursiveLock getLock();
- /** Returns the delegated GLDrawable */
- public final GLDrawable getDelegatedDrawable() { return drawable; }
-
/** Default implementation to handle repaint events from the windowing system */
protected final void defaultWindowRepaintOp() {
final GLDrawable _drawable = drawable;
@@ -103,29 +101,43 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
}
- /** Default implementation to handle resize events from the windowing system */
- protected final void defaultWindowResizedOp() {
- final GLDrawable _drawable = drawable;
+ /** Default implementation to handle resize events from the windowing system. All required locks are being claimed. */
+ protected final void defaultWindowResizedOp(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ GLDrawableImpl _drawable = drawable;
if( null!=_drawable ) {
if(DEBUG) {
- System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ if( ! _drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final RecursiveLock _lock = getLock();
+ _lock.lock();
+ try {
+ final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, context, newWidth, newHeight);
+ if(_drawable != _drawableNew) {
+ // write back
+ _drawable = _drawableNew;
+ drawable = _drawableNew;
+ }
+ } finally {
+ _lock.unlock();
+ }
}
sendReshape = true; // async if display() doesn't get called below, but avoiding deadlock
if( _drawable.isRealized() ) {
if( !_drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) {
display();
}
- }
+ }
}
}
-
+
/**
* Default implementation to handle destroy notifications from the windowing system.
*
*
* If the {@link NativeSurface} does not implement {@link WindowClosingProtocol}
* or {@link WindowClosingMode#DISPOSE_ON_CLOSE} is enabled (default),
- * {@link #defaultDestroy()} is being called.
+ * a thread safe destruction is being induced.
*
*/
protected final void defaultWindowDestroyNotifyOp() {
@@ -174,7 +186,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
ctrl.resume();
}
} else if (null != ns && ns.isSurfaceLockedByOtherThread()) {
- // surface is locked by another thread
+ // Surface is locked by another thread.
// Flag that destroy should be performed on the next
// attempt to display.
sendDestroy = true; // async, but avoiding deadlock
@@ -225,7 +237,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
}
_drawable.setRealized(false);
}
- if( ownDevice ) {
+ if( ownsDevice ) {
_drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice().close();
}
}
@@ -238,7 +250,6 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
_lock.lock();
try {
if(drawable!=null && context != null) {
- drawable.swapBuffers();
helper.invokeGL(drawable, context, defaultSwapAction, defaultInitAction);
}
} finally {
@@ -276,7 +287,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
destroy();
return;
}
- final RecursiveLock _lock = getLock();
+ final RecursiveLock _lock = getLock();
_lock.lock();
try {
if( null != context ) {
@@ -294,6 +305,11 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
drawable.swapBuffers();
} } ;
+ @Override
+ public final GLDrawable getDelegatedDrawable() {
+ return drawable;
+ }
+
@Override
public final GLContext getContext() {
return context;
@@ -305,7 +321,7 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
lock.lock();
try {
final GLContext oldCtx = context;
- final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
+ final boolean newCtxCurrent = GLDrawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags);
context=(GLContextImpl)newCtx;
if(newCtxCurrent) {
context.makeCurrent();
@@ -529,4 +545,10 @@ public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter {
final GLDrawable _drawable = drawable;
return null != _drawable ? _drawable.getHandle() : 0;
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + /** ", \n\tWindow: "+window+ ", \n\tFactory: "+factory+ */ "]";
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index e82756022..050c619fd 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -47,6 +47,7 @@ import java.util.Map;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLNameResolver;
@@ -85,6 +86,7 @@ public abstract class GLContextImpl extends GLContext {
private String glRenderer;
private String glRendererLowerCase;
+ private String glVersion;
// Tracks creation and initialization of buffer objects to avoid
// repeated glGet calls upon glMapBuffer operations
@@ -126,6 +128,9 @@ public abstract class GLContextImpl extends GLContext {
GLContextShareSet.synchronizeBufferObjectSharing(shareWith, this);
this.drawable = drawable;
+ if(null != drawable) {
+ drawable.associateContext(this, true);
+ }
this.drawableRead = drawable;
this.glDebugHandler = new GLDebugMessageHandler(this);
@@ -205,8 +210,10 @@ public abstract class GLContextImpl extends GLContext {
if(!setWriteOnly || drawableRead==drawable) { // if !setWriteOnly || !explicitReadDrawable
drawableRead = (GLDrawableImpl) readWrite;
}
- final GLDrawable old = drawable;
+ final GLDrawableImpl old = drawable;
+ old.associateContext(this, false);
drawable = (GLDrawableImpl) readWrite ;
+ drawable.associateContext(this, true);
if(lockHeld) {
makeCurrent();
}
@@ -272,7 +279,7 @@ public abstract class GLContextImpl extends GLContext {
if( actualRelease ) {
if( !inDestruction ) {
try {
- drawable.contextMadeCurrent(this, false);
+ contextMadeCurrent(false);
} catch (Throwable t) {
drawableContextMadeCurrentException = t;
}
@@ -331,7 +338,8 @@ public abstract class GLContextImpl extends GLContext {
makeCurrent();
}
try {
- drawable.contextRealized(this, false);
+ contextRealized(false);
+ drawable.associateContext(this, false);
} catch (Throwable t) {
drawableContextRealizedException = t;
}
@@ -514,19 +522,17 @@ public abstract class GLContextImpl extends GLContext {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
}
- drawable.contextRealized(this, true);
+ contextRealized(true);
if(DEBUG || TRACE_SWITCH) {
System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT_NEW - "+lock);
}
- } else {
- drawable.contextMadeCurrent(this, true);
-
- if(TRACE_SWITCH) {
- System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
- }
+ } else if(TRACE_SWITCH) {
+ System.err.println(getThreadName() +": GLContext.ContextSwitch: obj " + toHexString(hashCode()) + ", ctx "+toHexString(contextHandle)+" - switch - CONTEXT_CURRENT - "+lock);
}
+ contextMadeCurrent(true);
+
/* FIXME: refactor dependence on Java 2D / JOGL bridge
// Try cleaning up any stale server-side OpenGL objects
@@ -608,6 +614,20 @@ public abstract class GLContextImpl extends GLContext {
}
protected abstract void makeCurrentImpl() throws GLException;
+ /**
+ * @see GLDrawableImpl#contextRealized(GLContext, boolean)
+ */
+ protected void contextRealized(boolean realized) {
+ drawable.contextRealized(this, realized);
+ }
+
+ /**
+ * @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
+ */
+ protected void contextMadeCurrent(boolean current) {
+ drawable.contextMadeCurrent(this, current);
+ }
+
/**
* Platform dependent entry point for context creation.
*
@@ -934,52 +954,43 @@ public abstract class GLContextImpl extends GLContext {
/**
* If major > 0 || minor > 0 : Use passed values, determined at creation time
- * If major==0 && minor == 0 : Use GL_VERSION
* Otherwise .. don't touch ..
*/
private final void setContextVersion(int major, int minor, int ctp, boolean setVersionString) {
- if (0==ctp) {
+ if ( 0 == ctp ) {
throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
- if(major>0 || minor>0) {
- if (!GLContext.isValidGLVersion(major, minor)) {
- GLException e = new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
- throw e;
- }
- ctxMajorVersion = major;
- ctxMinorVersion = minor;
- ctxOptions = ctp;
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
- }
- return;
+
+ if (!GLContext.isValidGLVersion(major, minor)) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctp));
}
-
- if(major==0 && minor==0) {
- String versionStr = getGL().glGetString(GL.GL_VERSION);
- if(null==versionStr) {
- throw new GLException("GL_VERSION is NULL: "+this);
- }
- ctxOptions = ctp;
-
- // Set version
- GLVersionNumber version = new GLVersionNumber(versionStr);
+ ctxMajorVersion = major;
+ ctxMinorVersion = minor;
+ ctxOptions = ctp;
+ if(setVersionString) {
+ ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, getGL().glGetString(GL.GL_VERSION));
+ }
+ }
+
+ private static final VersionNumber getGLVersionNumber(int ctp, String glVersionStr) {
+ if( null != glVersionStr ) {
+ final GLVersionNumber version = new GLVersionNumber(glVersionStr);
if (version.isValid()) {
- ctxMajorVersion = version.getMajor();
- ctxMinorVersion = version.getMinor();
- // We cannot promote a non ARB context to >= 3.1,
- // reduce it to 3.0 then.
- if ( ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
- && 0 == (ctxOptions & CTX_IS_ARB_CREATED) ) {
- ctxMajorVersion = 3;
- ctxMinorVersion = 0;
- }
- if(setVersionString) {
- ctxVersionString = getGLVersion(ctxMajorVersion, ctxMinorVersion, ctxOptions, versionStr);
- }
- return;
+ int major = version.getMajor();
+ int minor = version.getMinor();
+ // We cannot promote a non ARB context to >= 3.1,
+ // reduce it to 3.0 then.
+ if ( 0 == (ctp & CTX_IS_ARB_CREATED) &&
+ ( major > 3 || major == 3 && minor >= 1 ) ) {
+ major = 3;
+ minor = 0;
+ }
+ if ( GLContext.isValidGLVersion(major, minor) ) {
+ return new VersionNumber(major, minor, 0);
+ }
}
}
+ return null;
}
//----------------------------------------------------------------------
@@ -1019,14 +1030,18 @@ public abstract class GLContextImpl extends GLContext {
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, binds this pbuffer to its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void bindPbufferToTexture();
+ public void bindPbufferToTexture() { throw new GLException("not implemented"); }
/**
* Pbuffer support; given that this is a GLContext associated with a
* pbuffer, releases this pbuffer from its texture target.
+ * @throws GLException if not implemented (default)
+ * @deprecated use FBO/GLOffscreenAutoDrawable instead of pbuffer
*/
- public abstract void releasePbufferFromTexture();
+ public void releasePbufferFromTexture() { throw new GLException("not implemented"); }
public abstract ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
@@ -1064,7 +1079,7 @@ public abstract class GLContextImpl extends GLContext {
table.reset(getDrawableImpl().getGLDynamicLookupHelper() );
}
- private final boolean initGLRendererStrings() {
+ private final boolean initGLRendererAndGLVersionStrings() {
final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
if(0 == _glGetString) {
@@ -1083,14 +1098,27 @@ public abstract class GLContextImpl extends GLContext {
Thread.dumpStack();
}
return false;
- } else {
- glRenderer = _glRenderer;
- glRendererLowerCase = glRenderer.toLowerCase();
- return true;
}
+ glRenderer = _glRenderer;
+ glRendererLowerCase = glRenderer.toLowerCase();
+
+ final String _glVersion = glGetStringInt(GL.GL_VERSION, _glGetString);
+ if(null == _glVersion) {
+ // FIXME
+ if(DEBUG) {
+ System.err.println("Warning: GL_VERSION is NULL.");
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ glVersion = _glVersion;
+ return true;
}
}
+ protected final String getGLVersionString() {
+ return glVersion;
+ }
protected final String getGLRendererString(boolean lowerCase) {
return lowerCase ? glRendererLowerCase : glRenderer;
}
@@ -1128,17 +1156,44 @@ public abstract class GLContextImpl extends GLContext {
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- if( !initGLRendererStrings() && DEBUG) {
- System.err.println("Warning: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ {
+ final boolean initGLRendererAndGLVersionStringsOK = initGLRendererAndGLVersionStrings();
+ if(DEBUG) {
+ if( !initGLRendererAndGLVersionStringsOK ) {
+ System.err.println("Warning: setGLFunctionAvailability: intialization of GL renderer strings failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ } else {
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail: Given "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion));
+ }
+ }
}
if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
-
+
+ // Pick the version from the GL-version string,
+ // if smaller _or_ given major == 0.
+ final VersionNumber glVersionNumber;
+ {
+ final VersionNumber setGLVersionNumber = new VersionNumber(major, minor, 0);
+ final VersionNumber strGLVersionNumber = getGLVersionNumber(ctxProfileBits, glVersion);
+ if( null != strGLVersionNumber && ( strGLVersionNumber.compareTo(setGLVersionNumber) <= 0 || 0 == major ) ) {
+ glVersionNumber = strGLVersionNumber;
+ major = glVersionNumber.getMajor();
+ minor = glVersionNumber.getMinor();
+ } else {
+ glVersionNumber = setGLVersionNumber;
+ }
+ }
+ if ( !GLContext.isValidGLVersion(major, minor) ) {
+ throw new GLException("Invalid GL Version "+major+"."+minor+", ctp "+toHexString(ctxProfileBits)+", "+glVersion+", "+glVersionNumber);
+ }
+ if( 2 > major ) { // there is no ES2-compat for a profile w/ major < 2
+ ctxProfileBits &= ~GLContext.CTX_IMPL_ES2_COMPAT;
+ }
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
- System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
+ System.err.println(getThreadName() + ": GLContext.setGLFuncAvail.0 validated FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, glVersion) + ", "+glVersionNumber);
}
//
@@ -1201,6 +1256,10 @@ public abstract class GLContextImpl extends GLContext {
ctxProfileBits |= CTX_IMPL_FBO;
}
+ if(FORCE_NO_FBO_SUPPORT) {
+ ctxProfileBits &= ~CTX_IMPL_FBO ;
+ }
+
//
// Set GL Version (complete w/ version string)
//
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index e1e253d35..4f965f620 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -48,18 +48,21 @@ import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.MutableSurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.opengl.GLCapabilities;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
+import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.DelegatedUpstreamSurfaceHookWithSurfaceSize;
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
/** Extends GLDrawableFactory with a few methods for handling
@@ -67,6 +70,7 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
Independent Bitmaps on Windows, pixmaps on X11). Direct access to
these GLDrawables is not supplied directly to end users, though
they may be instantiated by the GLJPanel implementation. */
+@SuppressWarnings("deprecation")
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
@@ -141,55 +145,53 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
if(null != ols) {
// layered surface -> Offscreen/[FBO|PBuffer]
- final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
- chosenCapsMod.setOnscreen(false);
- chosenCapsMod.setDoubleBuffered(false);
- /* if( isFBOAvailable ) { // FIXME JAU: FBO n/a yet
- chosenCapsMod.setFBO(true);
- } else */
- if( canCreateGLPbuffer(adevice) ) {
- chosenCapsMod.setPBuffer(true);
- } else {
- chosenCapsMod.setFBO(false);
- chosenCapsMod.setPBuffer(false);
+ final boolean isPbufferAvailable = canCreateGLPbuffer(adevice) ;
+ if(!isPbufferAvailable && !isFBOAvailable) {
+ throw new GLException("Neither FBO nor Pbuffer is available for "+target);
}
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, isFBOAvailable, isPbufferAvailable);
config.setChosenCapabilities(chosenCapsMod);
+ ols.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer");
+ System.err.println("chosenCaps: "+chosenCaps);
+ System.err.println("chosenCapsMod: "+chosenCapsMod);
+ System.err.println("OffscreenLayerSurface: **** "+ols);
+ System.err.println("Target: **** "+target);
+ Thread.dumpStack();
}
if( ! ( target instanceof MutableSurface ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
}
- if( ((GLCapabilitiesImmutable)config.getRequestedCapabilities()).isFBO() && isFBOAvailable ) {
- // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
- final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
- result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ if( chosenCapsMod.isFBO() && isFBOAvailable ) {
+ // target surface is already a native one
+ result = createFBODrawableImpl(target, chosenCapsMod, 0);
} else {
result = createOffscreenDrawableImpl(target);
}
} else if(chosenCaps.isOnscreen()) {
// onscreen
+ final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ config.setChosenCapabilities(chosenCapsMod);
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
}
result = createOnscreenDrawableImpl(target);
} else {
// offscreen
- final GLCapabilitiesImmutable reqCaps = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO req / chosen - avail, PBuffer: "+reqCaps.isFBO()+" / "+chosenCaps.isFBO()+" - "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable, FBO chosen / avail, PBuffer: "+
+ chosenCaps.isFBO()+" / "+isFBOAvailable+", "+chosenCaps.isPBuffer()+": "+target);
}
if( ! ( target instanceof MutableSurface ) ) {
- throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
+ throw new IllegalArgumentException("Passed NativeSurface must implement MutableSurface for offscreen: "+target);
}
- if( reqCaps.isFBO() && isFBOAvailable ) {
- // FIXME JAU: Need to revise passed MutableSurface to work w/ FBO ..
- final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(target);
- result = new GLFBODrawableImpl(this, dummyDrawable, target, target.getWidth(), target.getHeight(), 0 /* textureUnit */);
+ if( chosenCaps.isFBO() && isFBOAvailable ) {
+ // need to hook-up a native dummy surface since source may not have
+ final ProxySurface dummySurface = createDummySurfaceImpl(adevice, true, chosenCaps, null, 64, 64);
+ dummySurface.setUpstreamSurfaceHook(new DelegatedUpstreamSurfaceHookWithSurfaceSize(dummySurface.getUpstreamSurfaceHook(), target));
+ result = createFBODrawableImpl(dummySurface, chosenCaps, 0);
} else {
- final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
- chosenCapsMod.setDoubleBuffered(false);
- config.setChosenCapabilities(chosenCapsMod);
result = createOffscreenDrawableImpl(target);
}
}
@@ -211,7 +213,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//---------------------------------------------------------------------------
//
- // PBuffer Offscreen GLDrawable construction
+ // PBuffer Offscreen GLAutoDrawable construction
//
@Override
@@ -239,7 +241,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLDrawableImpl drawable = null;
device.lock();
try {
- drawable = (GLDrawableImpl) createGLDrawable( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ drawable = createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
if(null != drawable) {
drawable.setRealized(true);
}
@@ -247,10 +250,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.unlock();
}
- if(null==drawable) {
- throw new GLException("Could not create Pbuffer drawable for: "+device+", "+capsChosen+", "+width+"x"+height);
- }
- return new GLPbufferImpl( drawable, shareWith, true);
+ return new GLPbufferImpl( drawable, (GLContextImpl) drawable.createContext(shareWith) );
}
//---------------------------------------------------------------------------
@@ -258,6 +258,29 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// Offscreen GLDrawable construction
//
+ public final boolean canCreateFBO(AbstractGraphicsDevice deviceReq, GLProfile glp) {
+ AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
+ if(null == device) {
+ throw new GLException("No shared device for requested: "+deviceReq);
+ }
+ return GLContext.isFBOAvailable(device, glp);
+ }
+
+ @Override
+ public GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice deviceReq,
+ GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser,
+ int width, int height,
+ GLContext shareWith) {
+ final GLDrawable drawable = createOffscreenDrawable( deviceReq, capsRequested, chooser, width, height );
+ drawable.setRealized(true);
+ final GLContext context = drawable.createContext(shareWith);
+ if(drawable instanceof GLFBODrawableImpl) {
+ return new GLOffscreenAutoDrawableImpl.FBOImpl( (GLFBODrawableImpl)drawable, context, null, null );
+ }
+ return new GLOffscreenAutoDrawableImpl( drawable, context, null, null);
+ }
+
@Override
public GLDrawable createOffscreenDrawable(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsRequested,
@@ -274,10 +297,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
final GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(capsRequested,
GLContext.isFBOAvailable(device, capsRequested.getGLProfile()),
canCreateGLPbuffer(device));
+
if( capsChosen.isFBO() ) {
device.lock();
try {
- return createFBODrawableImpl(device, capsRequested, chooser, width, height);
+ final ProxySurface dummySurface = createDummySurfaceImpl(device, true, capsRequested, null, width, height);
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
+ return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, dummySurface, capsChosen, 0);
} finally {
device.unlock();
}
@@ -285,20 +311,17 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.lock();
try {
- return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser, width, height, null) );
+ return createOffscreenDrawableImpl( createMutableSurfaceImpl(device, true, capsChosen, capsRequested, chooser,
+ new UpstreamSurfaceHookMutableSize(width, height) ) );
} finally {
device.unlock();
}
}
- /** Creates a platform independent offscreen FBO GLDrawable implementation */
- protected GLDrawable createFBODrawableImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
- int initialWidth, int initialHeight) {
- final GLCapabilitiesImmutable dummyCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(requestedCaps);
- final NativeSurface dummySurface = createDummySurfaceImpl(device, true, dummyCaps, null, 64, 64);
+ /** Creates a platform independent FBO offscreen GLDrawable */
+ protected GLFBODrawable createFBODrawableImpl(NativeSurface dummySurface, GLCapabilitiesImmutable fboCaps, int textureUnit) {
final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(dummySurface);
-
- return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, initialWidth, initialHeight, 0 /* textureUnit */);
+ return new GLFBODrawableImpl(this, dummyDrawable, dummySurface, fboCaps, textureUnit);
}
/** Creates a platform dependent offscreen pbuffer/pixmap GLDrawable implementation */
@@ -318,15 +341,13 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param capsChosen
* @param capsRequested
* @param chooser the custom chooser, may be null for default
- * @param width the initial width
- * @param height the initial height
- * @param lifecycleHook optional control of the surface's lifecycle
+ * @param upstreamHook surface size information and optional control of the surface's lifecycle
* @return the created {@link MutableSurface} instance w/o defined surface handle
*/
protected abstract ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook);
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook);
/**
* A dummy surface is not visible on screen and will not be used to render directly to,
@@ -341,9 +362,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* @param width the initial width
* @param height the initial height
*
- * @return the created {@link MutableSurface} instance w/o defined surface handle
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
- public NativeSurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
+ public ProxySurface createDummySurface(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser,
int width, int height) {
final AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
@@ -369,9 +390,11 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* otherwise device
instance is used as-is.
* @param requestedCaps
* @param chooser the custom chooser, may be null for default
- * @param width the initial width
- * @param height the initial height
- * @return the created {@link MutableSurface} instance w/o defined surface handle
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()}, not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()}, not the actual dummy surface height,
+ * The latter is platform specific and small
+ * @return the created {@link ProxySurface} instance w/o defined surface handle but platform specific {@link UpstreamSurfaceHook}.
*/
public abstract ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice device, boolean createNewDevice,
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height);
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 090c5fe69..bdf0b6d74 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -43,12 +43,19 @@ package jogamp.opengl;
import java.util.ArrayList;
import java.util.HashSet;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import javax.media.opengl.GLRunnable;
import com.jogamp.opengl.util.Animator;
@@ -108,24 +115,27 @@ public class GLDrawableHelper {
/**
* Associate a new context to the drawable and also propagates the context/drawable switch by
* calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}.
- *
- * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable
- * is being cleared by calling
- * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}.
- *
*
* If the old or new context was current on this thread, it is being released before switching the drawable.
*
+ *
+ * Be aware that the old context is still bound to the drawable,
+ * and that one context can only bound to one drawable at one time!
+ *
+ *
+ * No locking is being performed on the drawable, caller is required to take care of it.
+ *
*
* @param drawable the drawable which context is changed
- * @param newCtx the new context
* @param oldCtx the old context
- * @return true if the newt context was current, otherwise false
+ * @param newCtx the new context
+ * @param newCtxCreationFlags additional creation flags if newCtx is not null and not been created yet, see {@link GLContext#setContextCreationFlags(int)}
+ * @return true if the new context was current, otherwise false
*
* @see GLAutoDrawable#setContext(GLContext)
*/
- public final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int additionalCtxCreationFlags) {
- if(null != oldCtx && oldCtx.isCurrent()) {
+ public static final boolean switchContext(GLDrawable drawable, GLContext oldCtx, GLContext newCtx, int newCtxCreationFlags) {
+ if( null != oldCtx && oldCtx.isCurrent() ) {
oldCtx.release();
}
final boolean newCtxCurrent;
@@ -134,17 +144,135 @@ public class GLDrawableHelper {
if(newCtxCurrent) {
newCtx.release();
}
- newCtx.setContextCreationFlags(additionalCtxCreationFlags);
+ newCtx.setContextCreationFlags(newCtxCreationFlags);
newCtx.setGLDrawable(drawable, true); // propagate context/drawable switch
} else {
newCtxCurrent = false;
}
- if(null!=oldCtx && oldCtx.getGLDrawable() instanceof GLAutoDrawable) {
- ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null);
- }
return newCtxCurrent;
}
+ /**
+ * If the drawable is not realized, OP is a NOP.
+ *
+ * release context if current
+ * destroy old drawable
+ * create new drawable
+ * attach new drawable to context
+ * make context current, if it was current
+ *
+ *
+ * No locking is being performed, caller is required to take care of it.
+ *
+ *
+ * @param drawable
+ * @param context maybe null
+ * @return the new drawable
+ */
+ public static final GLDrawableImpl recreateGLDrawable(GLDrawableImpl drawable, GLContext context) {
+ if( ! drawable.isRealized() ) {
+ return drawable;
+ }
+ final boolean contextCurrent = null != context && context.isCurrent();
+ final GLDrawableFactory factory = drawable.getFactory();
+ final NativeSurface surface = drawable.getNativeSurface();
+ final ProxySurface proxySurface = (surface instanceof ProxySurface) ? (ProxySurface)surface : null;
+
+ if(contextCurrent) {
+ context.release();
+ }
+
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(false);
+ }
+ try {
+ drawable.setRealized(false);
+ drawable = (GLDrawableImpl) factory.createGLDrawable(surface); // [2]
+ drawable.setRealized(true);
+ } finally {
+ if(null != proxySurface) {
+ proxySurface.enableUpstreamSurfaceHookLifecycle(true);
+ }
+ }
+
+ if(null != context) {
+ context.setGLDrawable(drawable, true); // re-association
+ }
+
+ if(contextCurrent) {
+ context.makeCurrent();
+ }
+ return drawable;
+ }
+
+ /**
+ * Performs resize operation on the given drawable, assuming it is offscreen.
+ *
+ * The {@link GLDrawableImpl}'s {@link NativeSurface} is being locked during operation.
+ * In case the holder is an auto drawable or similar, it's lock shall be claimed by the caller.
+ *
+ *
+ * May recreate the drawable via {@link #recreateGLDrawable(GLDrawableImpl, GLContext)}
+ * in case of a a pbuffer- or pixmap-drawable.
+ *
+ *
+ * FBO drawables are resized w/o drawable destruction.
+ *
+ *
+ * Offscreen resize operation is validated w/ drawable size in the end.
+ * An exception is thrown if not successful.
+ *
+ *
+ * @param drawable
+ * @param context
+ * @param newWidth the new width, it's minimum is capped to 1
+ * @param newHeight the new height, it's minimum is capped to 1
+ * @return the new drawable in case of an pbuffer/pixmap drawable, otherwise the passed drawable is being returned.
+ * @throws NativeWindowException is drawable is not offscreen or it's surface lock couldn't be claimed
+ * @throws GLException may be thrown a resize operation
+ */
+ public static final GLDrawableImpl resizeOffscreenDrawable(GLDrawableImpl drawable, GLContext context, int newWidth, int newHeight)
+ throws NativeWindowException, GLException
+ {
+ if(drawable.getChosenGLCapabilities().isOnscreen()) {
+ throw new NativeWindowException("Drawable is not offscreen: "+drawable);
+ }
+ final NativeSurface ns = drawable.getNativeSurface();
+ final int lockRes = ns.lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface of drawable: "+drawable);
+ }
+ try {
+ if(0>=newWidth) { newWidth = 1; }
+ if(0>=newHeight) { newHeight = 1; }
+ // propagate new size
+ if(ns instanceof ProxySurface) {
+ final ProxySurface ps = (ProxySurface) ns;
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else if(DEBUG) { // we have to assume UpstreamSurfaceHook contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen ProxySurface n.a. UpstreamSurfaceHook.MutableSize, but "+ush.getClass().getName()+": "+ush);
+ }
+ } else if(DEBUG) { // we have to assume surface contains the new size already, hence size check @ bottom
+ System.err.println("GLDrawableHelper.resizeOffscreenDrawable: Drawable's offscreen surface n.a. ProxySurface, but "+ns.getClass().getName()+": "+ns);
+ }
+ if(drawable instanceof GLFBODrawable) {
+ if( null != context && context.isCreated() ) {
+ ((GLFBODrawable) drawable).resetSize(context.getGL());
+ }
+ } else {
+ drawable = GLDrawableHelper.recreateGLDrawable(drawable, context);
+ }
+ } finally {
+ ns.unlockSurface();
+ }
+ if(drawable.getWidth() != newWidth || drawable.getHeight() != newHeight) {
+ throw new InternalError("Incomplete resize operation: expected "+newWidth+"x"+newHeight+", has: "+drawable);
+ }
+ return drawable;
+ }
+
public final void addGLEventListener(GLEventListener listener) {
addGLEventListener(-1, listener);
}
@@ -196,15 +324,11 @@ public class GLDrawableHelper {
}
}
- private final boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
- if(listenersToBeInit.remove(l)) {
- l.init(drawable);
- if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
- }
- return true;
+ private final void init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
+ l.init(drawable);
+ if(sendReshape) {
+ reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false /* checkInit */);
}
- return false;
}
/** The default init action to be called once after ctx is being created @ 1st makeCurrent(). */
@@ -214,14 +338,11 @@ public class GLDrawableHelper {
for (int i=0; i < _listeners.size(); i++) {
final GLEventListener listener = _listeners.get(i) ;
- // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
+ // If make ctx current, invoked by invokGL(..), results in a new ctx, init gets called.
// This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
- // hence the must always be initialized unconditional.
- listenersToBeInit.add(listener);
-
- if ( ! init( listener, drawable, true /* sendReshape */) ) {
- throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
- }
+ // hence it must be called unconditional, always.
+ listenersToBeInit.remove(listener); // remove if exist, avoiding dbl init
+ init( listener, drawable, true /* sendReshape */);
}
}
}
@@ -239,7 +360,9 @@ public class GLDrawableHelper {
final GLEventListener listener = _listeners.get(i) ;
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
- init( listener, drawable, true /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, true /* sendReshape */) ;
+ }
listener.display(drawable);
}
}
@@ -251,7 +374,9 @@ public class GLDrawableHelper {
// GLEventListener may need to be init,
// in case this one is added after the realization of the GLAutoDrawable
synchronized(listenersLock) {
- init( listener, drawable, false /* sendReshape */) ;
+ if( listenersToBeInit.remove(listener) ) {
+ init( listener, drawable, false /* sendReshape */) ;
+ }
}
}
if(setViewport) {
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index abf2bf557..311690f1d 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -43,6 +43,7 @@ package jogamp.opengl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -76,31 +77,46 @@ public abstract class GLDrawableImpl implements GLDrawable {
if( !realized ) {
return; // destroyed already
}
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
- if ( caps.getDoubleBuffered() ) {
- if(!surface.surfaceSwap()) {
- int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
- if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
- return;
+ int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
+ if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
+ return;
+ }
+ try {
+ if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
+ updateHandle();
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
+ if ( caps.getDoubleBuffered() ) {
+ if(!surface.surfaceSwap()) {
+ swapBuffersImpl(true);
}
- try {
- if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
- updateHandle();
- }
- swapBuffersImpl();
- } finally {
- unlockSurface();
+ } else {
+ final GLContext ctx = GLContext.getCurrent();
+ if(null!=ctx && ctx.getGLDrawable()==this) {
+ ctx.getGL().glFlush();
}
+ swapBuffersImpl(false);
}
- } else {
- GLContext ctx = GLContext.getCurrent();
- if(null!=ctx && ctx.getGLDrawable()==this) {
- ctx.getGL().glFinish();
- }
- }
+ } finally {
+ unlockSurface();
+ }
surface.surfaceUpdated(this, surface, System.currentTimeMillis());
}
- protected abstract void swapBuffersImpl();
+
+ /**
+ * Platform and implementation depending surface swap.
+ * The surface is locked.
+ *
+ * If doubleBuffered
is true
,
+ * an actual platform dependent surface swap shall be executed.
+ *
+ *
+ * If doubleBuffered
is false
,
+ * {@link GL#glFlush()} has been called already and
+ * the implementation may execute implementation specific code.
+ *
+ */
+ protected abstract void swapBuffersImpl(boolean doubleBuffered);
public final static String toHexString(long hex) {
return "0x" + Long.toHexString(hex);
@@ -181,6 +197,9 @@ public abstract class GLDrawableImpl implements GLDrawable {
System.err.println(getThreadName() + ": setRealized: "+getClass().getName()+" "+this.realized+" == "+realizedArg);
}
}
+ /**
+ * Platform specific realization of drawable
+ */
protected abstract void setRealizedImpl();
/**
@@ -189,7 +208,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
* If realized
is true
, the context has just been created and made current.
*
*
- * If realized
is false
, the context is still current and will be release and destroyed after this method returns.
+ * If realized
is false
, the context is still current and will be released and destroyed after this method returns.
*
*
* @see #contextMadeCurrent(GLContext, boolean)
@@ -199,18 +218,27 @@ public abstract class GLDrawableImpl implements GLDrawable {
/**
* Callback for special implementations, allowing GLContext to trigger GL related lifecycle: makeCurrent
, release
.
*
- * Will not be called if {@link #contextRealized(GLContext, boolean)} has been triggered.
- *
- *
* If current
is true
, the context has just been made current.
*
*
* If current
is false
, the context is still current and will be release after this method returns.
*
+ *
+ * Note: Will also be called after {@link #contextRealized(GLContext, boolean) contextRealized(ctx, true)}
+ * but not at context destruction, i.e. {@link #contextRealized(GLContext, boolean) contextRealized(ctx, false)}.
+ *
* @see #contextRealized(GLContext, boolean)
*/
protected void contextMadeCurrent(GLContext glc, boolean current) { }
+ /**
+ * Callback for special implementations, allowing to associate bound context to this drawable (bound == true)
+ * or to remove such association (bound == false).
+ * @param ctx the just bounded or unbounded context
+ * @param bound if true
create an association, otherwise remove it
+ */
+ protected void associateContext(GLContext ctx, boolean bound) { }
+
/** Callback for special implementations, allowing GLContext to fetch a custom default render framebuffer. Defaults to zero.*/
protected int getDefaultDrawFramebuffer() { return 0; }
/** Callback for special implementations, allowing GLContext to fetch a custom default read framebuffer. Defaults to zero. */
@@ -245,8 +273,8 @@ public abstract class GLDrawableImpl implements GLDrawable {
public String toString() {
return getClass().getSimpleName()+"[Realized "+isRealized()+
",\n\tFactory "+getFactory()+
- ",\n\thandle "+toHexString(getHandle())+
- ",\n\tWindow "+getNativeSurface()+"]";
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tSurface "+getNativeSurface()+"]";
}
protected static String getThreadName() {
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 03bc26cbc..de45466f3 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -1,142 +1,476 @@
package jogamp.opengl;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLFBODrawable;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.opengl.FBObject;
import com.jogamp.opengl.FBObject.Attachment;
+import com.jogamp.opengl.FBObject.Colorbuffer;
import com.jogamp.opengl.FBObject.TextureAttachment;
/**
- * Offscreen GLDrawable implementation using framebuffer object (FBO)
- * as it's offscreen rendering mechanism.
+ * {@link FBObject} offscreen GLDrawable implementation, i.e. {@link GLFBODrawable}.
+ *
+ * It utilizes the context lifecycle hook {@link #contextRealized(GLContext, boolean)}
+ * to initialize the {@link FBObject} instance.
+ *
+ *
+ * It utilizes the context current hook {@link #contextMadeCurrent(GLContext, boolean) contextMadeCurrent(context, true)}
+ * to {@link FBObject#bind(GL) bind} the FBO.
+ *
+ * See {@link GLFBODrawable} for double buffering details.
*
* @see GLDrawableImpl#contextRealized(GLContext, boolean)
* @see GLDrawableImpl#contextMadeCurrent(GLContext, boolean)
* @see GLDrawableImpl#getDefaultDrawFramebuffer()
* @see GLDrawableImpl#getDefaultReadFramebuffer()
*/
-public class GLFBODrawableImpl extends GLDrawableImpl {
- final GLDrawableImpl parent;
- final FBObject fbo;
- int texUnit;
- int samplesTexUnit = 0;
- int width=0, height=0, samples=0;
-
- protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent,
- NativeSurface surface, int initialWidth, int initialHeight, int textureUnit) {
+public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
+ protected static final boolean DEBUG = GLDrawableImpl.DEBUG || Debug.debug("FBObject");
+
+ private final GLDrawableImpl parent;
+
+ private boolean initialized;
+ private int texUnit;
+ private int samples;
+
+ private FBObject[] fbos;
+ private int fboIBack; // points to GL_BACK buffer
+ private int fboIFront; // points to GL_FRONT buffer
+ private FBObject pendingFBOReset = null;
+ private boolean fboBound;
+ private static final int bufferCount = 2; // number of FBOs for double buffering. TODO: Possible to configure!
+
+ // private DoubleBufferMode doubleBufferMode; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ private SwapBufferContext swapBufferContext;
+
+ public static interface SwapBufferContext {
+ public void swapBuffers(boolean doubleBuffered);
+ }
+
+ protected GLFBODrawableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, NativeSurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
super(factory, surface, false);
+ this.initialized = false;
+
+ // Replace the chosen caps of dummy-surface w/ it's clone and copied values of orig FBO caps request.
+ // The dummy-surface has already been configured, hence value replace is OK
+ // and due to cloning, the native GLCapability portion is being preserved.
+ final MutableGraphicsConfiguration msConfig = (MutableGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilities fboCapsNative = (GLCapabilities) msConfig.getChosenCapabilities().cloneMutable();
+ fboCapsNative.copyFrom(fboCaps);
+ msConfig.setChosenCapabilities(fboCapsNative);
+
this.parent = parent;
this.texUnit = textureUnit;
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- this.width = initialWidth;
- this.height = initialHeight;
- this.samples = caps.getNumSamples();
- this.fbo = new FBObject();
+ this.samples = fboCaps.getNumSamples();
+
+ // default .. // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ // this.doubleBufferMode = ( samples > 0 || fboCaps.getDoubleBuffered() ) ? DoubleBufferMode.FBO : DoubleBufferMode.NONE ;
+
+ this.swapBufferContext = null;
}
- @Override
- protected void contextRealized(GLContext glc, boolean realized) {
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
- final GL gl = glc.getGL();
- if(realized) {
- fbo.reset(gl, width, height, samples);
- samples = fbo.getNumSamples(); // update, maybe capped
+ private final void initialize(boolean realize, GL gl) {
+ if(realize) {
+ final int maxSamples = gl.getMaxRenderbufferSamples();
+ samples = samples <= maxSamples ? samples : maxSamples;
+
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ final int fbosN;
if(samples > 0) {
- fbo.attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
+ } else if( caps.getDoubleBuffered() ) {
+ fbosN = bufferCount;
} else {
- fbo.attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ fbosN = 1;
}
- if( caps.getStencilBits() > 0 ) {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
- } else {
- fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+
+ fbos = new FBObject[fbosN];
+ fboIBack = 0; // head
+ fboIFront = fbos.length - 1; // tail
+
+ for(int i=0; i 0) {
+ fbos[i].attachColorbuffer(gl, 0, caps.getAlphaBits()>0);
+ } else {
+ fbos[i].attachTexture2D(gl, 0, caps.getAlphaBits()>0);
+ }
+ if( caps.getStencilBits() > 0 ) {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+ } else {
+ fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+ }
}
- } else if(null != fbo) {
- fbo.destroy(gl);
- }
- }
-
- @Override
- protected void contextMadeCurrent(GLContext glc, boolean current) {
- final GL gl = glc.getGL();
- if(current) {
- fbo.bind(gl);
+ fbos[fboIFront].syncFramebuffer(gl);
+ fboBound = false;
+ final GLCapabilities fboCapsNative = (GLCapabilities) surface.getGraphicsConfiguration().getChosenCapabilities();
+ fbos[0].formatToGLCapabilities(fboCapsNative);
+ fboCapsNative.setDoubleBuffered( fboCapsNative.getDoubleBuffered() || samples > 0 );
+
+ initialized = true;
} else {
- fbo.unbind(gl);
- final TextureAttachment attachment = samples > 0 ? fbo.getSamplingSink() : (TextureAttachment) fbo.getColorbuffer(0) ;
- if(null == attachment) {
- throw new GLException("Null texture colorbuffer, samples "+samples+", "+fbo.toString());
- }
- gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
- fbo.use(gl, attachment );
- if( samples > 0) {
- gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbo.getReadFramebuffer());
+ initialized = false;
+
+ for(int i=0; i "+newSamples);
+ }
+ initialize(false, gl);
+ samples = newSamples;
+ initialize(true, gl);
+ } else {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.reset(): simple reconfig: "+samples+" -> "+newSamples);
+ }
+ final int nWidth = getWidth();
+ final int nHeight = getHeight();
+ samples = newSamples;
+ pendingFBOReset = ( 1 < fbos.length ) ? fbos[fboIFront] : null; // pending-front reset only w/ double buffering (or zero samples)
+ for(int i=0; i 0 ? fbos[fboIFront].getSamplingSink() : fbos[fboIFront].getColorbuffer(0);
+ final TextureAttachment texAttachment;
+ if(colorbuffer instanceof TextureAttachment) {
+ texAttachment = (TextureAttachment) colorbuffer;
+ } else {
+ if(null == colorbuffer) {
+ throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
+ } else {
+ throw new GLException("Front colorbuffer is not a texture: "+colorbuffer.getClass().getName()+": samples "+samples+", "+colorbuffer+", "+this);
+ }
+ }
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
+ fbos[fboIFront].use(gl, texAttachment);
+
+ /* Included in above use command:
+ gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, fbos[fboIBack].getDrawFramebuffer());
+ gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, fbos[fboIFront].getReadFramebuffer());
+ } */
+
+ if(DEBUG) {
+ System.err.println("Post FBO swap(X): fboI back "+fboIBack+", front "+fboIFront+", num "+fbos.length);
+ }
}
+ //
+ // GLFBODrawable
+ //
+
+ @Override
+ public final boolean isInitialized() {
+ return initialized;
+ }
+
@Override
- public int getHeight() {
- return height;
+ public final void resetSize(GL gl) throws GLException {
+ reset(gl, samples);
}
+
+ @Override
+ public final int getTextureUnit() { return texUnit; }
+
+ @Override
+ public final void setTextureUnit(int u) { texUnit = u; }
+
+ @Override
+ public final int getNumSamples() { return samples; }
+
+ @Override
+ public void setNumSamples(GL gl, int newSamples) throws GLException {
+ if(samples != newSamples) {
+ reset(gl, newSamples);
+ }
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public final DoubleBufferMode getDoubleBufferMode() {
+ return doubleBufferMode;
+ }
+
+ @Override
+ public final void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ if(initialized) {
+ throw new GLException("Not allowed past initialization: "+this);
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
+ if(0 == samples && caps.getDoubleBuffered() && DoubleBufferMode.NONE != mode) {
+ doubleBufferMode = mode;
+ }
+ } */
+
+ @Override
+ public FBObject getFBObject(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final FBObject res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSinkFBO();
+ } else {
+ res = fbos[fboIFront];
+ }
+ break;
+ case GL.GL_BACK:
+ res = fbos[fboIBack];
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+
+ @Override
+ public final TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException {
+ if(!initialized) {
+ return null;
+ }
+ final TextureAttachment res;
+ switch(bufferName) {
+ case GL.GL_FRONT:
+ if( samples > 0 ) {
+ res = fbos[0].getSamplingSink();
+ } else {
+ res = (TextureAttachment) fbos[fboIFront].getColorbuffer(0);
+ }
+ break;
+ case GL.GL_BACK:
+ if( samples > 0 ) {
+ throw new IllegalArgumentException("Cannot access GL_BACK buffer of MSAA FBO: "+this);
+ } else {
+ res = (TextureAttachment) fbos[fboIBack].getColorbuffer(0);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException(illegalBufferName+toHexString(bufferName));
+ }
+ return res;
+ }
+ private static final String illegalBufferName = "Only GL_FRONT and GL_BACK buffer are allowed, passed ";
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()+"[Initialized "+initialized+", realized "+isRealized()+", texUnit "+texUnit+", samples "+samples+
+ ",\n\tFactory "+getFactory()+
+ ",\n\tHandle "+toHexString(getHandle())+
+ ",\n\tCaps "+surface.getGraphicsConfiguration().getChosenCapabilities()+
+ ",\n\tfboI back "+fboIBack+", front "+fboIFront+", num "+(initialized ? fbos.length : 0)+
+ ",\n\tFBO front read "+getDefaultReadFramebuffer()+", "+getFBObject(GL.GL_FRONT)+
+ ",\n\tFBO back write "+getDefaultDrawFramebuffer()+", "+getFBObject(GL.GL_BACK)+
+ ",\n\tSurface "+getNativeSurface()+
+ "]";
+ }
+
+ public static class ResizeableImpl extends GLFBODrawableImpl implements GLFBODrawable.Resizeable {
+ protected ResizeableImpl(GLDrawableFactoryImpl factory, GLDrawableImpl parent, ProxySurface surface,
+ GLCapabilitiesImmutable fboCaps, int textureUnit) {
+ super(factory, parent, surface, fboCaps, textureUnit);
+ }
+
+ @Override
+ public final void setSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException {
+ if(DEBUG) {
+ System.err.println("GLFBODrawableImpl.ResizeableImpl setSize: ("+Thread.currentThread().getName()+"): "+newWidth+"x"+newHeight+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle()));
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock surface: "+this);
+ }
+ try {
+ // propagate new size
+ final ProxySurface ps = (ProxySurface) getNativeSurface();
+ final UpstreamSurfaceHook ush = ps.getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ ((UpstreamSurfaceHook.MutableSize)ush).setSize(newWidth, newHeight);
+ } else {
+ throw new InternalError("GLFBODrawableImpl.ResizableImpl's ProxySurface doesn't hold a UpstreamSurfaceHookMutableSize but "+ush.getClass().getName()+", "+ps+", ush");
+ }
+ if( null != context && context.isCreated() ) {
+ resetSize(context.getGL());
+ }
+ } finally {
+ unlockSurface();
+ }
+ }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 768fc6892..79f96b64a 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -28,8 +28,12 @@
package jogamp.opengl;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+
+import com.jogamp.common.os.Platform;
public class GLGraphicsConfigurationUtil {
public static final String NV_coverage_sample = "NV_coverage_sample";
@@ -119,26 +123,34 @@ public class GLGraphicsConfigurationUtil {
return getExclusiveWinAttributeBits(caps.isOnscreen(), caps.isFBO(), caps.isPBuffer(), caps.isBitmap());
}
- public static final GLCapabilities setWinAttributeBits(GLCapabilities caps, int winattrbits) {
+ public static final GLCapabilities fixWinAttribBitsAndHwAccel(AbstractGraphicsDevice device, int winattrbits, GLCapabilities caps) {
caps.setBitmap ( 0 != ( BITMAP_BIT & winattrbits ) );
caps.setPBuffer ( 0 != ( PBUFFER_BIT & winattrbits ) );
caps.setFBO ( 0 != ( FBO_BIT & winattrbits ) );
// we reflect availability semantics, hence setting onscreen at last (maybe overwritten above)!
- caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
- return caps;
- }
+ caps.setOnscreen( 0 != ( WINDOW_BIT & winattrbits ) );
+ final int accel = GLContext.isHardwareRasterizer( device, caps.getGLProfile() );
+ if(0 == accel && caps.getHardwareAccelerated() ) {
+ caps.setHardwareAccelerated(false);
+ }
+
+ return caps;
+ }
+
public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable)
{
if( !capsRequested.isOnscreen() ) {
return fixOffscreenGLCapabilities(capsRequested, fboAvailable, pbufferAvailable);
- }
+ } /* we maintain the offscreen mode flags in onscreen mode - else {
+ return fixOnscreenGLCapabilities(capsRequested);
+ } */
return capsRequested;
}
public static GLCapabilitiesImmutable fixOnscreenGLCapabilities(GLCapabilitiesImmutable capsRequested)
{
- if( !capsRequested.isOnscreen() ) {
+ if( !capsRequested.isOnscreen() || capsRequested.isFBO() || capsRequested.isPBuffer() || capsRequested.isBitmap() ) {
// fix caps ..
final GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setBitmap (false);
@@ -157,9 +169,11 @@ public class GLGraphicsConfigurationUtil {
public static GLCapabilitiesImmutable fixOffscreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean fboAvailable, boolean pbufferAvailable) {
final boolean auto = !capsRequested.isFBO() && !capsRequested.isPBuffer() && !capsRequested.isBitmap() ;
+
+ final boolean requestedPBuffer = capsRequested.isPBuffer() || Platform.getOSType() == Platform.OSType.MACOS ; // no native bitmap for OSX
final boolean useFBO = fboAvailable && ( auto || capsRequested.isFBO() ) ;
- final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || capsRequested.isPBuffer() ) ;
+ final boolean usePbuffer = !useFBO && pbufferAvailable && ( auto || requestedPBuffer ) ;
final boolean useBitmap = !useFBO && !usePbuffer && ( auto || capsRequested.isBitmap() ) ;
if( capsRequested.isOnscreen() ||
diff --git a/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
new file mode 100644
index 000000000..7701f209f
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/GLOffscreenAutoDrawableImpl.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright 2012 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:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLOffscreenAutoDrawable;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GLAutoDrawableDelegate;
+
+import jogamp.opengl.GLFBODrawableImpl;
+
+public class GLOffscreenAutoDrawableImpl extends GLAutoDrawableDelegate implements GLOffscreenAutoDrawable {
+
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param lock optional upstream lock, may be null
+ */
+ public GLOffscreenAutoDrawableImpl(GLDrawable drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, true, lock);
+ }
+
+ @Override
+ public void setSize(int newWidth, int newHeight) throws NativeWindowException, GLException {
+ this.defaultWindowResizedOp(newWidth, newHeight);
+ }
+
+ public static class FBOImpl extends GLOffscreenAutoDrawableImpl implements GLOffscreenAutoDrawable.FBO {
+ /**
+ * @param drawable a valid and already realized {@link GLDrawable}
+ * @param context a valid {@link GLContext}, may not be made current (created) yet.
+ * @param upstreamWidget optional UI element holding this instance, see {@link #getUpstreamWidget()}.
+ * @param lock optional upstream lock, may be null
+ */
+ public FBOImpl(GLFBODrawableImpl drawable, GLContext context, Object upstreamWidget, RecursiveLock lock) {
+ super(drawable, context, upstreamWidget, lock);
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return ((GLFBODrawableImpl)drawable).isInitialized();
+ }
+
+ @Override
+ public final int getTextureUnit() {
+ return ((GLFBODrawableImpl)drawable).getTextureUnit();
+ }
+
+ @Override
+ public final void setTextureUnit(int unit) {
+ ((GLFBODrawableImpl)drawable).setTextureUnit(unit);
+ }
+
+ @Override
+ public final int getNumSamples() {
+ return ((GLFBODrawableImpl)drawable).getNumSamples();
+ }
+
+ @Override
+ public final void setNumSamples(GL gl, int newSamples) throws GLException {
+ ((GLFBODrawableImpl)drawable).setNumSamples(gl, newSamples);
+ windowRepaintOp();
+ }
+
+ /** // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+ @Override
+ public DoubleBufferMode getDoubleBufferMode() {
+ return ((GLFBODrawableImpl)drawable).getDoubleBufferMode();
+ }
+
+ @Override
+ public void setDoubleBufferMode(DoubleBufferMode mode) throws GLException {
+ ((GLFBODrawableImpl)drawable).setDoubleBufferMode(mode);
+ } */
+
+ @Override
+ public final FBObject getFBObject(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getFBObject(bufferName);
+ }
+
+ public final FBObject.TextureAttachment getTextureBuffer(int bufferName) {
+ return ((GLFBODrawableImpl)drawable).getTextureBuffer(bufferName);
+ }
+
+ @Override
+ public void resetSize(GL gl) throws GLException {
+ ((GLFBODrawableImpl)drawable).resetSize(gl);
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index 32f4cb696..b438131bc 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -40,9 +40,6 @@
package jogamp.opengl;
-import javax.media.opengl.GLCapabilitiesImmutable;
-import javax.media.opengl.GLContext;
-import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
@@ -50,36 +47,18 @@ import javax.media.opengl.GLPbuffer;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-/** Platform-independent class exposing pbuffer functionality to
- applications. This class is not exposed in the public API as it
- would probably add no value; however it implements the GLDrawable
- interface so can be interacted with via its display() method. */
-
+@SuppressWarnings("deprecation")
public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer {
private int floatMode;
- public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContext sharedContext, boolean ownDevice) {
- super(pbufferDrawable, null, ownDevice); // drawable := pbufferDrawable
-
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
- if(caps.isOnscreen()) {
- if(caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
- }
- throw new IllegalArgumentException("Error: Given drawable is Onscreen: "+pbufferDrawable);
- } else {
- if(!caps.isPBuffer()) {
- throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable);
- }
- }
- context = (GLContextImpl) drawable.createContext(sharedContext);
+ public GLPbufferImpl(GLDrawableImpl pbufferDrawable, GLContextImpl pbufferContext) {
+ super(pbufferDrawable, pbufferContext, true); // drawable := pbufferDrawable, context := pbufferContext
}
//
// pbuffer specifics
- //
-
+ //
+
@Override
public void bindTexture() {
// Doesn't make much sense to try to do this on the event dispatch
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 03d0d650f..06953a8e1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -282,12 +282,6 @@ public abstract class EGLContext extends GLContextImpl {
return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
- @Override
- public abstract void bindPbufferToTexture();
-
- @Override
- public abstract void releasePbufferFromTexture();
-
//
// Accessible ..
//
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index 0dba4bb09..167eebf3a 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,7 +36,8 @@
package jogamp.opengl.egl;
-import javax.media.nativewindow.MutableSurface;
+import java.nio.IntBuffer;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.ProxySurface;
@@ -46,10 +47,10 @@ import javax.media.opengl.GLException;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public abstract class EGLDrawable extends GLDrawableImpl {
- private boolean ownEGLSurface = false; // for destruction
protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
super(factory, component, false);
@@ -58,21 +59,14 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
public abstract GLContext createContext(GLContext shareWith);
- protected abstract long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle);
+ protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);
- private final void recreateSurface() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if(DEBUG) {
- System.err.println(getThreadName() + ": createSurface using "+eglConfig);
- }
- if( EGL.EGL_NO_SURFACE != surface.getSurfaceHandle() ) {
- EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle());
- }
+ private final long createEGLSurface() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();
+ final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
- final EGLUpstreamSurfaceHook upstreamHook = (EGLUpstreamSurfaceHook) ((ProxySurface)surface).getUpstreamSurfaceHook();
- final NativeSurface upstreamSurface = upstreamHook.getUpstreamSurface();
- long eglSurface = createSurface(eglConfig, upstreamSurface.getSurfaceHandle());
+ long eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), upstreamSurface.getSurfaceHandle());
int eglError0;
if (EGL.EGL_NO_SURFACE == eglSurface) {
@@ -86,7 +80,7 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if(DEBUG) {
System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle");
}
- eglSurface = createSurface(eglConfig, nw.getWindowHandle());
+ eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), nw.getWindowHandle());
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
}
@@ -99,34 +93,53 @@ public abstract class EGLDrawable extends GLDrawableImpl {
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
}
-
if(DEBUG) {
- System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": createEGLSurface handle "+toHexString(eglSurface));
}
-
- ((MutableSurface)surface).setSurfaceHandle(eglSurface);
+ return eglSurface;
}
@Override
protected final void updateHandle() {
- if(ownEGLSurface) {
- recreateSurface();
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": updateHandle of "+eglws);
+ }
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) {
+ throw new InternalError("Set surface but claimed to be invalid: "+eglws);
+ }
+ eglws.setSurfaceHandle( createEGLSurface() );
+ } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ }
+
+ protected void destroyHandle() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+ }
+ if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglws.getGraphicsConfiguration().getScreen().getDevice();
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), eglws.getSurfaceHandle());
+ eglws.setSurfaceHandle(EGL.EGL_NO_SURFACE);
}
}
- protected static boolean isValidEGLSurface(EGLGraphicsDevice eglDevice, NativeSurface surface) {
- final long eglDisplayHandle = eglDevice.getHandle();
- if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
- throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+ protected static boolean isValidEGLSurface(long eglDisplayHandle, long surfaceHandle) {
+ if( 0 == surfaceHandle ) {
+ return false;
}
- boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
- if(eglSurfaceValid) {
- int[] tmp = new int[1];
- eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
- if(!eglSurfaceValid) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
- }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surfaceHandle, EGL.EGL_CONFIG_ID, val);
+ if( !eglSurfaceValid ) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
}
}
return eglSurfaceValid;
@@ -134,55 +147,19 @@ public abstract class EGLDrawable extends GLDrawableImpl {
@Override
protected final void setRealizedImpl() {
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
- if (realized) {
- final boolean eglSurfaceValid = isValidEGLSurface(eglDevice, surface);
- if(eglSurfaceValid) {
- // surface holds valid EGLSurface
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl re-using component's EGLSurface: handle "+toHexString(surface.getSurfaceHandle()));
- }
- ownEGLSurface=false;
- } else {
- // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
- // However .. let's validate the surface object first
- if( ! (surface instanceof ProxySurface) ) {
- throw new InternalError("surface not ProxySurface: "+surface.getClass().getName()+", "+surface);
- }
- final ProxySurface.UpstreamSurfaceHook upstreamHook = ((ProxySurface)surface).getUpstreamSurfaceHook();
- if( null == upstreamHook ) {
- throw new InternalError("null upstreamHook of: "+surface);
- }
- if( ! (upstreamHook instanceof EGLUpstreamSurfaceHook) ) {
- throw new InternalError("upstreamHook not EGLUpstreamSurfaceHook: Surface: "+surface.getClass().getName()+", "+surface+"; UpstreamHook: "+upstreamHook.getClass().getName()+", "+upstreamHook);
- }
- if( null == ((EGLUpstreamSurfaceHook)upstreamHook).getUpstreamSurface() ) {
- throw new InternalError("null upstream surface");
- }
- ownEGLSurface=true;
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl owning EGLSurface");
- }
- }
- } else if (ownEGLSurface && surface.getSurfaceHandle() != EGL.EGL_NO_SURFACE) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(surface.getSurfaceHandle()));
- }
- // Destroy the window surface
- if (!EGL.eglDestroySurface(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error destroying window surface (eglDestroySurface)");
- }
- ((MutableSurface)surface).setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealized("+realized+"): NOP - "+surface);
}
}
@Override
- protected final void swapBuffersImpl() {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
+ throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 292eb17c8..e98d69140 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -52,8 +52,7 @@ import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
-import javax.media.nativewindow.ProxySurface.UpstreamSurfaceHook;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.nativewindow.UpstreamSurfaceHook;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
@@ -65,6 +64,7 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.Debug;
import jogamp.opengl.GLDrawableFactoryImpl;
import jogamp.opengl.GLDrawableImpl;
@@ -76,10 +76,11 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.nativewindow.WrappedSurface;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+ protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG;
+
/* package */ static final boolean QUERY_EGL_ES = !Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.DontQuery", true);
/* package */ static final boolean QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
@@ -112,7 +113,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ defaultDevice = new EGLGraphicsDevice();
// FIXME: Probably need to move EGL from a static model
// to a dynamic one, where there can be 2 instances
@@ -310,6 +311,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
try {
final GLCapabilities reqCapsAny = new GLCapabilities(glp);
reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
final List availablePBufferCapsL = getAvailableEGLConfigs(sharedEGLDevice, reqCapsPBuffer);
hasPBuffer[0] = availablePBufferCapsL.size() > 0;
@@ -324,18 +326,20 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} else {
final List capsAnyL = getAvailableEGLConfigs(eglDevice, reqCapsAny);
if(capsAnyL.size() > 0) {
- final GLCapabilitiesImmutable caps = capsAnyL.get(0);
- EGLContext.mapStaticGLESVersion(eglDevice, caps);
+ final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
if(eglDevice != adevice) {
- EGLContext.mapStaticGLESVersion(adevice, caps);
+ EGLContext.mapStaticGLESVersion(adevice, chosenCaps);
}
+ final EGLGraphicsDevice adeviceEGLDevice = new EGLGraphicsDevice(adevice.getHandle(), EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), null);
+ EGLContext.mapStaticGLESVersion(adeviceEGLDevice, chosenCaps);
success = true;
}
if(DEBUG) {
System.err.println("EGLDrawableFactory.isEGLContextAvailable() no pbuffer config available, detected !pbuffer config: "+success);
EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
}
- }
+ }
} else {
surface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
upstreamSurface = ( surface instanceof ProxySurface ) ? (ProxySurface)surface : null ;
@@ -361,6 +365,8 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(eglDevice != adevice) {
context.mapCurrentAvailableGLVersion(adevice);
}
+ final EGLGraphicsDevice adeviceEGLDevice = new EGLGraphicsDevice(adevice.getHandle(), EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), null);
+ context.mapCurrentAvailableGLVersion(adeviceEGLDevice);
success = true;
} else {
// Oops .. something is wrong
@@ -538,70 +544,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, getEGLSurface(target));
+ return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
}
- protected static NativeSurface getEGLSurface(NativeSurface surface) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
- AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
- if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
- if(surface instanceof WrappedSurface) {
- // already wrapped surface - no wrapped recursion
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already wrapped surface - use as-is: "+surface);
- }
- return surface;
- }
- if(EGLDrawable.isValidEGLSurface((EGLGraphicsDevice)aDevice, surface)) {
- // already in native EGL format
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already valid EGL surface - use as-is: "+surface);
- }
- return surface;
- }
- }
- // create EGL instance out of platform native types
- final EGLGraphicsDevice eglDevice;
- if( aDevice instanceof EGLGraphicsDevice ) {
- eglDevice = (EGLGraphicsDevice) aDevice;
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Reusing eglDevice: "+eglDevice);
- }
- if(0 == eglDevice.getHandle()) {
- eglDevice.open();
- }
- } else {
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
- }
- final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
- final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
- final EGLGraphicsConfiguration eglConfig;
- if( aConfig instanceof EGLGraphicsConfiguration ) {
- // Config is already in EGL type - reuse ..
- final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
- if( 0 == capsChosen.getEGLConfig() ) {
- // 'refresh' the native EGLConfig handle
- capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
- if( 0 == capsChosen.getEGLConfig() ) {
- throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
- }
- }
- eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Reusing chosenCaps: "+eglConfig);
- }
- } else {
- eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
- capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
-
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
- } else if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - Chosen eglConfig: "+eglConfig);
- }
- }
- return new WrappedSurface(eglConfig, EGL.EGL_NO_SURFACE, surface.getWidth(), surface.getHeight(), new EGLUpstreamSurfaceHook(surface));
- }
static String getThreadName() { return Thread.currentThread().getName(); }
@Override
@@ -615,7 +560,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Non pbuffer not yet implemented");
}
// PBuffer GLDrawable Creation
- return new EGLPbufferDrawable(this, getEGLSurface(target));
+ return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
}
@Override
@@ -628,20 +573,24 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@Override
protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser, int width, int height, UpstreamSurfaceHook lifecycleHook) {
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
+ final boolean ownDevice;
final EGLGraphicsDevice device;
- if(createNewDevice) {
- final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
- device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ if(createNewDevice || ! ( deviceReq instanceof EGLGraphicsDevice ) ) {
+ final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
+ ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ ownDevice = true;
} else {
device = (EGLGraphicsDevice) deviceReq;
+ ownDevice = false;
}
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
if(null == config) {
throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
}
- return new WrappedSurface(config, 0, width, height, lifecycleHook);
+ return new WrappedSurface(config, 0, upstreamHook, ownDevice);
}
@Override
@@ -649,54 +598,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
final GLCapabilitiesImmutable chosenCaps =
GLGraphicsConfigurationUtil.fixDoubleBufferedGLCapabilities(
- GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)),
- false);
- return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, width, height, dummySurfaceLifecycleHook);
+ GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(requestedCaps, false, canCreateGLPbuffer(deviceReq)), false);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
}
- private static final ProxySurface.UpstreamSurfaceHook dummySurfaceLifecycleHook = new ProxySurface.UpstreamSurfaceHook() {
- @Override
- public final void create(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
- if(0 == eglDevice.getHandle()) {
- eglDevice.open();
- s.setImplBitfield(ProxySurface.OWN_DEVICE);
- }
- createPBufferSurfaceImpl(s, false);
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final void destroy(ProxySurface s) {
- if( EGL.EGL_NO_SURFACE != s.getSurfaceHandle() ) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) s.getGraphicsConfiguration();
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
- EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
- s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
- if( 0 != ( ProxySurface.OWN_DEVICE & s.getImplBitfield() ) ) {
- eglDevice.close();
- }
- if(DEBUG) {
- System.err.println("EGLDrawableFactory.dummySurfaceLifecycleHook.create: "+s);
- }
- }
- }
- @Override
- public final int getWidth(ProxySurface s) {
- return s.initialWidth;
- }
- @Override
- public final int getHeight(ProxySurface s) {
- return s.initialHeight;
- }
- @Override
- public String toString() {
- return "EGLSurfaceLifecycleHook[]";
- }
-
- };
/**
* @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface.
@@ -705,7 +609,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
* @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
*/
protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
- final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) ms.getGraphicsConfiguration();
+ return null;
+ }
+ protected static long createPBufferSurfaceImpl(EGLGraphicsConfiguration config, int width, int height, boolean useTexture) {
final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
final int texFormat;
@@ -720,15 +626,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.out.println("Pbuffer config: " + config);
}
- final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(ms.getWidth(), ms.getHeight(), texFormat);
+ final int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat);
final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs, 0);
if (EGL.EGL_NO_SURFACE==surf) {
- throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+ms.getWidth()+"x"+ms.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+width+"x"+height+", "+eglDevice+", "+config+", error 0x"+Integer.toHexString(EGL.eglGetError()));
} else if(DEBUG) {
System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
}
- ms.setSurfaceHandle(surf);
- return ms;
+ return surf;
}
@Override
@@ -737,7 +642,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- return new WrappedSurface(cfg, windowHandle, 0, 0, upstream);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..b172d4f35
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -0,0 +1,49 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public EGLDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ s.setSurfaceHandle( EGLDrawableFactory.createPBufferSurfaceImpl((EGLGraphicsConfiguration)s.getGraphicsConfiguration(), 64, 64, false) );
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no EGL surface: "+s);
+ }
+ EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 585638d21..84bd705db 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -79,15 +79,4 @@ public class EGLExternalContext extends EGLContext {
@Override
protected void destroyImpl() throws GLException {
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index e513a86cf..f857c6b5c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -57,8 +57,8 @@ public class EGLGLCapabilities extends GLCapabilities {
this.eglcfg = eglcfg;
this.eglcfgid = eglcfgid;
if(!isCompatible(glp, renderableType)) {
- throw new GLException("Incompatible "+glp+
- " with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
+ throw new GLException("Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
}
this.renderableType = renderableType;
this.nativeVisualID = visualID;
@@ -131,6 +131,7 @@ public class EGLGLCapabilities extends GLCapabilities {
sink = new StringBuilder();
}
boolean first=true;
+ sink.append("0x").append(Integer.toHexString(renderableType)).append(": ");
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
sink.append("GL"); first=false;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 8ee98072f..7bf201238 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -211,6 +211,13 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if(null == glp) {
glp = EGLGLCapabilities.getCompatible(device, rType);
}
+ if(!EGLGLCapabilities.isCompatible(glp, rType)) {
+ if(DEBUG) {
+ System.err.println("config "+toHexString(config)+": Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
+ }
+ return null;
+ }
caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
} catch (GLException gle) {
if(DEBUG) {
@@ -288,7 +295,7 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return null;
}
- return (EGLGLCapabilities) GLGraphicsConfigurationUtil.setWinAttributeBits(caps, drawableTypeBits);
+ return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps);
}
public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
index eae47fa92..325ad6142 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
@@ -41,16 +41,5 @@ public class EGLOnscreenContext extends EGLContext {
public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
super(drawable, shareWith);
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index d54057775..6440cf1e5 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -54,8 +54,8 @@ public class EGLOnscreenDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
index 7175d516f..bb9eeb892 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
@@ -46,15 +46,5 @@ public class EGLPbufferContext extends EGLContext {
public int getFloatingPointMode() {
return 0; // FIXME ??
}
-
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Not yet implemented");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Not yet implemented");
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 4a36625bd..eb7e320c8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -52,12 +52,8 @@ public class EGLPbufferDrawable extends EGLDrawable {
}
@Override
- protected long createSurface(EGLGraphicsConfiguration config, long nativeSurfaceHandle) {
- final MutableSurface ms = (MutableSurface)getNativeSurface();
- if(config != ms.getGraphicsConfiguration()) {
- throw new InternalError("Not same: "+config.hashCode()+", "+ms.getGraphicsConfiguration()+": "+config+", "+ms.getGraphicsConfiguration());
- }
- return EGLDrawableFactory.createPBufferSurfaceImpl(ms, useTexture).getSurfaceHandle();
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+ return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index 42c6e100e..342c4c417 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -1,38 +1,163 @@
package jogamp.opengl.egl;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook {
+public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
+ protected static final boolean DEBUG = EGLDrawableFactory.DEBUG;
private final NativeSurface upstreamSurface;
+ private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize;
public EGLUpstreamSurfaceHook(NativeSurface upstream) {
upstreamSurface = upstream;
+ if(upstreamSurface instanceof ProxySurface) {
+ final UpstreamSurfaceHook ush = ((ProxySurface)upstreamSurface).getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ // offscreen NativeSurface w/ MutableSize (default)
+ upstreamSurfaceHookMutableSize = (UpstreamSurfaceHook.MutableSize) ush;
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
}
public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+ static String getThreadName() { return Thread.currentThread().getName(); }
+
+ public final void setSize(int width, int height) {
+ if(null != upstreamSurfaceHookMutableSize) {
+ upstreamSurfaceHookMutableSize.setSize(width, height);
+ }
+ }
+
@Override
public final void create(ProxySurface surface) {
+ final String dbgPrefix;
+ if(DEBUG) {
+ dbgPrefix = getThreadName() + ": EGLUpstreamSurfaceHook.create("+surface.getClass().getSimpleName()+"): ";
+ System.err.println(dbgPrefix+this);
+ } else {
+ dbgPrefix = null;
+ }
+
if(upstreamSurface instanceof ProxySurface) {
+ // propagate createNotify(..) so upstreamSurface will be created
((ProxySurface)upstreamSurface).createNotify();
- if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
- throw new GLException("Could not lock: "+upstreamSurface);
+ }
+
+ // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+ throw new GLException("Could not lock: "+upstreamSurface);
+ }
+ try {
+ evalUpstreamSurface(dbgPrefix, surface);
+ } finally {
+ upstreamSurface.unlockSurface();
+ }
+ }
+
+ private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
+ //
+ // evaluate nature of upstreamSurface, may create EGL instances if required
+ //
+
+ boolean isEGLSurfaceValid = true; // assume yes
+
+ final AbstractGraphicsConfiguration aConfig = upstreamSurface.getGraphicsConfiguration();
+ final AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
+
+ final EGLGraphicsDevice eglDevice;
+ if( aDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) aDevice;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglDevice: "+eglDevice);
+ }
+ if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+ eglDevice.open();
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ } else {
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+
+ final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+ final EGLGraphicsConfiguration eglConfig;
+ if( aConfig instanceof EGLGraphicsConfiguration ) {
+ // Config is already in EGL type - reuse ..
+ final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+ if( !isEGLSurfaceValid || !EGLGraphicsConfiguration.isEGLConfigValid(eglDevice.getHandle(), capsChosen.getEGLConfig()) ) {
+ // 'refresh' the native EGLConfig handle
+ capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
+ if( 0 == capsChosen.getEGLConfig() ) {
+ throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
+ }
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Refreshing eglConfig: "+eglConfig);
+ }
+ isEGLSurfaceValid = false;
+ } else {
+ eglConfig = (EGLGraphicsConfiguration) aConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglConfig: "+eglConfig);
+ }
+ }
+ } else {
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false);
+
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+ } else if(DEBUG) {
+ System.err.println(dbgPrefix+"Chosen eglConfig: "+eglConfig);
}
+ isEGLSurfaceValid = false;
}
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.open();
+ surface.setGraphicsConfiguration(eglConfig);
+
+ if(isEGLSurfaceValid) {
+ isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+ }
+ if(isEGLSurfaceValid) {
+ surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: Already valid EGL surface - use as-is: "+upstreamSurface);
+ }
+ } else {
+ surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); // create/destroy in EGLDrawable
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: EGL surface n/a - TBD: "+upstreamSurface);
+ }
+ }
}
@Override
public final void destroy(ProxySurface surface) {
- final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
- eglDevice.close();
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this);
+ }
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
if(upstreamSurface instanceof ProxySurface) {
- upstreamSurface.unlockSurface();
((ProxySurface)upstreamSurface).destroyNotify();
}
}
@@ -49,8 +174,8 @@ public class EGLUpstreamSurfaceHook implements ProxySurface.UpstreamSurfaceHook
@Override
public String toString() {
- final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": " + upstreamSurface ) : "nil";
- return "EGLUpstreamSurfaceHook[upstream: "+us_s+"]";
+ final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": 0x" + Long.toHexString(upstreamSurface.getSurfaceHandle()) ) : "nil";
+ return "EGLUpstreamSurfaceHook[ "+ upstreamSurface.getWidth() + "x" + upstreamSurface.getHeight() + ", " + us_s+ "]";
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
new file mode 100644
index 000000000..b36303392
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
@@ -0,0 +1,26 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+
+import jogamp.nativewindow.WrappedSurface;
+
+public class EGLWrappedSurface extends WrappedSurface {
+
+ public static EGLWrappedSurface get(NativeSurface surface) {
+ if(surface instanceof EGLWrappedSurface) {
+ return (EGLWrappedSurface)surface;
+ }
+ return new EGLWrappedSurface(surface);
+ }
+
+ public EGLWrappedSurface(NativeSurface surface) {
+ super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLWrappedSurface.ctor(): "+this);
+ }
+ }
+
+ public final NativeSurface getUpstreamSurface() {
+ return ((EGLUpstreamSurfaceHook)super.getUpstreamSurfaceHook()).getUpstreamSurface();
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 55aea3a98..ec29558d1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -49,6 +49,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
@@ -58,6 +59,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLFBODrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -76,9 +78,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
boolean isNSContext();
long create(long share, int ctp, int major, int minor);
boolean destroy(long ctx);
+ boolean contextRealized(boolean realized);
boolean copyImpl(long src, int mask);
boolean makeCurrent(long ctx);
boolean release(long ctx);
+ boolean detachPBuffer();
boolean setSwapInterval(int interval);
boolean swapBuffers();
}
@@ -279,7 +283,24 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Error destroying OpenGL Context: "+this);
}
}
+
+ @Override
+ protected void contextRealized(boolean realized) {
+ // context stuff depends on drawable stuff
+ if(realized) {
+ super.contextRealized(true); // 1) init drawable stuff
+ impl.contextRealized(true); // 2) init context stuff
+ } else {
+ impl.contextRealized(false); // 1) free context stuff
+ super.contextRealized(false); // 2) free drawable stuff
+ }
+ }
+
+ /* pp */ void detachPBuffer() {
+ impl.detachPBuffer();
+ }
+
@Override
protected void copyImpl(GLContext source, int mask) throws GLException {
if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) {
@@ -365,16 +386,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
throw new GLException("Should not call this");
}
- @Override
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- @Override
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
// Support for "mode switching" as described in MacOSXCGLDrawable
public void setOpenGLMode(GLBackendType mode) {
if (mode == openGLMode) {
@@ -421,323 +432,486 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// NSOpenGLContext-based implementation
class NSOpenGLImpl implements GLBackendImpl {
- long nsOpenGLLayer = 0;
- long nsOpenGLLayerPFmt = 0;
- float screenVSyncTimeout; // microSec
- int vsyncTimeout; // microSec - for nsOpenGLLayer mode
-
- @Override
- public boolean isNSContext() { return true; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- final long nsViewHandle;
- if(drawable instanceof MacOSXCGLDrawable) {
- // we allow null here! (special pbuffer case)
- nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
- } else {
- // we only allow a valid NSView here
- final long aHandle = drawable.getHandle();
- if( OSXUtil.isNSView(aHandle) ) {
- nsViewHandle = aHandle;
- } else {
- throw new RuntimeException("Anonymous drawable instance's handle not of type NSView: "+drawable.getClass().getName()+", "+drawable);
- }
- }
- final NativeSurface surface = drawable.getNativeSurface();
- final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
- final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
-
- boolean allowIncompleteView = null != backingLayerHost;
- if( !allowIncompleteView && surface instanceof ProxySurface ) {
- allowIncompleteView = 0 != ( ProxySurface.INVISIBLE_WINDOW & ((ProxySurface)surface).getImplBitfield() ) ;
- }
- final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- if(DEBUG) {
- System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
- }
- return 0;
- }
- config.setChosenPixelFormat(pixelFormat);
- int sRefreshRate = CGL.getScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
- screenVSyncTimeout = 1000000f / sRefreshRate;
- if(DEBUG) {
- System.err.println("NS create OSX>=lion "+isLionOrLater);
- System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
- System.err.println("NS create backingLayerHost: "+backingLayerHost);
- System.err.println("NS create share: "+share);
- System.err.println("NS create chosenCaps: "+chosenCaps);
- System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
- System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
- System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
- System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
- // Thread.dumpStack();
- }
- try {
- int[] viewNotReady = new int[1];
- // Try to allocate a context with this
- ctx = CGL.createContext(share,
- nsViewHandle, allowIncompleteView,
- pixelFormat,
- chosenCaps.isBackgroundOpaque(),
- viewNotReady, 0);
- if (0 == ctx) {
- if(DEBUG) {
- System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
- }
- return 0;
- }
+ private OffscreenLayerSurface backingLayerHost = null;
+ private long nsOpenGLLayer = 0;
+ private long nsOpenGLLayerPFmt = 0;
+ private float screenVSyncTimeout; // microSec
+ private int vsyncTimeout; // microSec - for nsOpenGLLayer mode
+ private int lastWidth=0, lastHeight=0; // allowing to detect size change
+ private long lastPBufferHandle = 0; // allowing to detect pbuffer recreation
+
+ @Override
+ public boolean isNSContext() { return true; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ final NativeSurface surface = drawable.getNativeSurface();
+ final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final long nsViewHandle;
+ final boolean isPBuffer;
+ final boolean isFBO;
+ if(drawable instanceof GLFBODrawableImpl) {
+ nsViewHandle = 0;
+ isPBuffer = false;
+ isFBO = true;
+ if(DEBUG) {
+ System.err.println("NS create GLFBODrawableImpl drawable: isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else if(drawable instanceof MacOSXCGLDrawable) {
+ // we allow null here! (special pbuffer case)
+ nsViewHandle = ((MacOSXCGLDrawable)MacOSXCGLContext.this.drawable).getNSViewHandle();
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawable.getHandle());
+ isFBO = false;
+ if(DEBUG) {
+ System.err.println("NS create MacOSXCGLDrawable drawable handle isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else {
+ // we only allow a valid NSView here
+ final long drawableHandle = drawable.getHandle();
+ final boolean isNSView = OSXUtil.isNSView(drawableHandle);
+ final boolean isNSWindow = OSXUtil.isNSWindow(drawableHandle);
+ isPBuffer = CGL.isNSOpenGLPixelBuffer(drawableHandle);
+ isFBO = false;
- if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) {
- // Set the context opacity
- CGL.setContextOpacity(ctx, 0);
+ if(DEBUG) {
+ System.err.println("NS create Anonymous drawable handle "+toHexString(drawableHandle)+": isNSView "+isNSView+", isNSWindow "+isNSWindow+", isFBO "+isFBO+", isPBuffer "+isPBuffer+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ if( isNSView ) {
+ nsViewHandle = drawableHandle;
+ } else if( isNSWindow ) {
+ nsViewHandle = OSXUtil.GetNSView(drawableHandle);
+ } else if( isPBuffer ) {
+ nsViewHandle = 0;
+ } else {
+ throw new RuntimeException("Anonymous drawable instance's handle neither NSView, NSWindow nor PBuffer: "+toHexString(drawableHandle)+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
}
+ backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ boolean allowIncompleteView = null != backingLayerHost;
+ if( !allowIncompleteView && surface instanceof ProxySurface ) {
+ allowIncompleteView = ((ProxySurface)surface).containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE );
+ }
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ if(DEBUG) {
+ System.err.println("Unable to allocate pixel format with requested GLCapabilities: "+chosenCaps);
+ }
+ return 0;
+ }
GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
- fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
- if(!fixedCaps.isPBuffer()) {
+ if(chosenCaps.isOnscreen() || !fixedCaps.isPBuffer()) {
// not handled, so copy them
fixedCaps.setFBO(chosenCaps.isFBO());
+ fixedCaps.setPBuffer(chosenCaps.isPBuffer());
fixedCaps.setBitmap(chosenCaps.isBitmap());
fixedCaps.setOnscreen(chosenCaps.isOnscreen());
}
- config.setChosenCapabilities(fixedCaps);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ int sRefreshRate = OSXUtil.GetScreenRefreshRate(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getIndex());
+ screenVSyncTimeout = 1000000f / sRefreshRate;
if(DEBUG) {
+ System.err.println("NS create OSX>=lion "+isLionOrLater);
+ System.err.println("NS create allowIncompleteView: "+allowIncompleteView);
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create drawable type: "+drawable.getClass().getName());
+ System.err.println("NS create drawable handle: isPBuffer "+isPBuffer+", isFBO "+isFBO);
+ System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+ System.err.println("NS create chosenCaps: "+chosenCaps);
System.err.println("NS create fixedCaps: "+fixedCaps);
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create drawable NSView-handle: "+toHexString(nsViewHandle));
+ System.err.println("NS create screen refresh-rate: "+sRefreshRate+" hz, "+screenVSyncTimeout+" micros");
+ // Thread.dumpStack();
}
if(fixedCaps.isPBuffer()) {
- // Must now associate the pbuffer with our newly-created context
- CGL.setContextPBuffer(ctx, drawable.getHandle());
+ if(!isPBuffer) {
+ throw new InternalError("fixedCaps is PBuffer, handle not: "+drawable);
+ }
+ } else {
+ if(isPBuffer) {
+ throw new InternalError("handle is PBuffer, fixedCaps not: "+drawable);
+ }
}
- //
- // handled layered surface
- //
+ config.setChosenCapabilities(fixedCaps);
+ /**
if(null != backingLayerHost) {
- nsOpenGLLayerPFmt = pixelFormat;
- pixelFormat = 0;
- final int texWidth, texHeight;
- if(drawable instanceof MacOSXPbufferCGLDrawable) {
- final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
- texWidth = osxPDrawable.getTextureWidth();
- texHeight = osxPDrawable.getTextureHeight();
- } else {
- texWidth = drawable.getWidth();
- texHeight = drawable.getHeight();
+ backingLayerHost.setChosenCapabilities(fixedCaps);
+ } */
+
+ try {
+ int[] viewNotReady = new int[1];
+ // Try to allocate a context with this
+ ctx = CGL.createContext(share,
+ nsViewHandle, allowIncompleteView,
+ pixelFormat,
+ chosenCaps.isBackgroundOpaque(),
+ viewNotReady, 0);
+ if (0 == ctx) {
+ if(DEBUG) {
+ System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
+ }
+ return 0;
}
- if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) {
- throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if(null != backingLayerHost) {
+ nsOpenGLLayerPFmt = pixelFormat;
+ pixelFormat = 0;
}
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable);
+
+ if (chosenCaps.isOnscreen() && !chosenCaps.isBackgroundOpaque()) {
+ // Set the context opacity
+ CGL.setContextOpacity(ctx, 0);
+ }
+ } finally {
+ if(0!=pixelFormat) {
+ CGL.deletePixelFormat(pixelFormat);
+ pixelFormat = 0;
}
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
- }
- } finally {
- if(0!=pixelFormat) {
- CGL.deletePixelFormat(pixelFormat);
- }
- }
- return ctx;
- }
-
- @Override
- public boolean destroy(long ctx) {
- if(0 != nsOpenGLLayer) {
- final NativeSurface surface = drawable.getNativeSurface();
- if (DEBUG) {
- System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
- }
- final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
- if(null != ols && ols.isSurfaceLayerAttached()) {
- // still having a valid OLS attached to surface (parent OLS could have been removed)
- ols.detachSurfaceLayer();
}
- CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
- CGL.deletePixelFormat(nsOpenGLLayerPFmt);
- nsOpenGLLayerPFmt = 0;
- nsOpenGLLayer = 0;
+ return ctx;
}
- return CGL.deleteContext(ctx, true);
- }
-
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.copyContext(contextHandle, src, mask);
- return true;
- }
- @Override
- public boolean makeCurrent(long ctx) {
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+ @Override
+ public boolean destroy(long ctx) {
+ lastPBufferHandle = 0;
+ return CGL.deleteContext(ctx, true);
}
- int err = CGL.CGLLockContext(cglCtx);
- if(CGL.kCGLNoError == err) {
- return CGL.makeCurrentContext(ctx);
- } else if(DEBUG) {
- System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean contextRealized(boolean realized) {
+ if( realized ) {
+ if( null != backingLayerHost ) {
+ //
+ // handled layered surface
+ //
+ final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+ final long ctx = MacOSXCGLContext.this.getHandle();
+ final int texID;
+ final long drawableHandle = drawable.getHandle();
+ if(drawable instanceof GLFBODrawableImpl) {
+ final GLFBODrawableImpl fbod = (GLFBODrawableImpl)drawable;
+ texID = fbod.getTextureBuffer(GL.GL_FRONT).getName();
+ fbod.setSwapBufferContext(new GLFBODrawableImpl.SwapBufferContext() {
+ public void swapBuffers(boolean doubleBuffered) {
+ MacOSXCGLContext.NSOpenGLImpl.this.swapBuffers();
+ } } ) ;
+ lastPBufferHandle = 0;
+ } else if( chosenCaps.isPBuffer() && CGL.isNSOpenGLPixelBuffer(drawableHandle) ) {
+ texID = 0;
+ lastPBufferHandle = drawableHandle;
+ } else {
+ throw new GLException("BackingLayerHost w/ unknown handle (!FBO, !PBuffer): "+drawable);
+ }
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(0>=lastWidth || 0>=lastHeight || !drawable.isRealized()) {
+ throw new GLException("Drawable not realized yet or invalid texture size, texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, lastPBufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(lastPBufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
+ } else {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ }
+ } else {
+ if( 0 != nsOpenGLLayer ) {
+ final NativeSurface surface = drawable.getNativeSurface();
+ if (DEBUG) {
+ System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", "+drawable);
+ }
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ if(null != ols && ols.isSurfaceLayerAttached()) {
+ // still having a valid OLS attached to surface (parent OLS could have been removed)
+ ols.detachSurfaceLayer();
+ }
+ CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+ nsOpenGLLayer = 0;
+ }
+ if(0 != nsOpenGLLayerPFmt) {
+ CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+ nsOpenGLLayerPFmt = 0;
+ }
+ lastPBufferHandle = 0;
+ }
+ backingLayerHost = null;
+ return true;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ private final void validatePBufferConfig(long ctx) {
+ final GLCapabilitiesImmutable chosenCaps = drawable.getChosenGLCapabilities();
+ final long drawableHandle = drawable.getHandle();
+ if(chosenCaps.isPBuffer() && CGL.isNSOpenGLPixelBuffer(drawableHandle) && lastPBufferHandle != drawableHandle) {
+ // Must associate the pbuffer with our newly-created context
+ lastPBufferHandle = drawableHandle;
+ if(0 != drawableHandle) {
+ CGL.setContextPBuffer(ctx, drawableHandle);
+ }
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig bind pbuffer "+toHexString(drawableHandle)+" -> ctx "+toHexString(ctx));
+ }
}
}
- final boolean res = CGL.clearCurrentContext(ctx);
- final long cglCtx = CGL.getCGLContext(ctx);
- if(0 == cglCtx) {
- throw new InternalError("Null CGLContext for: "+this);
+
+ /** Returns true if size has been updated, otherwise false (same size). */
+ private final boolean validateDrawableSizeConfig(long ctx) {
+ final int width = drawable.getWidth();
+ final int height = drawable.getHeight();
+ if( lastWidth != width || lastHeight != height ) {
+ lastWidth = drawable.getWidth();
+ lastHeight = drawable.getHeight();
+ if(DEBUG) {
+ System.err.println("NS.validateDrawableConfig size changed");
+ }
+ return true;
+ }
+ return false;
}
- final int err = CGL.CGLUnlockContext(cglCtx);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.copyContext(contextHandle, src, mask);
+ return true;
}
- return res && CGL.kCGLNoError == err;
- }
- @Override
- public boolean setSwapInterval(int interval) {
- if(0 != nsOpenGLLayer) {
- CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
- vsyncTimeout = interval * (int)screenVSyncTimeout;
- if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
+ @Override
+ public boolean makeCurrent(long ctx) {
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ int err = CGL.CGLLockContext(cglCtx);
+ if(CGL.kCGLNoError == err) {
+ validatePBufferConfig(ctx); // required to handle pbuffer change ASAP
+ return CGL.makeCurrentContext(ctx);
+ } else if(DEBUG) {
+ System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.NSOpenGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
+ }
+ final boolean res = CGL.clearCurrentContext(ctx);
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final int err = CGL.CGLUnlockContext(cglCtx);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return res && CGL.kCGLNoError == err;
}
- CGL.setSwapInterval(contextHandle, interval);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- if( 0 != nsOpenGLLayer ) {
- // If v-sync is disabled, frames will be drawn as quickly as possible
- // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
- CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ @Override
+ public boolean detachPBuffer() {
+ if(0 != lastPBufferHandle) {
+ lastPBufferHandle = 0;
+ if(0 != nsOpenGLLayer) {
+ CGL.flushNSOpenGLLayerPBuffer(nsOpenGLLayer); // notify invalid pbuffer
+ }
+ // CGL.setContextPBuffer(contextHandle, 0); // doesn't work, i.e. not taking nil
+ }
+ return true;
}
- if(CGL.flushBuffer(contextHandle)) {
+
+ @Override
+ public boolean setSwapInterval(int interval) {
if(0 != nsOpenGLLayer) {
- // trigger CALayer to update
- CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+ CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+ vsyncTimeout = interval * (int)screenVSyncTimeout + 1000; // +1ms
+ if(DEBUG) { System.err.println("NS setSwapInterval: "+vsyncTimeout+" micros"); }
}
+ CGL.setSwapInterval(contextHandle, interval);
return true;
}
- return false;
- }
+
+ private int skipSync=0;
+
+ @Override
+ public boolean swapBuffers() {
+ final boolean res;
+ if( 0 != nsOpenGLLayer ) {
+ if( validateDrawableSizeConfig(contextHandle) ) {
+ // skip wait-for-vsync for a few frames if size has changed,
+ // allowing to update the texture IDs ASAP.
+ skipSync = 10;
+ }
+
+ final int texID;
+ final boolean valid;
+ if(drawable instanceof GLFBODrawableImpl) {
+ texID = ((GLFBODrawableImpl)drawable).getTextureBuffer(GL.GL_FRONT).getName();
+ valid = 0 != texID;
+ } else {
+ texID = 0;
+ valid = 0 != lastPBufferHandle;
+ }
+ if(valid) {
+ if(0 == skipSync) {
+ // If v-sync is disabled, frames will be drawn as quickly as possible
+ // w/o delay but in sync w/ CALayer. Otherwise wait until next swap interval (v-sync).
+ CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, vsyncTimeout);
+ } else {
+ skipSync--;
+ }
+ res = CGL.flushBuffer(contextHandle);
+ if(res) {
+ // trigger CALayer to update incl. possible surface change
+ CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer, lastPBufferHandle, texID, lastWidth, lastHeight);
+ }
+ } else {
+ res = true;
+ }
+ } else {
+ res = CGL.flushBuffer(contextHandle);
+ }
+ return res;
+ }
+
}
class CGLImpl implements GLBackendImpl {
- @Override
- public boolean isNSContext() { return false; }
-
- @Override
- public long create(long share, int ctp, int major, int minor) {
- long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
- if (pixelFormat == 0) {
- throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
- }
- config.setChosenPixelFormat(pixelFormat);
- try {
- // Create new context
- PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
- if (DEBUG) {
- System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ @Override
+ public boolean isNSContext() { return false; }
+
+ @Override
+ public long create(long share, int ctp, int major, int minor) {
+ long ctx = 0;
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
}
- int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
- if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while creating context");
- }
- if(chosenCaps.isPBuffer()) {
- // Attach newly-created context to the pbuffer
- res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0);
+ try {
+ // Create new context
+ PointerBuffer ctxPB = PointerBuffer.allocateDirect(1);
+ if (DEBUG) {
+ System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share));
+ }
+ int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB);
if (res != CGL.kCGLNoError) {
- throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ throw new GLException("Error code " + res + " while creating context");
}
- }
- ctx = ctxPB.get(0);
- if(0!=ctx) {
- if(DEBUG) {
- GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
- System.err.println("NS created: "+caps0);
+ ctx = ctxPB.get(0);
+
+ if (0 != ctx) {
+ GLCapabilities fixedCaps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ if(chosenCaps.isOnscreen() || !fixedCaps.isPBuffer()) {
+ // not handled, so copy them
+ fixedCaps.setFBO(chosenCaps.isFBO());
+ fixedCaps.setPBuffer(chosenCaps.isPBuffer());
+ fixedCaps.setBitmap(chosenCaps.isBitmap());
+ fixedCaps.setOnscreen(chosenCaps.isOnscreen());
+ }
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("CGL create fixedCaps: "+fixedCaps);
+ }
+ if(fixedCaps.isPBuffer()) {
+ // Must now associate the pbuffer with our newly-created context
+ res = CGL.CGLSetPBuffer(ctx, drawable.getHandle(), 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while attaching context to pbuffer");
+ }
+ }
}
+ } finally {
+ CGL.CGLDestroyPixelFormat(pixelFormat);
}
- } finally {
- CGL.CGLDestroyPixelFormat(pixelFormat);
+ return ctx;
}
- return ctx;
- }
- @Override
- public boolean destroy(long ctx) {
- return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
- }
+ @Override
+ public boolean destroy(long ctx) {
+ return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError;
+ }
- @Override
- public boolean copyImpl(long src, int mask) {
- CGL.CGLCopyContext(src, contextHandle, mask);
- return true;
- }
+ @Override
+ public boolean contextRealized(boolean realized) {
+ return true;
+ }
+
+ @Override
+ public boolean copyImpl(long src, int mask) {
+ CGL.CGLCopyContext(src, contextHandle, mask);
+ return true;
+ }
- @Override
- public boolean makeCurrent(long ctx) {
- int err = CGL.CGLLockContext(ctx);
- if(CGL.kCGLNoError == err) {
- err = CGL.CGLSetCurrentContext(ctx);
+ @Override
+ public boolean makeCurrent(long ctx) {
+ int err = CGL.CGLLockContext(ctx);
if(CGL.kCGLNoError == err) {
- return true;
+ err = CGL.CGLSetCurrentContext(ctx);
+ if(CGL.kCGLNoError == err) {
+ return true;
+ } else if(DEBUG) {
+ System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ }
} else if(DEBUG) {
- System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
}
- } else if(DEBUG) {
- System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ return false;
}
- return false;
- }
- @Override
- public boolean release(long ctx) {
- try {
- gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
- gle.printStackTrace();
+ @Override
+ public boolean release(long ctx) {
+ try {
+ gl.glFlush(); // w/o glFlush()/glFinish() OSX < 10.7 (NVidia driver) may freeze
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("MacOSXCGLContext.CGLImpl.release: INFO: glFlush() catched exception:");
+ gle.printStackTrace();
+ }
}
+ int err = CGL.CGLSetCurrentContext(0);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ int err2 = CGL.CGLUnlockContext(ctx);
+ if(DEBUG && CGL.kCGLNoError != err2) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ }
+ return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
+ }
+
+ @Override
+ public boolean detachPBuffer() {
+ /* Doesn't work, i.e. not taking NULL
+ final int res = CGL.CGLSetPBuffer(contextHandle, 0, 0, 0, 0);
+ if (res != CGL.kCGLNoError) {
+ throw new GLException("Error code " + res + " while detaching context from pbuffer");
+ } */
+ return true;
}
- int err = CGL.CGLSetCurrentContext(0);
- if(DEBUG && CGL.kCGLNoError != err) {
- System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+
+ @Override
+ public boolean setSwapInterval(int interval) {
+ int[] lval = new int[] { interval } ;
+ CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
+ return true;
}
- int err2 = CGL.CGLUnlockContext(ctx);
- if(DEBUG && CGL.kCGLNoError != err2) {
- System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ @Override
+ public boolean swapBuffers() {
+ return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
}
- return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
- }
-
- @Override
- public boolean setSwapInterval(int interval) {
- int[] lval = new int[] { interval } ;
- CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
- return true;
- }
- @Override
- public boolean swapBuffers() {
- return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
- }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index af767f0c3..cc727c8e1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -42,10 +42,10 @@ package jogamp.opengl.macosx.cgl;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -92,7 +92,7 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
this.id = id;
}
}
- private List> createdContexts = new ArrayList>();
+ /* pp */ List> createdContexts = new ArrayList>();
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
@@ -110,26 +110,42 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
return GLBackendType.NSOPENGL == openGLMode ? getHandle() : 0;
}
- protected void registerContext(MacOSXCGLContext ctx) {
+ @Override
+ protected void associateContext(GLContext ctx, boolean bound) {
// NOTE: we need to keep track of the created contexts in order to
// implement swapBuffers() because of how Mac OS X implements its
// OpenGL window interface
synchronized (createdContexts) {
- createdContexts.add(new WeakReference