From f9a00b91dcd146c72a50237b62270f33bd0da98e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Wed, 21 May 2014 08:53:54 +0200 Subject: Bug 742 HiDPI: [Core API Change] Distinguish window-units and pixel-units; Add HiDPI for AWT GLCanvas w/ OSX CALayer Core API Change: To support HiDPI thoroughly in JOGL (NativeWindow, JOGL, NEWT) we need to separate window- and pixel units. NativeWindow and NativeSurface now have distinguished access methods for window units and pixel units. NativeWindow: Using window units - getWindowWidth() * NEW Method * - getWindowHeight() * NEW Method * - getX(), getY(), ... NativeSurface: Using pixel units - getWidth() -> getSurfaceWidth() * RENAMED * - getHeight() -> getSurfaceHeight() * RENAMED * GLDrawable: Using pixel units - getWidth() -> getSurfaceWidth() * RENAMED, aligned w/ NativeSurface * - getHeight() -> getSurfaceHeight() * RENAMED, aligned w/ NativeSurface * Above changes also removes API collision w/ other windowing TK, e.g. AWT's getWidth()/getHeight() in GLCanvas and the same method names in GLDrawable before this change. +++ Now preliminary 'working': - AWT GLCanvas - AWT GLJPanel Tested manually on OSX w/ and w/o HiDPI Retina: java com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT -manual -noanim -time 1000000 java com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT -manual -noanim -time 1000000 +++ TODO: - NEWT - Change Window.setSize(..) to use pixel units ? - OSX HiDPI support - Testing .. - API refinement --- src/newt/classes/com/jogamp/newt/NewtFactory.java | 2 +- src/newt/classes/com/jogamp/newt/Window.java | 41 +++++++++++++--------- .../classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 14 ++++---- .../classes/com/jogamp/newt/event/MouseEvent.java | 21 ++++++++--- .../com/jogamp/newt/event/PinchToZoomGesture.java | 4 +-- .../classes/com/jogamp/newt/opengl/GLWindow.java | 34 ++++++++++++++---- .../classes/com/jogamp/newt/swt/NewtCanvasSWT.java | 30 ++++++++++++++-- .../newt/util/applet/JOGLNewtApplet3Run.java | 15 ++++---- .../newt/util/applet/JOGLNewtAppletBase.java | 2 +- 9 files changed, 115 insertions(+), 48 deletions(-) (limited to 'src/newt/classes/com/jogamp') diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java index 9685200eb..3b31861f0 100644 --- a/src/newt/classes/com/jogamp/newt/NewtFactory.java +++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java @@ -296,7 +296,7 @@ public class NewtFactory { } final Window win = WindowImpl.create(parentWindow, 0, screen, caps); - win.setSize(parentWindow.getWidth(), parentWindow.getHeight()); + win.setSize(parentWindow.getSurfaceWidth(), parentWindow.getSurfaceHeight()); if ( null != newtParentWindow ) { newtParentWindow.addChild(win); win.setVisible(newtParentWindow.isVisible()); diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 4816e62e5..9cf67c56f 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -232,7 +232,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol { // /** - * Sets the size of the window's client area, excluding decorations. + * Sets the size of the window's client area in window units, excluding decorations. * *

