aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/classes/jogamp
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/jogamp
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/jogamp')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java75
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java7
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java19
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java15
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java11
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java51
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java36
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java22
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java15
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java51
10 files changed, 270 insertions, 32 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
new file mode 100644
index 000000000..0c2a1e43f
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/GlobalToolkitLock.java
@@ -0,0 +1,75 @@
+/**
+ * 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.nativewindow;
+
+import javax.media.nativewindow.ToolkitLock;
+
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+/**
+ * Implementing a global recursive {@link javax.media.nativewindow.ToolkitLock}.
+ * <p>
+ * This is the last resort for unstable driver, e.g. proprietary ATI/X11 12.8 and 12.9,
+ * where multiple X11 display connections to the same connection name are not treated
+ * thread safe within the GL/X11 driver.
+ * </p>
+ */
+public class GlobalToolkitLock implements ToolkitLock {
+ private static final RecursiveLock globalLock = LockFactory.createRecursiveLock();
+
+ /** Singleton via {@link NativeWindowFactoryImpl#getGlobalToolkitLock()} */
+ protected GlobalToolkitLock() { }
+
+ @Override
+ public final void lock() {
+ globalLock.lock();
+ if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.lock()"); }
+ }
+
+ @Override
+ public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("GlobalToolkitLock.unlock()"); }
+ globalLock.unlock(); // implicit lock validation
+ }
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ globalLock.validateLocked();
+ }
+
+ @Override
+ public final void dispose() {
+ // nop
+ }
+
+ public String toString() {
+ return "GlobalToolkitLock[obj 0x"+Integer.toHexString(hashCode())+", isOwner "+globalLock.isOwner(Thread.currentThread())+", "+globalLock.toString()+"]";
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index 29564da3b..c35cede77 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -44,9 +44,14 @@ import com.jogamp.common.util.ReflectionUtil.AWTNames;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
+ private static final ToolkitLock globalToolkitLock = new GlobalToolkitLock();
public static ToolkitLock getNullToolkitLock() {
- return nullToolkitLock;
+ return nullToolkitLock;
+ }
+
+ public static ToolkitLock getGlobalToolkitLock() {
+ return globalToolkitLock;
}
// This subclass of NativeWindowFactory handles the case of
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
index e59910138..211e15955 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NullToolkitLock.java
@@ -31,15 +31,16 @@ package jogamp.nativewindow;
import javax.media.nativewindow.ToolkitLock;
/**
- * Implementing a singleton global recursive {@link javax.media.nativewindow.ToolkitLock}
- * without any locking. Since there is no locking it all,
- * it is intrinsically recursive.
+ * Implementing a singleton global NOP {@link javax.media.nativewindow.ToolkitLock}
+ * without any locking. Since there is no locking it all, it is intrinsically recursive.
*/
public class NullToolkitLock implements ToolkitLock {
-
+ public static final boolean INVALID_LOCKED = Debug.isPropertyDefined("nativewindow.debug.NullToolkitLock.InvalidLocked", true);
+
/** Singleton via {@link NativeWindowFactoryImpl#getNullToolkitLock()} */
protected NullToolkitLock() { }
+ @Override
public final void lock() {
if(TRACE_LOCK) {
System.err.println("NullToolkitLock.lock()");
@@ -47,10 +48,20 @@ public class NullToolkitLock implements ToolkitLock {
}
}
+ @Override
public final void unlock() {
if(TRACE_LOCK) { System.err.println("NullToolkitLock.unlock()"); }
}
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ /* nop */
+ if(INVALID_LOCKED) {
+ throw new RuntimeException("NullToolkitLock does not lock");
+ }
+ }
+
+ @Override
public final void dispose() {
// nop
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
index a3b0804fa..5b79de0b8 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/ResourceToolkitLock.java
@@ -41,8 +41,6 @@ import com.jogamp.common.util.locks.RecursiveLock;
* </p>
*/
public class ResourceToolkitLock implements ToolkitLock {
- public static final boolean DEBUG = Debug.debug("ToolkitLock");
-
public static final ResourceToolkitLock create() {
return new ResourceToolkitLock();
}
@@ -53,17 +51,24 @@ public class ResourceToolkitLock implements ToolkitLock {
this.lock = LockFactory.createRecursiveLock();
}
-
+ @Override
public final void lock() {
- if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); }
lock.lock();
+ if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.lock()"); }
}
+ @Override
public final void unlock() {
if(TRACE_LOCK) { System.err.println("ResourceToolkitLock.unlock()"); }
- lock.unlock();
+ lock.unlock(); // implicit lock validation
+ }
+
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ lock.validateLocked();
}
+ @Override
public final void dispose() {
// nop
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
index 5d7ae8abb..94d12e6fc 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SharedResourceToolkitLock.java
@@ -49,7 +49,6 @@ import com.jogamp.common.util.locks.RecursiveLock;
* </p>
*/
public class SharedResourceToolkitLock implements ToolkitLock {
- public static final boolean DEBUG = Debug.debug("ToolkitLock");
private static final LongObjectHashMap handle2Lock;
static {
handle2Lock = new LongObjectHashMap();
@@ -109,16 +108,24 @@ public class SharedResourceToolkitLock implements ToolkitLock {
}
+ @Override
public final void lock() {
- if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); }
lock.lock();
+ if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.lock()"); }
}
+ @Override
public final void unlock() {
if(TRACE_LOCK) { System.err.println("SharedResourceToolkitLock.unlock()"); }
lock.unlock();
}
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ lock.validateLocked();
+ }
+
+ @Override
public final void dispose() {
if(0 < refCount) { // volatile OK
synchronized(handle2Lock) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
new file mode 100644
index 000000000..2062d1f58
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/ToolkitProperties.java
@@ -0,0 +1,51 @@
+package jogamp.nativewindow;
+
+import javax.media.nativewindow.NativeWindowFactory;
+
+/**
+ * Marker interface.
+ * <p>
+ * Implementation requires to provide static methods:
+ * <pre>
+ public static void initSingleton() {}
+
+ public static void shutdown() {}
+
+ public static boolean requiresToolkitLock() {}
+
+ public static boolean requiresGlobalToolkitLock() {}
+ * </pre>
+ * Above static methods are invoked by {@link NativeWindowFactory#initSingleton()},
+ * or {@link NativeWindowFactory#shutdown()} via reflection.
+ * </p>
+ * <p>
+ * If <code>requiresGlobalToolkitLock() == true</code>, then
+ * <code>requiresToolkitLock() == true</code> shall be valid as well.
+ * </p>
+ */
+public interface ToolkitProperties {
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // void initSingleton();
+
+ /**
+ * Cleanup resources.
+ * <p>
+ * Called by {@link NativeWindowFactory#shutdown()}
+ * </p>
+ */
+ // void shutdown();
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // boolean requiresToolkitLock();
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ */
+ // boolean requiresGlobalToolkitLock();
+
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index 7c934b154..2dadfb16b 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -79,6 +79,8 @@ public class JAWTUtil {
private static final Method sunToolkitAWTLockMethod;
private static final Method sunToolkitAWTUnlockMethod;
private static final boolean hasSunToolkitAWTLock;
+
+ private static volatile Thread exclusiveOwnerThread;
private static final ToolkitLock jawtToolkitLock;
@@ -229,13 +231,23 @@ public class JAWTUtil {
}
hasSunToolkitAWTLock = _hasSunToolkitAWTLock;
// hasSunToolkitAWTLock = false;
+ exclusiveOwnerThread = null;
jawtToolkitLock = new ToolkitLock() {
public final void lock() {
+ NativeWindowFactory.getGlobalToolkitLock().lock();
JAWTUtil.lockToolkit();
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.lock()"); }
}
public final void unlock() {
+ if(TRACE_LOCK) { System.err.println("JAWTToolkitLock.unlock()"); }
JAWTUtil.unlockToolkit();
+ NativeWindowFactory.getGlobalToolkitLock().unlock();
+ }
+ @Override
+ public final void validateLocked() throws RuntimeException {
+ NativeWindowFactory.getGlobalToolkitLock().validateLocked();
+ JAWTUtil.validateLocked();
}
public final void dispose() {
// nop
@@ -312,7 +324,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- private static void awtLock() {
+ private static final void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -322,6 +334,7 @@ public class JAWTUtil {
} else {
jawtLockObject.Lock();
}
+ exclusiveOwnerThread = Thread.currentThread();
}
/**
@@ -330,7 +343,9 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- private static void awtUnlock() {
+ private static final void awtUnlock() {
+ awtValidateLocked();
+ exclusiveOwnerThread = null;
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -342,6 +357,16 @@ public class JAWTUtil {
}
}
+ private static final void awtValidateLocked() throws RuntimeException {
+ final Thread ct = Thread.currentThread();
+ if( ct != exclusiveOwnerThread ) {
+ if ( null == exclusiveOwnerThread ) {
+ throw new RuntimeException(ct.getName()+": JAWT-ToolkitLock not locked");
+ }
+ throw new RuntimeException(ct.getName()+": Not JAWT-ToolkitLock owner. Owner is "+exclusiveOwnerThread.getName());
+ }
+ }
+
public static void lockToolkit() throws NativeWindowException {
if(ToolkitLock.TRACE_LOCK) { System.err.println("JAWTUtil-ToolkitLock.lock()"); }
if(!headlessMode && !isJava2DQueueFlusherThread()) {
@@ -355,6 +380,13 @@ public class JAWTUtil {
awtUnlock();
}
}
+
+ public static final void validateLocked() throws RuntimeException {
+ if(!headlessMode && !isJava2DQueueFlusherThread()) {
+ awtValidateLocked();
+ }
+ }
+
public static ToolkitLock getJAWTToolkitLock() {
return jawtToolkitLock;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index b7a83e133..481cbbe39 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -34,13 +34,15 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
-public class OSXUtil {
+public class OSXUtil implements ToolkitProperties {
private static boolean isInit = false;
private static final boolean DEBUG = Debug.debug("OSXUtil");
/**
* Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
*/
public static synchronized void initSingleton() {
if(!isInit) {
@@ -60,13 +62,21 @@ public class OSXUtil {
/**
* Called by {@link NativeWindowFactory#shutdown()}
+ * @see ToolkitProperties
*/
- public static void shutdown() {
- }
+ public static void shutdown() { }
- public static boolean requiresToolkitLock() {
- return false;
- }
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static boolean requiresToolkitLock() { return false; }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresGlobalToolkitLock() { return false; }
public static boolean isNSView(long object) {
return isNSView0(object);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
index 613c76032..4408a0903 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -33,9 +33,10 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.NWJNILibLoader;
import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.ToolkitProperties;
import jogamp.nativewindow.x11.X11Util;
-public class GDIUtil {
+public class GDIUtil implements ToolkitProperties {
private static final boolean DEBUG = Debug.debug("GDIUtil");
private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ;
@@ -44,6 +45,7 @@ public class GDIUtil {
/**
* Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
*/
public static synchronized void initSingleton() {
if(!isInit) {
@@ -67,12 +69,23 @@ public class GDIUtil {
/**
* Called by {@link NativeWindowFactory#shutdown()}
+ * @see ToolkitProperties
*/
public static void shutdown() {
}
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
public static boolean requiresToolkitLock() { return false; }
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresGlobalToolkitLock() { return false; }
+
private static RegisteredClass dummyWindowClass = null;
private static Object dummyWindowSync = new Object();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 30792113d..a331fa940 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -43,13 +43,15 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.ToolkitProperties;
+
import com.jogamp.common.util.LongObjectHashMap;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
/**
* Contains a thread safe X11 utility to retrieve display connections.
*/
-public class X11Util {
+public class X11Util implements ToolkitProperties {
/**
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
* <p>
@@ -88,11 +90,15 @@ public class X11Util {
private static String nullDisplayName = null;
private static volatile boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
+ private static boolean requiresGlobalToolkitLock = false; // ATI/AMD X11 driver issues
private static Object setX11ErrorHandlerLock = new Object();
+ private static final String X11_EXTENSION_ATIFGLRXDRI = "ATIFGLRXDRI";
+ private static final String X11_EXTENSION_ATIFGLEXTENSION = "ATIFGLEXTENSION";
/**
* Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
*/
public static void initSingleton() {
if(!isInit) {
@@ -100,7 +106,7 @@ public class X11Util {
if(!isInit) {
isInit = true;
if(DEBUG) {
- System.out.println("X11UtilUtil.initSingleton()");
+ System.out.println("X11Util.initSingleton()");
}
if(!NWJNILibLoader.loadNativeWindow("x11")) {
throw new NativeWindowException("NativeWindow X11 native library load error.");
@@ -108,6 +114,7 @@ public class X11Util {
final boolean isInitOK = initialize0( XERROR_STACKDUMP );
+ final boolean hasX11_EXTENSION_ATIFGLRXDRI, hasX11_EXTENSION_ATIFGLEXTENSION;
final long dpy = X11Lib.XOpenDisplay(null);
if(0 != dpy) {
if(XSYNC_ENABLED) {
@@ -115,17 +122,29 @@ public class X11Util {
}
try {
nullDisplayName = X11Lib.XDisplayString(dpy);
+ hasX11_EXTENSION_ATIFGLRXDRI = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLRXDRI);
+ hasX11_EXTENSION_ATIFGLEXTENSION = X11Lib.QueryExtension(dpy, X11_EXTENSION_ATIFGLEXTENSION);
} finally {
X11Lib.XCloseDisplay(dpy);
}
} else {
nullDisplayName = "nil";
+ hasX11_EXTENSION_ATIFGLRXDRI = false;
+ hasX11_EXTENSION_ATIFGLEXTENSION = false;
}
+ requiresGlobalToolkitLock = hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION;
+ markAllDisplaysUnclosable = ATI_HAS_XCLOSEDISPLAY_BUG && ( hasX11_EXTENSION_ATIFGLRXDRI || hasX11_EXTENSION_ATIFGLEXTENSION );
if(DEBUG) {
- System.err.println("X11Util init OK "+isInitOK+"]"+
- ", X11 Display(NULL) <"+nullDisplayName+">"+
- ", XSynchronize Enabled: "+XSYNC_ENABLED);
+ System.err.println("X11Util.initSingleton(): OK "+isInitOK+"]"+
+ ",\n\t X11 Display(NULL) <"+nullDisplayName+">"+
+ ",\n\t XSynchronize Enabled: " + XSYNC_ENABLED+
+ ",\n\t X11_EXTENSION_ATIFGLRXDRI " + hasX11_EXTENSION_ATIFGLRXDRI+
+ ",\n\t X11_EXTENSION_ATIFGLEXTENSION " + hasX11_EXTENSION_ATIFGLEXTENSION+
+ ",\n\t requiresToolkitLock "+requiresToolkitLock()+
+ ",\n\t requiresGlobalToolkitLock "+requiresGlobalToolkitLock()+
+ ",\n\t markAllDisplaysUnclosable "+getMarkAllDisplaysUnclosable()
+ );
// Thread.dumpStack();
}
}
@@ -147,6 +166,7 @@ public class X11Util {
* <p>
* Called by {@link NativeWindowFactory#shutdown()}
* </p>
+ * @see ToolkitProperties
*/
public static void shutdown() {
if(isInit) {
@@ -189,8 +209,20 @@ public class X11Util {
}
}
- public static boolean requiresToolkitLock() {
- return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock.
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresToolkitLock() {
+ return true; // JAWT locking: yes, instead of native X11 locking w use a recursive lock per display connection.
+ }
+
+ /**
+ * Called by {@link NativeWindowFactory#initSingleton()}
+ * @see ToolkitProperties
+ */
+ public static final boolean requiresGlobalToolkitLock() {
+ return requiresGlobalToolkitLock; // JAWT locking: yes, instead of native X11 locking w use a global lock.
}
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
@@ -206,9 +238,6 @@ public class X11Util {
public static boolean getMarkAllDisplaysUnclosable() {
return markAllDisplaysUnclosable;
}
- public static void setMarkAllDisplaysUnclosable(boolean v) {
- markAllDisplaysUnclosable = v;
- }
private X11Util() {}
@@ -373,7 +402,7 @@ public class X11Util {
name = validateDisplayName(name);
boolean reused = false;
- synchronized(globalLock) {
+ synchronized(globalLock) {
for(int i=0; i<reusableDisplayList.size(); i++) {
if(reusableDisplayList.get(i).getName().equals(name)) {
namedDpy = reusableDisplayList.remove(i);