summaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/javax/media
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-09-30 19:47:46 +0200
committerSven Gothel <[email protected]>2012-09-30 19:47:46 +0200
commit92398025abdabb2fdef0d78edd41e730991a6f94 (patch)
tree8d209c588d1246aa126c29465206ba1f8167c0e2 /src/nativewindow/classes/javax/media
parent43891be36e8485353ac74f329fd2f7438303a846 (diff)
Workaround for Bug 623: Sporadic XCB assertion failures w/ ATI proprietary driver and w/o native X11 locking
The proprietary ATI X11 driver does not handle multi-threaded [GL] clients well, i.e. triggers an XCB assertion 'from time to time'. It almost seems like that the driver either: - aliases all display connections to it's connection name, i.e. server; or - utilizes a build-in display connection w/o locking, used for some reason +++ - X11Lib: Add QueryExtension(dpy, name) allowing early driver determination w/o GL - X11Util detects 'requiresGlobalToolkitLock' and 'markAllDisplaysUnclosable' via X11 extensions. In case certain ATI extensions are available, both are set to true. - X11GLXDrawableFactory: Dropped setting 'markAllDisplaysUnclosable', using X11Util's detection (see above). - New GlobalToolkitLock to satisfy certain driver restrictions (ATI's XCB multithreading bug) - NativeWindowFactory handles new property requiresGlobalToolkitLock, in which case the new GlobalToolkitLock is being used instead of ResourceToolkitLock. - JAWTUtil ToolkitLock locks GlobalToolkitLock 1st to match new 'requiresGlobalToolkitLock' property. - Document static method requirement of X11Util, GDIUtil and OSXUtil via marker interface ToolkitProperties - ToolkitLock: New method 'validateLocked()', allowing use to validate whether the device/toolkit is properly locked and hence to detect implementation bugs. See unit test class: ValidateLockListener
Diffstat (limited to 'src/nativewindow/classes/javax/media')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java11
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java21
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java101
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java22
4 files changed, 107 insertions, 48 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 5eaaa6613..8ecd5242d 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -102,17 +102,24 @@ public interface AbstractGraphicsDevice extends Cloneable {
public long getHandle();
/**
- * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * Optionally locking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#lock()}.
* The lock implementation must be recursive.
*/
public void lock();
/**
- * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock}.
+ * Optionally unlocking the device, utilizing eg {@link javax.media.nativewindow.ToolkitLock#unlock()}.
* The lock implementation must be recursive.
+ *
+ * @throws RuntimeException in case the lock is not acquired by this thread.
*/
public void unlock();
+ /**
+ * @throws RuntimeException if current thread does not hold the lock
+ */
+ public void validateLocked() throws RuntimeException;
+
/**
* Optionally [re]opening the device if handle is <code>null</code>.
* <p>
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index b16b0c75c..9288652d9 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -60,7 +60,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
/**
* Create an instance with the system default {@link ToolkitLock}.
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* @param type
* @param handle
*/
@@ -70,7 +70,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- this.toolkitLock = NativeWindowFactory.createDefaultToolkitLock(type, handle);
+ this.toolkitLock = NativeWindowFactory.getDefaultToolkitLock(type, handle);
}
/**
@@ -123,8 +123,10 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
/**
- * No lock is performed on the graphics device per default,
- * instead the aggregated recursive {@link ToolkitLock#lock()} is invoked.
+ * {@inheritDoc}
+ * <p>
+ * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+ * </p>
*
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
@@ -134,9 +136,16 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
toolkitLock.lock();
}
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ toolkitLock.validateLocked();
+ }
+
/**
- * No lock is performed on the graphics device per default,
- * instead the aggregated recursive {@link ToolkitLock#unlock()} is invoked.
+ * {@inheritDoc}
+ * <p>
+ * Locking is perfomed via delegation to {@link ToolkitLock#lock()}, {@link ToolkitLock#unlock()}.
+ * </p>
*
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
* @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 4f4bb629b..af8008f0f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -42,6 +42,7 @@ import java.util.Map;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NativeWindowFactoryImpl;
+import jogamp.nativewindow.ToolkitProperties;
import jogamp.nativewindow.ResourceToolkitLock;
import com.jogamp.common.os.Platform;
@@ -87,13 +88,17 @@ public abstract class NativeWindowFactory {
private static boolean isAWTAvailable;
private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
+ /** {@link jogamp.nativewindow.x11.X11Util} implements {@link ToolkitProperties}. */
private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+ /** {@link jogamp.nativewindow.macosx.OSXUtil} implements {@link ToolkitProperties}. */
private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+ /** {@link jogamp.nativewindow.windows.GDIUtil} implements {@link ToolkitProperties}. */
private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
private static ToolkitLock jawtUtilJAWTToolkitLock;
private static boolean requiresToolkitLock;
+ private static boolean requiresGlobalToolkitLock;
private static volatile boolean isJVMShuttingDown = false;
@@ -156,11 +161,18 @@ public abstract class NativeWindowFactory {
if( null != clazzName ) {
ReflectionUtil.callStaticMethod(clazzName, "initSingleton", null, null, cl );
- final Boolean res = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
- requiresToolkitLock = res.booleanValue();
+ final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl);
+ requiresToolkitLock = res1.booleanValue();
+ if(requiresToolkitLock) {
+ final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresGlobalToolkitLock", null, null, cl);
+ requiresGlobalToolkitLock = res2.booleanValue();
+ } else {
+ requiresGlobalToolkitLock = false;
+ }
} else {
requiresToolkitLock = false;
- }
+ requiresGlobalToolkitLock = false;
+ }
}
private static void shutdownNativeImpl(final ClassLoader cl) {
@@ -261,7 +273,7 @@ public abstract class NativeWindowFactory {
}
if(DEBUG) {
- System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock);
+ System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+", requiresGlobalToolkitLock "+requiresGlobalToolkitLock);
System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory);
}
@@ -295,7 +307,12 @@ public abstract class NativeWindowFactory {
/** @return true if the underlying toolkit requires locking, otherwise false. */
public static boolean requiresToolkitLock() {
return requiresToolkitLock;
- }
+ }
+
+ /** @return true if the underlying toolkit requires global locking, otherwise false. */
+ public static boolean requiresGlobalToolkitLock() {
+ return requiresGlobalToolkitLock;
+ }
/** @return true if not headless, AWT Component and NativeWindow's AWT part available */
public static boolean isAWTAvailable() { return isAWTAvailable; }
@@ -331,9 +348,28 @@ public abstract class NativeWindowFactory {
return defaultFactory;
}
+ /**
+ * Returns the AWT {@link ToolkitLock} (JAWT based) if {@link #isAWTAvailable}, otherwise null.
+ * <p>
+ * The JAWT based {@link ToolkitLock} also locks the global lock,
+ * which matters if the latter is required.
+ * </p>
+ */
+ public static ToolkitLock getAWTToolkitLock() {
+ return jawtUtilJAWTToolkitLock;
+ }
+
+ public static ToolkitLock getNullToolkitLock() {
+ return NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
+ public static ToolkitLock getGlobalToolkitLock() {
+ return NativeWindowFactoryImpl.getGlobalToolkitLock();
+ }
+
/**
- * Provides the system default {@link ToolkitLock}, a singleton instance.
- * <br>
+ * Provides the system default {@link ToolkitLock} for the default system windowing type.
+ * @see #getNativeWindowType(boolean)
* @see #getDefaultToolkitLock(java.lang.String)
*/
public static ToolkitLock getDefaultToolkitLock() {
@@ -341,57 +377,44 @@ public abstract class NativeWindowFactory {
}
/**
- * Provides the default {@link ToolkitLock} for <code>type</code>, a singleton instance.
+ * Provides the default {@link ToolkitLock} for <code>type</code>.
* <ul>
- * <li> JAWT {@link ToolkitLock} if required and AWT available, otherwise</li>
+ * <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+ * <li> {@link jogamp.nativewindow.GlobalToolkitLock} if required, otherwise</li>
+ * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
* <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock getDefaultToolkitLock(String type) {
- if( requiresToolkitLock() ) {
- if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+ if( requiresToolkitLock ) {
+ if( TYPE_AWT == type && isAWTAvailable() ) {
return getAWTToolkitLock();
}
- }
- return NativeWindowFactoryImpl.getNullToolkitLock();
- }
-
- /** Returns the AWT Toolkit (JAWT based) if {@link #isAWTAvailable}, otherwise null. */
- public static ToolkitLock getAWTToolkitLock() {
- return jawtUtilJAWTToolkitLock;
- }
-
- public static ToolkitLock getNullToolkitLock() {
- return NativeWindowFactoryImpl.getNullToolkitLock();
- }
-
- /**
- * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
- * <ul>
- * <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
- * <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
- * </ul>
- */
- public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
- if( requiresToolkitLock() ) {
+ if( requiresGlobalToolkitLock ) {
+ return NativeWindowFactoryImpl.getGlobalToolkitLock();
+ }
return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
-
+
/**
- * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
+ * Provides the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
* <ul>
- * <li> JAWT {@link ToolkitLock} if required and AWT available,</li>
+ * <li> JAWT {@link ToolkitLock} if required and <code>type</code> is of {@link #TYPE_AWT} and AWT available,</li>
+ * <li> {@link jogamp.nativewindow.GlobalToolkitLock} if required, otherwise</li>
* <li> {@link jogamp.nativewindow.ResourceToolkitLock} if required, otherwise</li>
* <li> {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
- if( requiresToolkitLock() ) {
- if( TYPE_AWT == sharedType && isAWTAvailable() ) {
+ public static ToolkitLock getDefaultToolkitLock(String type, long deviceHandle) {
+ if( requiresToolkitLock ) {
+ if( TYPE_AWT == type && isAWTAvailable() ) {
return getAWTToolkitLock();
}
+ if( requiresGlobalToolkitLock ) {
+ return NativeWindowFactoryImpl.getGlobalToolkitLock();
+ }
return ResourceToolkitLock.create();
}
return NativeWindowFactoryImpl.getNullToolkitLock();
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
index 18b7cf5d9..eccfcfa4f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ToolkitLock.java
@@ -37,15 +37,35 @@ import jogamp.nativewindow.Debug;
* Toolkit locks are created solely via {@link NativeWindowFactory}.
* </p>
* <p>
- * One use case is the AWT locking on X11, see {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * One use case is the AWT locking on X11, see {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
* </p>
*/
public interface ToolkitLock {
+ public static final boolean DEBUG = Debug.debug("ToolkitLock");
public static final boolean TRACE_LOCK = Debug.isPropertyDefined("nativewindow.debug.ToolkitLock.TraceLock", true);
+ /**
+ * Blocking until the lock is acquired by this Thread or a timeout is reached.
+ * <p>
+ * Timeout is implementation specific, if used at all.
+ * </p>
+ *
+ * @throws RuntimeException in case of a timeout
+ */
public void lock();
+
+ /**
+ * Release the lock.
+ *
+ * @throws RuntimeException in case the lock is not acquired by this thread.
+ */
public void unlock();
+ /**
+ * @throws RuntimeException if current thread does not hold the lock
+ */
+ public void validateLocked() throws RuntimeException;
+
/**
* Dispose this instance.
* <p>