aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-09-27 17:33:39 +0200
committerSven Gothel <[email protected]>2012-09-27 17:33:39 +0200
commitfbe331f013608eb31ff0d8675f4e4c9881c9c48b (patch)
tree535aae61f299884ce6b61d026a60ed0546e9703b /src/newt/classes/jogamp
parentba846a478d616327817dd530dbdcd9a786be5b7a (diff)
Fix Bug 616: X11: Remove XInitThreads() dependency while cleaning up device locking, resulting in a native-lock-free impl.
The X11 implementation details of NativeWindow and NEWT used the X11 implicit locking facility XLockDisplay/XUnlockDisplay, enabled via XInitThreads(). The latter useage is complicated within an unsure environment where the initialization point of JOGL is unknown, but XInitThreads() requires to be called once and before any other X11 calls. The solution is simple and thorough, replace native X11 locking w/ 'application level' locking. Following this pattern actually cleans up a pretty messy part of X11 NativeWindow and NEWT, since the generalization of platform independent locking simplifies code. Simply using our RecursiveLock also speeds up locking, since it doesn't require JNI calls down to X11 anymore. It allows us to get rid of X11ToolkitLock and X11JAWTToolkitLock. Using the RecursiveLock also allows us to remove the shortcut of explicitly createing a NullToolkitLocked device for 'private' display connections. All devices use proper locking as claimed in their toolkit util 'requiresToolkitLock()' in X11Util, OSXUtil, .. Further more a bug has been fixed of X11ErrorHandler usage, i.e. we need to keep our handler alive at all times due to async X11 messaging behavior. This allows to remove the redundant code in X11/NEWT. The AbstractGraphicsDevice lifecycle has been fixed as well, i.e. called when closing NEWT's Display for all driver implementations. On the NEWT side the Display's AbstractGraphicsDevice semantics has been clarified, i.e. it's usage for EDT and lifecycle operations. Hence the X11 Display 2nd device for rendering operations has been moved to X11 Window where it belongs - and the X11 Display's default device used for EDT/lifecycle-ops as it should be. This allows running X11/NEWT properly with the default usage, where the Display instance and hence the EDT thread is shared with many Screen and Window. Rendering using NEWT Window is decoupled from it's shared Display lock via it's own native X11 display. Lock free AbstractGraphicsDevice impl. (Windows, OSX, ..) don't require any attention in this regard since they use NullToolkitLock. Tests: ====== This implementation has been tested manually with Mesa3d (soft, Intel), ATI and Nvidia on X11, Windows and OSX w/o any regressions found in any unit test. Issues on ATI: ============== Only on ATI w/o a composite renderer the unit tests expose a driver or WM bug where XCB claims a lack of locking. Setting env. var 'LIBXCB_ALLOW_SLOPPY_LOCK=true' is one workaround if users refuse to enable compositing. We may investigate this issue in more detail later on.
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java79
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java3
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java33
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java1
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java1
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java65
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java31
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java107
11 files changed, 174 insertions, 156 deletions
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index bca7f6e5b..daeb3e886 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -42,6 +42,7 @@ import com.jogamp.newt.event.NEWTEventConsumer;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
import java.util.ArrayList;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
@@ -66,7 +67,7 @@ public abstract class DisplayImpl extends Display {
name = display.validateDisplayName(name, handle);
synchronized(displayList) {
if(reuse) {
- Display display0 = Display.getLastDisplayOf(type, name, -1);
+ Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
if(null != display0) {
if(DEBUG) {
System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
@@ -74,9 +75,9 @@ public abstract class DisplayImpl extends Display {
return display0;
}
}
+ display.exclusive = !reuse;
display.name = name;
display.type=type;
- display.destroyWhenUnused=false;
display.refCount=0;
display.id = serialno++;
display.fqname = getFQName(display.type, display.name, display.id);
@@ -94,7 +95,7 @@ public abstract class DisplayImpl extends Display {
throw new RuntimeException(e);
}
}
-
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -116,10 +117,12 @@ public abstract class DisplayImpl extends Display {
return true;
}
+ @Override
public int hashCode() {
return hashCode;
}
+ @Override
public synchronized final void createNative()
throws NativeWindowException
{
@@ -148,10 +151,6 @@ public abstract class DisplayImpl extends Display {
}
}
- protected boolean shallRunOnEDT() {
- return true;
- }
-
protected EDTUtil createEDTUtil() {
final EDTUtil def;
if(NewtFactory.useEDT()) {
@@ -179,12 +178,7 @@ public abstract class DisplayImpl extends Display {
if(DEBUG) {
System.err.println("Display.setEDTUtil: "+oldEDTUtil+" -> "+newEDTUtil);
}
- if(null != oldEDTUtil) {
- stopEDT( new Runnable() { public void run() {} } );
- // ready for restart ..
- oldEDTUtil.waitUntilStopped();
- oldEDTUtil.reset();
- }
+ removeEDT( new Runnable() { public void run() {} } );
edtUtil = newEDTUtil;
return oldEDTUtil;
}
@@ -194,16 +188,19 @@ public abstract class DisplayImpl extends Display {
return edtUtil;
}
- private void stopEDT(final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil ) {
+ private void removeEDT(final Runnable task) {
+ if(null!=edtUtil) {
edtUtil.invokeStop(task);
+ // ready for restart ..
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
} else {
task.run();
}
}
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
+ if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
edtUtil.invoke(wait, task);
} else {
task.run();
@@ -212,18 +209,17 @@ public abstract class DisplayImpl extends Display {
public boolean validateEDT() {
if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
// nop
}
} );
- edtUtil.waitUntilStopped();
- edtUtil.reset();
return true;
}
return false;
}
+ @Override
public synchronized final void destroy() {
if(DEBUG) {
dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
@@ -239,17 +235,13 @@ public abstract class DisplayImpl extends Display {
}
final AbstractGraphicsDevice f_aDevice = aDevice;
final DisplayImpl f_dpy = this;
- stopEDT( new Runnable() {
+ removeEDT( new Runnable() {
public void run() {
if ( null != f_aDevice ) {
f_dpy.closeNativeImpl();
}
}
} );
- if(null!=edtUtil) {
- edtUtil.waitUntilStopped();
- edtUtil.reset();
- }
aDevice = null;
refCount=0;
if(DEBUG) {
@@ -290,21 +282,30 @@ public abstract class DisplayImpl extends Display {
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
+ @Override
public final int getId() {
return id;
}
+ @Override
public final String getType() {
return type;
}
+ @Override
public final String getName() {
return name;
}
+ @Override
public final String getFQName() {
return fqname;
}
+
+ @Override
+ public final boolean isExclusive() {
+ return exclusive;
+ }
public static final String nilString = "nil" ;
@@ -324,9 +325,10 @@ public abstract class DisplayImpl extends Display {
sb.append(name);
sb.append("-");
sb.append(id);
- return sb.toString().intern();
+ return sb.toString();
}
+ @Override
public final long getHandle() {
if(null!=aDevice) {
return aDevice.getHandle();
@@ -334,14 +336,17 @@ public abstract class DisplayImpl extends Display {
return 0;
}
+ @Override
public final AbstractGraphicsDevice getGraphicsDevice() {
return aDevice;
}
+ @Override
public synchronized final boolean isNativeValid() {
return null != aDevice;
}
+ @Override
public boolean isEDTRunning() {
if(null!=edtUtil) {
return edtUtil.isRunning();
@@ -351,7 +356,7 @@ public abstract class DisplayImpl extends Display {
@Override
public String toString() {
- return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
}
protected abstract void dispatchMessagesNative();
@@ -403,6 +408,7 @@ public abstract class DisplayImpl extends Display {
eventTask.notifyCaller();
}
+ @Override
public void dispatchMessages() {
// System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
if(0==refCount || // no screens
@@ -475,20 +481,23 @@ public abstract class DisplayImpl extends Display {
public interface DisplayRunnable<T> {
T run(long dpy);
}
- public final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- final AbstractGraphicsDevice aDevice = getGraphicsDevice();
- if(null == aDevice) {
- throw new RuntimeException("null device - not initialized: "+this);
- }
+ public static final <T> T runWithLockedDevice(AbstractGraphicsDevice device, DisplayRunnable<T> action) {
T res;
- aDevice.lock();
+ device.lock();
try {
- res = action.run(aDevice.getHandle());
+ res = action.run(device.getHandle());
} finally {
- aDevice.unlock();
+ device.unlock();
}
return res;
}
+ public final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ final AbstractGraphicsDevice device = getGraphicsDevice();
+ if(null == device) {
+ throw new RuntimeException("null device - not initialized: "+this);
+ }
+ return runWithLockedDevice(device, action);
+ }
protected EDTUtil edtUtil = null;
protected int id;
@@ -497,7 +506,7 @@ public abstract class DisplayImpl extends Display {
protected String fqname;
protected int hashCode;
protected int refCount; // number of Display references by Screen
- protected boolean destroyWhenUnused;
+ protected boolean exclusive; // do not share this display, uses NullLock!
protected AbstractGraphicsDevice aDevice;
}
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index e2c0f746f..1cc53e80e 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -42,7 +42,6 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.Point;
@@ -130,7 +129,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
}
screen.screen_idx = idx;
- screen.fqname = (display.getFQName()+idx).intern();
+ screen.fqname = display.getFQName()+"-s"+idx;
screen.hashCode = screen.fqname.hashCode();
screenList.add(screen);
if(DEBUG) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index c1ac87d38..79770189b 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -85,7 +85,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private volatile long windowHandle = 0; // lifecycle critical
private volatile boolean visible = false; // lifecycle critical
private RecursiveLock windowLock = LockFactory.createRecursiveLock(); // Window instance wide lock
- private RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); // Surface only lock
+ private int surfaceLockCount = 0; // surface lock recursion count
private ScreenImpl screen; // never null after create - may change reference though (reparent)
private boolean screenReferenceAdded = false;
@@ -553,10 +553,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final int lockSurface() throws NativeWindowException, RuntimeException {
final RecursiveLock _wlock = windowLock;
- final RecursiveLock _slock = surfaceLock;
_wlock.lock();
- _slock.lock();
- int res = _slock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
+ surfaceLockCount++;
+ int res = ( 1 == surfaceLockCount ) ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
@@ -573,7 +572,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
- _slock.unlock();
_wlock.unlock();
}
}
@@ -583,12 +581,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void unlockSurface() {
- final RecursiveLock _slock = surfaceLock;
final RecursiveLock _wlock = windowLock;
- _slock.validateLocked();
_wlock.validateLocked();
- if (_slock.getHoldCount() == 1) {
+ if ( 1 == surfaceLockCount ) {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
@@ -596,42 +592,48 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
adevice.unlock();
}
}
- _slock.unlock();
+ surfaceLockCount--;
_wlock.unlock();
}
@Override
public final boolean isSurfaceLockedByOtherThread() {
- return surfaceLock.isLockedByOtherThread();
+ return windowLock.isLockedByOtherThread();
}
@Override
public final Thread getSurfaceLockOwner() {
- return surfaceLock.getOwner();
+ return windowLock.getOwner();
}
public final RecursiveLock getLock() {
return windowLock;
}
+ @Override
public long getSurfaceHandle() {
return windowHandle; // default: return window handle
}
+ @Override
public boolean surfaceSwap() {
return false;
}
+ @Override
public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
return config.getNativeGraphicsConfiguration();
}
- public final long getDisplayHandle() {
- return getScreen().getDisplay().getHandle();
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return screen.getDisplay().getHandle(); // shortcut
}
+ @Override
public final int getScreenIndex() {
- return getScreen().getIndex();
+ return screen.getIndex();
}
//----------------------------------------------------------------------
@@ -1554,8 +1556,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("], surfaceLock "+surfaceLock);
- sb.append(", windowLock "+windowLock+"]");
+ sb.append("], windowLock "+windowLock+"]");
return sb.toString();
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 70e9ba570..ead567d82 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -66,7 +66,9 @@ public class DisplayDriver extends DisplayImpl {
return def;
}
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
protected void dispatchMessagesNative() { /* nop */ }
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
index 65ca63eec..cc55c336e 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
@@ -39,6 +39,7 @@ import javax.media.nativewindow.NativeWindowException;
import jogamp.newt.NEWTJNILibLoader;
import jogamp.opengl.egl.EGL;
+import jogamp.opengl.egl.EGLDisplayUtil;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
@@ -72,6 +73,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
DestroyDisplay(aDevice.getHandle());
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
index 97c384d33..e370038d9 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
@@ -84,6 +84,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
}
}
}
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index 1a3f14859..b49c6b6e0 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -72,7 +72,9 @@ public class DisplayDriver extends DisplayImpl {
aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() { }
+ protected void closeNativeImpl() {
+ aDevice.close();
+ }
public static void runNSApplication() {
runNSApplication0();
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index 579ec5be8..615f9e63b 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -73,6 +73,7 @@ public class DisplayDriver extends DisplayImpl {
protected void closeNativeImpl() {
sharedClassFactory.releaseSharedClass();
+ aDevice.close();
}
protected void dispatchMessagesNative() {
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 714324d63..bff050030 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -36,7 +36,6 @@ package jogamp.newt.driver.x11;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
@@ -74,71 +73,48 @@ public class DisplayDriver extends DisplayImpl {
* {@inheritDoc}
*
* We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL.
- * <p>
- * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED},
- * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms.
- * </p>
- * <p>
- * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)},
- * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}.
- * </p>
*/
- @SuppressWarnings("unused")
protected void createNativeImpl() {
+ X11Util.setX11ErrorHandler(true, DEBUG ? false : true); // make sure X11 error handler is set
long handle = X11Util.openDisplay(name);
if( 0 == handle ) {
throw new RuntimeException("Error creating display(Win): "+name);
}
- if(USE_SEPARATE_DISPLAY_FOR_EDT) {
- edtDisplayHandle = X11Util.openDisplay(name);
- if( 0 == edtDisplayHandle ) {
- X11Util.closeDisplay(handle);
- throw new RuntimeException("Error creating display(EDT): "+name);
- }
- } else {
- edtDisplayHandle = handle;
- }
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, true);
try {
- CompleteDisplay0(edtDisplayHandle);
+ CompleteDisplay0(aDevice.getHandle());
} catch(RuntimeException e) {
closeNativeImpl();
throw e;
- }
-
- // see API doc above!
- if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);
- } else {
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
- }
+ }
}
protected void closeNativeImpl() {
- DisplayRelease0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom);
javaObjectAtom = 0;
windowDeleteAtom = 0;
- // closing using ATI driver bug 'same order'
- final long handle = getHandle();
- X11Util.closeDisplay(handle);
- if(handle != edtDisplayHandle) {
- X11Util.closeDisplay(edtDisplayHandle);
- }
- edtDisplayHandle = 0;
+ aDevice.close(); // closes X11 display
}
protected void dispatchMessagesNative() {
- if(0 != edtDisplayHandle) {
- DispatchMessages0(edtDisplayHandle, javaObjectAtom, windowDeleteAtom);
+ aDevice.lock();
+ try {
+ final long handle = aDevice.getHandle();
+ if(0 != handle) {
+ DispatchMessages0(handle, javaObjectAtom, windowDeleteAtom);
+ }
+ } finally {
+ aDevice.unlock();
}
}
- protected long getEDTHandle() { return edtDisplayHandle; }
protected long getJavaObjectAtom() { return javaObjectAtom; }
protected long getWindowDeleteAtom() { return windowDeleteAtom; }
//----------------------------------------------------------------------
// Internals only
//
+
private static native boolean initIDs0(boolean debug);
private native void CompleteDisplay0(long handle);
@@ -151,17 +127,6 @@ public class DisplayDriver extends DisplayImpl {
private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
- /**
- * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, ..
- * https://bugs.freedesktop.org/show_bug.cgi?id=20708
- * https://jogamp.org/bugzilla/show_bug.cgi?id=502
- * Affects: Ubuntu 11.04, OpenSuSE 11, ..
- * Workaround: Using a separate X11 Display connection for event dispatching (EDT)
- */
- private final boolean USE_SEPARATE_DISPLAY_FOR_EDT = true;
-
- private long edtDisplayHandle;
-
/** X11 Window delete atom marker used on EDT */
private long windowDeleteAtom;
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index 10f6b84da..b09d98e06 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -59,7 +59,7 @@ public class ScreenDriver extends ScreenImpl {
protected void createNativeImpl() {
// validate screen index
- Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
+ Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Long>() {
public Long run(long dpy) {
return new Long(GetScreen0(dpy, screen_idx));
} } );
@@ -81,7 +81,7 @@ public class ScreenDriver extends ScreenImpl {
private int nmode_number;
protected int[] getScreenModeFirstImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
// initialize iterators and static data
nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
@@ -110,7 +110,7 @@ public class ScreenDriver extends ScreenImpl {
protected int[] getScreenModeNextImpl() {
// assemble: w x h x bpp x f x r
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<int[]>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<int[]>() {
public int[] run(long dpy) {
/**
System.err.println("******** mode: "+nmode_number);
@@ -176,7 +176,7 @@ public class ScreenDriver extends ScreenImpl {
}
protected ScreenMode getCurrentScreenModeImpl() {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<ScreenMode>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<ScreenMode>() {
public ScreenMode run(long dpy) {
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
if(0 == screenConfigHandle) {
@@ -237,7 +237,7 @@ public class ScreenDriver extends ScreenImpl {
throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
}
final long t0 = System.currentTimeMillis();
- boolean done = runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
boolean done = false;
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
@@ -276,23 +276,21 @@ public class ScreenDriver extends ScreenImpl {
return done;
}
- private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+ private DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
return new Boolean(X11Util.XineramaIsEnabled(dpy));
- }
- }
- private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery();
+ } };
protected int validateScreenIndex(final int idx) {
if(getDisplay().isNativeValid()) {
- return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ return X11Util.XineramaIsEnabled((X11GraphicsDevice)getDisplay().getGraphicsDevice()) ? 0 : idx;
} else {
- return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ return runWithTempDisplayHandle( xineramaEnabledQueryWithTemp ).booleanValue() ? 0 : idx;
}
}
protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
- display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
virtualOrigin.setX(0);
virtualOrigin.setY(0);
@@ -305,10 +303,8 @@ public class ScreenDriver extends ScreenImpl {
//----------------------------------------------------------------------
// Internals only
//
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return display.runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
- // return runWithoutLock(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return display.runWithLockedDisplayDevice(action);
}
private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
@@ -324,9 +320,6 @@ public class ScreenDriver extends ScreenImpl {
}
return res;
}
- private final <T> T runWithoutLock(DisplayRunnable<T> action) {
- return action.run(display.getHandle());
- }
private static native long GetScreen0(long dpy, int scrn_idx);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 97d1ae3db..aea86a420 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -35,6 +35,7 @@
package jogamp.newt.driver.x11;
import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.WindowImpl;
@@ -44,6 +45,8 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.nativewindow.x11.X11GraphicsDevice;
+import com.jogamp.nativewindow.x11.X11GraphicsScreen;
import com.jogamp.newt.event.MouseEvent;
public class WindowDriver extends WindowImpl {
@@ -63,9 +66,19 @@ public class WindowDriver extends WindowImpl {
protected void createNativeImpl() {
final ScreenDriver screen = (ScreenDriver) getScreen();
final DisplayDriver display = (DisplayDriver) screen.getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+
+ // Decoupled X11 Device/Screen allowing X11 display lock-free off-thread rendering
+ final long renderDeviceHandle = X11Util.openDisplay(edtDevice.getConnection());
+ if( 0 == renderDeviceHandle ) {
+ throw new RuntimeException("Error creating display(EDT): "+edtDevice.getConnection());
+ }
+ renderDevice = new X11GraphicsDevice(renderDeviceHandle, AbstractGraphicsDevice.DEFAULT_UNIT, true);
+ AbstractGraphicsScreen renderScreen = new X11GraphicsScreen((X11GraphicsDevice) renderDevice, screen.getIndex());
+
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice(), capsRequested);
final AbstractGraphicsConfiguration cfg = factory.chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen(), VisualIDHolder.VID_UNDEFINED);
+ capsRequested, capsRequested, capabilitiesChooser, renderScreen, VisualIDHolder.VID_UNDEFINED);
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
@@ -78,11 +91,16 @@ public class WindowDriver extends WindowImpl {
}
setGraphicsConfiguration(cfg);
final int flags = getReconfigureFlags(0, true) &
- ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
- setWindowHandle(CreateWindow0(getParentWindowHandle(),
- display.getEDTHandle(), screen.getIndex(), visualID,
- display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
- getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ ( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
+ edtDevice.lock();
+ try {
+ setWindowHandle(CreateWindow0(getParentWindowHandle(),
+ edtDevice.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
+ getX(), getY(), getWidth(), getHeight(), autoPosition(), flags));
+ } finally {
+ edtDevice.unlock();
+ }
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
@@ -92,8 +110,10 @@ public class WindowDriver extends WindowImpl {
protected void closeNativeImpl() {
if(0!=windowHandleClose && null!=getScreen() ) {
DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice();
+ edtDevice.lock();
try {
- CloseWindow0(display.getEDTHandle(), windowHandleClose,
+ CloseWindow0(edtDevice.getHandle(), windowHandleClose,
display.getJavaObjectAtom(), display.getWindowDeleteAtom());
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -101,28 +121,47 @@ public class WindowDriver extends WindowImpl {
e.printStackTrace();
}
} finally {
+ edtDevice.unlock();
windowHandleClose = 0;
}
}
+ if(null != renderDevice) {
+ renderDevice.close(); // closes X11 display
+ renderDevice = null;
+ }
}
- protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
+ @Override
+ public long getDisplayHandle() {
+ // Actually: return getGraphicsConfiguration().getScreen().getDevice().getHandle();
+ return renderDevice.getHandle(); // shortcut
+ }
+
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
+ final int _x, _y;
if(0 == ( FLAG_IS_UNDECORATED & flags)) {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
+ _x = x - i.getLeftWidth() ;
+ _y = y - i.getTopHeight() ;
+ } else {
+ _x = x;
+ _y = y;
}
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
- reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(),
- getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
- x, y, width, height, flags);
-
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ reconfigureWindow0( dpy, getScreenIndex(),
+ getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
+ _x, _y, width, height, flags);
+ return null;
+ }
+ });
return true;
}
@@ -133,13 +172,18 @@ public class WindowDriver extends WindowImpl {
}
}
- protected void requestFocusImpl(boolean force) {
- requestFocus0(getDisplayEDTHandle(), getWindowHandle(), force);
+ protected void requestFocusImpl(final boolean force) {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ requestFocus0(dpy, getWindowHandle(), force);
+ return null;
+ }
+ });
}
@Override
protected void setTitleImpl(final String title) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
setTitle0(dpy, getWindowHandle(), title);
return null;
@@ -149,35 +193,38 @@ public class WindowDriver extends WindowImpl {
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(setPointerVisible0(getDisplayEDTHandle(), getWindowHandle(), pointerVisible));
+ return Boolean.valueOf(setPointerVisible0(dpy, getWindowHandle(), pointerVisible));
}
}).booleanValue();
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
- return Boolean.valueOf(confinePointer0(getDisplayEDTHandle(), getWindowHandle(), confine));
+ return Boolean.valueOf(confinePointer0(dpy, getWindowHandle(), confine));
}
}).booleanValue();
}
@Override
protected void warpPointerImpl(final int x, final int y) {
- runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
- warpPointer0(getDisplayEDTHandle(), getWindowHandle(), x, y);
+ warpPointer0(dpy, getWindowHandle(), x, y);
return null;
}
});
}
protected Point getLocationOnScreenImpl(final int x, final int y) {
- // X11Util.GetRelativeLocation: locks display already !
- return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
+ public Point run(long dpy) {
+ return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+ } );
}
protected void updateInsetsImpl(Insets insets) {
@@ -229,16 +276,11 @@ public class WindowDriver extends WindowImpl {
//----------------------------------------------------------------------
// Internals only
//
-
private static final String getCurrentThreadName() { return Thread.currentThread().getName(); } // Callback for JNI
private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI
- private final long getDisplayEDTHandle() {
- return ((DisplayDriver) getScreen().getDisplay()).getEDTHandle();
- }
- private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
- return ((DisplayImpl) getScreen().getDisplay()).runWithLockedDisplayHandle(action);
- // return runWithTempDisplayHandle(action);
+ private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ return ((DisplayDriver) getScreen().getDisplay()).runWithLockedDisplayDevice(action);
}
protected static native boolean initIDs0();
@@ -258,4 +300,5 @@ public class WindowDriver extends WindowImpl {
private static native void warpPointer0(long display, long windowHandle, int x, int y);
private long windowHandleClose;
+ private AbstractGraphicsDevice renderDevice;
}