summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax/media
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/javax/media')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java11
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java74
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java111
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java287
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java184
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java246
8 files changed, 522 insertions, 403 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f93d443e0..534e449bc 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -294,6 +294,17 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns true if the GL context supports non power of two (NPOT) textures,
+ * otherwise false.
+ * <p>
+ * NPOT textures are supported in OpenGL >= 3, GLES2 or if the
+ * 'GL_ARB_texture_non_power_of_two' extension is available.
+ * </p>
+ * @return
+ */
+ public boolean isNPOTTextureAvailable();
+
/** 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 9d99a32ff..8626400f7 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -45,9 +45,12 @@ import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.HashMap;
import java.util.HashSet;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
@@ -65,7 +68,8 @@ import jogamp.opengl.GLContextImpl;
abstraction provides a stable object which clients can use to
refer to a given context. */
public abstract class GLContext {
-
+ public static final boolean DEBUG = Debug.debug("GLContext");
+
/** Reflects property jogl.debug.DebugGL. If true, the debug pipeline is enabled at context creation. */
public final static boolean DEBUG_GL;
/** Reflects property jogl.debug.TraceGL. If true, the trace pipeline is enabled at context creation. */
@@ -105,12 +109,15 @@ public abstract class GLContext {
protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 0;
/** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL hardware implementation */
protected static final int CTX_IMPL_ACCEL_HARD = 1 << 1;
-
+
private static ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
private 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();
+
/** The underlying native OpenGL context */
protected long contextHandle;
@@ -293,8 +300,11 @@ public abstract class GLContext {
/**
* Destroys this OpenGL context and frees its associated
- * resources. The context should have been released before this
- * method is called.
+ * resources.
+ * <p>
+ * The context may be current w/o recursion when calling <code>destroy()</code>,
+ * in which case this method destroys the context and releases the lock.
+ * </p>
*/
public abstract void destroy();
@@ -406,6 +416,8 @@ public abstract class GLContext {
sb.append(",\n\tDrawable: ");
sb.append(getGLDrawable());
}
+ sb.append(", lock ");
+ sb.append(lock.toString());
return sb;
}
@@ -767,12 +779,12 @@ public abstract class GLContext {
/**
* @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
*/
- protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+ protected static /*final*/ HashMap<String, Integer> deviceVersionAvailable = new HashMap<String, Integer>();
/**
* @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
*/
- private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+ private static /*final*/ HashSet<String> deviceVersionsAvailableSet = new HashSet<String>();
protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0));
@@ -791,16 +803,18 @@ public abstract class GLContext {
throw new InternalError("Already set: "+devKey);
}
deviceVersionsAvailableSet.add(devKey);
- if (GLContextImpl.DEBUG) {
+ if (DEBUG) {
System.err.println(getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet "+devKey);
// Thread.dumpStack();
}
}
}
+ /** clears the device/context mappings as well as the GL/GLX proc address tables. */
protected static void shutdown() {
deviceVersionAvailable.clear();
- deviceVersionsAvailableSet.clear();
+ deviceVersionsAvailableSet.clear();
+ GLContextImpl.shutdownImpl(); // well ..
}
/**
@@ -824,7 +838,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.put( key, val );
+ val = deviceVersionAvailable.put( key, val );
}
return val;
}
@@ -833,7 +847,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val;
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.get( key );
+ val = deviceVersionAvailable.get( key );
}
return val;
}
@@ -875,29 +889,29 @@ public abstract class GLContext {
return null != getAvailableGLVersion(device, major, profile);
}
- public static boolean isGLES1Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGLES2Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL4Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
- }
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
- public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL3Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
- }
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
public static boolean isGL2Available(AbstractGraphicsDevice device) {
return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
@@ -941,6 +955,10 @@ public abstract class GLContext {
return sb.toString();
}
+ //
+ // internal string utils
+ //
+
protected static String toString(int val, boolean hex) {
if(hex) {
return "0x" + Integer.toHexString(val);
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
index f4cd77059..2b86a04ba 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -158,6 +158,12 @@ public interface GLDrawable {
*/
public GLProfile getGLProfile();
+ /**
+ * Returns the underlying native surface which surface handle
+ * represents this OpenGL drawable's native resource.
+ *
+ * @see #getHandle()
+ */
public NativeSurface getNativeSurface();
/**
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 1282eb168..3f9700436 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -47,12 +47,14 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import jogamp.common.Debug;
+
import com.jogamp.common.util.ReflectionUtil;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLProfile.ShutdownType;
/** <P> Provides a virtual machine- and operating system-independent
mechanism for creating {@link GLDrawable}s. </P>
@@ -87,14 +89,12 @@ import javax.media.nativewindow.ProxySurface;
property <code>opengl.factory.class.name</code> to the
fully-qualified name of the desired class. </P>
*/
-
public abstract class GLDrawableFactory {
- private static final String nativeOSType;
static final String macosxFactoryClassNameCGL = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
static final String macosxFactoryClassNameAWTCGL = "jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
- private static volatile boolean initialized = false;
+ private static volatile boolean isInit = false;
private static GLDrawableFactory eglFactory;
private static GLDrawableFactory nativeOSFactory;
@@ -107,16 +107,20 @@ public abstract class GLDrawableFactory {
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
*/
- static {
- nativeOSType = NativeWindowFactory.getNativeWindowType(true);
- }
-
- protected static final void initialize() {
- if(initialized) { return; }
- initialized = true;
-
+ public static final void initSingleton() {
+ if (!isInit) { // volatile: ok
+ synchronized (GLDrawableFactory.class) {
+ if (!isInit) {
+ isInit=true;
+ initSingletonImpl();
+ }
+ }
+ }
+ }
+ private static final void initSingletonImpl() {
registerFactoryShutdownHook();
+ final String nativeOSType = NativeWindowFactory.getNativeWindowType(true);
GLDrawableFactory tmp = null;
String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true, AccessController.getContext());
ClassLoader cl = GLDrawableFactory.class.getClassLoader();
@@ -165,16 +169,40 @@ public abstract class GLDrawableFactory {
eglFactory = tmp;
}
+ protected static void shutdown(ShutdownType shutdownType) {
+ if (isInit) { // volatile: ok
+ synchronized (GLDrawableFactory.class) {
+ if (isInit) {
+ isInit=false;
+ unregisterFactoryShutdownHook();
+ shutdownImpl(shutdownType);
+ }
+ }
+ }
+ }
+ private static void shutdownImpl(ShutdownType shutdownType) {
+ synchronized(glDrawableFactories) {
+ for(int i=0; i<glDrawableFactories.size(); i++) {
+ glDrawableFactories.get(i).destroy(shutdownType);
+ }
+ glDrawableFactories.clear();
+
+ // both were members of glDrawableFactories and are shutdown already
+ nativeOSFactory = null;
+ eglFactory = null;
+ }
+ }
+
private static synchronized void registerFactoryShutdownHook() {
if (factoryShutdownHookRegistered) {
return;
}
factoryShutdownHook = new Thread(new Runnable() {
public void run() {
- GLDrawableFactory.shutdownImpl();
+ GLDrawableFactory.shutdownImpl(GLProfile.ShutdownType.COMPLETE);
}
});
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
return null;
@@ -187,7 +215,7 @@ public abstract class GLDrawableFactory {
if (!factoryShutdownHookRegistered) {
return;
}
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
return null;
@@ -196,23 +224,6 @@ public abstract class GLDrawableFactory {
factoryShutdownHookRegistered = false;
}
- private static void shutdownImpl() {
- synchronized(glDrawableFactories) {
- for(int i=0; i<glDrawableFactories.size(); i++) {
- GLDrawableFactory factory = glDrawableFactories.get(i);
- factory.shutdownInstance();
- }
- glDrawableFactories.clear();
- }
- }
-
- protected static void shutdown() {
- unregisterFactoryShutdownHook();
- shutdownImpl();
- eglFactory = null;
- nativeOSFactory = null;
- initialized = false;
- }
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
@@ -223,7 +234,7 @@ public abstract class GLDrawableFactory {
protected void enterThreadCriticalZone() {};
protected void leaveThreadCriticalZone() {};
- protected abstract void shutdownInstance();
+ protected abstract void destroy(ShutdownType shutdownType);
/**
* Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
@@ -258,34 +269,31 @@ public abstract class GLDrawableFactory {
}
/**
- * Returns true if a shared context could be created while initialization
- * of shared resources for <code>device</code> {@link AbstractGraphicsDevice#getConnection()}.<br>
- * This does not imply a shared context is mapped, but was available<br>.
- *
- * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * Validate and start the shared resource runner thread if necessary and
+ * if the implementation uses it.
+ *
+ * @return the shared resource runner thread, if implementation uses it.
*/
- public abstract boolean getWasSharedContextCreated(AbstractGraphicsDevice device);
-
+ protected abstract Thread getSharedResourceThread();
+
/**
- * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
- * either a pre-existing or newly created, or <code>null</code> if creation failed or not supported.<br>
- * Creation of the shared context is tried only once.
+ * Create the shared resource used internally as a reference for capabilities etc.
+ * <p>
+ * Returns true if a shared resource could be created
+ * for the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}.<br>
+ * This does not imply a shared resource is mapped (ie. made persistent), but is available in general<br>.
+ * </p>
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @return true if a shared resource could been created, otherwise false.
*/
- public final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
- device = validateDevice(device);
- if(null!=device) {
- return getOrCreateSharedContextImpl(device);
- }
- return null;
- }
- protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
-
+ protected abstract boolean createSharedResource(AbstractGraphicsDevice device);
+
/**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
*/
public static GLDrawableFactory getDesktopFactory() {
+ GLProfile.initSingleton();
return nativeOSFactory;
}
@@ -293,6 +301,7 @@ public abstract class GLDrawableFactory {
* Returns the sole GLDrawableFactory instance for EGL if exist or null
*/
public static GLDrawableFactory getEGLFactory() {
+ GLProfile.initSingleton();
return eglFactory;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 20e2f2a33..6b39fe765 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -48,6 +48,8 @@ import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.cache.TempJarCache;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveThreadGroupLock;
import com.jogamp.nativewindow.NativeWindowVersion;
import com.jogamp.opengl.JoglVersion;
@@ -74,56 +76,80 @@ public class GLProfile {
public static final boolean DEBUG = Debug.debug("GLProfile");
+ static {
+ // Also initializes TempJarCache if shall be used.
+ Platform.initSingleton();
+ }
+
/**
- * Static one time initialization of JOGL.
+ * Static initialization of JOGL.
* <p>
* The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
* see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
* </p>
* <p>
- * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br>
- * You may issue the call in your <code>main class</code> static block, which is the earliest point in your application/applet lifecycle,
- * or within the <code>main function</code>.<br>
- * In case applications are able to initialize JOGL before any other UI action,<br>
- * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P>
- * <P>
- * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL may not be able to initialize JOGL
- * before the first UI action.<br>
- * In such case you shall invoke this method with <code>firstUIActionOnProcess=false</code>.<br>
- * On some platforms, notably X11 with AWT usage, JOGL will utilize special locking mechanisms which may slow down your
- * application.</P>
+ * Applications using this method may place it's call before any other UI invocation
+ * in the <code>main class</code>'s static block or within the <code>main function</code>.
+ * In such case, applications may pass <code>firstUIActionOnProcess=true</code> to use native toolkit locking.</P>
* <P>
- * Remark: NEWT is currently not affected by this behavior, ie always uses native multithreading.</P>
+ * 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 <code>firstUIActionOnProcess=false</code>.</P>
* <P>
- * However, in case this method is not invoked, hence GLProfile is not initialized explicitly by the user,<br>
- * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}, etc, will initialize with <code>firstUIActionOnProcess=false</code>,<br>
- * hence without the possibility to enable native multithreading.<br>
- * This is not the recommended way, since it may has a performance impact, but it allows you to run code without explicit initialization.</P>
+ * In case this method is not invoked, GLProfile is initialized implicit by
+ * the first call to {@link #getDefault()}, {@link #get(java.lang.String)} passing <code>firstUIActionOnProcess=false</code>.
* <P>
*
* @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
* otherwise <code>false</code>.
+ *
+ * @deprecated This method shall not need to be called for other reasons than having a defined initialization sequence.
+ * To ensure homogeneous behavior with application not calling this method, you shall pass <code>firstUIActionOnProcess=false</code>.
+ * This method is subject to be removed in future versions of JOGL.
*/
- public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
- if(!initialized) {
- initialized = true;
- // run the whole static initialization privileged to speed up,
- // since this skips checking further access
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- if(TempJarCache.isInitialized()) {
- String[] atomicNativeJarBaseNames = new String[] { "nativewindow", "jogl", null };
- if( ReflectionUtil.isClassAvailable("com.jogamp.newt.NewtFactory", GLProfile.class.getClassLoader()) ) {
- atomicNativeJarBaseNames[2] = "newt";
- }
- JNILibLoaderBase.addNativeJarLibs(GLProfile.class, "jogl.all", "jogl-all", atomicNativeJarBaseNames);
- }
- initProfilesForDefaultDevices(firstUIActionOnProcess);
- return null;
+ public static void initSingleton(final boolean firstUIActionOnProcess) {
+ initLock.lock();
+ try {
+ if(!initialized) { // volatile: ok
+ initialized = true;
+ if(DEBUG) {
+ System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
+ Thread.dumpStack();
}
- });
+
+ // run the whole static initialization privileged to speed up,
+ // since this skips checking further access
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ Platform.initSingleton();
+
+ if(TempJarCache.isInitialized()) {
+ String[] atomicNativeJarBaseNames = new String[] { "nativewindow", "jogl", null };
+ if( ReflectionUtil.isClassAvailable("com.jogamp.newt.NewtFactory", GLProfile.class.getClassLoader()) ) {
+ atomicNativeJarBaseNames[2] = "newt";
+ }
+ JNILibLoaderBase.addNativeJarLibs(GLProfile.class, "jogl-all", atomicNativeJarBaseNames);
+ }
+ initProfilesForDefaultDevices(firstUIActionOnProcess);
+ return null;
+ }
+ });
+ }
+ } finally {
+ initLock.unlock();
}
}
+
+ /**
+ * Static initialization of JOGL.
+ *
+ * <p>
+ * This method shall not need to be called for other reasons than having a defined initialization sequence.
+ * </p>
+ */
+ public static void initSingleton() {
+ GLProfile.initSingleton(false);
+ }
/**
* Trigger eager initialization of GLProfiles for the given device,
@@ -132,21 +158,50 @@ public class GLProfile {
* @throws GLException if no profile for the given device is available.
*/
public static void initProfiles(AbstractGraphicsDevice device) throws GLException {
- getProfileMap(device);
+ getProfileMap(device, true);
}
+ /**
+ * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}.
+ * <p>
+ * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.<br>
+ * {@link #COMPLETE} Everything.<br>
+ * </p>
+ */
+ 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.<br>
* It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
- * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked here.<br>
- * Invoke <code>shutdown()</code> manually is recommended, due to the unreliable JVM state within the shutdown hook.<br>
+ * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br>
+ * <p>
+ * This method shall not need to be called for other reasons than issuing a proper shutdown of resources.
+ * </p>
+ * @param type the shutdown type, see {@link ShutdownType}.
*/
- public static synchronized void shutdown() {
- if(initialized) {
- initialized = false;
- GLDrawableFactory.shutdown();
- GLContext.shutdown();
+ public static void shutdown(ShutdownType type) {
+ initLock.lock();
+ try {
+ if(initialized) { // volatile: ok
+ initialized = false;
+ if(DEBUG) {
+ System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ GLDrawableFactory.shutdown(type);
+ if(ShutdownType.COMPLETE == type) {
+ GLContext.shutdown();
+ }
+ NativeWindowFactory.shutdown();
+ }
+ } finally {
+ initLock.unlock();
}
}
@@ -163,12 +218,13 @@ public class GLProfile {
* @return true if the profile is available for the device, otherwise false.
*/
public static boolean isAvailable(AbstractGraphicsDevice device, String profile) {
- try {
- return null != getProfileMap(device).get(profile);
- } catch (GLException gle) { /* profiles for device n/a */ }
- return false;
+ initSingleton();
+ return isAvailableImpl(getProfileMap(device, false), profile);
}
-
+ private static boolean isAvailableImpl(HashMap<String /*GLProfile_name*/, GLProfile> map, String profile) {
+ return null != map && null != map.get(profile);
+ }
+
/**
* Returns the availability of a profile on the default device.
*
@@ -193,74 +249,71 @@ public class GLProfile {
boolean avail;
StringBuffer sb = new StringBuffer();
- validateInitialization();
-
+ initSingleton();
+
if(null==device) {
device = defaultDevice;
}
-
+ final HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, false);
+
sb.append("GLAvailability[Native[GL4bc ");
- avail=isAvailable(device, GL4bc);
+ avail=isAvailableImpl(map, GL4bc);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL4 ");
- avail=isAvailable(device, GL4);
+ avail=isAvailableImpl(map, GL4);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL3bc ");
- avail=isAvailable(device, GL3bc);
+ avail=isAvailableImpl(map, GL3bc);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL3 ");
- avail=isAvailable(device, GL3);
+ avail=isAvailableImpl(map, GL3);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL2 ");
- avail=isAvailable(device, GL2);
+ avail=isAvailableImpl(map, GL2);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL2ES1 ");
- sb.append(isAvailable(device, GL2ES1));
+ sb.append(isAvailableImpl(map, GL2ES1));
sb.append(", GLES1 ");
- avail=isAvailable(device, GLES1);
+ avail=isAvailableImpl(map, GLES1);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 1, GLContext.CTX_PROFILE_ES);
}
sb.append(", GL2ES2 ");
- sb.append(isAvailable(device, GL2ES2));
+ sb.append(isAvailableImpl(map, GL2ES2));
sb.append(", GLES2 ");
- avail=isAvailable(device, GLES2);
+ avail=isAvailableImpl(map, GLES2);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_ES);
}
sb.append("], Profiles[");
- HashMap<String /*GLProfile_name*/, GLProfile> profileMap = null;
- try {
- profileMap = getProfileMap(device);
- } catch (GLException gle) { /* profiles for device n/a */ }
- if(null != profileMap) {
- for(Iterator<GLProfile> i=profileMap.values().iterator(); i.hasNext(); ) {
+ if(null != map) {
+ for(Iterator<GLProfile> i=map.values().iterator(); i.hasNext(); ) {
sb.append(i.next().toString());
sb.append(", ");
}
@@ -275,7 +328,7 @@ public class GLProfile {
return sb.toString();
}
-
+
/** Uses the default device */
public static String glAvailabilityToString() {
return glAvailabilityToString(null);
@@ -596,7 +649,7 @@ public class GLProfile {
if(null==profile || profile.equals("GL")) {
profile = GL_DEFAULT;
}
- final HashMap<String /*GLProfile_name*/, GLProfile> glpMap = getProfileMap(device);
+ final HashMap<String /*GLProfile_name*/, GLProfile> glpMap = getProfileMap(device, true);
final GLProfile glp = glpMap.get(profile);
if(null == glp) {
throw new GLException("Profile "+profile+" is not available on "+device+", but: "+glpMap.values());
@@ -626,7 +679,7 @@ public class GLProfile {
public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
throws GLException
{
- HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device);
+ HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, true);
for(int i=0; i<profiles.length; i++) {
String profile = profiles[i];
GLProfile glProfile = map.get(profile);
@@ -1137,10 +1190,6 @@ public class GLProfile {
return "GLProfile[" + getName() + "/" + getImplName() + "]";
}
- static {
- Platform.initSingleton();
- }
-
private static /*final*/ boolean isAWTAvailable;
private static /*final*/ boolean hasDesktopGLFactory;
@@ -1155,7 +1204,8 @@ public class GLProfile {
private static /*final*/ AbstractGraphicsDevice defaultDesktopDevice;
private static /*final*/ AbstractGraphicsDevice defaultEGLDevice;
- static boolean initialized = false;
+ private static volatile boolean initialized = false;
+ private static RecursiveThreadGroupLock initLock = LockFactory.createRecursiveThreadGroupLock();
/**
* Tries the profiles implementation and native libraries.
@@ -1191,7 +1241,7 @@ public class GLProfile {
// - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
// which will register at GLContext ..
//
- GLDrawableFactory.initialize();
+ GLDrawableFactory.initSingleton();
Throwable t=null;
// if successfull it has a shared dummy drawable and context created
@@ -1295,19 +1345,24 @@ public class GLProfile {
* @param device the device for which profiles shall be initialized
* @return true if any profile for the device exists, otherwise false
*/
- private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ private static boolean initProfilesForDevice(AbstractGraphicsDevice device) {
if(null == device) {
return false;
}
- GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
- factory.enterThreadCriticalZone();
+ initLock.lock();
try {
- return initProfilesForDeviceCritical(device);
+ GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
+ factory.enterThreadCriticalZone();
+ try {
+ return initProfilesForDeviceCritical(device);
+ } finally {
+ factory.leaveThreadCriticalZone();
+ }
} finally {
- factory.leaveThreadCriticalZone();
+ initLock.unlock();
}
}
- private static synchronized boolean initProfilesForDeviceCritical(AbstractGraphicsDevice device) {
+ private static boolean initProfilesForDeviceCritical(AbstractGraphicsDevice device) {
boolean isSet = GLContext.getAvailableGLVersionsSet(device);
if(DEBUG) {
@@ -1331,11 +1386,21 @@ public class GLProfile {
// Triggers eager initialization of share context in GLDrawableFactory for the device,
// hence querying all available GLProfiles
- boolean desktopSharedCtxAvail = desktopFactory.getWasSharedContextCreated(device);
+ final Thread sharedResourceThread = desktopFactory.getSharedResourceThread();
+ if(null != sharedResourceThread) {
+ initLock.addOwner(sharedResourceThread);
+ }
+ boolean desktopSharedCtxAvail = desktopFactory.createSharedResource(device);
+ if(null != sharedResourceThread) {
+ initLock.removeOwner(sharedResourceThread);
+ }
+ if(!desktopSharedCtxAvail) {
+ hasDesktopGLFactory = false;
+ }
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
}
- if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
+ if( hasDesktopGLFactory && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
// nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
// so we have to add the usual suspect
GLContext.mapAvailableGLVersion(device,
@@ -1350,7 +1415,22 @@ public class GLProfile {
// Triggers eager initialization of share context in GLDrawableFactory for the device,
// hence querying all available GLProfiles
- boolean eglSharedCtxAvail = eglFactory.getWasSharedContextCreated(device);
+ final Thread sharedResourceThread = eglFactory.getSharedResourceThread();
+ if(null != sharedResourceThread) {
+ initLock.addOwner(sharedResourceThread);
+ }
+ boolean eglSharedCtxAvail = eglFactory.createSharedResource(device);
+ if(null != sharedResourceThread) {
+ initLock.removeOwner(sharedResourceThread);
+ }
+ if(!eglSharedCtxAvail) {
+ // Remark: On Windows there is a libEGL.dll delivered w/ Chrome 15.0.874.121m and Firefox 8.0.1
+ // but it seems even EGL.eglInitialize(eglDisplay, null, null)
+ // fails in some scenarios (eg VirtualBox 4.1.6) w/ EGL error 0x3001 (EGL_NOT_INITIALIZED).
+ hasEGLFactory = false;
+ hasGLES2Impl = false;
+ hasGLES1Impl = false;
+ }
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
}
@@ -1423,30 +1503,20 @@ public class GLProfile {
}
public static AbstractGraphicsDevice getDefaultDevice() {
- validateInitialization();
+ initSingleton();
return defaultDevice;
}
public static AbstractGraphicsDevice getDefaultDesktopDevice() {
- validateInitialization();
+ initSingleton();
return defaultDesktopDevice;
}
public static AbstractGraphicsDevice getDefaultEGLDevice() {
- validateInitialization();
+ initSingleton();
return defaultEGLDevice;
}
- private static void validateInitialization() {
- if(!initialized) {
- synchronized(GLProfile.class) {
- if(!initialized) {
- initSingleton(false);
- }
- }
- }
- }
-
private static String array2String(String[] list) {
StringBuffer msg = new StringBuffer();
msg.append("[");
@@ -1608,29 +1678,38 @@ public class GLProfile {
* - initialization<br<
*
* @param device the key 'device -> GLProfiles-Map'
+ * @param throwExceptionOnZeroProfile true if <code>GLException</code> shall be thrown in case of no mapped profile, otherwise false.
* @return the GLProfile HashMap if exists, otherwise null
* @throws GLException if no profile for the given device is available.
*/
- private static HashMap<String /*GLProfile_name*/, GLProfile> getProfileMap(AbstractGraphicsDevice device) throws GLException {
- validateInitialization();
+ private static HashMap<String /*GLProfile_name*/, GLProfile> getProfileMap(AbstractGraphicsDevice device, boolean throwExceptionOnZeroProfile)
+ throws GLException
+ {
+ initSingleton();
+
if(null==device) {
device = defaultDevice;
}
String deviceKey = device.getUniqueID();
HashMap<String /*GLProfile_name*/, GLProfile> map = deviceConn2ProfileMap.get(deviceKey);
- if( null == map ) {
- if( !initProfilesForDevice(device) ) {
+ if( null != map ) {
+ return map;
+ }
+ if( !initProfilesForDevice(device) ) {
+ if( throwExceptionOnZeroProfile ) {
throw new GLException("No Profile available for "+device);
+ } else {
+ return null;
}
- if( null == deviceConn2ProfileMap.get(deviceKey) ) {
- throw new InternalError("initProfilesForDevice(..) didn't issue setProfileMap(..) on "+device);
- }
+ }
+ map = deviceConn2ProfileMap.get(deviceKey);
+ if( null == map && throwExceptionOnZeroProfile ) {
+ throw new InternalError("initProfilesForDevice(..) didn't setProfileMap(..) for "+device);
}
return map;
}
private static void setProfileMap(AbstractGraphicsDevice device, HashMap<String /*GLProfile_name*/, GLProfile> mappedProfiles) {
- validateInitialization();
synchronized ( deviceConn2ProfileMap ) {
deviceConn2ProfileMap.put(device.getUniqueID(), mappedProfiles);
}
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
index 5c9388be2..475ff4546 100644
--- a/src/jogl/classes/javax/media/opengl/GLUniformData.java
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -107,10 +107,10 @@ public class GLUniformData {
if(data instanceof Buffer) {
final int sz = rows*columns;
final Buffer buffer = (Buffer)data;
- if(buffer.limit()<sz || 0!=buffer.limit()%sz) {
- throw new GLException("data buffer size invalid: new buffer limit: "+buffer.limit()+"\n\t"+this);
+ if(buffer.remaining()<sz || 0!=buffer.remaining()%sz) {
+ throw new GLException("remaining data buffer size invalid: buffer: "+buffer.toString()+"\n\t"+this);
}
- this.count=buffer.limit()/(rows*columns);
+ this.count=buffer.remaining()/(rows*columns);
} else {
if(isMatrix) {
throw new GLException("Atom type not allowed for matrix : "+this);
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index ada9f5222..cd341593e 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -59,8 +59,9 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -92,6 +93,8 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+
+import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
@@ -136,7 +139,7 @@ import jogamp.opengl.ThreadingImpl;
*/
@SuppressWarnings("serial")
-public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol, OffscreenLayerOption {
private static final boolean DEBUG;
@@ -156,6 +159,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private GLContext shareWith;
private int additionalCtxCreationFlags = 0;
private GraphicsDevice device;
+ private boolean shallUseOffscreenLayer = false;
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
@@ -250,6 +254,22 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
this.device = device;
}
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ if(null != drawable) {
+ return ((JAWTWindow)drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+ }
+ return false;
+ }
+
+
/**
* Overridden to choose a GraphicsConfiguration on a parent container's
* GraphicsDevice because both devices
@@ -279,7 +299,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* otherwise it is from an ancestor component that this Canvas is being
* added to, and we go into this block.
*/
- GraphicsConfiguration chosen = awtConfig.getGraphicsConfiguration();
+ GraphicsConfiguration chosen = awtConfig.getAWTGraphicsConfiguration();
if (gc != null && chosen != null && !chosen.equals(gc)) {
/*
@@ -308,7 +328,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
AWTGraphicsConfiguration config = chooseGraphicsConfiguration( (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities(),
(GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities(),
chooser, gc.getDevice());
- final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ final GraphicsConfiguration compatible = (null!=config)?config.getAWTGraphicsConfiguration():null;
boolean equalCaps = config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities());
if(DEBUG) {
Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
@@ -406,15 +426,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private void dispose(boolean regenerate) {
drawableSync.lock();
try {
+ final GLAnimatorControl animator = getAnimator();
if(DEBUG) {
- Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
- (null!=context) + ", hasDrawable " + (null!=drawable));
+ Exception ex1 = new Exception("Info: dispose("+regenerate+") - START, hasContext " +
+ (null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
ex1.printStackTrace();
}
if(null!=context) {
boolean animatorPaused = false;
- GLAnimatorControl animator = getAnimator();
if(null!=animator) {
// can't remove us from animator for recreational addNotify()
animatorPaused = animator.pause();
@@ -422,37 +442,38 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
disposeRegenerate=regenerate;
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- // Workaround for termination issues with applets --
- // sun.applet.AppletPanel should probably be performing the
- // remove() call on the EDT rather than on its own thread
- // Hint: User should run remove from EDT.
- if (ThreadingImpl.isAWTMode() &&
- Thread.holdsLock(getTreeLock())) {
- // The user really should not be invoking remove() from this
- // thread -- but since he/she is, we can not go over to the
- // EDT at this point. Try to destroy the context from here.
- if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ if(context.isCreated()) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ // Hint: User should run remove from EDT.
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
}
- } else if(context.isCreated()) {
- Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
- }
- } else if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
}
if(animatorPaused) {
animator.resume();
}
}
+
if(!regenerate) {
disposeAbstractGraphicsDevice();
}
if(DEBUG) {
- System.err.println("dispose("+regenerate+") - stop");
+ System.err.println("dispose("+regenerate+") - END, "+animator);
}
} finally {
drawableSync.unlock();
@@ -532,15 +553,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
throw new GLException("Error: NULL AWTGraphicsConfiguration");
}
- if (!Beans.isDesignTime()) {
- // no lock required, since this resource ain't available yet
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
- .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setSynchronized(true);
- context.setContextCreationFlags(additionalCtxCreationFlags);
- }
-
// before native peer is valid: X11
disableBackgroundErase();
@@ -550,6 +562,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// 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();
@@ -562,6 +578,21 @@ 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.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ jawtWindow.lockSurface();
+ try {
+ drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ } finally {
+ jawtWindow.unlockSurface();
+ }
+ }
+
private boolean validateGLDrawable() {
boolean realized = false;
if (!Beans.isDesignTime()) {
@@ -636,7 +667,11 @@ 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);
- sendReshape = true;
+ if(null != drawable && drawable.isRealized() && !drawable.getChosenGLCapabilities().isOnscreen()) {
+ dispose(true);
+ } else {
+ sendReshape = true;
+ }
}
/** <B>Overrides:</B>
@@ -800,63 +835,60 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
- class DisposeAction implements Runnable {
+ class PostDisposeAction implements Runnable {
public void run() {
- drawableHelper.dispose(GLCanvas.this);
-
- if(null!=context) {
- context.makeCurrent(); // implicit wait for lock ..
- context.destroy();
- context=null;
- }
-
+ context=null;
if(null!=drawable) {
+ final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
drawable.setRealized(false);
drawable=null;
+ if(null!=jawtWindow) {
+ jawtWindow.destroy();
+ }
}
-
+
if(disposeRegenerate) {
- // recreate GLDrawable to reflect it's new graphics configuration
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
- .createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig));
+ // Similar process as in addNotify()!
+
+ // Recreate GLDrawable/GLContext to reflect it's new graphics configuration
+ createDrawableAndContext();
+
if(DEBUG) {
System.err.println("GLCanvas.dispose(true): new drawable: "+drawable);
}
- drawable.setRealized(true);
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setSynchronized(true);
- sendReshape=true; // ensure a reshape is being send ..
+ validateGLDrawable(); // immediate attempt to recreate the drawable
}
}
}
private boolean disposeRegenerate;
- private DisposeAction disposeAction = new DisposeAction();
+ private PostDisposeAction postDisposeAction = new PostDisposeAction();
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
new DisposeOnEventDispatchThreadAction();
class DisposeOnEventDispatchThreadAction implements Runnable {
public void run() {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
}
}
class DisposeAbstractGraphicsDeviceAction implements Runnable {
public void run() {
- AbstractGraphicsConfiguration aconfig = (null!=awtConfig) ? awtConfig.getNativeGraphicsConfiguration() : null;
- AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
- AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null;
- if(null!=adevice) {
- String adeviceMsg=null;
+ if(null != awtConfig) {
+ final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final String adeviceMsg;
if(DEBUG) {
adeviceMsg = adevice.toString();
+ } else {
+ adeviceMsg = null;
}
boolean closed = adevice.close();
if(DEBUG) {
System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
+ awtConfig=null;
}
- awtConfig=null;
}
}
private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
@@ -1001,7 +1033,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
return null;
}
- final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AbstractGraphicsScreen aScreen = null != device ?
+ AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT):
+ AWTGraphicsScreen.createDefault();
AWTGraphicsConfiguration config = null;
if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
@@ -1045,7 +1079,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- GLProfile.initSingleton(false);
GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
List<GLCapabilitiesImmutable> availCaps = factory.getAvailableCapabilities(null);
for(int i=0; i<availCaps.size(); i++) {
@@ -1053,9 +1086,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
- Frame frame = new Frame("JOGL AWT Test");
+ final Frame frame = new Frame("JOGL AWT Test");
- GLCanvas glCanvas = new GLCanvas(caps);
+ final GLCanvas glCanvas = new GLCanvas(caps);
frame.add(glCanvas);
frame.setSize(128, 128);
@@ -1064,24 +1097,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
GL gl = drawable.getGL();
System.err.println(JoglVersion.getGLInfo(gl, null));
}
-
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- }
-
- public void display(GLAutoDrawable drawable) {
- }
-
- public void dispose(GLAutoDrawable drawable) {
- }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ public void display(GLAutoDrawable drawable) { }
+ public void dispose(GLAutoDrawable drawable) { }
});
- final Frame _frame = frame;
- final GLCanvas _glCanvas = glCanvas;
-
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- _frame.setVisible(true);
+ frame.setVisible(true);
}});
} catch (Throwable t) {
t.printStackTrace();
@@ -1090,9 +1114,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- _frame.setVisible(false);
- _frame.remove(_glCanvas);
- _frame.dispose();
+ frame.dispose();
}});
} catch (Throwable t) {
t.printStackTrace();
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 92be62b4d..7a87882ca 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -82,7 +82,10 @@ import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
+
import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.util.GLBuffers;
+
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -123,9 +126,9 @@ import jogamp.opengl.awt.Java2DGLContext;
* </P>
*/
+@SuppressWarnings("serial")
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
- private static final boolean VERBOSE = Debug.verbose();
private GLDrawableHelper drawableHelper = new GLDrawableHelper();
private volatile boolean isInitialized;
@@ -268,70 +271,51 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
- protected void dispose(boolean regenerate) {
+ protected void dispose() {
if(DEBUG) {
- Exception ex1 = new Exception("Info: dispose("+regenerate+") - start");
- ex1.printStackTrace();
+ System.err.println("Info: dispose() - start - "+Thread.currentThread().getName());
+ Thread.dumpStack();
}
- if (backend != null) {
+ if (backend != null && backend.getContext() != null) {
boolean animatorPaused = false;
GLAnimatorControl animator = getAnimator();
if(null!=animator) {
- if(regenerate) {
- animatorPaused = animator.pause();
- }
- }
-
- disposeRegenerate=regenerate;
- disposeContext=backend.getContext();
- disposeDrawable=backend.getDrawable();
-
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- // Workaround for termination issues with applets --
- // sun.applet.AppletPanel should probably be performing the
- // remove() call on the EDT rather than on its own thread
- if (ThreadingImpl.isAWTMode() &&
- Thread.holdsLock(getTreeLock())) {
- // The user really should not be invoking remove() from this
- // thread -- but since he/she is, we can not go over to the
- // EDT at this point. Try to destroy the context from here.
- if(disposeContext.isCreated()) {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
- }
- } else if(disposeContext.isCreated()) {
- Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
- }
- } else if(disposeContext.isCreated()) {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ animatorPaused = animator.pause();
}
- if(!regenerate) {
- AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
- String adeviceMsg=null;
- if(DEBUG) {
- adeviceMsg = adevice.toString();
- }
- // boolean closed = adevice.close();
- boolean closed = false;
- if (DEBUG) {
- System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
+ if(backend.getContext().isCreated()) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
}
}
-
- backend.setContext(disposeContext);
- if(null==disposeContext) {
- isInitialized = false;
+ if(null != backend) {
+ // not yet destroyed due to backend.isUsingOwnThreadManagment() == true
+ backend.destroy();
+ isInitialized = false;
}
if(animatorPaused) {
animator.resume();
- }
+ }
}
-
+
if(DEBUG) {
- System.err.println("dispose("+regenerate+") - stop");
+ System.err.println("dispose() - stop");
}
}
@@ -347,8 +331,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.paintComponent() in their paintComponent() method in order
to function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>paintComponent</CODE> in class <CODE>javax.swing.JComponent</CODE></DD></DL> */
+ @Override
protected void paintComponent(final Graphics g) {
if (Beans.isDesignTime()) {
// Make GLJPanel behave better in NetBeans GUI builder
@@ -396,8 +380,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.addNotify() in their addNotify() method in order to
function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
public void addNotify() {
super.addNotify();
if (DEBUG) {
@@ -410,26 +394,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.removeNotify() in their removeNotify() method in order to
function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
public void removeNotify() {
- if(DEBUG) {
- Exception ex1 = new Exception("Info: removeNotify - start");
- ex1.printStackTrace();
- }
-
awtWindowClosingProtocol.removeClosingListener();
- dispose(false);
- if (backend != null) {
- backend.destroy();
- backend = null;
- }
- isInitialized = false;
+ dispose();
super.removeNotify();
- if(DEBUG) {
- System.err.println("Info: removeNotify - end");
- }
}
/** Overridden to cause {@link GLDrawableHelper#reshape} to be
@@ -437,9 +408,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
which override this method must call super.reshape() in
their reshape() method in order to function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- public void reshape(int x, int y, int width, int height) {
+ @SuppressWarnings("deprecation")
+ @Override
+public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
// reshapeX = x;
@@ -449,6 +421,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
handleReshape = true;
}
+ @Override
public void setOpaque(boolean opaque) {
if (backend != null) {
backend.setOpaque(opaque);
@@ -481,7 +454,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- return backend.createContext(shareWith);
+ return (null != backend) ? backend.createContext(shareWith) : null;
}
public void setRealized(boolean realized) {
@@ -690,7 +663,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return;
}
if (sendReshape) {
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")");
}
drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight);
@@ -713,42 +686,26 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]";
}
- private boolean disposeRegenerate;
- private GLContext disposeContext;
- private GLDrawable disposeDrawable;
- private DisposeAction disposeAction = new DisposeAction();
-
- class DisposeAction implements Runnable {
+ class PostDisposeAction implements Runnable {
public void run() {
- updater.dispose(GLJPanel.this);
-
- if (null != disposeContext) {
- disposeContext.destroy();
- disposeContext = null;
- }
- if (null != disposeDrawable) {
- disposeDrawable.setRealized(false);
- }
- if (null != disposeDrawable) {
- if (disposeRegenerate) {
- disposeDrawable.setRealized(true);
- disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
- disposeContext.setSynchronized(true);
- }
+ if (backend != null && !backend.isUsingOwnThreadManagment()) {
+ backend.destroy();
+ backend = null;
+ isInitialized = false;
}
}
}
+ private PostDisposeAction postDisposeAction = new PostDisposeAction();
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
new DisposeOnEventDispatchThreadAction();
class DisposeOnEventDispatchThreadAction implements Runnable {
public void run() {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
}
}
-
-
+
class InitAction implements Runnable {
public void run() {
updater.init(GLJPanel.this);
@@ -776,17 +733,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (number == 0) {
return 2;
}
-
- if (((number-1) & number) == 0) {
- //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
- return number;
- }
- int power = 0;
- while (number > 0) {
- number = number>>1;
- power++;
- }
- return (1<<power);
+ return GLBuffers.getNextPowerOf2(number);
}
private int getGLInteger(GL gl, int which) {
@@ -803,6 +750,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// software / pixmap rendering, pbuffer-based acceleration, Java 2D
// / JOGL bridge
static interface Backend {
+ // Create, Destroy, ..
+ public boolean isUsingOwnThreadManagment();
+
// Called each time the backend needs to initialize itself
public void initialize();
@@ -862,7 +812,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
protected int readBackWidthInPixels;
protected int readBackHeightInPixels;
- private int awtFormat;
private int glFormat;
private int glType;
@@ -1031,7 +980,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private GLDrawableImpl offscreenDrawable;
private GLContextImpl offscreenContext;
+ public boolean isUsingOwnThreadManagment() { return false; }
+
public void initialize() {
+ if(DEBUG) {
+ System.err.println("SoftwareBackend: initialize() - "+Thread.currentThread().getName());
+ }
// Fall-through path: create an offscreen context instead
offscreenDrawable = (GLDrawableImpl) factory.createOffscreenDrawable(
null /* default platform device */,
@@ -1039,6 +993,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
chooser,
Math.max(1, panelWidth),
Math.max(1, panelHeight));
+ offscreenDrawable.setRealized(true);
offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
offscreenContext.setSynchronized(true);
offscreenContext.setContextCreationFlags(additionalCtxCreationFlags);
@@ -1047,18 +1002,25 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("SoftwareBackend: destroy() - offscreenContext: "+(null!=offscreenContext)+" - offscreenDrawable: "+(null!=offscreenDrawable)+" - "+Thread.currentThread().getName());
+ }
if (offscreenContext != null) {
offscreenContext.destroy();
offscreenContext = null;
}
if (offscreenDrawable != null) {
+ final AbstractGraphicsDevice adevice = offscreenDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
offscreenDrawable.destroy();
offscreenDrawable = null;
+ if(null != adevice) {
+ adevice.close();
+ }
}
}
public GLContext createContext(GLContext shareWith) {
- return offscreenDrawable.createContext(shareWith);
+ return (null != offscreenDrawable) ? offscreenDrawable.createContext(shareWith) : null;
}
public void setContext(GLContext ctx) {
@@ -1117,10 +1079,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private int pbufferWidth = 256;
private int pbufferHeight = 256;
+ public boolean isUsingOwnThreadManagment() { return false; }
+
public void initialize() {
if (pbuffer != null) {
throw new InternalError("Creating pbuffer twice without destroying it (memory leak / correctness bug)");
}
+ if(DEBUG) {
+ System.err.println("PbufferBackend: initialize() - "+Thread.currentThread().getName());
+ }
try {
pbuffer = factory.createGLPbuffer(null /* default platform device */,
offscreenCaps,
@@ -1144,6 +1111,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("PbufferBackend: destroy() - pbuffer: "+(null!=pbuffer)+" - "+Thread.currentThread().getName());
+ }
if (pbuffer != null) {
pbuffer.destroy();
pbuffer = null;
@@ -1151,7 +1121,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- return pbuffer.createContext(shareWith);
+ return (null != pbuffer) ? pbuffer.createContext(shareWith) : null;
}
public void setContext(GLContext ctx) {
@@ -1265,7 +1235,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private Object j2dSurface;
// Graphics object being used during Java2D update action
// (absolutely essential to cache this)
- private Graphics cached2DGraphics;
// No-op context representing the Java2D OpenGL context
private GLContext j2dContext;
// Context associated with no-op drawable representing the JOGL
@@ -1308,7 +1277,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// comment related to Issue 274 below
private GraphicsConfiguration workaroundConfig;
+ public boolean isUsingOwnThreadManagment() { return true; }
+
public void initialize() {
+ if(DEBUG) {
+ System.err.println("J2DOGL: initialize() - "+Thread.currentThread().getName());
+ }
// No-op in this implementation; everything is done lazily
isInitialized = true;
}
@@ -1316,6 +1290,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
public void destroy() {
Java2D.invokeWithOGLContextCurrent(null, new Runnable() {
public void run() {
+ if(DEBUG) {
+ System.err.println("J2DOGL: destroy() - joglContext: "+(null!=joglContext)+" - joglDrawable: "+(null!=joglDrawable)+" - "+Thread.currentThread().getName());
+ }
if (joglContext != null) {
joglContext.destroy();
joglContext = null;
@@ -1334,9 +1311,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- // FIXME: should implement this, but it was not properly
- // implemented before the refactoring anyway
- throw new GLException("Not yet implemented");
+ if(null != shareWith) {
+ throw new GLException("J2DOGLBackend cannot create context w/ additional shared context, since it already needs to share the context w/ J2D.");
+ }
+ return (null != joglDrawable && null != j2dContext) ? joglDrawable.createContext(j2dContext) : null;
}
public void setContext(GLContext ctx) {
@@ -1372,12 +1350,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
Rectangle r = Java2D.getOGLScissorBox(g);
if (r == null) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("Java2D.getOGLScissorBox() returned null");
}
return false;
}
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: gl.glScissor(" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + ")");
}
@@ -1418,14 +1396,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Need to do workarounds
fbObjectWorkarounds = true;
createNewDepthBuffer = true;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: ERR GL_FRAMEBUFFER_BINDING: Discovered Invalid J2D FBO("+frameBuffer[0]+"): "+FBObject.getStatusString(status) +
", frame_buffer_object workarounds to be necessary");
}
} else {
// Don't need the frameBufferTexture temporary any more
frameBufferTexture = null;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]);
}
}
@@ -1472,7 +1450,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
fboTextureTarget,
frameBufferTexture[0],
0);
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]);
}
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
@@ -1489,7 +1467,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
} else {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: Setting up drawBuffer " + drawBuffer[0] +
" and readBuffer " + readBuffer[0]);
}
@@ -1547,14 +1525,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
Java2D.invokeWithOGLContextCurrent(g, new Runnable() {
public void run() {
- if (DEBUG && VERBOSE) {
- System.err.println("-- In invokeWithOGLContextCurrent");
+ if (DEBUG) {
+ System.err.println("-- In invokeWithOGLContextCurrent - "+Thread.currentThread().getName());
}
// Create no-op context representing Java2D context
if (j2dContext == null) {
j2dContext = factory.createExternalGLContext();
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("-- Created External Context: "+j2dContext);
}
if (DEBUG) {
@@ -1595,15 +1573,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
backend = null;
oglPipelineEnabled = false;
handleReshape = true;
- j2dContext.release();
j2dContext.destroy();
j2dContext = null;
return;
}
- j2dContext.release();
+ } else {
+ j2dContext.makeCurrent();
}
-
- j2dContext.makeCurrent();
try {
captureJ2DState(j2dContext.getGL(), g);
Object curSurface = Java2D.getOGLSurfaceIdentifier(g);
@@ -1614,13 +1590,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
joglContext = null;
joglDrawable = null;
sendReshape = true;
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("Sending reshape because surface changed");
System.err.println("New surface = " + curSurface);
}
}
j2dSurface = curSurface;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.print("-- Surface type: ");
int surfaceType = Java2D.getOGLSurfaceType(g);
if (surfaceType == Java2D.UNDEFINED) {
@@ -1641,22 +1617,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
if (joglContext == null) {
- AbstractGraphicsDevice device = j2dContext.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ AbstractGraphicsDevice device = j2dContext.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
if (factory.canCreateExternalGLDrawable(device)) {
joglDrawable = factory.createExternalGLDrawable();
- // FIXME: Need to share with j2d context, due to FBO resource ..
- // - ORIG: joglContext = joglDrawable.createContext(shareWith);
joglContext = joglDrawable.createContext(j2dContext);
- if (DEBUG||VERBOSE) {
+ joglContext.setSynchronized(true);
+ if (DEBUG) {
System.err.println("-- Created External Drawable: "+joglDrawable);
System.err.println("-- Created Context: "+joglContext);
}
} else if (factory.canCreateContextOnJava2DSurface(device)) {
// Mac OS X code path
- // FIXME: Need to share with j2d context, due to FBO resource ..
- // - ORIG: joglContext = factory.createContextOnJava2DSurface(g, shareWith);
joglContext = factory.createContextOnJava2DSurface(g, j2dContext);
- if (DEBUG||VERBOSE) {
+ joglContext.setSynchronized(true);
+ if (DEBUG) {
System.err.println("-- Created Context: "+joglContext);
}
}
@@ -1694,7 +1668,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
checkedForFBObjectWorkarounds=true;
fbObjectWorkarounds = true;
createNewDepthBuffer = true;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: Fetched ERR GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]+" - NOT A FBO"+
", frame_buffer_object workarounds to be necessary");
}
@@ -1713,7 +1687,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
GL.GL_COLOR_ATTACHMENT0,
GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
frameBufferTexture, 0);
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]);
}
}