aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-05-26 18:54:27 +0200
committerSven Gothel <[email protected]>2014-05-26 18:54:27 +0200
commit56d60b36798fa8dae48bf2aa5e2de6f3178ab0d1 (patch)
tree4c86190128414205d0b768780e3272e32bd1e81a /src/newt/classes/com
parent98ed02cdb7b325d8afde596a5ef04f97be2018d4 (diff)
Bug 741 HiDPI: Refine Monitor/Screen [virtual] Viewport Definition / Add NEWT Support / Fix JAWT getPixelScale deadlock
- NativeWindow/Surface/NEWT API DOC: Define Coordinate System of Window and Screen - OSXUtil: Add getPixelScale(..) via Screen index and 'windowOrView' - JAWTWindow/JAWTUtil.getPixelScale(..): Use pre-fetched AWT GraphicsConfiguration to solve AWT-TreeLock (deadlock) - [Virtual] Viewport of MonitorDevice and Screen: - Properly calculate and expose [virtual] viewport in window and pixel units - OSX Monitor viewports in pixel units are 'reconstructed' - Window/Viewport to Monitor selection shall be perfomed via window units (unique) - OSX NEWT Window create/init (native): Use given size and coordinates even in fullscreen mode Don't override by quering NSScreen coordinates, trust given values. - Fix test cases, i.e. usage of pixel- and window-units
Diffstat (limited to 'src/newt/classes/com')
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorDevice.java97
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java52
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java23
3 files changed, 112 insertions, 60 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
index af0ce0146..8e5d305dd 100644
--- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java
+++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
@@ -52,6 +52,9 @@ import com.jogamp.common.util.ArrayHashSet;
* <li>{@link RectangleImmutable} viewport (rotated)</li>
* </ul></li>
* </ul>
+ * <p>
+ * All values of this interface are represented in pixel units, if not stated otherwise.
+ * </p>
*/
public abstract class MonitorDevice {
protected final Screen screen; // backref
@@ -61,16 +64,18 @@ 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 viewport;
+ protected Rectangle viewportPU; // in pixel units
+ protected Rectangle viewportWU; // in window units
- protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
+ protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewportPU, Rectangle viewportWU, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
this.screen = screen;
this.nativeId = nativeId;
this.sizeMM = sizeMM;
this.originalMode = currentMode;
this.supportedModes = supportedModes;
this.currentMode = currentMode;
- this.viewport = viewport;
+ this.viewportPU = viewportPU;
+ this.viewportWU = viewportWU;
this.modeChanged = false;
}
@@ -170,11 +175,22 @@ public abstract class MonitorDevice {
/**
* Returns the {@link RectangleImmutable rectangular} portion
- * of the rotated virtual {@link Screen} size in pixel units
- * represented by this monitor.
+ * 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
*/
public final RectangleImmutable getViewport() {
- return viewport;
+ return viewportPU;
+ }
+
+ /**
+ * Returns the {@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
+ */
+ public final RectangleImmutable getViewportInWindowUnits() {
+ return viewportWU;
}
/**
@@ -184,46 +200,45 @@ public abstract class MonitorDevice {
* @param y y-coord in pixel units
*/
public final boolean contains(final int x, final int y) {
- return x >= viewport.getX() &&
- x < viewport.getX() + viewport.getWidth() &&
- y >= viewport.getY() &&
- y < viewport.getY() + viewport.getHeight() ;
+ return x >= viewportPU.getX() &&
+ x < viewportPU.getX() + viewportPU.getWidth() &&
+ y >= viewportPU.getY() &&
+ y < viewportPU.getY() + viewportPU.getHeight() ;
}
/**
- * Returns the coverage of given rectangle in pixel units
- * w/ this {@link #getViewport() viewport}, i.e. between <code>0.0</code> and <code>1.0</code>.
- * <p>
- * Coverage is computed by:
- * <pre>
- * isect = viewport.intersection(r);
- * coverage = area( isect ) / area( viewport ) ;
- * </pre>
- * </p>
- * @param r {@link RectangleImmutable rectangle} in pixel units
- */
- public final float coverage(final RectangleImmutable r) {
- return viewport.coverage(r);
- }
-
- /**
- * Returns the union of the given monitor's {@link #getViewport() viewport} in pixel units.
- * @param result storage for result, will be returned
+ * Calculates the union of the given monitor's {@link #getViewport() viewport} in pixel- and window units.
+ * @param viewport storage for result in pixel units, maybe null
+ * @param viewportInWindowUnits storage for result in window units, maybe null
* @param monitors given list of monitors
- * @return viewport representing the union of given monitor's viewport in pixel units, i.e. result storage for chaining
*/
- public static Rectangle unionOfViewports(final Rectangle result, final List<MonitorDevice> monitors) {
- int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE;
- int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE;
+ public static void unionOfViewports(final Rectangle viewport, final Rectangle viewportInWindowUnits, final List<MonitorDevice> monitors) {
+ int x1PU=Integer.MAX_VALUE, y1PU=Integer.MAX_VALUE;
+ int x2PU=Integer.MIN_VALUE, y2PU=Integer.MIN_VALUE;
+ int x1WU=Integer.MAX_VALUE, y1WU=Integer.MAX_VALUE;
+ int x2WU=Integer.MIN_VALUE, y2WU=Integer.MIN_VALUE;
for(int i=monitors.size()-1; i>=0; i--) {
- final RectangleImmutable vp = monitors.get(i).getViewport();
- x1 = Math.min(x1, vp.getX());
- x2 = Math.max(x2, vp.getX() + vp.getWidth());
- y1 = Math.min(y1, vp.getY());
- y2 = Math.max(y2, vp.getY() + vp.getHeight());
+ if( null != viewport ) {
+ final RectangleImmutable viewPU = monitors.get(i).getViewport();
+ x1PU = Math.min(x1PU, viewPU.getX());
+ x2PU = Math.max(x2PU, viewPU.getX() + viewPU.getWidth());
+ y1PU = Math.min(y1PU, viewPU.getY());
+ y2PU = Math.max(y2PU, viewPU.getY() + viewPU.getHeight());
+ }
+ if( null != viewportInWindowUnits ) {
+ final RectangleImmutable viewWU = monitors.get(i).getViewportInWindowUnits();
+ x1WU = Math.min(x1WU, viewWU.getX());
+ x2WU = Math.max(x2WU, viewWU.getX() + viewWU.getWidth());
+ y1WU = Math.min(y1WU, viewWU.getY());
+ y2WU = Math.max(y2WU, viewWU.getY() + viewWU.getHeight());
+ }
+ }
+ if( null != viewport ) {
+ viewport.set(x1PU, y1PU, x2PU - x1PU, y2PU - y1PU);
+ }
+ if( null != viewportInWindowUnits ) {
+ viewportInWindowUnits.set(x1WU, y1WU, x2WU - x1WU, y2WU - y1WU);
}
- result.set(x1, y1, x2 - x1, y2 - y1);
- return result;
}
public final boolean isOriginalMode() {
@@ -247,6 +262,7 @@ public abstract class MonitorDevice {
* <p>
* The returned {@link MonitorMode} is element of the lists {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
* </p>
+ * @see #queryCurrentMode()
*/
public final MonitorMode getCurrentMode() {
return currentMode;
@@ -257,6 +273,7 @@ public abstract class MonitorDevice {
* <p>
* The returned {@link MonitorMode} is element of the lists {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
* </p>
+ * @see #getCurrentMode()
*/
public abstract MonitorMode queryCurrentMode();
@@ -269,7 +286,7 @@ public abstract class MonitorDevice {
@Override
public String toString() {
- return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewport+ ", orig "+originalMode+", curr "+currentMode+
+ return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+
", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]";
}
}
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index 919b98b45..cef254634 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -28,12 +28,14 @@
package com.jogamp.newt;
import com.jogamp.newt.event.MonitorModeListener;
+
import jogamp.newt.Debug;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Rectangle;
@@ -41,7 +43,18 @@ import javax.media.nativewindow.util.RectangleImmutable;
/**
* A screen may span multiple {@link MonitorDevice}s representing their combined virtual size.
- */
+ * <p>
+ * All values of this interface are represented in pixel units, if not stated otherwise.
+ * </p>
+ *
+ * <a name="coordinateSystem"><h5>Coordinate System</h5></a>
+ * <p>
+ * <ul>
+ * <li>Screen space has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * <li>{@link #getViewport() Virtual viewport} covers all {@link MonitorDevice}s {@link MonitorDevice#getViewport() viewports} and has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * </ul>
+ * </p>
+*/
public abstract class Screen {
/**
@@ -131,11 +144,15 @@ public abstract class Screen {
public abstract int getIndex();
/**
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
* @return the x position of the virtual viewport's top-left origin in pixel units.
*/
public abstract int getX();
/**
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
* @return the y position of the virtual viewport's top-left origin in pixel units.
*/
public abstract int getY();
@@ -151,20 +168,20 @@ public abstract class Screen {
public abstract int getHeight();
/**
- * @return the <b>rotated</b> virtual viewport, i.e. origin and size in pixel units.
- * @see #getViewportInWindowUnits(Window)
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
+ * @return the <b>rotated</b> virtual viewport, i.e. top-left origin and size, in pixel units.
+ * @see #getViewportInWindowUnits()
*/
public abstract RectangleImmutable getViewport();
/**
- * Returns a newly created {@link Rectangle} containing the <b>rotated</b> virtual viewport
- * in window units of the given {@link Window} instance.
- * @return rotated viewport values, i.e. origin and size, in pixel units.
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
+ * @return the <b>rotated</b> virtual viewport, i.e. top-left origin and size, in window units.
* @see #getViewport()
*/
- public final Rectangle getViewportInWindowUnits(final Window win) {
- return win.convertToWindowUnits( (Rectangle) getViewport().cloneMutable() );
- }
+ public abstract RectangleImmutable getViewportInWindowUnits();
/**
* @return the associated Display
@@ -192,12 +209,12 @@ public abstract class Screen {
public abstract List<MonitorDevice> getMonitorDevices();
/**
- * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewport() viewport}
- * {@link MonitorDevice#coverage(RectangleImmutable) coverage} of the given rectangle in pixel units.
+ * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
+ * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units.
* <p>
* If no coverage is detected the first {@link MonitorDevice} is returned.
* </p>
- * @param r arbitrary rectangle in pixel units
+ * @param r arbitrary rectangle in window units
*/
public final MonitorDevice getMainMonitor(final RectangleImmutable r) {
MonitorDevice res = null;
@@ -205,7 +222,7 @@ public abstract class Screen {
final List<MonitorDevice> monitors = getMonitorDevices();
for(int i=monitors.size()-1; i>=0; i--) {
final MonitorDevice monitor = monitors.get(i);
- final float coverage = monitor.coverage(r);
+ final float coverage = monitor.getViewportInWindowUnits().coverage(r);
if( coverage > maxCoverage ) {
maxCoverage = coverage;
res = monitor;
@@ -218,15 +235,16 @@ public abstract class Screen {
}
/**
- * Returns the union of all monitor's {@link MonitorDevice#getViewport() viewport} in pixel units.
+ * Calculates the union of all monitor's {@link MonitorDevice#getViewport() viewport} in pixel- and window units.
* <p>
* Should be equal to {@link #getX()}, {@link #getY()}, {@link #getWidth()} and {@link #getHeight()},
* however, some native toolkits may choose a different virtual screen area.
* </p>
- * @param result storage for result, will be returned
+ * @param viewport storage for result in pixel units, maybe null
+ * @param viewportInWindowUnits storage for result in window units, maybe null
*/
- public final Rectangle unionOfMonitorViewportSize(final Rectangle result) {
- return MonitorDevice.unionOfViewports(result, getMonitorDevices());
+ public final void unionOfMonitorViewports(final Rectangle viewport, final Rectangle viewportInWindowUnits) {
+ MonitorDevice.unionOfViewports(viewport, viewportInWindowUnits, getMonitorDevices());
}
/**
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 872d67087..57fcb626d 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -46,7 +46,6 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.WindowClosingProtocol;
-import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
@@ -65,6 +64,20 @@ import javax.media.nativewindow.util.RectangleImmutable;
* window operation to an instance of this interface while providing OpenGL
* functionality.
* </p>
+ * <p>
+ * All values of this interface are represented in window units, if not stated otherwise.
+ * </p>
+ *
+ * <a name="coordinateSystem"><h5>Coordinate System</h5></a>
+ * <p>
+ * <ul>
+ * <li>Screen space has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * <li>Window origin is in it's top-left corner, see {@link #getX()} and {@link #getY()}. </li>
+ * <li>Window client-area excludes {@link #getInsets() insets}, i.e. window decoration.</li>
+ * <li>Window origin is relative to it's parent window if exist, or the screen position (top-level).</li>
+ * </ul>
+ * See {@link NativeWindow} and {@link Screen}.
+ * </p>
* <a name="customwindowicons"><h5>Custom Window Icons</h5></a>
* <p>
* Custom window icons can be defined via system property <code>newt.window.icons</code>,
@@ -108,8 +121,8 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
Screen getScreen();
/**
- * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport}
- * {@link MonitorDevice#coverage(RectangleImmutable) covers} this window the most.
+ * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
+ * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of this window.
* <p>
* If no coverage is detected the first {@link MonitorDevice} is returned.
* </p>
@@ -242,6 +255,10 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
/**
* Returns a newly created {@link Rectangle} containing the scaled window origin, {@link #getX()} & {@link #getY()},
* and size, {@link #getSurfaceWidth()} & {@link #getSurfaceHeight()}, in pixel units.
+ *
+ * @deprecated The returned position in pixel units might be erroneous in case of multiple monitor setup where a mixed pixel-scale exist,
+ * since this method currently does not take the monitor viewport and each of it's pixel-scale into account (expensive).
+ * Either we fix this issue or remove this method at a later time.
*/
Rectangle getSurfaceBounds();