Skip to content

Commit

Permalink
NEWT MonitorDevice: Identify cloned devices (fully covered) ; Windows…
Browse files Browse the repository at this point in the history
…: Iterate-over and identify all adapter:monitor. (Bug 1129)

- Identify cloned devices (fully covered)
  - MonitorDevice gets 'isCloned()' to identify whether
    it is a cloned device, i.e. fully covered by another monitor.
    This detection may happen natively but will always performed
    platform agnostic.

  - getMainMonitor(..) now exclude 'cloned' devices

- Windows: Iterate-over and identify all adapter:monitor
  - Since we also list cloned monitor,
    we need to iterate over all adapter and all it's monitor-devices.
  - The native monitor-id is now defined as: ( adapter-idx << 8 ) | monitor-idx.

- Bug 1129 <- listed under this bug entry for convenience
  • Loading branch information
sgothel committed Feb 17, 2015
1 parent 42d88f9 commit 559ecad
Show file tree
Hide file tree
Showing 20 changed files with 177 additions and 97 deletions.
23 changes: 15 additions & 8 deletions src/newt/classes/com/jogamp/newt/MonitorDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,39 @@ public abstract class MonitorDevice {
protected final DimensionImmutable sizeMM; // in [mm]
protected final MonitorMode originalMode;
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 final float[] pixelScale;
protected final Rectangle viewportPU; // in pixel units
protected final Rectangle viewportWU; // in window units
protected boolean isClone;
protected MonitorMode currentMode;
protected boolean modeChanged;

/**
* @param screen associated {@link Screen}
* @param nativeId unique monitor device ID
* @param isClone flag
* @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) {
protected MonitorDevice(final Screen screen, final int nativeId, final boolean isClone,
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.isClone = isClone;
this.currentMode = currentMode;
this.modeChanged = false;
}

Expand Down Expand Up @@ -134,6 +138,9 @@ public final int hashCode() {
/** @return the immutable unique native Id of this monitor device. */
public final int getId() { return nativeId; }

/** @return {@code true} if this device represents a <i>clone</i>, otherwise return {@code false}. */
public final boolean isClone() { return isClone; }

/**
* @return the immutable monitor size in millimeters.
*/
Expand Down Expand Up @@ -323,7 +330,7 @@ public final MonitorMode getCurrentMode() {

@Override
public String toString() {
return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+
return "Monitor[Id "+Display.toHexString(nativeId)+", clone "+isClone+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+
"], viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+
", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]";
}
Expand Down
16 changes: 10 additions & 6 deletions src/newt/classes/com/jogamp/newt/Screen.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ public boolean equals(final Object obj) {

/**
* Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
* {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units.
* {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units,
* which is not a {@link MonitorDevice#isClone() clone}.
* <p>
* If no coverage is detected the first {@link MonitorDevice} is returned.
* </p>
Expand All @@ -220,12 +221,15 @@ public final MonitorDevice getMainMonitor(final RectangleImmutable r) {
MonitorDevice res = null;
float maxCoverage = Float.MIN_VALUE;
final List<MonitorDevice> monitors = getMonitorDevices();
for(int i=monitors.size()-1; i>=0; i--) {
final int monitorCount = monitors.size();
for(int i=0; i<monitorCount; i++) {
final MonitorDevice monitor = monitors.get(i);
final float coverage = monitor.getViewportInWindowUnits().coverage(r);
if( coverage > maxCoverage ) {
maxCoverage = coverage;
res = monitor;
if( !monitor.isClone() ) {
final float coverage = monitor.getViewportInWindowUnits().coverage(r);
if( coverage > maxCoverage ) {
maxCoverage = coverage;
res = monitor;
}
}
}
if( maxCoverage > 0.0f && null != res ) {
Expand Down
4 changes: 2 additions & 2 deletions src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -1007,8 +1007,8 @@ public void init(final GLAutoDrawable drawable) {
final MonitorDevice monitor = glWindow.getMainMonitor();
System.err.println("Main Monitor: "+monitor);
final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]);
System.err.println(" pp/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]");
System.err.println(" pp/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]");
System.err.println(" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]");
System.err.println(" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]");
final GL gl = drawable.getGL();
System.err.println(JoglVersion.getGLInfo(gl, null));
System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
Expand Down
17 changes: 11 additions & 6 deletions src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@

package jogamp.newt;

import java.util.ArrayList;

import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.DimensionImmutable;
import com.jogamp.nativewindow.util.Rectangle;

import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
Expand All @@ -42,18 +43,19 @@ public class MonitorDeviceImpl extends MonitorDevice {
/**
* @param screen associated {@link Screen}
* @param nativeId unique monitor device ID
* @param isClone TODO
* @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
*/
public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final DimensionImmutable sizeMM,
final MonitorMode currentMode,
final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU,
final ArrayHashSet<MonitorMode> supportedModes) {
super(screen, nativeId, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final boolean isClone,
final DimensionImmutable sizeMM,
final MonitorMode currentMode, final float[] pixelScale, final Rectangle viewportPU,
final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) {
super(screen, nativeId, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
}

@Override
Expand Down Expand Up @@ -157,4 +159,7 @@ private final void setCurrentModeValue(final MonitorMode currentMode) {
return supportedModes;
}

/* pp */ final void setIsClone(final boolean isClone) {
this.isClone = isClone;
}
}
45 changes: 41 additions & 4 deletions src/newt/classes/jogamp/newt/MonitorModeProps.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@
import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
import com.jogamp.newt.Screen;

import java.util.ArrayList;
import java.util.List;

import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.nativewindow.util.Dimension;
import com.jogamp.nativewindow.util.DimensionImmutable;
import com.jogamp.nativewindow.util.Rectangle;
import com.jogamp.nativewindow.util.SurfaceSize;
import com.jogamp.opengl.math.FloatUtil;

import jogamp.newt.MonitorDeviceImpl;
import jogamp.newt.ScreenImpl;
Expand Down Expand Up @@ -128,6 +132,7 @@ public class MonitorModeProps {
* <ul>
* <li>count</li>
* <li>id</li>
* <li>IsClone</li>
* <li>ScreenSizeMM[width, height] (2 elements)</li>
* <li>Rotated Viewport pixel-units (4 elements)</li>
* <li>Rotated Viewport window-units (4 elements)</li>
Expand All @@ -142,7 +147,7 @@ public class MonitorModeProps {
* WARNING: must be synchronized with ScreenMode.h, native implementation
* </p>
*/
public static final int MIN_MONITOR_DEVICE_PROPERTIES = 15;
public static final int MIN_MONITOR_DEVICE_PROPERTIES = 16;

public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count
+ 1 // native mode
Expand Down Expand Up @@ -285,6 +290,7 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
offset++;
final List<MonitorMode> allMonitorModes = cache.monitorModes.getData();
final int id = monitorProperties[offset++];
final boolean isClone = 0 == monitorProperties[offset++] ? false : true;
final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
Expand All @@ -304,7 +310,7 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
}
}
}
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
}
Expand Down Expand Up @@ -365,10 +371,11 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
}
offset++;
final int id = monitorProperties[offset++];
final boolean isClone = 0 == monitorProperties[offset++] ? false : true;
final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
}
Expand All @@ -393,6 +400,7 @@ public static int[] streamOutMonitorDevice (final MonitorDevice monitorDevice) {
int idx=0;
data[idx++] = data.length;
data[idx++] = monitorDevice.getId();
data[idx++] = monitorDevice.isClone() ? 1 : 0;
data[idx++] = monitorDevice.getSizeMM().getWidth();
data[idx++] = monitorDevice.getSizeMM().getHeight();
data[idx++] = monitorDevice.getViewport().getX();
Expand All @@ -415,7 +423,36 @@ public static int[] streamOutMonitorDevice (final MonitorDevice monitorDevice) {
return data;
}

public final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) {
/** Identify monitor devices in <i>cloned</i> mode, i.e. consecutive devices being 100% covered by preceding devices. */
/* pp */ static void identifyClonedMonitorDevices(final MonitorModeProps.Cache cache) {
final ArrayList<MonitorDevice> monitors = cache.monitorDevices.toArrayList();
final int monitorCount = monitors.size();
for(int i=0; i<monitorCount; i++) {
final MonitorDevice a = monitors.get(i);
if( !a.isClone() ) {
for(int j=i+1; j<monitorCount; j++) {
final MonitorDevice b = monitors.get(j);
if( !b.isClone() ) {
final float coverage = b.getViewport().coverage( a.getViewport() );
if( FloatUtil.isZero( 1f - coverage, FloatUtil.EPSILON ) ) {
((MonitorDeviceImpl)b).setIsClone(true);
if( Screen.DEBUG ) {
System.err.printf("MonitorCloneTest[%d of %d]: %f -> _is_ covered%n", j, i, coverage);
System.err.printf(" Monitor[%d] %s%n", j, b.toString());
System.err.printf(" Monitor[%d] %s%n", i, a.toString());
}
} else if( Screen.DEBUG ) {
System.err.printf("MonitorDevice-CloneTest[%d of %d]: %f -> not covered%n", j, i, coverage);
System.err.printf(" Monitor[%d] %s%n", j, b.toString());
System.err.printf(" Monitor[%d] %s%n", i, a.toString());
}
}
}
}
}
}

public static final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) {
if( MonitorMode.ROTATE_0 == rotation || MonitorMode.ROTATE_180 == rotation ) {
// nop
return;
Expand Down
2 changes: 2 additions & 0 deletions src/newt/classes/jogamp/newt/ScreenImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ private final MonitorDevice getVirtualMonitorDevice(final MonitorModeProps.Cache
int i = 0;
props[i++] = MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES;
props[i++] = monitorId;
props[i++] = 0; // is-clone
props[i++] = default_sm_widthmm;
props[i++] = default_sm_heightmm;
props[i++] = 0; // rotated viewport x pixel-units
Expand Down Expand Up @@ -608,6 +609,7 @@ private final ScreenMonitorState initMonitorState() {
private final int collectNativeMonitorModes(final MonitorModeProps.Cache cache) {
if(!DEBUG_TEST_SCREENMODE_DISABLED) {
collectNativeMonitorModesAndDevicesImpl(cache);
MonitorModeProps.identifyClonedMonitorDevices(cache);
}
// filter out insufficient modes
for(int i=cache.monitorModes.size()-1; i>=0; i--) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ protected void collectNativeMonitorModesAndDevicesImpl(final Cache cache) {
int i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
i = getScreenSizeMM(outMetrics, props, i); // sizeMM
props[i++] = 0; // rotated viewport x pixel-units
props[i++] = 0; // rotated viewport y pixel-units
Expand Down
1 change: 1 addition & 0 deletions src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ protected void collectNativeMonitorModesAndDevicesImpl(final Cache cache) {
int i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
props[i++] = 0; // rotated viewport x pixel-units
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModePr
i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
props[i++] = 0; // rotated viewport x pixel-units
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModePr
i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
props[i++] = 0; // rotated viewport x pixel-units
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModePr
i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
props[i++] = 0; // rotated viewport x pixel-units
Expand Down
1 change: 1 addition & 0 deletions src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModePr
i = 0;
props[i++] = props.length;
props[i++] = 0; // crt_idx
props[i++] = 0; // is-clone
props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
props[i++] = 0; // rotated viewport x pixel-units
Expand Down
Loading

0 comments on commit 559ecad

Please sign in to comment.