summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-07-27 20:05:09 +0200
committerSven Gothel <[email protected]>2015-07-27 20:05:09 +0200
commitb0af5159bc6100a6262afe6b52f9092a207ac2b3 (patch)
tree8379e6a283fd3c5028889ef9ad0e96ed77c3c3c3
parent6ae08be1742e6d805b316c0d440364854a49e68f (diff)
Bug 1181 - JOGL WebStart Applications using GLCanvas/AWT may Deadlock by two AWT-EDT on Java >= 1.8.0_45
Root cause: - AWT Toolkit global Lock Our locking scheme (AWT-EDT-1): - Surface Lock - sun.awt.SunToolkit.awtLock() - Component.getGraphicsConfiguration() -> synchronized(Component.getTreeLock()) Other AWT-EDT-2 by Webstart: - synchronized(Component.getTreeLock()) - sun.awt.SunToolkit.awtLock() Results in a deadlock. Solution: - Issue Component.getGraphicsConfiguration() before awtLock(), where Component.getGraphicsConfiguration() is being used to detect possible reconfiguration. - Also use updated AWTGraphicsConfiguration's GraphicsConfiguration if no 'new' detection is required.
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java56
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java5
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java6
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java6
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java7
5 files changed, 54 insertions, 26 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 3a8cbefc6..3eece0759 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -340,9 +340,10 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
/**
* Updates bounds and pixelScale
+ * @param gc GraphicsConfiguration for {@link #updatePixelScale(GraphicsConfiguration, boolean)}
* @return true if bounds or pixelScale has changed, otherwise false
*/
- protected final boolean updateLockedData(final JAWT_Rectangle jawtBounds) {
+ protected final boolean updateLockedData(final JAWT_Rectangle jawtBounds, final GraphicsConfiguration gc) {
final Rectangle jb = new Rectangle(jawtBounds.getX(), jawtBounds.getY(), jawtBounds.getWidth(), jawtBounds.getHeight());
final boolean changedBounds = !bounds.equals(jb);
@@ -358,29 +359,31 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
}
}
- updatePixelScale(false);
+ updatePixelScale(gc, false);
return hasPixelScaleChanged || changedBounds;
}
/**
* Updates the minimum and maximum pixel-scale values
* and returns {@code true} if they were updated.
+ * @param gc pre-fetched {@link GraphicsConfiguration} instance of {@link #getAWTComponent() upstream component},
+ * caller may use cached {@link #getAWTGraphicsConfiguration()}'s {@link AWTGraphicsConfiguration#getAWTGraphicsConfiguration() GC}
+ * or a {@link Component#getGraphicsConfiguration()}.
* @param clearFlag if {@code true}, the {@code hasPixelScaleChanged} flag will be cleared
* @return {@code true} if values were updated, otherwise {@code false}.
* @see #hasPixelScaleChanged()
+ * @see #getAWTGraphicsConfiguration()
+ * @see Component#getGraphicsConfiguration()
*/
- public final boolean updatePixelScale(final boolean clearFlag) {
- // Using GraphicsConfiguration from component, which may change by moving to diff monitor
- if( EventQueue.isDispatchThread() || Thread.holdsLock(component.getTreeLock()) ) {
- if( JAWTUtil.getPixelScale(component.getGraphicsConfiguration(), minPixelScale, maxPixelScale) ) {
- hasPixelScaleChanged = true;
- if( DEBUG ) {
- System.err.println("JAWTWindow.updatePixelScale: updated req["+
- reqPixelScale[0]+", "+reqPixelScale[1]+"], min["+
- minPixelScale[0]+", "+minPixelScale[1]+"], max["+
- maxPixelScale[0]+", "+maxPixelScale[1]+"], has["+
- hasPixelScale[0]+", "+hasPixelScale[1]+"]");
- }
+ public final boolean updatePixelScale(final GraphicsConfiguration gc, final boolean clearFlag) {
+ if( JAWTUtil.getPixelScale(gc, minPixelScale, maxPixelScale) ) {
+ hasPixelScaleChanged = true;
+ if( DEBUG ) {
+ System.err.println("JAWTWindow.updatePixelScale: updated req["+
+ reqPixelScale[0]+", "+reqPixelScale[1]+"], min["+
+ minPixelScale[0]+", "+minPixelScale[1]+"], max["+
+ maxPixelScale[0]+", "+maxPixelScale[1]+"], has["+
+ hasPixelScale[0]+", "+hasPixelScale[1]+"]");
}
}
if( clearFlag ) {
@@ -391,6 +394,12 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
return hasPixelScaleChanged;
}
}
+ /**
+ * @deprecated Use {@link #updatePixelScale(GraphicsConfiguration, boolean)}.
+ */
+ public final boolean updatePixelScale(final boolean clearFlag) {
+ return updatePixelScale(awtConfig.getAWTGraphicsConfiguration(), clearFlag);
+ }
/**
* Returns and clears the {@code hasPixelScaleChanged} flag, as set via {@link #lockSurface()}.
@@ -414,7 +423,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
* @return true if pixelScale has changed, otherwise false
*/
protected final boolean setReqPixelScale() {
- updatePixelScale(true);
+ updatePixelScale(awtConfig.getAWTGraphicsConfiguration(), true);
return SurfaceScaleUtils.setNewPixelScale(hasPixelScale, hasPixelScale, reqPixelScale, minPixelScale, maxPixelScale, DEBUG ? getClass().getSimpleName() : null);
}
@@ -619,7 +628,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
* @throws NativeWindowException
*/
protected abstract JAWT fetchJAWTImpl() throws NativeWindowException;
- protected abstract int lockSurfaceImpl() throws NativeWindowException;
+ protected abstract int lockSurfaceImpl(GraphicsConfiguration gc) throws NativeWindowException;
protected void dumpJAWTInfo() {
System.err.println(jawt2String(null).toString());
@@ -640,6 +649,19 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
ExceptionUtils.dumpStack(System.err);
}
} else {
+ final GraphicsConfiguration gc;
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(component.getTreeLock()) ) {
+ /**
+ * Trigger detection of possible reconfiguration before 'sun.awt.SunToolkit.awtLock()',
+ * which maybe triggered via adevice.lock() below (X11).
+ * See setAWTGraphicsConfiguration(..).
+ */
+ gc = component.getGraphicsConfiguration();
+ } else {
+ // Reuse cached instance
+ gc = awtConfig.getAWTGraphicsConfiguration();
+ }
+
determineIfApplet();
try {
final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
@@ -649,7 +671,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
jawt = fetchJAWTImpl();
isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
}
- res = lockSurfaceImpl();
+ res = lockSurfaceImpl(gc);
if(LOCK_SUCCESS == res && drawable_old != drawable) {
res = LOCK_SURFACE_CHANGED;
if(DEBUG) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 6f3f1ed6b..264bdf9d3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -41,6 +41,7 @@
package jogamp.nativewindow.jawt.macosx;
import java.awt.Component;
+import java.awt.GraphicsConfiguration;
import java.nio.Buffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -242,7 +243,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
@Override
- protected int lockSurfaceImpl() throws NativeWindowException {
+ protected int lockSurfaceImpl(final GraphicsConfiguration gc) throws NativeWindowException {
int ret = NativeSurface.LOCK_SURFACE_NOT_READY;
ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
@@ -279,7 +280,7 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
unlockSurfaceImpl();
return NativeSurface.LOCK_SURFACE_NOT_READY;
}
- updateLockedData(dsi.getBounds());
+ updateLockedData(dsi.getBounds(), gc);
if (DEBUG && firstLock ) {
dumpInfo();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index a6c9452af..655dadd6b 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -40,6 +40,8 @@
package jogamp.nativewindow.jawt.windows;
+import java.awt.GraphicsConfiguration;
+
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindow;
@@ -72,7 +74,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
}
@Override
- protected int lockSurfaceImpl() throws NativeWindowException {
+ protected int lockSurfaceImpl(final GraphicsConfiguration gc) throws NativeWindowException {
int ret = NativeSurface.LOCK_SUCCESS;
ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
@@ -99,7 +101,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- updateLockedData(dsi.getBounds());
+ updateLockedData(dsi.getBounds(), gc);
win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (win32dsi == null) {
unlockSurfaceImpl();
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
index 2620b60e0..80cf3ba6f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -37,6 +37,8 @@
package jogamp.nativewindow.jawt.x11;
+import java.awt.GraphicsConfiguration;
+
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.nativewindow.NativeWindow;
@@ -67,7 +69,7 @@ public class X11JAWTWindow extends JAWTWindow {
}
@Override
- protected int lockSurfaceImpl() throws NativeWindowException {
+ protected int lockSurfaceImpl(final GraphicsConfiguration gc) throws NativeWindowException {
int ret = NativeSurface.LOCK_SUCCESS;
ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
@@ -94,7 +96,7 @@ public class X11JAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- updateLockedData(dsi.getBounds());
+ updateLockedData(dsi.getBounds(), gc);
x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (x11dsi == null) {
unlockSurfaceImpl();
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 0a27f7f22..ae32fd164 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -626,8 +626,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
}
- private final boolean updatePixelScale() {
- if( jawtWindow.updatePixelScale(true) ) {
+ private final boolean updatePixelScale(final GraphicsConfiguration gc) {
+ if( jawtWindow.updatePixelScale(gc, true) ) {
final Window cWin = newtChild;
final Window dWin = cWin.getDelegatedWindow();
if( dWin instanceof WindowImpl ) {
@@ -718,6 +718,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
} else {
NewtFactoryAWT.destroyNativeWindow(jawtWindow);
jawtWindow=null;
+ awtConfig=null;
destroyJAWTPending = false;
}
}
@@ -747,7 +748,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
System.err.println("NewtCanvasAWT.reshape: "+x+"/"+y+" "+width+"x"+height);
}
if( validateComponent(true) ) {
- if( !printActive && updatePixelScale() ) {
+ if( !printActive && updatePixelScale(getGraphicsConfiguration()) ) {
// NOP
} else {
// newtChild.setSize(width, height);