diff options
author | Sven Gothel <[email protected]> | 2010-04-27 07:18:54 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-04-27 07:18:54 +0200 |
commit | d370be30dc75cc3b63246f026090a7377bf07135 (patch) | |
tree | 1de511925eefc2f7237d0551fae1e3e417f55805 /src/nativewindow/classes | |
parent | edaf669e1b8c8412c1fd4acfc799138b629bf031 (diff) |
- Fix GLProcAddressResolver regression: Use GLProcAddressResolver !
- X11GLXDrawableFactory:
- Move shared resource creation/destruction into it's own thread
- Remove the ATI hack (no XDisplay closing) for every Display,
this is only necessary for the shared XDisplay and in case of AWT.
- Newt
- Display: Only pumpMessages if device is ready.
- X11Display: Verify handle not null at DispatchMessage.
- Common recursive ToolkitLock implementation, from
src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java and
src/newt/classes/com/jogamp/newt/Window.java,
-> com.jogamp.nativewindow.impl.RecursiveToolkitLock
- Unique XLockDisplay/XUnlockDisplay call via X11Util to simplify debugging.
X11Util: Added debug code for XLockDisplay/XUnlockDisplay.
Added fast LongObjectHashMap
Added static lib loading and initialization.
Removed active and passive list, as well as unused methods,
to easy maintenance. Possible since the only 'uncloseable' Display
might be the shareable one.
- X11Lib: Added static initialization via X11Util
Test:
junit/com/jogamp/test/junit/jogl/demos/gl2/gears/TestGears*
- Add WindowListener for quit ..
Diffstat (limited to 'src/nativewindow/classes')
5 files changed, 167 insertions, 148 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java index fd2478ab2..203ae3d12 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/LockingNativeWindowFactory.java @@ -35,39 +35,7 @@ package com.jogamp.nativewindow.impl; import javax.media.nativewindow.*; public class LockingNativeWindowFactory extends NativeWindowFactoryImpl { - // Provides a generic basic and recursive locking mechanism for your discretion. - private ToolkitLock toolkitLock = new ToolkitLock() { - private Thread owner; - private int recursionCount; - - public synchronized void lock() { - Thread cur = Thread.currentThread(); - if (owner == cur) { - ++recursionCount; - return; - } - while (owner != null) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - owner = cur; - } - - public synchronized void unlock() { - if (owner != Thread.currentThread()) { - throw new RuntimeException("Not owner"); - } - if (recursionCount > 0) { - --recursionCount; - return; - } - owner = null; - notifyAll(); - } - }; + private ToolkitLock toolkitLock = new RecursiveToolkitLock(); public ToolkitLock getToolkitLock() { return toolkitLock; diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java new file mode 100644 index 000000000..06ce54368 --- /dev/null +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java @@ -0,0 +1,83 @@ +package com.jogamp.nativewindow.impl; + +import javax.media.nativewindow.*; + +// +// Reentrance locking toolkit +// +public class RecursiveToolkitLock implements ToolkitLock { + private Thread owner; + private int recursionCount; + private Exception lockedStack = null; + private static final long timeout = 3000; // maximum wait 3s + + public Exception getLockedStack() { + return lockedStack; + } + + public Thread getOwner() { + return owner; + } + + public boolean isOwner() { + return isOwner(Thread.currentThread()); + } + + public synchronized boolean isOwner(Thread thread) { + return owner == thread ; + } + + public synchronized boolean isLocked() { + return null != owner; + } + + /** Recursive and blocking lockSurface() implementation */ + public synchronized void lock() { + Thread cur = Thread.currentThread(); + if (owner == cur) { + ++recursionCount; + return; + } + + long ts = System.currentTimeMillis(); + while (owner != null && (System.currentTimeMillis()-ts) < timeout) { + try { + wait(timeout); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + if(owner != null) { + lockedStack.printStackTrace(); + throw new RuntimeException("Waited "+timeout+"ms for: "+owner+" - "+cur); + } + owner = cur; + lockedStack = new Exception("Previously locked by "+owner); + } + + + /** Recursive and unblocking unlockSurface() implementation */ + public synchronized void unlock() { + unlock(null); + } + + /** Recursive and unblocking unlockSurface() implementation */ + public synchronized void unlock(Runnable releaseAfterUnlockBeforeNotify) { + Thread cur = Thread.currentThread(); + if (owner != cur) { + lockedStack.printStackTrace(); + throw new RuntimeException(cur+": Not owner, owner is "+owner); + } + if (recursionCount > 0) { + --recursionCount; + return; + } + owner = null; + lockedStack = null; + if(null!=releaseAfterUnlockBeforeNotify) { + releaseAfterUnlockBeforeNotify.run(); + } + notifyAll(); + } +} + diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java index a6f52f3c0..0cd02558a 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11GraphicsConfigurationFactory.java @@ -58,7 +58,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor int num[] = { -1 }; long display = screen.getDevice().getHandle(); - X11Lib.XLockDisplay(display); + X11Util.XLockDisplay(display); try { XVisualInfo[] xvis = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0); @@ -68,7 +68,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor return XVisualInfo.create(xvis[0]); } finally { - X11Lib.XUnlockDisplay(display); + X11Util.XUnlockDisplay(display); } } @@ -90,7 +90,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor vinfo_template.setC_class(c_class); long display = screen.getDevice().getHandle(); - X11Lib.XLockDisplay(display); + X11Util.XLockDisplay(display); try { XVisualInfo[] vinfos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, vinfo_template, num, 0); XVisualInfo best=null; @@ -111,7 +111,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor return ret; } finally { - X11Lib.XUnlockDisplay(display); + X11Util.XUnlockDisplay(display); } } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java index 5f5c10885..d93302e57 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; +import com.jogamp.common.util.LongObjectHashMap; import javax.media.nativewindow.*; @@ -51,25 +52,29 @@ import com.jogamp.nativewindow.impl.*; */ public class X11Util { private static final boolean DEBUG = Debug.debug("X11Util"); + private static final boolean DEBUG_XDISPLAY_LOCK = false; static { NWJNILibLoader.loadNativeWindow("x11"); - installIOErrorHandler(); + initialize(); } - private X11Util() {} + public static void initSingleton() { + // just exist to ensure static init has been run + } - private static ThreadLocal currentDisplayMap = new ThreadLocal(); + private X11Util() {} // not exactly thread safe, but good enough for our purpose, // which is to tag a NamedDisplay uncloseable after creation. private static Object globalLock = new Object(); - private static Collection globalNamedDisplayActive = new ArrayList(); - private static Collection globalNamedDisplayPassive = new ArrayList(); + private static LongObjectHashMap globalNamedDisplayMap = new LongObjectHashMap(); + + private static ThreadLocal currentDisplayMap = new ThreadLocal(); public static final String nullDeviceName = "nil" ; - public static class NamedDisplay implements Cloneable { + public static class NamedDisplay extends RecursiveToolkitLock implements Cloneable { String name; long handle; int refCount; @@ -102,10 +107,9 @@ public class X11Util { */ public static int shutdown(boolean realXClosePendingDisplays, boolean verbose) { int num=0; - String msg; + String msg = null; if(DEBUG||verbose) { - msg = "X11Util.Display: Shutdown (active: "+globalNamedDisplayActive.size()+ - ", passive: "+globalNamedDisplayPassive.size() + ")"; + msg = "X11Util.Display: Shutdown (global: "+globalNamedDisplayMap.size()+ ")" ; if(DEBUG) { Exception e = new Exception(msg); e.printStackTrace(); @@ -114,36 +118,8 @@ public class X11Util { } } - msg = realXClosePendingDisplays ? "Close" : "Keep" ; - synchronized(globalLock) { - // for all passive displays .. - Collection namedDisplays = globalNamedDisplayPassive; - globalNamedDisplayPassive = new ArrayList(); - for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) { - NamedDisplay ndpy = (NamedDisplay)iter.next(); - if(DEBUG||verbose) { - System.err.println(msg+" passive: "+ndpy); - } - if(realXClosePendingDisplays) { - X11Lib.XCloseDisplay(ndpy.getHandle()); - } - num++; - } - - // for all active displays .. - namedDisplays = globalNamedDisplayActive; - globalNamedDisplayActive = new ArrayList(); - for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) { - NamedDisplay ndpy = (NamedDisplay)iter.next(); - if(DEBUG||verbose) { - System.err.println(msg+" active: "+ndpy); - } - if(realXClosePendingDisplays) { - X11Lib.XCloseDisplay(ndpy.getHandle()); - } - num++; - } + globalNamedDisplayMap.clear(); } return num; } @@ -162,24 +138,14 @@ public class X11Util { public static long createThreadLocalDisplay(String name) { NamedDisplay namedDpy = getCurrentDisplay(name); if(null==namedDpy) { - synchronized(globalLock) { - namedDpy = getNamedDisplay(globalNamedDisplayPassive, name); - if(null != namedDpy) { - if(!globalNamedDisplayPassive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); } - globalNamedDisplayActive.add(namedDpy); - addCurrentDisplay( namedDpy ); - } - } - } - if(null==namedDpy) { long dpy = X11Lib.XOpenDisplay(name); if(0==dpy) { throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName()); } namedDpy = new NamedDisplay(name, dpy); + addCurrentDisplay( namedDpy ); synchronized(globalLock) { - globalNamedDisplayActive.add(namedDpy); - addCurrentDisplay( namedDpy ); + globalNamedDisplayMap.put(dpy, namedDpy); } if(DEBUG) { Exception e = new Exception("X11Util.Display: Created new TLS "+namedDpy+" in thread "+Thread.currentThread().getName()); @@ -203,7 +169,7 @@ public class X11Util { public static long closeThreadLocalDisplay(String name) { NamedDisplay namedDpy = getCurrentDisplay(name); if(null==namedDpy) { - throw new RuntimeException("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName()); + throw new RuntimeException("X11Util.Display: Display("+name+") with given name is not mapped to TLS in thread "+Thread.currentThread().getName()); } if(0==namedDpy.refCount) { throw new RuntimeException("X11Util.Display: "+namedDpy+" has refCount already 0 in thread "+Thread.currentThread().getName()); @@ -211,20 +177,18 @@ public class X11Util { long dpy = namedDpy.getHandle(); namedDpy.refCount--; if(0==namedDpy.refCount) { - synchronized(globalLock) { - if(!globalNamedDisplayActive.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); } - if(namedDpy.isUncloseable()) { - globalNamedDisplayPassive.add(namedDpy); - } else { - X11Lib.XCloseDisplay(dpy); - } - removeCurrentDisplay(namedDpy); - } if(DEBUG) { String type = namedDpy.isUncloseable() ? "passive" : "real" ; Exception e = new Exception("X11Util.Display: Closing ( "+type+" ) TLS "+namedDpy+" in thread "+Thread.currentThread().getName()); e.printStackTrace(); } + removeCurrentDisplay(namedDpy); + synchronized(globalLock) { + if(null==globalNamedDisplayMap.remove(dpy)) { throw new RuntimeException("Internal: "+namedDpy); } + } + if(!namedDpy.isUncloseable()) { + X11Lib.XCloseDisplay(dpy); + } } else if(DEBUG) { Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName()); e.printStackTrace(); @@ -232,39 +196,64 @@ public class X11Util { return dpy; } - public static String getThreadLocalDisplayName(long handle) { - NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle); - return null != ndpy ? ndpy.getName() : null; + public static long closeThreadLocalDisplay(long handle) { + NamedDisplay ndpy; + synchronized(globalLock) { + ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + } + if(null==ndpy) { + throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, in thread "+Thread.currentThread().getName()); + } + return closeThreadLocalDisplay(ndpy.getName()); } - public static boolean markThreadLocalDisplayUndeletable(long handle) { - NamedDisplay ndpy = getNamedDisplay(getCurrentDisplayMapImpl().values(), handle); - if( null != ndpy ) { - ndpy.unCloseable=true; - return true; + public static void XLockDisplay(long handle) { + if(DEBUG_XDISPLAY_LOCK) { + NamedDisplay ndpy; + synchronized(globalLock) { + ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + } + if(null==ndpy) { + throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, thread "+Thread.currentThread().getName()); + } + ndpy.lock(); + try { + X11Lib.XLockDisplay(handle); + } catch (Throwable t) { + ndpy.unlock(); + throw new RuntimeException(t); + } + } else { + X11Lib.XLockDisplay(handle); } - return false; } - public static String getGlobalDisplayName(long handle, boolean active) { - String name; - synchronized(globalLock) { - NamedDisplay ndpy = getNamedDisplay(active ? globalNamedDisplayActive : globalNamedDisplayPassive, handle); - name = null != ndpy ? ndpy.getName() : null; + public static void XUnlockDisplay(long handle) { + if(DEBUG_XDISPLAY_LOCK) { + NamedDisplay ndpy; + synchronized(globalLock) { + ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + } + if(null==ndpy) { + throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, thread "+Thread.currentThread().getName()); + } + X11Lib.XUnlockDisplay(handle); + ndpy.unlock(); + } else { + X11Lib.XUnlockDisplay(handle); } - return name; } - public static boolean markGlobalDisplayUndeletable(long handle) { - boolean r=false; + public static boolean markThreadLocalDisplayUncloseable(long handle) { + NamedDisplay ndpy; synchronized(globalLock) { - NamedDisplay ndpy = getNamedDisplay(globalNamedDisplayActive, handle); - if( null != ndpy ) { - ndpy.unCloseable=true; - r=true; - } + ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + } + if( null != ndpy ) { + ndpy.unCloseable=true; + return true; } - return r; + return false; } private static Map getCurrentDisplayMapImpl() { @@ -309,26 +298,5 @@ public class X11Util { return (NamedDisplay) displayMap.get(name); } - private static NamedDisplay getNamedDisplay(Collection namedDisplays, String name) { - if(null==name) name=nullDeviceName; - for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) { - NamedDisplay ndpy = (NamedDisplay)iter.next(); - if (ndpy.getNameSafe().equals(name)) { - return ndpy; - } - } - return null; - } - - private static NamedDisplay getNamedDisplay(Collection namedDisplays, long handle) { - for(Iterator iter=namedDisplays.iterator(); iter.hasNext(); ) { - NamedDisplay ndpy = (NamedDisplay)iter.next(); - if (ndpy.getHandle()==handle) { - return ndpy; - } - } - return null; - } - - private static native void installIOErrorHandler(); + private static native void initialize(); } diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java index 58b40efe0..a18ee91c2 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java +++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java @@ -59,12 +59,12 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); try { long display = X11Util.createThreadLocalDefaultDisplay(); - X11Lib.XLockDisplay(display); + X11Util.XLockDisplay(display); try{ int scrnIdx = X11Lib.DefaultScreen(display); return createScreenDevice(display, scrnIdx); }finally{ - X11Lib.XUnlockDisplay(display); + X11Util.XUnlockDisplay(display); } } finally { NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); @@ -76,12 +76,12 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); try { long display = getDevice().getHandle(); - X11Lib.XLockDisplay(display); + X11Util.XLockDisplay(display); try{ int scrnIdx = X11Lib.DefaultScreen(display); return X11Lib.DefaultVisualID(display, scrnIdx); }finally{ - X11Lib.XUnlockDisplay(display); + X11Util.XUnlockDisplay(display); } } finally { NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); @@ -93,13 +93,13 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); try { long display = device.getHandle(); - X11Lib.XLockDisplay(display); + X11Util.XLockDisplay(display); try{ if(X11Lib.XineramaEnabled(display)) { screen = 0; // Xinerama -> 1 screen } }finally{ - X11Lib.XUnlockDisplay(display); + X11Util.XUnlockDisplay(display); } } finally { NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); |