aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-06-08 08:11:57 +0200
committerSven Gothel <[email protected]>2014-06-08 08:11:57 +0200
commit2571ed0b5ef14155d204540d38b564a7d4cd47b6 (patch)
tree8aaf1171af1b95f1cb1ebe706771a4aff3752c2f /src/newt/classes
parentff7bf3122fd2007bbe70cfadca9f0f978ee96456 (diff)
Bug 741 HiDPI: Add ScalableSurface interface to get/set pixelScale w/ full OSX impl.
Add ScalableSurface interface - To set pixelScale before and after realization - To get pixelScale - Implemented on: - NEWT Window - Generic impl. in WindowImpl - OSX WindowDriver impl. - Also propagetes pixelScale to parent JAWTWindow if offscreen (NewtCanvasAWT) - AWT WindowDriver impl. - JAWTWindow / OSXCalayer - AWT GLCanvas - AWT GLJPanel - NEWTCanvasAWT: - Propagates NEWT Window's pixelScale to underlying JAWTWindow - WrappedSurface for pixelScale propagation using offscreen drawables, i.e. GLJPanel - Generic helper in SurfaceScaleUtils (nativewindow package) - Fully implemented on OSX - Capable to switch pixelScale before realization, i.e. native-creation, as well as on-the-fly. - Impl. uses int[2] for pixelScale to support non-uniform scale. Test cases: - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT - Press 'x' to toggle HiDPI - Commandline '-pixelScale <value>' - Added basic auto unit test (setting pre-realization)
Diffstat (limited to 'src/newt/classes')
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java10
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java25
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java15
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java21
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java102
7 files changed, 126 insertions, 51 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 82199e9b5..88134f3ef 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -45,6 +45,7 @@ import jogamp.newt.WindowImpl;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ScalableSurface;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
@@ -94,7 +95,7 @@ import javax.media.nativewindow.util.RectangleImmutable;
* </pre>
* </p>
*/
-public interface Window extends NativeWindow, WindowClosingProtocol {
+public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSurface {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent");
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 37e9f9813..baaa69e8e 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -865,6 +865,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
newtChild.setVisible(false);
newtChild.setSize(w, h);
+ jawtWindow.setSurfaceScale(newtChild.getSurfaceScale(new int[2]));
newtChild.reparentWindow(jawtWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE);
newtChild.addSurfaceUpdatedListener(jawtWindow);
if( jawtWindow.isOffscreenLayerSurfaceEnabled() &&
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index a61085fb0..6610bd74f 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -404,6 +404,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@Override
+ public final void setSurfaceScale(final int[] pixelScale) {
+ window.setSurfaceScale(pixelScale);
+ }
+
+ @Override
+ public final int[] getSurfaceScale(final int[] result) {
+ return window.getSurfaceScale(result);
+ }
+
+ @Override
public final void setPosition(int x, int y) {
window.setPosition(x, y);
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 5288bfcc5..f02b9740d 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ScalableSurface;
import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.util.DimensionImmutable;
@@ -59,6 +60,7 @@ import javax.media.nativewindow.util.PointImmutable;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
+import jogamp.nativewindow.SurfaceScaleUtils;
import jogamp.nativewindow.SurfaceUpdatedHelper;
import com.jogamp.common.util.ArrayHashSet;
@@ -150,6 +152,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private volatile boolean hasFocus = false;
private volatile int pixWidth = 128, pixHeight = 128; // client-area size w/o insets in pixel units, default: may be overwritten by user
private volatile int winWidth = 128, winHeight = 128; // client-area size w/o insets in window units, default: may be overwritten by user
+ protected int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ protected int[] reqPixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
+
private volatile int x = 64, y = 64; // client-area pos w/o insets in window units
private volatile Insets insets = new Insets(); // insets of decoration (if top-level && decorated)
private boolean blockInsetsChange = false; // block insets change (from same thread)
@@ -1953,9 +1958,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/** HiDPI: We currently base scaling of window units to pixel units on an integer scale factor per component. */
- protected int getPixelScaleX() { return 1; }
+ protected final int getPixelScaleX() {
+ return hasPixelScale[0];
+ }
+
/** HiDPI: We currently base scaling of window units to pixel units on an integer scale factor per component. */
- protected int getPixelScaleY() { return 1; }
+ protected final int getPixelScaleY() {
+ return hasPixelScale[1];
+ }
+
+ @Override
+ public void setSurfaceScale(final int[] pixelScale) {
+ SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getSimpleName() : null);
+ }
+
+ @Override
+ public final int[] getSurfaceScale(final int[] result) {
+ System.arraycopy(isNativeValid() ? hasPixelScale : reqPixelScale, 0, result, 0, 2);
+ return result;
+ }
protected final boolean autoPosition() { return autoPosition; }
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 5dab64e39..d01a2f21f 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -66,10 +66,16 @@ public class AWTCanvas extends Canvas {
private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private CapabilitiesChooser chooser=null;
private final CapabilitiesImmutable capabilities;
+ private final UpstreamScalable upstreamScale;
+
+ public static interface UpstreamScalable {
+ int[] getReqPixelScale();
+ void setHasPixelScale(final int[] pixelScale);
+ }
private boolean displayConfigChanged=false;
- public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
+ public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser, UpstreamScalable upstreamScale) {
super();
if(null==capabilities) {
@@ -77,6 +83,7 @@ public class AWTCanvas extends Canvas {
}
this.capabilities=capabilities;
this.chooser=chooser;
+ this.upstreamScale = upstreamScale;
}
public AWTGraphicsConfiguration getAWTGraphicsConfiguration() {
@@ -139,7 +146,9 @@ public class AWTCanvas extends Canvas {
{
jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
// trigger initialization cycle
+ jawtWindow.setSurfaceScale( upstreamScale.getReqPixelScale() );
jawtWindow.lockSurface();
+ upstreamScale.setHasPixelScale(jawtWindow.getSurfaceScale(new int[2]));
jawtWindow.unlockSurface();
}
@@ -152,10 +161,6 @@ public class AWTCanvas extends Canvas {
}
}
- public int getPixelScale() {
- final JAWTWindow _jawtWindow = jawtWindow;
- return (null != _jawtWindow) ? _jawtWindow.getPixelScale() : 1;
- }
public NativeWindow getNativeWindow() {
final JAWTWindow _jawtWindow = jawtWindow;
return (null != _jawtWindow) ? _jawtWindow : null;
diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index cc92c4963..4064fdb05 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -98,16 +98,17 @@ public class WindowDriver extends WindowImpl {
}
}
- @Override
- protected final int getPixelScaleX() {
- final AWTCanvas _awtCanvas = awtCanvas;
- return null != _awtCanvas ? _awtCanvas.getPixelScale() : 1;
- }
+ private final AWTCanvas.UpstreamScalable upstreamScalable = new AWTCanvas.UpstreamScalable() {
+ @Override
+ public int[] getReqPixelScale() {
+ return WindowDriver.this.reqPixelScale;
+ }
- @Override
- protected final int getPixelScaleY() {
- return getPixelScaleX();
- }
+ @Override
+ public void setHasPixelScale(final int[] pixelScale) {
+ System.arraycopy(pixelScale, 0, WindowDriver.this.hasPixelScale, 0, 2);
+ }
+ };
@Override
protected void createNativeImpl() {
@@ -130,7 +131,7 @@ public class WindowDriver extends WindowImpl {
awtContainer.setLayout(new BorderLayout());
if( null == awtCanvas ) {
- awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser);
+ awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
// canvas.addComponentListener(listener);
awtContainer.add(awtCanvas, BorderLayout.CENTER);
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index cd852bb09..0fa4739a3 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -39,11 +39,13 @@ import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.ScalableSurface;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
+import jogamp.nativewindow.SurfaceScaleUtils;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.PointerIconImpl;
import jogamp.newt.ScreenImpl;
@@ -62,43 +64,42 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
DisplayDriver.initSingleton();
}
- private int pixelScale;
-
public WindowDriver() {
- pixelScale = 1;
}
- private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw) {
- final int newPixelScaleSafe = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) newPixelScaleRaw;
- final boolean changed = pixelScale != newPixelScaleSafe;
- if( DEBUG_IMPLEMENTATION ) {
- System.err.println("WindowDriver.updatePixelScale.X: "+pixelScale+" -> "+newPixelScaleSafe+" (raw "+newPixelScaleRaw+") - changed "+changed);
+ private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float pixelScaleRaw) {
+ final int[] pixelScaleInt;
+ {
+ final int ps = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) pixelScaleRaw;
+ pixelScaleInt = new int[] { ps, ps };
}
- if( changed ) {
- pixelScale = newPixelScaleSafe;
+
+ if( SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, pixelScaleInt, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) {
if( sendEvent ) {
super.sizeChanged(defer, getWidth(), getHeight(), true);
} else {
defineSize(getWidth(), getHeight());
}
+ return true;
+ } else {
+ return false;
}
- return changed;
}
private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) {
final float newPixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex());
if( DEBUG_IMPLEMENTATION ) {
- System.err.println("WindowDriver.updatePixelScale.1: "+pixelScale+" -> "+newPixelScaleRaw);
+ System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+" -> "+newPixelScaleRaw);
}
return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
}
private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) {
- final long wh = getWindowHandle();
- if( 0 != wh ) {
- final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(wh);
+ final long handle = getWindowHandle();
+ if( 0 != handle ) {
+ final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(handle);
if( DEBUG_IMPLEMENTATION ) {
- System.err.println("WindowDriver.updatePixelScale.2: "+pixelScale+" -> "+newPixelScaleRaw);
+ System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+" -> "+newPixelScaleRaw);
}
return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
} else {
@@ -109,10 +110,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
/** Called from native code */
protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw) {
final long handle = getWindowHandle();
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (raw), drop "+(0==handle));
+ }
if( 0 != handle ) {
- if( DEBUG_IMPLEMENTATION ) {
- System.err.println("WindowDriver.updatePixelScale.3: "+pixelScale+" -> "+newPixelScaleRaw);
- }
updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw);
}
}
@@ -134,13 +135,43 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
@Override
- protected final int getPixelScaleX() {
- return pixelScale;
- }
-
- @Override
- protected final int getPixelScaleY() {
- return pixelScale;
+ public final void setSurfaceScale(final int[] pixelScale) {
+ SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null);
+
+ final int[] resPixelScale;
+ if( isNativeValid() ) {
+ if( isOffscreenInstance ) {
+ final NativeWindow pWin = getParent();
+ if( pWin instanceof ScalableSurface ) {
+ final ScalableSurface sSurf = (ScalableSurface)pWin;
+ sSurf.setSurfaceScale(reqPixelScale);
+ final int[] pPixelScale = sSurf.getSurfaceScale(new int[2]);
+ updatePixelScale(true /* sendEvent */, true /* defer */, pPixelScale[0]); // HiDPI: uniformPixelScale
+ } else {
+ // just notify updated pixelScale if offscreen
+ SurfaceScaleUtils.replaceAutoMaxWithPlatformMax(reqPixelScale);
+ updatePixelScale(true /* sendEvent */, true /* defer */, reqPixelScale[0]); // HiDPI: uniformPixelScale
+ }
+ } else {
+ // set pixelScale in native code, will issue an update PixelScale
+ OSXUtil.RunOnMainThread(true, new Runnable() {
+ @Override
+ public void run() {
+ setPixelScale0(getWindowHandle(), surfaceHandle, reqPixelScale[0]); // HiDPI: uniformPixelScale
+ }
+ } );
+ }
+ resPixelScale = hasPixelScale;
+ } else {
+ hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
+ hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
+ resPixelScale = reqPixelScale;
+ }
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.setPixelScale: "+pixelScale[0]+"x"+pixelScale[1]+" (req) -> "+
+ reqPixelScale[0]+"x"+reqPixelScale[1]+" (validated) -> "+
+ resPixelScale[0]+"x"+resPixelScale[1]+" (result) - realized "+isNativeValid());
+ }
}
@Override
@@ -351,6 +382,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
}
+ final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags);
+ final boolean hasFocus = hasFocus();
+
if(DEBUG_IMPLEMENTATION) {
final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration();
final NativeWindow pWin = getParent();
@@ -362,12 +396,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+
", ioi: "+_isOffscreenInstance+
") -> "+isOffscreenInstance+
- "\n\t, "+getReconfigureFlagsAsString(null, flags));
+ "\n\t, "+getReconfigureFlagsAsString(null, flags)+", setVisible "+setVisible+", hasFocus "+hasFocus);
// Thread.dumpStack();
}
- final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags);
-
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && !setVisible ) {
if ( !isOffscreenInstance ) {
OSXUtil.RunOnMainThread(false, new Runnable() {
@@ -395,6 +427,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
updatePixelScaleByWindowHandle(false /* sendEvent */);
super.sizeChanged(false, width, height, true);
visibleChanged(false, setVisible);
+ if( hasFocus ) {
+ requestFocusImpl(true);
+ }
} else {
if( width>0 && height>0 ) {
if( !isOffscreenInstance ) {
@@ -613,7 +648,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
if( 0 != surfaceHandle ) {
throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView");
}
- surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen);
+ surfaceHandle = createView0(pS.getX(), pS.getY(), width, height);
if( 0 == surfaceHandle ) {
throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this);
}
@@ -633,7 +668,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
OSXUtil.RunOnMainThread(true, new Runnable() {
@Override
public void run() {
- initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height,
+ initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height, reqPixelScale[0] /* HiDPI uniformPixelScale */,
isOpaque, visible && !offscreenInstance, surfaceHandle);
if( offscreenInstance ) {
orderOut0(0!=parentWinHandle ? parentWinHandle : newWin);
@@ -648,11 +683,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
protected static native boolean initIDs0();
- private native long createView0(int x, int y, int w, int h, boolean fullscreen);
+ private native long createView0(int x, int y, int w, int h);
private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view);
/** Must be called on Main-Thread */
- private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h,
+ private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, float reqPixelScale,
boolean opaque, boolean visible, long view);
+ private native void setPixelScale0(long window, long view, float reqPixelScale);
private native boolean lockSurface0(long window, long view);
private native boolean unlockSurface0(long window, long view);
/** Must be called on Main-Thread */