diff options
Diffstat (limited to 'src/nativewindow')
5 files changed, 131 insertions, 39 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java index 62fd49092..cc70b6b7b 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/AWTGraphicsConfiguration.java @@ -73,19 +73,42 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple } /** + * @deprecated Use {@link #create(GraphicsConfiguration, CapabilitiesImmutable, CapabilitiesImmutable)} + * Method constructs a new {@link AWTGraphicsConfiguration} primarily based + * on the given {@link Component}'s {@link GraphicsConfiguration}. + * @param awtComp the {@link Component}, which {@link GraphicsConfiguration} is used for the resulting {@link AWTGraphicsConfiguration} * @param capsChosen if null, <code>capsRequested</code> is copied and aligned * with the graphics {@link Capabilities} of the AWT Component to produce the chosen {@link Capabilities}. * Otherwise the <code>capsChosen</code> is used. * @param capsRequested if null, default {@link Capabilities} are used, otherwise the given values. */ - public static AWTGraphicsConfiguration create(final Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) { - final GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration(); - if(null==awtGfxConfig) { - throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsConfiguration @ "+awtComp); + public static AWTGraphicsConfiguration create(final Component awtComp, final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested) { + if(null==awtComp) { + throw new IllegalArgumentException("Null AWT Component"); } - final GraphicsDevice awtGraphicsDevice = awtGfxConfig.getDevice(); + final GraphicsConfiguration gc = awtComp.getGraphicsConfiguration(); + if( null == gc ) { + throw new NativeWindowException("Null AWT GraphicsConfiguration @ "+awtComp); + } + return create(gc, capsChosen, capsRequested); + } + + /** + * Method constructs a new {@link AWTGraphicsConfiguration} primarily based + * on the given {@link GraphicsConfiguration}. + * @param gc the {@link GraphicsConfiguration} for the resulting {@link AWTGraphicsConfiguration} + * @param capsChosen if null, <code>capsRequested</code> is copied and aligned + * with the graphics {@link Capabilities} of the AWT Component to produce the chosen {@link Capabilities}. + * Otherwise the <code>capsChosen</code> is used. + * @param capsRequested if null, default {@link Capabilities} are used, otherwise the given values. + */ + public static AWTGraphicsConfiguration create(final GraphicsConfiguration gc, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) { + if(null==gc) { + throw new IllegalArgumentException("Null AWT GraphicsConfiguration"); + } + final GraphicsDevice awtGraphicsDevice = gc.getDevice(); if(null==awtGraphicsDevice) { - throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsDevice @ "+awtGfxConfig); + throw new NativeWindowException("Null AWT GraphicsDevice @ "+gc); } // Create Device/Screen @@ -96,7 +119,6 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple capsRequested = new Capabilities(); } if(null==capsChosen) { - final GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration(); capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc); } final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice, capsChosen); @@ -105,7 +127,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple return (AWTGraphicsConfiguration) config; } // System.err.println("Info: AWTGraphicsConfiguration.create: Expected AWTGraphicsConfiguration got: "+config.getClass()+" w/ factory "+factory.getClass()+" - Unable to encapsulate native GraphicsConfiguration."); - return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig); + return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, gc); } // open access to superclass method diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java index d315e1876..5d84325de 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java @@ -49,7 +49,6 @@ import java.awt.Container; import java.awt.Cursor; import java.awt.EventQueue; import java.awt.GraphicsConfiguration; -import java.awt.Window; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.HierarchyEvent; @@ -91,10 +90,10 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, // lifetime: forever protected final Component component; private final AppContextInfo appContextInfo; - private final AWTGraphicsConfiguration config; // control access due to delegation private final SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper(); private final RecursiveLock surfaceLock = LockFactory.createRecursiveLock(); private final JAWTComponentListener jawtComponentListener; + private volatile AWTGraphicsConfiguration awtConfig; // control access through delegation // lifetime: valid after lock but may change with each 1st lock, purges after invalidate private boolean isApplet; @@ -128,9 +127,9 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } appContextInfo = new AppContextInfo("<init>"); this.component = (Component)comp; - this.config = (AWTGraphicsConfiguration) config; this.jawtComponentListener = new JAWTComponentListener(); invalidate(); + this.awtConfig = (AWTGraphicsConfiguration) config; this.isApplet = false; this.offscreenSurfaceLayer = 0; } @@ -138,7 +137,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, private String jawtStr() { return "JAWTWindow["+id(JAWTWindow.this)+"]"; } private class JAWTComponentListener implements ComponentListener, HierarchyListener { - private boolean isShowing; + private volatile boolean isShowing; private String str(final Object obj) { if( null == obj ) { @@ -179,6 +178,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, AWTEDTExecutor.singleton.invoke(false, new Runnable() { // Bug 952: Avoid deadlock via AWTTreeLock acquisition .. @Override public void run() { + isShowing = component.isShowing(); // Bug 1161: Runnable might be deferred, hence need to update if(DEBUG) { System.err.println(jawtStr()+".attach @ Thread "+getThreadName()+": "+JAWTComponentListener.this.toString()); } @@ -248,7 +248,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, final java.awt.Component changed = e.getChanged(); final boolean displayable = changed.isDisplayable(); final boolean showing = changed.isShowing(); - System.err.println(jawtStr()+".hierarchyChanged: action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+isShowing+"], "+s(e)); + System.err.println(jawtStr()+".hierarchyChanged: action "+action+", displayable "+displayable+", showing [changed "+showing+", comp "+wasShowing+" -> "+isShowing+"], "+s(e)); } } } @@ -265,6 +265,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } invalidateNative(); jawt = null; + awtConfig = null; isOffscreenLayerSurface = false; drawable= 0; drawable_old = 0; @@ -280,6 +281,34 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, } protected abstract void invalidateNative(); + /** + * Set a new {@link AWTGraphicsConfiguration} instance, + * as required if {@link #getAWTComponent() upstream component}'s {@link GraphicsConfiguration} has been changed + * due to reconfiguration, e.g. moving to a different monitor or changed capabilities. + * <p> + * {@link #getAWTComponent() Upstream component} shall override {@link Component#getGraphicsConfiguration()}, + * which shall call this method if detecting a reconfiguration. + * See JOGL's GLCanvas and NewtCanvasAWT. + * </p> + * @param config the new {@link AWTGraphicsConfiguration} + * @see #getAWTGraphicsConfiguration() + */ + public final void setAWTGraphicsConfiguration(final AWTGraphicsConfiguration config) { + if(DEBUG) { + System.err.println(jawtStr()+".setAWTGraphicsConfiguration(): "+this.awtConfig+" -> "+config); + // Thread.dumpStack(); + } + this.awtConfig = config; + } + /** + * Return the current {@link AWTGraphicsConfiguration} instance, + * which also holds its {@link #getAWTComponent() upstream component}'s {@link GraphicsConfiguration} + * @see #setAWTGraphicsConfiguration(AWTGraphicsConfiguration) + */ + public final AWTGraphicsConfiguration getAWTGraphicsConfiguration() { + return awtConfig; + } + @Override public boolean setSurfaceScale(final float[] pixelScale) { System.arraycopy(pixelScale, 0, reqPixelScale, 0, 2); @@ -312,9 +341,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); @@ -330,29 +360,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 ) { @@ -363,6 +395,26 @@ 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); + } + + /** + * @deprecated Use {@link #updateLockedData(JAWT_Rectangle, GraphicsConfiguration)}. + */ + protected final boolean updateLockedData(final JAWT_Rectangle jawtBounds) { + throw new RuntimeException("Invalid API entry"); + } + /** + * @deprecated Use {@link #lockSurfaceImpl(GraphicsConfiguration)} + */ + protected int lockSurfaceImpl() throws NativeWindowException { + throw new RuntimeException("Invalid API entry"); + } + /** * Returns and clears the {@code hasPixelScaleChanged} flag, as set via {@link #lockSurface()}. @@ -386,7 +438,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); } @@ -527,7 +579,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, @Override public final void setChosenCapabilities(final CapabilitiesImmutable caps) { ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps); - config.setChosenCapabilities(caps); + awtConfig.setChosenCapabilities(caps); } @Override @@ -591,7 +643,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()); @@ -612,6 +664,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(); @@ -621,7 +686,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) { @@ -706,7 +771,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, @Override public final AbstractGraphicsConfiguration getGraphicsConfiguration() { - return config.getNativeGraphicsConfiguration(); + return awtConfig.getNativeGraphicsConfiguration(); } @Override @@ -877,7 +942,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, "], pixels[scale "+getPixelScaleX()+", "+getPixelScaleY()+" -> "+getSurfaceWidth()+"x"+getSurfaceHeight()+"]"+ ", visible "+component.isVisible()); sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+ - ",\n\tconfig "+config+ + ",\n\tconfig "+awtConfig+ ",\n\tawtComponent "+getAWTComponent()+ ",\n\tsurfaceLock "+surfaceLock+"]"); 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(); |