aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java16
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java58
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java40
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java6
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/macosx/MacOSXJAWTWindow.java2
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/WindowsJAWTWindow.java2
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java37
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java231
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java12
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java44
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java15
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java7
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java24
14 files changed, 271 insertions, 229 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
index 82f57f33e..3d213c54b 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -236,23 +236,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("!!! Screen : "+sharedScreen);
}
- // may cause JVM SIGSEGV ?
- // X11Util.closePendingDisplayConnections();
-
sharedResourcesRunner.releaseAndWait();
- if(X11Util.getOpenDisplayConnectionNumber() > 0) {
- System.err.println("X11GLXDrawableFactory.shutdown(): Open (no close attempt) X11 Display Connection");
- X11Util.dumpOpenDisplayConnections();
- }
-
- if(X11Util.getPendingDisplayConnectionNumber()>0) {
- System.err.println("X11GLXDrawableFactory.shutdown(): Pending X11 Display Connection");
- X11Util.dumpPendingDisplayConnections();
- }
-
- // don't close pending XDisplay, since this might be a different thread as the opener
- X11Util.shutdown( false, DEBUG );
+ X11Util.shutdown( true, DEBUG );
}
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
index 225dc25a4..4b5b72cc6 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -83,7 +83,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
if(0==displayHandle) {
- displayHandle = X11Util.createThreadLocalDisplay(null);
+ displayHandle = X11Util.createDisplay(null);
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
}
@@ -91,10 +91,12 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
}
+ String name = X11Util.XDisplayString(displayHandle);
+ displayHandle = X11Util.createDisplay(name);
}
((AWTGraphicsDevice)awtScreen.getDevice()).setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle);
-
+ x11Device.setCloseDisplay(true);
X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen);
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index c165a4833..d2a20f467 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -49,6 +49,7 @@ import com.jogamp.opengl.impl.*;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
+import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
@@ -328,6 +329,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
// Workaround for termination issues with applets --
// sun.applet.AppletPanel should probably be performing the
// remove() call on the EDT rather than on its own thread
+ // Hint: User should run remove from EDT.
if (ThreadingImpl.isAWTMode() &&
Thread.holdsLock(getTreeLock())) {
// The user really should not be invoking remove() from this
@@ -347,6 +349,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
animator.resume();
}
}
+ if(!regenerate) {
+ disposeAbstractGraphicsDeviceAction.run();
+ }
if(DEBUG) {
System.err.println("dispose("+regenerate+") - stop");
@@ -401,6 +406,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
<B>Overrides:</B>
<DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
public void addNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start");
+ ex1.printStackTrace();
+ }
super.addNotify();
if (!Beans.isDesignTime()) {
disableBackgroundErase();
@@ -419,8 +428,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
try {
awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device);
if(DEBUG) {
- Exception e = new Exception("Info: Created Config: "+awtConfig);
- e.printStackTrace();
+ System.err.println(Thread.currentThread().getName()+" - Created Config: "+awtConfig);
}
if(null!=awtConfig) {
// update ..
@@ -444,21 +452,25 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
if(DEBUG) {
- System.err.println("Created Drawable: "+drawable);
+ System.err.println(Thread.currentThread().getName()+" - Created Drawable: "+drawable);
}
}
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end");
+ }
}
- /** Overridden to track when this component is removed from a
+ /** <p>Overridden to track when this component is removed from a
container. Subclasses which override this method must call
super.removeNotify() in their removeNotify() method in order to
- function properly. <P>
-
+ function properly. </p>
+ <p>User shall not call this method outside of EDT, read the AWT/Swing specs
+ about this.</p>
<B>Overrides:</B>
<DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
public void removeNotify() {
if(DEBUG) {
- Exception ex1 = new Exception("Info: removeNotify - start");
+ Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: removeNotify - start");
ex1.printStackTrace();
}
@@ -473,7 +485,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
if(DEBUG) {
- System.err.println("Info: removeNotify - end");
+ System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end");
}
}
@@ -609,14 +621,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
- private boolean disposeRegenerate;
- private DisposeAction disposeAction = new DisposeAction(this);
-
class DisposeAction implements Runnable {
- private GLCanvas canvas;
- public DisposeAction(GLCanvas canvas) {
- this.canvas = canvas;
- }
public void run() {
drawableHelper.dispose(GLCanvas.this);
@@ -632,7 +637,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
if(disposeRegenerate) {
// recreate GLDrawable to reflect it's new graphics configuration
- drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(canvas, awtConfig));
+ drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig));
if(DEBUG) {
System.err.println("GLCanvas.dispose(true): new drawable: "+drawable);
}
@@ -643,6 +648,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
}
+ private boolean disposeRegenerate;
+ private DisposeAction disposeAction = new DisposeAction();
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
new DisposeOnEventDispatchThreadAction();
@@ -653,6 +660,25 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
+ class DisposeAbstractGraphicsDeviceAction implements Runnable {
+ public void run() {
+ AbstractGraphicsConfiguration aconfig = (null!=awtConfig) ? awtConfig.getNativeGraphicsConfiguration() : null;
+ AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
+ AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null;
+ if(null!=adevice) {
+ String adeviceMsg=null;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if(DEBUG) {
+ System.err.println("GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ }
+ }
+ DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
+
class InitAction implements Runnable {
public void run() {
drawableHelper.init(GLCanvas.this);
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 10aeefaf5..b9bbf71c2 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -631,22 +631,34 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
private DisposeAction disposeAction = new DisposeAction();
class DisposeAction implements Runnable {
- public void run() {
- updater.dispose(GLJPanel.this);
+ public void run() {
+ updater.dispose(GLJPanel.this);
- if(null!=disposeContext) {
- disposeContext.destroy();
- disposeContext=null;
- }
- if(null!=disposeDrawable) {
- disposeDrawable.setRealized(false);
- }
- if(disposeRegenerate && null!=disposeDrawable) {
- disposeDrawable.setRealized(true);
- disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
- disposeContext.setSynchronized(true);
+ if (null != disposeContext) {
+ disposeContext.destroy();
+ disposeContext = null;
+ }
+ if (null != disposeDrawable) {
+ disposeDrawable.setRealized(false);
+ }
+ if (null != disposeDrawable) {
+ if (disposeRegenerate) {
+ disposeDrawable.setRealized(true);
+ disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
+ disposeContext.setSynchronized(true);
+ } else {
+ AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if (DEBUG) {
+ System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
+ }
+ }
+ }
}
- }
}
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
index 00d64b4e4..8ef2ba227 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/JAWTWindow.java
@@ -37,12 +37,10 @@
package com.jogamp.nativewindow.impl.jawt;
-import com.jogamp.nativewindow.impl.*;
import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
import java.awt.Window;
-import java.awt.GraphicsEnvironment;
import javax.media.nativewindow.*;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
@@ -69,10 +67,10 @@ public abstract class JAWTWindow implements NativeWindow {
protected void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
- initNative();
+ validateNative();
}
- protected abstract void initNative() throws NativeWindowException;
+ protected abstract void validateNative() throws NativeWindowException;
protected synchronized void invalidate() {
component = null;
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/macosx/MacOSXJAWTWindow.java
index ed932ff91..bcaa66847 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/macosx/MacOSXJAWTWindow.java
@@ -54,7 +54,7 @@ public class MacOSXJAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void initNative() throws NativeWindowException {
+ protected void validateNative() throws NativeWindowException {
}
protected int lockSurfaceImpl() throws NativeWindowException {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/WindowsJAWTWindow.java
index b6da7166d..d19a11f66 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/windows/WindowsJAWTWindow.java
@@ -54,7 +54,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void initNative() throws NativeWindowException {
+ protected void validateNative() throws NativeWindowException {
}
protected synchronized void invalidate() {
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
index 4a2c9ada3..a5d36b6dd 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/jawt/x11/X11JAWTWindow.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 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
@@ -38,14 +39,10 @@ package com.jogamp.nativewindow.impl.jawt.x11;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
-import javax.media.nativewindow.x11.*;
import com.jogamp.nativewindow.impl.x11.*;
import com.jogamp.nativewindow.impl.jawt.*;
-import com.jogamp.nativewindow.impl.*;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
public class X11JAWTWindow extends JAWTWindow {
@@ -53,15 +50,31 @@ public class X11JAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void initNative() throws NativeWindowException {
- if(0==config.getScreen().getDevice().getHandle()) {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
- long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
- if(0==displayHandle) {
- displayHandle = X11Util.createThreadLocalDisplay(null);
- }
- awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
+ protected void validateNative() throws NativeWindowException {
+ AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+
+ if(awtDevice.getHandle() != 0) {
+ // subtype and handle set already, done
+ return;
+ }
+
+ long displayHandle = 0;
+
+ // first try a pre-existing attached native configuration, ie native X11GraphicsDevice
+ AbstractGraphicsConfiguration aconfig = (null!=config) ? config.getNativeGraphicsConfiguration() : null;
+ AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
+ AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null; // X11GraphicsDevice
+ if(null!=adevice) {
+ displayHandle = adevice.getHandle();
+ }
+
+ if(0 == displayHandle) {
+ displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
+ }
+ if(0==displayHandle) {
+ throw new InternalError("X11JAWTWindow: No X11 Display handle available");
}
+ awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
}
protected int lockSurfaceImpl() throws NativeWindowException {
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 14e285187..524b142ec 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 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
@@ -35,7 +36,6 @@ package com.jogamp.nativewindow.impl.x11;
import java.util.HashMap;
import java.util.Map;
import com.jogamp.common.util.LongObjectHashMap;
-import com.jogamp.common.util.locks.RecursiveLock;
import javax.media.nativewindow.*;
@@ -44,13 +44,11 @@ import java.nio.Buffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.List;
/**
- * Contains a thread safe X11 utility to retrieve thread local display connection,<br>
- * as well as the static global display connection.<br>
- *
- * The TLS variant is thread safe per se, but be aware of the memory leak risk
- * where an application heavily utilizing this class on temporary new threads.<br>
+ * Contains a thread safe X11 utility to retrieve display connections.
*/
public class X11Util {
private static final boolean DEBUG = Debug.debug("X11Util");
@@ -123,29 +121,37 @@ public class X11Util {
// which is to tag a NamedDisplay uncloseable after creation.
private static Object globalLock = new Object();
private static LongObjectHashMap globalNamedDisplayMap = new LongObjectHashMap();
-
- private static ThreadLocal currentDisplayMap = new ThreadLocal();
+ private static List openDisplayList = new ArrayList();
+ private static List pendingDisplayList = new ArrayList();
public static class NamedDisplay {
String name;
long handle;
int refCount;
boolean unCloseable;
+ Throwable creationStack;
protected NamedDisplay(String name, long handle) {
this.name=name;
this.handle=handle;
this.refCount=1;
this.unCloseable=false;
+ if(DEBUG) {
+ this.creationStack=new Throwable("NamedDisplay Created at:");
+ } else {
+ this.creationStack=null;
+ }
}
public final String getName() { return name; }
public final long getHandle() { return handle; }
public final int getRefCount() { return refCount; }
- public void setUncloseable(boolean v) { unCloseable = v; }
+ public final void setUncloseable(boolean v) { unCloseable = v; }
public final boolean isUncloseable() { return unCloseable; }
+ public final Throwable getCreationStack() { return creationStack; }
+
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@@ -156,116 +162,107 @@ public class X11Util {
}
/** Returns the number of unclosed X11 Displays.
- * @param realXClosePendingDisplays if true, call XCloseDisplay on the remaining ones
+ * @param realXCloseAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
*/
- public static int shutdown(boolean realXClosePendingDisplays, boolean verbose) {
+ public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
- if(DEBUG||verbose) {
- String msg = "X11Util.Display: Shutdown (closePendingDisplays: "+realXClosePendingDisplays+
- ", global: "+globalNamedDisplayMap.size()+ ")" ;
+ if(DEBUG||verbose||pendingDisplayList.size() > 0) {
+ String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
+ ", open (no close attempt): "+globalNamedDisplayMap.size()+"/"+openDisplayList.size()+
+ ", open (no close attempt and uncloseable): "+pendingDisplayList.size()+")" ;
if(DEBUG) {
Exception e = new Exception(msg);
e.printStackTrace();
- } else if(verbose) {
+ } else {
System.err.println(msg);
}
+ if( openDisplayList.size() > 0) {
+ X11Util.dumpOpenDisplayConnections();
+ }
+ if( pendingDisplayList.size() > 0 ) {
+ X11Util.dumpPendingDisplayConnections();
+ }
}
synchronized(globalLock) {
+ if(realXCloseOpenAndPendingDisplays) {
+ closePendingDisplayConnections();
+ }
+ openDisplayList.clear();
+ pendingDisplayList.clear();
globalNamedDisplayMap.clear();
}
return num;
}
- /*******************************
- **
- ** TLS Management
- **
- *******************************/
-
- /** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */
- public static Map getCurrentDisplayMap() {
- return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone();
- }
-
- /** Returns this thread named display. If it doesn not exist, it is being created, otherwise the reference count is increased */
- public static long createThreadLocalDisplay(String name) {
- name = validateDisplayName(name);
- NamedDisplay namedDpy = getCurrentDisplay(name);
- if(null==namedDpy) {
- long dpy = XOpenDisplay(name);
- if(0==dpy) {
- throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
- }
- // if you like to debug and synchronize X11 commands ..
- // setSynchronizeDisplay(dpy, true);
- namedDpy = new NamedDisplay(name, dpy);
- addCurrentDisplay( namedDpy );
- synchronized(globalLock) {
- globalNamedDisplayMap.put(dpy, namedDpy);
- }
+ /**
+ * Closing pending Display connections in reverse order.
+ *
+ * @return number of closed Display connections
+ */
+ public static int closePendingDisplayConnections() {
+ int num=0;
+ synchronized(globalLock) {
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Created new TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ System.err.println("X11Util: Closing Pending X11 Display Connections: "+pendingDisplayList.size());
}
- } else {
- namedDpy.refCount++;
- if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Reused TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ for(int i=pendingDisplayList.size()-1; i>=0; i--) {
+ NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
+ if(DEBUG) {
+ System.err.println("X11Util.closePendingDisplayConnections(): Closing ["+i+"]: "+ndpy);
+ }
+ XCloseDisplay(ndpy.getHandle());
+ num++;
}
}
- return namedDpy.getHandle();
+ return num;
}
- /** Decrease the reference count of this thread named display. If it reaches 0, close it.
- It returns the handle of the to be closed display.
- It throws a RuntimeException in case the named display does not exist,
- or the reference count goes below 0.
- */
- public static long closeThreadLocalDisplay(String name) {
- name = validateDisplayName(name);
- NamedDisplay namedDpy = getCurrentDisplay(name);
- if(null==namedDpy) {
- 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());
+ public static int getOpenDisplayConnectionNumber() {
+ synchronized(globalLock) {
+ return openDisplayList.size();
}
- long dpy = namedDpy.getHandle();
- namedDpy.refCount--;
- if(0==namedDpy.refCount) {
- 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()) {
- XCloseDisplay(dpy);
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ synchronized(globalLock) {
+ System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size());
+ for(int i=0; i<pendingDisplayList.size(); i++) {
+ NamedDisplay ndpy = (NamedDisplay) openDisplayList.get(i);
+ System.err.println("X11Util: ["+i+"]: "+ndpy);
+ if(null!=ndpy) {
+ Throwable t = ndpy.getCreationStack();
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ }
}
- } else if(DEBUG) {
- Exception e = new Exception("X11Util.Display: Keep TLS "+namedDpy+" in thread "+Thread.currentThread().getName());
- e.printStackTrace();
}
- return dpy;
}
- public static long closeThreadLocalDisplay(long handle) {
- NamedDisplay ndpy;
+ public static int getPendingDisplayConnectionNumber() {
synchronized(globalLock) {
- ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle);
+ return pendingDisplayList.size();
}
- if(null==ndpy) {
- throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped, in thread "+Thread.currentThread().getName());
+ }
+
+ public static void dumpPendingDisplayConnections() {
+ synchronized(globalLock) {
+ System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
+ for(int i=0; i<pendingDisplayList.size(); i++) {
+ NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
+ System.err.println("X11Util: ["+i+"]: "+ndpy);
+ if(null!=ndpy) {
+ Throwable t = ndpy.getCreationStack();
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ }
+ }
}
- return closeThreadLocalDisplay(ndpy.getName());
}
- public static boolean markThreadLocalDisplayUncloseable(long handle) {
+ public static boolean markDisplayUncloseable(long handle) {
NamedDisplay ndpy;
synchronized(globalLock) {
ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle);
@@ -277,53 +274,6 @@ public class X11Util {
return false;
}
- private static Map getCurrentDisplayMapImpl() {
- Map displayMap = (Map) currentDisplayMap.get();
- if(null==displayMap) {
- displayMap = new HashMap();
- currentDisplayMap.set( displayMap );
- }
- return displayMap;
- }
-
- /** maps the given display to the thread local display map
- * and notifies all threads synchronized to this display map. */
- private static NamedDisplay addCurrentDisplay(NamedDisplay newDisplay) {
- Map displayMap = getCurrentDisplayMapImpl();
- NamedDisplay oldDisplay = null;
- synchronized(displayMap) {
- oldDisplay = (NamedDisplay) displayMap.put(newDisplay.getName(), newDisplay);
- displayMap.notifyAll();
- }
- return oldDisplay;
- }
-
- /** removes the mapping of the given name from the thread local display map
- * and notifies all threads synchronized to this display map. */
- private static NamedDisplay removeCurrentDisplay(NamedDisplay ndpy) {
- Map displayMap = getCurrentDisplayMapImpl();
- synchronized(displayMap) {
- NamedDisplay ndpyDel = (NamedDisplay) displayMap.remove(ndpy.getName());
- if(ndpyDel!=ndpy) {
- throw new RuntimeException("Wrong mapping req: "+ndpy+", got "+ndpyDel);
- }
- displayMap.notifyAll();
- }
- return ndpy;
- }
-
- /** Returns the thread local display mapped to the given name */
- private static NamedDisplay getCurrentDisplay(String name) {
- Map displayMap = getCurrentDisplayMapImpl();
- return (NamedDisplay) displayMap.get(name);
- }
-
- /*******************************
- **
- ** Non TLS Functions
- **
- *******************************/
-
/** Returns this created named display. */
public static long createDisplay(String name) {
name = validateDisplayName(name);
@@ -336,6 +286,8 @@ public class X11Util {
NamedDisplay namedDpy = new NamedDisplay(name, dpy);
synchronized(globalLock) {
globalNamedDisplayMap.put(dpy, namedDpy);
+ openDisplayList.add(namedDpy);
+ pendingDisplayList.add(namedDpy);
}
if(DEBUG) {
Exception e = new Exception("X11Util.Display: Created new "+namedDpy+". Thread "+Thread.currentThread().getName());
@@ -349,11 +301,16 @@ public class X11Util {
synchronized(globalLock) {
namedDpy = (NamedDisplay) globalNamedDisplayMap.remove(handle);
+ if(namedDpy!=null) {
+ if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ }
}
if(null==namedDpy) {
+ X11Util.dumpPendingDisplayConnections();
throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") with given handle is not mapped. Thread "+Thread.currentThread().getName());
}
if(namedDpy.getHandle()!=handle) {
+ X11Util.dumpPendingDisplayConnections();
throw new RuntimeException("X11Util.Display: Display(0x"+Long.toHexString(handle)+") Mapping error: "+namedDpy+". Thread "+Thread.currentThread().getName());
}
@@ -363,6 +320,9 @@ public class X11Util {
}
if(!namedDpy.isUncloseable()) {
+ synchronized(globalLock) {
+ if(!pendingDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
+ }
XCloseDisplay(namedDpy.getHandle());
}
}
@@ -392,6 +352,7 @@ public class X11Util {
** Locked X11Lib wrapped functions
**
*******************************/
+
public static long XOpenDisplay(String arg0) {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index b003db8f5..581df5163 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -68,4 +68,16 @@ public interface AbstractGraphicsDevice extends Cloneable {
* The lock implementation must be recursive.
*/
public void unlock();
+
+ /**
+ * Optionally closing the device.<br>
+ * The default implementation is a NOP operation, returning false.<br>
+ * The specific implementing, ie {@link javax.media.nativewindow.x11.X11GraphicsDevice},
+ * shall have a enable/disable like {@link javax.media.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},<br>
+ * which shall be invoked at creation time to determine ownership/role of freeing the resource.<br>
+ *
+ * @return true if a specialized closing operation was successfully issued, otherwise false,
+ * ie no native closing operation was issued, which doesn't imply an error at all.
+ */
+ public boolean close();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index ca0f106f5..b67688116 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -91,26 +91,6 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
/**
- * Set the internal ToolkitLock, which is used within the
- * {@link #lock()} and {@link #unlock()} implementation.
- *
- * @param locker the ToolkitLock, if null, {@link com.jogamp.nativewindow.impl.NullToolkitLock} is being used
- */
- protected void setToolkitLock(ToolkitLock locker) {
- this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
- }
-
- /**
- * @return the used ToolkitLock
- *
- * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
- * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
- */
- public final ToolkitLock getToolkitLock() {
- return toolkitLock;
- }
-
- /**
* No lock is performed on the graphics device per default,
* instead the aggregated recursive {@link ToolkitLock#lock()} is invoked.
*
@@ -132,7 +112,31 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
toolkitLock.unlock();
}
+ public boolean close() {
+ return false;
+ }
+
public String toString() {
return getClass().toString()+"[type "+getType()+", handle 0x"+Long.toHexString(getHandle())+"]";
}
+
+ /**
+ * Set the internal ToolkitLock, which is used within the
+ * {@link #lock()} and {@link #unlock()} implementation.
+ *
+ * @param locker the ToolkitLock, if null, {@link com.jogamp.nativewindow.impl.NullToolkitLock} is being used
+ */
+ protected void setToolkitLock(ToolkitLock locker) {
+ this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ }
+
+ /**
+ * @return the used ToolkitLock
+ *
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long)
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(java.lang.String, long, javax.media.nativewindow.ToolkitLock)
+ */
+ public final ToolkitLock getToolkitLock() {
+ return toolkitLock;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
index 31744702d..c60597661 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
@@ -32,12 +32,15 @@
package javax.media.nativewindow.x11;
+import com.jogamp.nativewindow.impl.x11.X11Util;
import javax.media.nativewindow.*;
/** Encapsulates a graphics device on X11 platforms.
*/
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
+ boolean closeDisplay = false;
+
/** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
* {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.
*/
@@ -62,5 +65,17 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
public Object clone() {
return super.clone();
}
+
+ public void setCloseDisplay(boolean close) {
+ closeDisplay = close;
+ }
+ public boolean close() {
+ if(closeDisplay && 0 != handle) {
+ X11Util.closeDisplay(handle);
+ handle = 0;
+ return true;
+ }
+ return true;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index 73af5f852..dca0d1de3 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -53,13 +53,6 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
return new X11GraphicsScreen(new X11GraphicsDevice(display), screenIdx);
}
- /** Creates a new X11GraphicsScreen using a thread local display connection */
- public static AbstractGraphicsScreen createDefault() {
- long display = X11Util.createThreadLocalDisplay(null);
- int scrnIdx = X11Util.DefaultScreen(display);
- return createScreenDevice(display, scrnIdx);
- }
-
public long getDefaultVisualID() {
// It still could be an AWT hold handle ..
long display = getDevice().getHandle();
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java
index bbf75798e..9b0ec6907 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java
@@ -37,12 +37,10 @@ import com.jogamp.newt.Window;
import java.awt.Canvas;
import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
import java.awt.GraphicsConfiguration;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
-import com.jogamp.newt.impl.Debug;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -102,6 +100,28 @@ public class AWTCanvas extends Canvas {
}
}
+ public void removeNotify() {
+ try {
+ dispose();
+ } finally {
+ super.removeNotify();
+ }
+ }
+
+ private void dispose() {
+ if(null != awtConfig) {
+ AbstractGraphicsDevice adevice = awtConfig.getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(Window.DEBUG_IMPLEMENTATION) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println("AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ }
+
/**
* Overridden to choose a GraphicsConfiguration on a parent container's
* GraphicsDevice because both devices