summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java137
-rw-r--r--src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java50
2 files changed, 175 insertions, 12 deletions
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 5920d6de8..0a27f7f22 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -37,6 +37,7 @@ import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
import java.awt.KeyboardFocusManager;
import java.awt.geom.NoninvertibleTransformException;
import java.beans.Beans;
@@ -47,6 +48,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Set;
+import com.jogamp.nativewindow.CapabilitiesImmutable;
import com.jogamp.nativewindow.NativeWindow;
import com.jogamp.nativewindow.OffscreenLayerOption;
import com.jogamp.nativewindow.WindowClosingProtocol;
@@ -71,6 +73,7 @@ import jogamp.opengl.awt.AWTTilePainter;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.util.awt.AWTEDTExecutor;
+import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
import com.jogamp.nativewindow.awt.AWTPrintLifecycle;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.nativewindow.awt.JAWTWindow;
@@ -101,7 +104,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
public static final boolean DEBUG = Debug.debug("Window");
private final Object sync = new Object();
- private JAWTWindow jawtWindow = null;
+ private volatile JAWTWindow jawtWindow = null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private boolean isApplet = false;
private boolean shallUseOffscreenLayer = false;
private Window newtChild = null;
@@ -112,6 +115,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private final AWTAdapter awtMouseAdapter;
private final AWTAdapter awtKeyAdapter;
+ private volatile AWTGraphicsConfiguration awtConfig;
+
/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() invoked before Applet.destroy(). */
private boolean destroyJAWTPending = false;
/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() invoked before Applet.destroy(). */
@@ -452,14 +457,142 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
+ private void setAWTGraphicsConfiguration(final AWTGraphicsConfiguration config) {
+ // Cache awtConfig
+ awtConfig = config;
+ if( null != jawtWindow ) {
+ // Notify JAWTWindow ..
+ jawtWindow.setAWTGraphicsConfiguration(config);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Overridden to choose a {@link GraphicsConfiguration} from a parent container's
+ * {@link GraphicsDevice}.
+ * </p>
+ * <p>
+ * Method also intercepts {@link GraphicsConfiguration} changes regarding to
+ * its capabilities and its {@link GraphicsDevice}. This may happen in case
+ * the display changes its configuration or the component is moved to another screen.
+ * </p>
+ */
+ @Override
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ /**
+ * parentGC will be null unless:
+ * - A native peer has assigned it. This means we have a native
+ * peer, and are already committed to a graphics configuration.
+ * - This canvas has been added to a component hierarchy and has
+ * an ancestor with a non-null GC, but the native peer has not
+ * yet been created. This means we can still choose the GC on
+ * all platforms since the peer hasn't been created.
+ */
+ final GraphicsConfiguration parentGC = super.getGraphicsConfiguration();
+
+ if( Beans.isDesignTime() ) {
+ return parentGC;
+ }
+ final GraphicsConfiguration oldGC = null != awtConfig ? awtConfig.getAWTGraphicsConfiguration() : null;
+
+ if ( null != parentGC && null != oldGC && !oldGC.equals(parentGC) ) {
+ // Previous oldGC != parentGC of native peer
+
+ if ( !oldGC.getDevice().getIDstring().equals(parentGC.getDevice().getIDstring()) ) {
+ // Previous oldGC's GraphicsDevice != parentGC's GraphicsDevice of native peer
+
+ /**
+ * Here we select a GraphicsConfiguration on the alternate device.
+ * In case the new configuration differs (-> !equalCaps),
+ * we might need a reconfiguration,
+ */
+ final AWTGraphicsConfiguration newConfig = AWTGraphicsConfiguration.create(parentGC,
+ awtConfig.getChosenCapabilities(),
+ awtConfig.getRequestedCapabilities());
+ final GraphicsConfiguration newGC = newConfig.getAWTGraphicsConfiguration();
+ final boolean equalCaps = newConfig.getChosenCapabilities().equals(awtConfig.getChosenCapabilities());
+ if(DEBUG) {
+ System.err.println(getThreadName()+": getGraphicsConfiguration() Info: Changed GC and GD");
+ System.err.println("Created Config (n): Old GC "+oldGC);
+ System.err.println("Created Config (n): Old GD "+oldGC.getDevice().getIDstring());
+ System.err.println("Created Config (n): Parent GC "+parentGC);
+ System.err.println("Created Config (n): Parent GD "+parentGC.getDevice().getIDstring());
+ System.err.println("Created Config (n): New GC "+newGC);
+ System.err.println("Created Config (n): Old CF "+awtConfig);
+ System.err.println("Created Config (n): New CF "+newConfig);
+ System.err.println("Created Config (n): EQUALS CAPS "+equalCaps);
+ // Thread.dumpStack();
+ }
+ if ( null != newGC ) {
+ setAWTGraphicsConfiguration(newConfig);
+ /**
+ * Return the newGC, which covers the desired capabilities and is compatible
+ * with the available GC's of its devices.
+ */
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: getGraphicsConfiguration - end.01: newGC "+newGC);
+ }
+ return newGC;
+ } else {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: getGraphicsConfiguration - end.00: oldGC "+oldGC);
+ }
+ }
+ }
+ /**
+ * If a new GC was _not_ found/defined above,
+ * method returns oldGC as selected in the constructor or first addNotify().
+ * This may cause an exception in Component.checkGD when adding to a
+ * container, and is the desired behavior.
+ */
+ return oldGC;
+ } else if (null == parentGC) {
+ /**
+ * The parentGC is null, which means we have no native peer, and are not
+ * part of a (realized) component hierarchy. So we return the
+ * desired visual that was selected in the constructor (possibly
+ * null).
+ */
+ return oldGC;
+ } else {
+ /**
+ * Otherwise we have not explicitly selected a GC in the constructor, so
+ * just return what Canvas would have.
+ */
+ return parentGC;
+ }
+ }
+ private static String getThreadName() { return Thread.currentThread().getName(); }
+
@Override
public void addNotify() {
if( Beans.isDesignTime() ) {
super.addNotify();
} else {
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overridden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
// before native peer is valid: X11
disableBackgroundErase();
+ // Query AWT GraphicsDevice from parent tree, default
+ final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ if(null==gc) {
+ throw new GLException("Error: NULL AWT GraphicsConfiguration");
+ }
+ final CapabilitiesImmutable capsReq = null != newtChild ? newtChild.getRequestedCapabilities() : null;
+ final AWTGraphicsConfiguration awtConfig = AWTGraphicsConfiguration.create(gc, null, capsReq);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
+ setAWTGraphicsConfiguration(awtConfig);
+
// creates the native peer
super.addNotify();
@@ -472,7 +605,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
System.err.println("NewtCanvasAWT.addNotify.0 - isApplet "+isApplet+", addedOnAWTEDT "+EventQueue.isDispatchThread()+" @ "+currentThreadName());
ExceptionUtils.dumpStack(System.err);
}
- jawtWindow = NewtFactoryAWT.getNativeWindow(NewtCanvasAWT.this, null != newtChild ? newtChild.getRequestedCapabilities() : null);
+ jawtWindow = NewtFactoryAWT.getNativeWindow(NewtCanvasAWT.this, awtConfig);
jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
// enforce initial lock on AWT-EDT, allowing acquisition of pixel-scale
jawtWindow.lockSurface();
diff --git a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
index 8eaca7c0e..cc71fb559 100644
--- a/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
+++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
@@ -28,8 +28,6 @@
package jogamp.newt.awt;
-import java.awt.GraphicsDevice;
-
import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
import com.jogamp.nativewindow.CapabilitiesImmutable;
import com.jogamp.nativewindow.NativeWindow;
@@ -57,6 +55,8 @@ public class NewtFactoryAWT extends NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
/**
+ * @deprecated Use {@link #getNativeWindow(java.awt.Component, AWTGraphicsConfiguration)}
+ *
* Wraps an AWT component into a {@link com.jogamp.nativewindow.NativeWindow} utilizing the {@link com.jogamp.nativewindow.NativeWindowFactory},<br>
* using a configuration agnostic dummy {@link com.jogamp.nativewindow.DefaultGraphicsConfiguration}.<br>
* <p>
@@ -78,9 +78,37 @@ public class NewtFactoryAWT extends NewtFactory {
return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
}
+ /**
+ * @deprecated Use {@link #getNativeWindow(java.awt.Component, AWTGraphicsConfiguration)}
+ * @param awtComp
+ * @param capsRequested
+ * @return
+ */
public static JAWTWindow getNativeWindow(final java.awt.Component awtComp, final CapabilitiesImmutable capsRequested) {
- final AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
- final NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ final AWTGraphicsConfiguration awtConfig = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
+ return getNativeWindow(awtComp, awtConfig);
+ }
+
+ /**
+ * Wraps an AWT component into a {@link com.jogamp.nativewindow.NativeWindow} utilizing the {@link com.jogamp.nativewindow.NativeWindowFactory},<br>
+ * using the given {@link AWTGraphicsConfiguration}.
+ * <p>
+ * The actual wrapping implementation is {@link com.jogamp.nativewindow.awt.JAWTWindow}.
+ * </p>
+ * <p>
+ * The required {@link AWTGraphicsConfiguration} may be constructed via
+ * {@link AWTGraphicsConfiguration#create(java.awt.GraphicsConfiguration, CapabilitiesImmutable, CapabilitiesImmutable)}
+ * </p>
+ * <p>
+ * Purpose of this wrapping is to access the AWT window handle,<br>
+ * not to actually render into it.
+ * </p>
+ *
+ * @param awtComp {@link java.awt.Component}
+ * @param awtConfig {@link AWTGraphicsConfiguration} reflecting the used {@link java.awt.GraphicsConfiguration}
+ */
+ public static JAWTWindow getNativeWindow(final java.awt.Component awtComp, final AWTGraphicsConfiguration awtConfig) {
+ final NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, awtConfig); // a JAWTWindow
if(! ( nw instanceof JAWTWindow ) ) {
throw new NativeWindowException("Not an AWT NativeWindow: "+nw);
}
@@ -101,13 +129,15 @@ public class NewtFactoryAWT extends NewtFactory {
* @throws IllegalArgumentException if {@code awtComp} is not {@link java.awt.Component#isDisplayable() displayable}
* or has {@code null} {@link java.awt.Component#getGraphicsConfiguration() GraphicsConfiguration}.
*/
- private static void checkComponentValid(final java.awt.Component awtComp) throws IllegalArgumentException {
+ private static java.awt.GraphicsConfiguration checkComponentValid(final java.awt.Component awtComp) throws IllegalArgumentException {
if( !awtComp.isDisplayable() ) {
throw new IllegalArgumentException("Given AWT-Component is not displayable: "+awtComp);
}
- if( null == awtComp.getGraphicsConfiguration() ) {
+ final java.awt.GraphicsConfiguration gc = awtComp.getGraphicsConfiguration();
+ if( null == gc ) {
throw new IllegalArgumentException("Given AWT-Component has no GraphicsConfiguration set: "+awtComp);
}
+ return gc;
}
/**
@@ -120,8 +150,8 @@ public class NewtFactoryAWT extends NewtFactory {
* @see #getAbstractGraphicsScreen(java.awt.Component)
*/
public static Display createDisplay(final java.awt.Component awtComp, final boolean reuse) throws IllegalArgumentException {
- checkComponentValid(awtComp);
- final GraphicsDevice device = awtComp.getGraphicsConfiguration().getDevice();
+ final java.awt.GraphicsConfiguration gc = checkComponentValid(awtComp);
+ final java.awt.GraphicsDevice device = gc.getDevice();
final String displayConnection;
final String nwt = NativeWindowFactory.getNativeWindowType(true);
@@ -174,13 +204,13 @@ public class NewtFactoryAWT extends NewtFactory {
* @see #createScreen(java.awt.Component, boolean)
*/
public static MonitorDevice getMonitorDevice(final Screen screen, final java.awt.Component awtComp) throws IllegalArgumentException {
- checkComponentValid(awtComp);
+ final java.awt.GraphicsConfiguration gc = checkComponentValid(awtComp);
final String nwt = NativeWindowFactory.getNativeWindowType(true);
MonitorDevice res = null;
screen.addReference();
try {
if( NativeWindowFactory.TYPE_MACOSX == nwt ) {
- res = screen.getMonitor( JAWTUtil.getMonitorDisplayID( awtComp.getGraphicsConfiguration().getDevice() ) );
+ res = screen.getMonitor( JAWTUtil.getMonitorDisplayID( gc.getDevice() ) );
}
if( null == res ) {
// Fallback, use AWT component coverage