diff options
author | Sven Gothel <[email protected]> | 2015-01-27 00:49:51 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-01-27 00:49:51 +0100 |
commit | 6516a52d3da5cced924db63b64af911d55355325 (patch) | |
tree | fe4404bbd72d4db624722459c76a520019cfb4ca /src/newt/classes/com | |
parent | 26f965bbe7b40968158901c3f4ef2f54e821ac70 (diff) |
Bug 1120 - Refine HiDPI Support ( Part-2 ) (API CHANGE)
- Use float[2] for pixel-scale.
Utilize simple integer rounding:
int-pixel-units = (int) ( int-window-units * pixel-scale + 0.5f )
- Provide minimum and maximum allowed pixel-scale values
to be set by platform, supporting generic pixel-scale validation.
- Remove 'OSXUtil.GetPixelScale(final RectangleImmutable r, final int[] screenIndexOut)',
implementation for all platforms would cause huge redundancy of
Screen and MonitorDevice code (duplication of NEWT).
- instead, add 'float[2] pixelScale' to NEWT's MonitorDevice
- Detect change of pixel-scale and propagate accordingly.
This allows GLCanvas, GLJPanel and NewtCanvasAWT instances
to be dragged between monitor devices w/ different pixel-scale.
- OSX: Handle native triggered reshape events off-thread to avoid EDT congestion
due to locked window when consuming deferred events on EDT.
Diffstat (limited to 'src/newt/classes/com')
4 files changed, 85 insertions, 24 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 126162006..1a3222c71 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -30,6 +30,7 @@ package com.jogamp.newt; import java.util.List; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; @@ -51,6 +52,7 @@ import com.jogamp.common.util.ArrayHashSet; * <ul> * <li>{@link MonitorMode} current mode</li> * <li>{@link RectangleImmutable} viewport (rotated)</li> + * <li>pixel-scale (rotated)</li> * </ul></li> * </ul> * <p> @@ -65,16 +67,31 @@ public abstract class MonitorDevice { protected final ArrayHashSet<MonitorMode> supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly! protected MonitorMode currentMode; protected boolean modeChanged; - protected Rectangle viewportPU; // in pixel units - protected Rectangle viewportWU; // in window units + protected final float[] pixelScale; + protected final Rectangle viewportPU; // in pixel units + protected final Rectangle viewportWU; // in window units - protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, final Rectangle viewportPU, final Rectangle viewportWU, final MonitorMode currentMode, final ArrayHashSet<MonitorMode> supportedModes) { + /** + * @param screen associated {@link Screen} + * @param nativeId unique monitor device ID + * @param sizeMM size in millimeters + * @param currentMode + * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param viewportPU viewport in pixel-units + * @param viewportWU viewport in window-units + * @param supportedModes all supported {@link MonitorMode}s + */ + protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, + final MonitorMode currentMode, + final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, + final ArrayHashSet<MonitorMode> supportedModes) { this.screen = screen; this.nativeId = nativeId; this.sizeMM = sizeMM; this.originalMode = currentMode; this.supportedModes = supportedModes; this.currentMode = currentMode; + this.pixelScale = null != pixelScale ? pixelScale : new float[] { 1.0f, 1.0f }; this.viewportPU = viewportPU; this.viewportWU = viewportWU; this.modeChanged = false; @@ -180,26 +197,40 @@ public abstract class MonitorDevice { } /** - * Returns the {@link RectangleImmutable rectangular} portion + * Returns the current {@link RectangleImmutable rectangular} portion * of the <b>rotated</b> virtual {@link Screen} size in pixel units * represented by this monitor, i.e. top-left origin and size. - * @see Screen + * @see #getPixelScale() + * @see Screen#getViewport() */ public final RectangleImmutable getViewport() { return viewportPU; } /** - * Returns the {@link RectangleImmutable rectangular} portion + * Returns the current {@link RectangleImmutable rectangular} portion * of the <b>rotated</b> virtual {@link Screen} size in window units * represented by this monitor, i.e. top-left origin and size. - * @see Screen + * @see #getPixelScale() + * @see Screen#getViewportInWindowUnits() */ public final RectangleImmutable getViewportInWindowUnits() { return viewportWU; } /** + * Returns the current <b>rotated</b> pixel-scale + * of this monitor, i.e. horizontal and vertical. + * @see #getViewportInWindowUnits() + * @see #getViewport() + * @see ScalableSurface#getMaximumSurfaceScale(float[]) + */ + public float[] getPixelScale(final float[] result) { + System.arraycopy(pixelScale, 0, result, 0, 2); + return result; + } + + /** * Returns <code>true</code> if given screen coordinates in pixel units * are contained by this {@link #getViewport() viewport}, otherwise <code>false</code>. * @param x x-coord in pixel units @@ -292,7 +323,8 @@ public abstract class MonitorDevice { @Override public String toString() { - return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ + return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ + "], viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]"; } } diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index c4ca9a554..7b7937c98 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -273,7 +273,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur * according to the {@link #getMainMonitor() main monitor}'s <i>current</i> {@link MonitorMode mode}'s * {@link SurfaceSize#getResolution() surface resolution}. * <p> - * Method takes the {@link #getCurrentSurfaceScale(int[]) current surface-scale} and {@link #getNativeSurfaceScale(int[]) native surface-scale} + * Method takes the {@link #getCurrentSurfaceScale(float[]) current surface-scale} and {@link #getMaximumSurfaceScale(float[]) native surface-scale} * into account, i.e.: * <pre> * surfacePpMM = monitorPpMM * currentSurfaceScale / nativeSurfaceScale, diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index e890bc640..b469492c8 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -474,6 +474,13 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } jawtWindow = NewtFactoryAWT.getNativeWindow(NewtCanvasAWT.this, null != newtChild ? newtChild.getRequestedCapabilities() : null); jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer); + // enforce initial lock on AWT-EDT, allowing acquisition of pixel-scale + jawtWindow.lockSurface(); + try { + // attachNewtChild sets surface scale! + } finally { + jawtWindow.unlockSurface(); + } awtWindowClosingProtocol.addClosingListener(); componentAdded = true; // Bug 910 if(DEBUG) { @@ -486,6 +493,25 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } } } + private final boolean updatePixelScale() { + if( jawtWindow.updatePixelScale(true) ) { + final Window cWin = newtChild; + final Window dWin = cWin.getDelegatedWindow(); + if( dWin instanceof WindowImpl ) { + final float[] maxPixelScale = jawtWindow.getMaximumSurfaceScale(new float[2]); + final float[] minPixelScale = jawtWindow.getMinimumSurfaceScale(new float[2]); + ((WindowImpl)dWin).pixelScaleChangeNotify(minPixelScale, maxPixelScale, true); + // ((WindowImpl)dWin).sizeChangedNotify(true /* defer */, getWidth(), getHeight(), true /* force */); + } else { + final float[] reqPixelScale = jawtWindow.getRequestedSurfaceScale(new float[2]); + if( jawtWindow.setSurfaceScale(reqPixelScale) ) { + // jawtWindow.getRequestedSurfaceScale(reqPixelScale); + } + } + return true; + } + return false; + } @Override public void removeNotify() { @@ -588,7 +614,11 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("NewtCanvasAWT.reshape: "+x+"/"+y+" "+width+"x"+height); } if( validateComponent(true) ) { - // newtChild.setSize(width, height); + if( !printActive && updatePixelScale() ) { + // NOP + } else { + // newtChild.setSize(width, height); + } } } } @@ -877,18 +907,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } final int w = getWidth(); final int h = getHeight(); - final boolean isNValid = newtChild.isNativeValid(); if(DEBUG) { - System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h+", isNValid "+isNValid); + System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h+", isNValid "+newtChild.isNativeValid()); } newtChild.setVisible(false); newtChild.setSize(w, h); - final int[] reqSurfaceScale = new int[2]; - if( isNValid ) { - newtChild.getCurrentSurfaceScale(reqSurfaceScale); - } else { - newtChild.getRequestedSurfaceScale(reqSurfaceScale); - } + final float[] reqSurfaceScale = newtChild.getRequestedSurfaceScale(new float[2]); jawtWindow.setSurfaceScale(reqSurfaceScale); newtChild.reparentWindow(jawtWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); newtChild.addSurfaceUpdatedListener(jawtWindow); diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 2ba030f76..0d286f25a 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -401,23 +401,28 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override - public final void setSurfaceScale(final int[] pixelScale) { - window.setSurfaceScale(pixelScale); + public final boolean setSurfaceScale(final float[] pixelScale) { + return window.setSurfaceScale(pixelScale); } @Override - public final int[] getRequestedSurfaceScale(final int[] result) { + public final float[] getRequestedSurfaceScale(final float[] result) { return window.getRequestedSurfaceScale(result); } @Override - public final int[] getCurrentSurfaceScale(final int[] result) { + public final float[] getCurrentSurfaceScale(final float[] result) { return window.getCurrentSurfaceScale(result); } @Override - public final int[] getNativeSurfaceScale(final int[] result) { - return window.getNativeSurfaceScale(result); + public final float[] getMinimumSurfaceScale(final float[] result) { + return window.getMinimumSurfaceScale(result); + } + + @Override + public final float[] getMaximumSurfaceScale(final float[] result) { + return window.getMaximumSurfaceScale(result); } @Override |