* Zero size semantics are respected, see {@link #setVisible(boolean)}:
@@ -248,22 +248,22 @@ public interface Window extends NativeWindow, WindowClosingProtocol { *

* This call is ignored if in fullscreen mode.

* - * @param width of the window's client area - * @param height of the window's client area + * @param width of the window's client area in window units + * @param height of the window's client area in window units * * @see #getInsets() */ void setSize(int width, int height); /** - * Sets the size of the top-level window including insets (window decorations). + * Sets the size of the top-level window including insets (window decorations) in window units. * *

* Note: Insets (if supported) are available only after the window is set visible and hence has been created. *

* - * @param width of the top-level window area - * @param height of the top-level window area + * @param width of the top-level window area in window units + * @param height of the top-level window area in window units * * @see #setSize(int, int) * @see #getInsets() @@ -271,19 +271,19 @@ public interface Window extends NativeWindow, WindowClosingProtocol { void setTopLevelSize(int width, int height); /** - * Sets the location of the window's client area, excluding insets (window decorations).
+ * Sets the location of the window's client area excluding insets (window decorations) in window units.
* * This call is ignored if in fullscreen mode.
* - * @param x coord of the client-area's top left corner - * @param y coord of the client-area's top left corner + * @param x coord of the client-area's top left corner in window units + * @param y coord of the client-area's top left corner in window units * * @see #getInsets() */ void setPosition(int x, int y); /** - * Sets the location of the top-level window inclusive insets (window decorations).
+ * Sets the location of the top-level window inclusive insets (window decorations) in window units.
* *

* Note: Insets (if supported) are available only after the window is set visible and hence has been created. @@ -291,8 +291,8 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * * This call is ignored if in fullscreen mode.
* - * @param x coord of the top-level left corner - * @param y coord of the top-level left corner + * @param x coord of the top-level left corner in window units + * @param y coord of the top-level left corner in window units * * @see #setPosition(int, int) * @see #getInsets() @@ -356,10 +356,10 @@ public interface Window extends NativeWindow, WindowClosingProtocol { void confinePointer(boolean confine); /** - * Moves the pointer to x/y relative to this window's origin. + * Moves the pointer to x/y relative to this window's origin in pixel units. * - * @param x relative pointer x position within this window - * @param y relative pointer y position within this window + * @param x relative pointer x position within this window in pixel units + * @param y relative pointer y position within this window in pixel units * * @see #confinePointer(boolean) */ @@ -431,8 +431,8 @@ public interface Window extends NativeWindow, WindowClosingProtocol { * this window is added to it's list of children.

* * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window. - * @param x new top-level position, use -1 for default position. - * @param y new top-level position, use -1 for default position. + * @param x new top-level position in window units, use -1 for default position. + * @param y new top-level position in window units, use -1 for default position. * @param hints May contain hints (bitfield values) like {@link #REPARENT_HINT_FORCE_RECREATION} or {@link #REPARENT_HINT_BECOMES_VISIBLE}. * * @return The issued reparent action type (strategy) as defined in Window.ReparentAction @@ -520,6 +520,13 @@ public interface Window extends NativeWindow, WindowClosingProtocol { */ void requestFocus(boolean wait); + /** + * Trigger window repaint while passing the dirty region in pixel units. + * @param x dirty-region y-pos in pixel units + * @param y dirty-region x-pos in pixel units + * @param width dirty-region width in pixel units + * @param height dirty-region height in pixel units + */ void windowRepaint(int x, int y, int width, int height); void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event); diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index f0cc68903..891843cb7 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -400,7 +400,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto final Window w = newtChild; if( null != w ) { // use NEWT child's size for min/pref size! - java.awt.Dimension minSize = new java.awt.Dimension(w.getWidth(), w.getHeight()); + java.awt.Dimension minSize = new java.awt.Dimension(w.getSurfaceWidth(), w.getSurfaceHeight()); setMinimumSize(minSize); setPreferredSize(minSize); } @@ -645,8 +645,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto final int printNumSamples = printAWTTiles.getNumSamples(caps); GLDrawable printDrawable = printGLAD.getDelegatedDrawable(); final boolean reqNewGLADSamples = printNumSamples != caps.getNumSamples(); - final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getWidth() || - printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getHeight(); + final boolean reqNewGLADSize = printAWTTiles.customTileWidth != -1 && printAWTTiles.customTileWidth != printDrawable.getSurfaceWidth() || + printAWTTiles.customTileHeight != -1 && printAWTTiles.customTileHeight != printDrawable.getSurfaceHeight(); final boolean reqNewGLADOnscrn = caps.isOnscreen(); // It is desired to use a new offscreen GLAD, however Bug 830 forbids this for AA onscreen context. @@ -654,7 +654,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto final boolean reqNewGLAD = !caps.getSampleBuffers() && ( reqNewGLADOnscrn || reqNewGLADSamples || reqNewGLADSize ); if( DEBUG ) { System.err.println("AWT print.setup: reqNewGLAD "+reqNewGLAD+"[ onscreen "+reqNewGLADOnscrn+", samples "+reqNewGLADSamples+", size "+reqNewGLADSize+"], "+ - ", drawableSize "+printDrawable.getWidth()+"x"+printDrawable.getHeight()+ + ", drawableSize "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+ ", customTileSize "+printAWTTiles.customTileWidth+"x"+printAWTTiles.customTileHeight+ ", scaleMat "+printAWTTiles.scaleMatX+" x "+printAWTTiles.scaleMatY+ ", numSamples "+printAWTTiles.customNumSamples+" -> "+printNumSamples+", printAnimator "+printAnimator); @@ -674,13 +674,13 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto printDrawable = printGLAD.getDelegatedDrawable(); } printAWTTiles.setGLOrientation(printGLAD.isGLOriented(), printGLAD.isGLOriented()); - printAWTTiles.renderer.setTileSize(printDrawable.getWidth(), printDrawable.getHeight(), 0); + printAWTTiles.renderer.setTileSize(printDrawable.getSurfaceWidth(), printDrawable.getSurfaceHeight(), 0); printAWTTiles.renderer.attachAutoDrawable(printGLAD); if( DEBUG ) { System.err.println("AWT print.setup "+printAWTTiles); System.err.println("AWT print.setup AA "+printNumSamples+", "+caps); - System.err.println("AWT print.setup printGLAD: "+printGLAD.getWidth()+"x"+printGLAD.getHeight()+", "+printGLAD); - System.err.println("AWT print.setup printDraw: "+printDrawable.getWidth()+"x"+printDrawable.getHeight()+", "+printDrawable); + System.err.println("AWT print.setup printGLAD: "+printGLAD.getSurfaceWidth()+"x"+printGLAD.getSurfaceHeight()+", "+printGLAD); + System.err.println("AWT print.setup printDraw: "+printDrawable.getSurfaceWidth()+"x"+printDrawable.getSurfaceHeight()+", "+printDrawable); } } } diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java index fb74b5a09..43cac31bb 100644 --- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java @@ -42,6 +42,11 @@ package com.jogamp.newt.event; *

* http://www.w3.org/Submission/pointer-events/#pointerevent-interface *

+ *
Unit of Coordinates
+ *

+ * All pointer coordinates of this interface are represented in pixel units, + * see {@link NativeSurface} and {@link NativeWindow}. + *

*
Multiple-Pointer Events
*

* In case an instance represents a multiple-pointer event, i.e. {@link #getPointerCount()} is > 1, @@ -349,10 +354,18 @@ public class MouseEvent extends InputEvent return clickCount; } + /** + * See details for multiple-pointer events. + * @return X-Coord of the triggering pointer-index zero in pixel units. + */ public final int getX() { return x[0]; } + /** + * See details for multiple-pointer events. + * @return Y-Coord of the triggering pointer-index zero in pixel units. + */ public final int getY() { return y[0]; } @@ -360,7 +373,7 @@ public class MouseEvent extends InputEvent /** * See details for multiple-pointer events. * @param index pointer-index within [0 .. {@link #getPointerCount()}-1] - * @return X-Coord associated with the pointer-index. + * @return X-Coord associated with the pointer-index in pixel units. * @see getPointerId(index) */ public final int getX(final int index) { @@ -370,7 +383,7 @@ public class MouseEvent extends InputEvent /** * See details for multiple-pointer events. * @param index pointer-index within [0 .. {@link #getPointerCount()}-1] - * @return Y-Coord associated with the pointer-index. + * @return Y-Coord associated with the pointer-index in pixel units. * @see getPointerId(index) */ public final int getY(final int index) { @@ -379,7 +392,7 @@ public class MouseEvent extends InputEvent /** * See details for multiple-pointer events. - * @return array of all X-Coords for all pointers + * @return array of all X-Coords for all pointers in pixel units. */ public final int[] getAllX() { return x; @@ -387,7 +400,7 @@ public class MouseEvent extends InputEvent /** * See details for multiple-pointer events. - * @return array of all Y-Coords for all pointers + * @return array of all Y-Coords for all pointers in pixel units. */ public final int[] getAllY() { return y; diff --git a/src/newt/classes/com/jogamp/newt/event/PinchToZoomGesture.java b/src/newt/classes/com/jogamp/newt/event/PinchToZoomGesture.java index 7d22128cf..1521036d6 100644 --- a/src/newt/classes/com/jogamp/newt/event/PinchToZoomGesture.java +++ b/src/newt/classes/com/jogamp/newt/event/PinchToZoomGesture.java @@ -173,7 +173,7 @@ public class PinchToZoomGesture implements GestureHandler { } final int eventType = pe.getEventType(); - final boolean useY = surface.getWidth() >= surface.getHeight(); // use smallest dimension + final boolean useY = surface.getSurfaceWidth() >= surface.getSurfaceHeight(); // use smallest dimension switch ( eventType ) { case MouseEvent.EVENT_MOUSE_PRESSED: { if( 1 == pointerDownCount ) { @@ -221,7 +221,7 @@ public class PinchToZoomGesture implements GestureHandler { } else if( zoomMode ) { final int d = Math.abs(edge0-edge1); final int dd = d - zoomLastEdgeDist; - final float screenEdge = useY ? surface.getHeight() : surface.getWidth(); + final float screenEdge = useY ? surface.getSurfaceHeight() : surface.getSurfaceWidth(); final float delta = dd / screenEdge; // [-1..1] if(DEBUG) { System.err.println("XXX2: id0 "+pIds[0]+" -> idx0 "+p0Idx+", id1 "+pIds[1]+" -> idx1 "+p1Idx); diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 4b740927b..c4a5fcab1 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -130,7 +130,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind @Override public void windowResized(WindowEvent e) { - defaultWindowResizedOp(getWidth(), getHeight()); + defaultWindowResizedOp(getSurfaceWidth(), getSurfaceHeight()); } }); @@ -353,13 +353,33 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override - public final int getWidth() { - return window.getWidth(); + public final int getWindowWidth() { + return window.getWindowWidth(); } @Override - public final int getHeight() { - return window.getHeight(); + public final int getWindowHeight() { + return window.getWindowHeight(); + } + + @Override + public final int[] getWindowUnitXY(int[] result, final int[] pixelUnitXY) { + return window.getWindowUnitXY(result, pixelUnitXY); + } + + @Override + public final int[] getPixelUnitXY(int[] result, final int[] windowUnitXY) { + return window.getPixelUnitXY(result, windowUnitXY); + } + + @Override + public final int getSurfaceWidth() { + return window.getSurfaceWidth(); + } + + @Override + public final int getSurfaceHeight() { + return window.getSurfaceHeight(); } @Override @@ -516,7 +536,7 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind t0 = 0; } - if (null == drawable && visible && 0 != window.getWindowHandle() && 0 display setVisible(true); } diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java index 6f4be75f5..ee01212cb 100644 --- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java +++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java @@ -460,12 +460,38 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol { } @Override - public int getWidth() { + public int getWindowWidth() { + return getSurfaceWidth(); // FIXME: Use 'scale' or an actual window-width + } + + @Override + public int getWindowHeight() { + return getSurfaceHeight(); // FIXME: Use 'scale' or an actual window-width + } + + @Override + public final int[] getWindowUnitXY(int[] result, final int[] pixelUnitXY) { + final int scale = 1; // FIXME: Use 'scale' .. + result[0] = pixelUnitXY[0] / scale; + result[1] = pixelUnitXY[1] / scale; + return result; + } + + @Override + public final int[] getPixelUnitXY(int[] result, final int[] windowUnitXY) { + final int scale = 1; // FIXME: Use 'scale' .. + result[0] = windowUnitXY[0] * scale; + result[1] = windowUnitXY[1] * scale; + return result; + } + + @Override + public int getSurfaceWidth() { return clientArea.width; } @Override - public int getHeight() { + public int getSurfaceHeight() { return clientArea.height; } diff --git a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java index 8123126ee..8a3e5616d 100644 --- a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java +++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtApplet3Run.java @@ -44,7 +44,7 @@ import javax.media.opengl.FPSCounter; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; -import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSizePos; +import com.jogamp.nativewindow.UpstreamWindowHookMutableSizePos; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.Window; import com.jogamp.newt.opengl.GLWindow; @@ -103,7 +103,7 @@ public class JOGLNewtApplet3Run implements Applet3 { int glXd=Integer.MAX_VALUE, glYd=Integer.MAX_VALUE, glWidth=Integer.MAX_VALUE, glHeight=Integer.MAX_VALUE; Applet3Context ctx; boolean glStandalone = false; - UpstreamSurfaceHookMutableSizePos upstreamSizePosHook; + UpstreamWindowHookMutableSizePos upstreamSizePosHook; PointImmutable upstreamLocOnScreen; NativeWindow browserWin; @@ -147,8 +147,9 @@ public class JOGLNewtApplet3Run implements Applet3 { final AbstractGraphicsDevice aDevice = NativeWindowFactory.createDevice(upstreamWin.getDisplayConnection(), true /* own */); // open and own! (for upstreamLocOnScreen) final AbstractGraphicsScreen aScreen = NativeWindowFactory.createScreen(aDevice, upstreamWin.getScreenIndex()); - upstreamSizePosHook = new UpstreamSurfaceHookMutableSizePos(upstreamWin.getX(), upstreamWin.getY(), - upstreamWin.getWidth(), upstreamWin.getHeight()); + upstreamSizePosHook = new UpstreamWindowHookMutableSizePos(upstreamWin.getX(), upstreamWin.getY(), + upstreamWin.getWidth(), upstreamWin.getHeight(), + upstreamWin.getWidth(), upstreamWin.getHeight()); // FIXME: pixel-dim == window-dim 'for now' ? browserWin = NativeWindowFactory.createWrappedWindow(aScreen, 0 /* surfaceHandle */, upstreamWin.getWindowHandle(), upstreamSizePosHook); upstreamLocOnScreen = NativeWindowFactory.getLocationOnScreen(browserWin); @@ -171,7 +172,7 @@ public class JOGLNewtApplet3Run implements Applet3 { glWindow = GLWindow.create(w); glWindow.setUndecorated(glUndecorated); glWindow.setAlwaysOnTop(glAlwaysOnTop); - glWindow.setSize(browserWin.getWidth(), browserWin.getHeight()); + glWindow.setSize(browserWin.getSurfaceWidth(), browserWin.getSurfaceHeight()); return new NativeWindowDownstream() { @Override @@ -183,7 +184,7 @@ public class JOGLNewtApplet3Run implements Applet3 { @Override public void setSize(int width, int height) { - upstreamSizePosHook.setSize(width, height); + upstreamSizePosHook.setPixelSize(width, height); if( null != glWindow ) { glWindow.setSize(width, height); } @@ -226,7 +227,7 @@ public class JOGLNewtApplet3Run implements Applet3 { @Override public void notifyPositionChanged(NativeWindowUpstream nw) { - upstreamSizePosHook.setPos(nw.getX(), nw.getY()); + upstreamSizePosHook.setWinPos(nw.getX(), nw.getY()); if( null != glWindow ) { glWindow.setPosition(nw.getX(), nw.getY()); } diff --git a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java index bbe6b8527..eee8ab23e 100644 --- a/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java +++ b/src/newt/classes/com/jogamp/newt/util/applet/JOGLNewtAppletBase.java @@ -377,7 +377,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener { new Thread() { public void run() { System.err.println("[set mouse pos pre]"); - glWindow.warpPointer(glWindow.getWidth()/2, glWindow.getHeight()/2); + glWindow.warpPointer(glWindow.getSurfaceWidth()/2, glWindow.getSurfaceHeight()/2); System.err.println("[set mouse pos post]"); } }.start(); } -- cgit v1.2.3