From 9ff5c973b2fb60b11a61035e623557be2aa277b3 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:07:30 +0100 Subject: [PATCH 01/34] Add --density sketch arg --- core/src/processing/core/PApplet.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 473e032e8..46137db94 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -787,6 +787,8 @@ public class PApplet implements PConstants { */ static public final String ARGS_SKETCH_FOLDER = "--sketch-path"; + static public final String ARGS_DENSITY = "--density"; + /** * When run externally to a PdeEditor, * this is sent by the sketch when it quits. @@ -906,6 +908,7 @@ public class PApplet implements PConstants { // Unlike the others above, needs to be public to support // the pixelWidth and pixelHeight fields. public int pixelDensity = 1; + int suggestedDensity = -1; String outputPath; OutputStream outputStream; @@ -10367,6 +10370,7 @@ public class PApplet implements PConstants { // boolean fullScreen = false; boolean present = false; // boolean spanDisplays = false; + int density = -1; String param = null, value = null; String folder = calcSketchPath(); @@ -10409,6 +10413,15 @@ public class PApplet implements PConstants { } else if (param.equals(ARGS_LOCATION)) { location = parseInt(split(value, ',')); + + } else if (param.equals(ARGS_DENSITY)) { + density = parseInt(value, -1); + if (density == -1) { + System.err.println("Could not parse " + value + " for " + ARGS_DENSITY); + } else if (density != 1 && density != 2) { + density = -1; + System.err.println(ARGS_DENSITY + " should be 1 or 2"); + } } } else { @@ -10477,6 +10490,10 @@ public class PApplet implements PConstants { // (and most likely, from the PDE's preference setting). sketch.display = displayNum; + // Set the suggested density that is coming from command line + // (most likely set from the PDE based on a system DPI scaling) + sketch.suggestedDensity = density; + // For 3.0.1, moved this above handleSettings() so that loadImage() can be // used inside settings(). Sets a terrible precedent, but the alternative // of not being able to size a sketch to an image is driving people loopy. From d30f29f3930f44dcea388470466b54ac130564a0 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:13:09 +0100 Subject: [PATCH 02/34] Return command line density arg value from displayDensity() --- core/src/processing/core/PApplet.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 46137db94..3c4849ee4 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1143,7 +1143,7 @@ public class PApplet implements PConstants { /** * @param display the display number to check */ - static public int displayDensity(int display) { + public int displayDensity(int display) { if (PApplet.platform == PConstants.MACOSX) { // This should probably be reset each time there's a display change. // A 5-minute search didn't turn up any such event in the Java 7 API. @@ -1186,6 +1186,15 @@ public class PApplet implements PConstants { } } catch (Exception ignore) { } } + } else if (PApplet.platform == PConstants.WINDOWS || + PApplet.platform == PConstants.LINUX) { + if (suggestedDensity == -1) { + // TODO: detect and return DPI scaling using JNA; Windows has + // a system-wide value, not sure how it works on Linux + return 1; + } else if (suggestedDensity == 1 || suggestedDensity == 2) { + return suggestedDensity; + } } return 1; } From 6ac2529f80f79457be336ac94c368b73665c6a68 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 13:24:09 +0100 Subject: [PATCH 03/34] Pass display density from PDE to sketches as a command line arg --- java/src/processing/mode/java/runner/Runner.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/src/processing/mode/java/runner/Runner.java b/java/src/processing/mode/java/runner/Runner.java index 1223ee752..65058b881 100644 --- a/java/src/processing/mode/java/runner/Runner.java +++ b/java/src/processing/mode/java/runner/Runner.java @@ -24,6 +24,7 @@ package processing.mode.java.runner; import processing.app.*; import processing.app.exec.StreamRedirectThread; +import processing.app.ui.Toolkit; import processing.core.*; import processing.data.StringList; import processing.mode.java.JavaBuild; @@ -466,6 +467,10 @@ public class Runner implements MessageConsumer { // removed for 3.0a6 because it would break the args passed to sketches. params.append(PApplet.ARGS_SKETCH_FOLDER + "=" + build.getSketchPath()); + if (Toolkit.zoom(100) >= 200) { // Use 100 to bypass possible rounding in zoom() + params.append(PApplet.ARGS_DENSITY + "=2"); + } + params.append(build.getSketchClassName()); } // Add command-line arguments to be given to the sketch itself From f0c75dae167ff425fbf373374b6a1d38396be5a0 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:13:23 +0100 Subject: [PATCH 04/34] pixelDensity (Java2D): scale window up --- core/src/processing/awt/PSurfaceAWT.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index cd4649436..6d642f901 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -90,6 +90,8 @@ public class PSurfaceAWT extends PSurfaceNone { int sketchWidth; int sketchHeight; + int windowScaleFactor; + public PSurfaceAWT(PGraphics graphics) { //this.graphics = graphics; @@ -224,7 +226,7 @@ public class PSurfaceAWT extends PSurfaceNone { if (!oldSize.equals(newSize)) { // System.out.println("validate() render old=" + oldSize + " -> new=" + newSize); oldSize = newSize; - sketch.setSize(newSize.width, newSize.height); + sketch.setSize(newSize.width / windowScaleFactor, newSize.height / windowScaleFactor); // try { render(); // } catch (IllegalStateException ise) { @@ -423,8 +425,11 @@ public class PSurfaceAWT extends PSurfaceNone { sketch.displayWidth = screenRect.width; sketch.displayHeight = screenRect.height; - sketchWidth = sketch.sketchWidth(); - sketchHeight = sketch.sketchHeight(); + windowScaleFactor = PApplet.platform == PConstants.MACOSX ? + 1 : sketch.pixelDensity; + + sketchWidth = sketch.sketchWidth() * windowScaleFactor; + sketchHeight = sketch.sketchHeight() * windowScaleFactor; boolean fullScreen = sketch.sketchFullScreen(); // Removing the section below because sometimes people want to do the @@ -481,7 +486,7 @@ public class PSurfaceAWT extends PSurfaceNone { // http://dev.processing.org/bugs/show_bug.cgi?id=908 frame.add(canvas); - setSize(sketchWidth, sketchHeight); + setSize(sketchWidth / windowScaleFactor, sketchHeight / windowScaleFactor); /* if (fullScreen) { @@ -954,8 +959,8 @@ public class PSurfaceAWT extends PSurfaceNone { return; // unchanged, don't rebuild everything } - sketchWidth = wide; - sketchHeight = high; + sketchWidth = wide * windowScaleFactor; + sketchHeight = high * windowScaleFactor; // canvas.setSize(wide, high); // frame.setSize(wide, high); @@ -1142,8 +1147,9 @@ public class PSurfaceAWT extends PSurfaceNone { // overall size of the window. Perhaps JFrame sets its coord // system so that (0, 0) is always the upper-left of the content // area. Which seems nice, but breaks any f*ing AWT-based code. - setSize(windowSize.width - currentInsets.left - currentInsets.right, - windowSize.height - currentInsets.top - currentInsets.bottom); + int w = windowSize.width - currentInsets.left - currentInsets.right; + int h = windowSize.height - currentInsets.top - currentInsets.bottom; + setSize(w / windowScaleFactor, h / windowScaleFactor); // correct the location when inset size changes setLocation(x - currentInsets.left, y - currentInsets.top); From b5002d297a7a470870f1bdb1bc27a9226d9d5004 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:13:53 +0100 Subject: [PATCH 05/34] pixelDensity (Java2D): set default transform --- core/src/processing/awt/PGraphicsJava2D.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 325563526..5a1c8aca3 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -409,8 +409,6 @@ public class PGraphicsJava2D extends PGraphics { checkSettings(); resetMatrix(); // reset model matrix vertexCount = 0; - - g2.scale(pixelDensity, pixelDensity); } @@ -2236,6 +2234,7 @@ public class PGraphicsJava2D extends PGraphics { @Override public void resetMatrix() { g2.setTransform(new AffineTransform()); + g2.scale(pixelDensity, pixelDensity); } From 0342545a4fe15437d00679522b654a90d578a332 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 16 Feb 2017 16:15:36 +0100 Subject: [PATCH 06/34] pixelDensity (Java2D): scale mouse input --- core/src/processing/awt/PSurfaceAWT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 6d642f901..27c7b8e6b 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -1318,7 +1318,8 @@ public class PSurfaceAWT extends PSurfaceNone { sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(), peAction, peModifiers, - nativeEvent.getX(), nativeEvent.getY(), + nativeEvent.getX() / windowScaleFactor, + nativeEvent.getY() / windowScaleFactor, peButton, peCount)); } From cb1ff465300781b30124e64c2d75ad1e991794cf Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 01:07:32 +0100 Subject: [PATCH 07/34] pixelDensity (FX): fix window size --- core/src/processing/javafx/PSurfaceFX.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 8239c8f5b..508040016 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -22,6 +22,8 @@ package processing.javafx; +import com.sun.glass.ui.Screen; + import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; @@ -244,6 +246,13 @@ public class PSurfaceFX implements PSurface { PApplet sketch = surface.sketch; + float renderScale = Screen.getMainScreen().getRenderScale(); + float uiScale = Screen.getMainScreen().getUIScale(); + if (sketch.pixelDensity == 2 && renderScale < 2) { + sketch.pixelDensity = 1; + System.err.println("pixelDensity(2) is not available for this display"); + } + // Use AWT display code, because FX orders screens in different way GraphicsDevice displayDevice = null; @@ -308,14 +317,14 @@ public class PSurfaceFX implements PSurface { int sketchHeight = sketch.sketchHeight(); if (fullScreen || spanDisplays) { - sketchWidth = (int) screenRect.getWidth(); - sketchHeight = (int) screenRect.getHeight(); + sketchWidth = (int) (screenRect.getWidth() / uiScale); + sketchHeight = (int) (screenRect.getHeight() / uiScale); stage.initStyle(StageStyle.UNDECORATED); - stage.setX(screenRect.getMinX()); - stage.setY(screenRect.getMinY()); - stage.setWidth(screenRect.getWidth()); - stage.setHeight(screenRect.getHeight()); + stage.setX(screenRect.getMinX() / uiScale); + stage.setY(screenRect.getMinY() / uiScale); + stage.setWidth(screenRect.getWidth() / uiScale); + stage.setHeight(screenRect.getHeight() / uiScale); } Canvas canvas = surface.canvas; From 20ac27293c164beff5697305b8b480be8dfefa5b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 01:08:54 +0100 Subject: [PATCH 08/34] pixelDensity (FX): fix updatePixels being low res --- core/src/processing/javafx/PGraphicsFX2D.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index 52425e3c7..4e6e11da4 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -645,9 +645,27 @@ public class PGraphicsFX2D extends PGraphics { int mw = mx2 - mx1; int mh = my2 - my1; - PixelWriter pw = context.getPixelWriter(); - pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, - mx1 + my1 * pixelWidth, pixelWidth); + if (pixelDensity == 1) { + PixelWriter pw = context.getPixelWriter(); + pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, + mx1 + my1 * pixelWidth, pixelWidth); + } else { + // The only way to push all the pixels is to draw a scaled-down image + if (snapshotImage == null || + snapshotImage.getWidth() != pixelWidth || + snapshotImage.getHeight() != pixelHeight) { + snapshotImage = new WritableImage(pixelWidth, pixelHeight); + } + + PixelWriter pw = snapshotImage.getPixelWriter(); + pw.setPixels(mx1, my1, mw, mh, argbFormat, pixels, + mx1 + my1 * pixelWidth, pixelWidth); + context.save(); + resetMatrix(); + context.scale(1d / pixelDensity, 1d / pixelDensity); + context.drawImage(snapshotImage, mx1, my1, mw, mh, mx1, my1, mw, mh); + context.restore(); + } } modified = false; @@ -2133,8 +2151,9 @@ public class PGraphicsFX2D extends PGraphics { snapshotImage = new WritableImage(pixelWidth, pixelHeight); } - SnapshotParameters sp = new SnapshotParameters(); + SnapshotParameters sp = null; if (pixelDensity != 1) { + sp = new SnapshotParameters(); sp.setTransform(Transform.scale(pixelDensity, pixelDensity)); } snapshotImage = ((PSurfaceFX) surface).canvas.snapshot(sp, snapshotImage); From a28a043c3e74519f7993b67b50ffad586f2485ff Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 13:37:20 +0100 Subject: [PATCH 09/34] pixelDensity (Java2D): fix set() clamping on wrong boundary --- core/src/processing/awt/PGraphicsJava2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 5a1c8aca3..67d3d75e7 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -2889,7 +2889,7 @@ public class PGraphicsJava2D extends PGraphics { @Override public void set(int x, int y, int argb) { - if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return; + if ((x < 0) || (y < 0) || (x >= pixelWidth) || (y >= pixelHeight)) return; // ((BufferedImage) image).setRGB(x, y, argb); getset[0] = argb; // WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); From 3e5500c457fe99a950cb5b43c798b4dbf87717cb Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 17 Feb 2017 13:38:09 +0100 Subject: [PATCH 10/34] pixelDensity (Java2D): set modified to false after updatePixels() --- core/src/processing/awt/PGraphicsJava2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 67d3d75e7..22145cfaa 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -2796,7 +2796,7 @@ public class PGraphicsJava2D extends PGraphics { if (pixels != null) { getRaster().setDataElements(0, 0, pixelWidth, pixelHeight, pixels); } - modified = true; + modified = false; } From 9bbf7de853ab7a043c25884bc428bb3b0280e2be Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 19:11:17 +0100 Subject: [PATCH 11/34] pixelDensity (OpenGL): fix pixel operations --- .../processing/opengl/PGraphicsOpenGL.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index eeebcc9cc..6ab34bf16 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -637,6 +637,9 @@ public class PGraphicsOpenGL extends PGraphics { height = iheight; updatePixelSize(); + texture = null; + ptexture = null; + // init perspective projection based on new dimensions defCameraFOV = 60 * DEG_TO_RAD; // at least for now defCameraX = width / 2.0f; @@ -5417,30 +5420,29 @@ public class PGraphicsOpenGL extends PGraphics { protected void drawPixels(int x, int y, int w, int h) { - int f = (int)pgl.getPixelScale(); - int len = f * w * f * h; + int len = w * h; if (nativePixels == null || nativePixels.length < len) { nativePixels = new int[len]; nativePixelBuffer = PGL.allocateIntBuffer(nativePixels); } try { - if (0 < x || 0 < y || w < width || h < height) { + if (0 < x || 0 < y || w < pixelWidth || h < pixelHeight) { // The pixels to be copied to the texture need to be consecutive, and // they are not in the pixels array, so putting each row one after // another in nativePixels. - int offset0 = f * (y * width + x); + int offset0 = y * pixelWidth + x; int offset1 = 0; - for (int yc = f * y; yc < f * (y + h); yc++) { - System.arraycopy(pixels, offset0, nativePixels, offset1, f * w); - offset0 += f * width; - offset1 += f * w; + for (int yc = y; yc < y + h; yc++) { + System.arraycopy(pixels, offset0, nativePixels, offset1, w); + offset0 += pixelWidth; + offset1 += w; } } else { PApplet.arrayCopy(pixels, 0, nativePixels, 0, len); } - PGL.javaToNativeARGB(nativePixels, f * w, f * h); + PGL.javaToNativeARGB(nativePixels, w, h); } catch (ArrayIndexOutOfBoundsException e) { } PGL.putIntArray(nativePixelBuffer, nativePixels); @@ -5464,10 +5466,10 @@ public class PGraphicsOpenGL extends PGraphics { // (off)screen buffer. // First, copy the pixels to the texture. We don't need to invert the // pixel copy because the texture will be drawn inverted. - int tw = PApplet.min(texture.glWidth - f * x, f * w); - int th = PApplet.min(texture.glHeight - f * y, f * h); + int tw = PApplet.min(texture.glWidth - x, w); + int th = PApplet.min(texture.glHeight - y, h); pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName, - f * x, f * y, tw, th, nativePixelBuffer); + x, y, tw, th, nativePixelBuffer); beginPixelsOp(OP_WRITE); drawTexture(x, y, w, h); endPixelsOp(); @@ -5476,7 +5478,7 @@ public class PGraphicsOpenGL extends PGraphics { // currently drawing to. Because the texture is invertex along Y, we // need to reflect that in the vertical arguments. pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName, - f * x, f * (height - (y + h)), f * w, f * h, nativePixelBuffer); + x, pixelHeight - (y + h), w, h, nativePixelBuffer); } } @@ -5960,9 +5962,9 @@ public class PGraphicsOpenGL extends PGraphics { pgl.disable(PGL.BLEND); pgl.drawTexture(texture.glTarget, texture.glName, texture.glWidth, texture.glHeight, - 0, 0, width, height, + 0, 0, pixelWidth, pixelHeight, 1, x, y, x + w, y + h, - x, height - (y + h), x + w, height - y); + x, pixelHeight - (y + h), x + w, pixelHeight - y); pgl.enable(PGL.BLEND); } } From 68e8f848b9ae75bf8483a2b6272eeb3b63a06ef1 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:28:06 +0100 Subject: [PATCH 12/34] pixelDensity (OpenGL): update sketch pixel size when display density changes --- core/src/processing/opengl/PGraphicsOpenGL.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 6ab34bf16..2a03b88bc 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -695,6 +695,10 @@ public class PGraphicsOpenGL extends PGraphics { float f = pgl.getPixelScale(); pixelWidth = (int)(width * f); pixelHeight = (int)(height * f); + if (primaryGraphics) { + parent.pixelWidth = pixelWidth; + parent.pixelHeight = pixelHeight; + } } From fc7fb7464f7e4141e92ca75a54f4ed7299c43e79 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:28:38 +0100 Subject: [PATCH 13/34] pixelDensity (OpenGL): make sure sketch pixel size is initialized --- core/src/processing/opengl/PSurfaceJOGL.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index b314ad451..0649e389e 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -390,6 +390,8 @@ public class PSurfaceJOGL implements PSurface { sketchHeight = screenRect.height; } + sketch.setSize(sketchWidth, sketchHeight); + float[] reqSurfacePixelScale; if (graphics.is2X()) { // Retina From 8cf56e1fdf5a01d31eae5c95f9290b5fd2273f0a Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 20:29:59 +0100 Subject: [PATCH 14/34] pixelDensity (OpenGL): size sketch and graphics when density changes --- core/src/processing/opengl/PSurfaceJOGL.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 0649e389e..90b3526dc 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -816,15 +816,15 @@ public class PSurfaceJOGL implements PSurface { public void setSize(final int width, final int height) { - if (width == sketch.width && height == sketch.height) { - return; - } + if (pgl.presentMode()) return; - if (!pgl.presentMode()) { - sketch.setSize(width, height); - sketchWidth = width; - sketchHeight = height; - graphics.setSize(width, height); + sketchWidth = width; + sketchHeight = height; + + sketch.setSize(width, height); + graphics.setSize(width, height); + + if (window.getWidth() != width || window.getHeight() != height) { window.setSize(width, height); } } From 8f7e3b1ff364c0f98f3cf5cfa9f1c1fc9e966077 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 18 Feb 2017 21:28:09 +0100 Subject: [PATCH 15/34] pixelDensity (OpenGL): scale window and mouse input --- core/src/processing/opengl/PSurfaceJOGL.java | 54 +++++++------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 90b3526dc..7811cd733 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -110,6 +110,8 @@ public class PSurfaceJOGL implements PSurface { protected NewtCanvasAWT canvas; + protected int windowScaleFactor; + protected float[] currentPixelScale = {0, 0}; protected boolean external = false; @@ -331,6 +333,8 @@ public class PSurfaceJOGL implements PSurface { // window = GLWindow.create(displayDevice.getScreen(), pgl.getCaps()); // } + windowScaleFactor = PApplet.platform == PConstants.MACOSX ? + 1 : sketch.pixelDensity; boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN; screenRect = spanDisplays ? @@ -386,14 +390,14 @@ public class PSurfaceJOGL implements PSurface { */ if (fullScreen || spanDisplays) { - sketchWidth = screenRect.width; - sketchHeight = screenRect.height; + sketchWidth = screenRect.width / windowScaleFactor; + sketchHeight = screenRect.height / windowScaleFactor; } sketch.setSize(sketchWidth, sketchHeight); float[] reqSurfacePixelScale; - if (graphics.is2X()) { + if (graphics.is2X() && PApplet.platform == PConstants.MACOSX) { // Retina reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; @@ -403,7 +407,7 @@ public class PSurfaceJOGL implements PSurface { ScalableSurface.IDENTITY_PIXELSCALE }; } window.setSurfaceScale(reqSurfacePixelScale); - window.setSize(sketchWidth, sketchHeight); + window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor); window.setResizable(false); setSize(sketchWidth, sketchHeight); sketchX = displayDevice.getViewportInWindowUnits().getX(); @@ -825,20 +829,20 @@ public class PSurfaceJOGL implements PSurface { graphics.setSize(width, height); if (window.getWidth() != width || window.getHeight() != height) { - window.setSize(width, height); + window.setSize(width * windowScaleFactor, height * windowScaleFactor); } } public float getPixelScale() { - if (graphics.is2X()) { + float result = graphics.pixelDensity; + if (graphics.pixelDensity == 2 && PApplet.platform == PConstants.MACOSX) { // Even if the graphics are retina, the user might have moved the window // into a non-retina monitor, so we need to check window.getCurrentSurfaceScale(currentPixelScale); - return currentPixelScale[0]; - } else { - return 1; + result = currentPixelScale[0]; } + return result; } @@ -941,32 +945,10 @@ public class PSurfaceJOGL implements PSurface { } public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { -// int c = graphics.backgroundColor; -// pgl.clearColor(((c >> 16) & 0xff) / 255f, -// ((c >> 8) & 0xff) / 255f, -// ((c >> 0) & 0xff) / 255f, -// ((c >> 24) & 0xff) / 255f); -// pgl.clear(PGL.COLOR_BUFFER_BIT); pgl.resetFBOLayer(); -// final float[] valReqSurfacePixelScale = window.getRequestedSurfaceScale(new float[2]); - window.getCurrentSurfaceScale(currentPixelScale); -// final float[] nativeSurfacePixelScale = window.getMaximumSurfaceScale(new float[2]); -// System.err.println("[set PixelScale post]: "+ -// valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ -// hasSurfacePixelScale[0]+"x"+hasSurfacePixelScale[1]+" (has), "+ -// nativeSurfacePixelScale[0]+"x"+nativeSurfacePixelScale[1]+" (native)"); - - - - -// System.out.println("reshape: " + w + ", " + h); pgl.getGL(drawable); -// if (!graphics.is2X() && 1 < hasSurfacePixelScale[0]) { -// setSize(w/2, h/2); -// } else { -// setSize(w, h); -// } - setSize((int)(w/currentPixelScale[0]), (int)(h/currentPixelScale[1])); + int pixelScale = (int) getPixelScale(); + setSize(w / pixelScale, h / pixelScale); } } @@ -1114,9 +1096,9 @@ public class PSurfaceJOGL implements PSurface { peCount = nativeEvent.getClickCount(); } - window.getCurrentSurfaceScale(currentPixelScale); - int sx = (int)(nativeEvent.getX()/currentPixelScale[0]); - int sy = (int)(nativeEvent.getY()/currentPixelScale[1]); + int pixelScale = (int) getPixelScale(); + int sx = nativeEvent.getX() / pixelScale; + int sy = nativeEvent.getY() / pixelScale; int mx = sx; int my = sy; From c24164c320b8f0f588942aa2eb4132cb77ef75e6 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 00:18:01 +0100 Subject: [PATCH 16/34] pixelDensity (FX): draw 2x images properly --- core/src/processing/javafx/PGraphicsFX2D.java | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/core/src/processing/javafx/PGraphicsFX2D.java b/core/src/processing/javafx/PGraphicsFX2D.java index 4e6e11da4..157540fed 100644 --- a/core/src/processing/javafx/PGraphicsFX2D.java +++ b/core/src/processing/javafx/PGraphicsFX2D.java @@ -1031,8 +1031,8 @@ public class PGraphicsFX2D extends PGraphics { // Nuke the cache if the image was resized if (cash != null) { - if (who.width != cash.image.getWidth() || - who.height != cash.image.getHeight()) { + if (who.pixelWidth != cash.image.getWidth() || + who.pixelHeight != cash.image.getHeight()) { cash = null; } } @@ -1059,12 +1059,17 @@ public class PGraphicsFX2D extends PGraphics { // This might be a PGraphics that hasn't been drawn to yet. // Can't just bail because the cache has been created above. // https://github.com/processing/processing/issues/2208 - who.pixels = new int[who.width * who.height]; + who.pixels = new int[who.pixelWidth * who.pixelHeight]; } cash.update(who, tint, tintColor); who.setModified(false); } + u1 *= who.pixelDensity; + v1 *= who.pixelDensity; + u2 *= who.pixelDensity; + v2 *= who.pixelDensity; + context.drawImage(((ImageCache) getCache(who)).image, u1, v1, u2-u1, v2-v1, x1, y1, x2-x1, y2-y1); @@ -1105,14 +1110,14 @@ public class PGraphicsFX2D extends PGraphics { // BufferedImage.TYPE_INT_ARGB); // } if (image == null) { - image = new WritableImage(source.width, source.height); + image = new WritableImage(source.pixelWidth, source.pixelHeight); } //WritableRaster wr = image.getRaster(); PixelWriter pw = image.getPixelWriter(); if (tint) { - if (tintedTemp == null || tintedTemp.length != source.width) { - tintedTemp = new int[source.width]; + if (tintedTemp == null || tintedTemp.length != source.pixelWidth) { + tintedTemp = new int[source.pixelWidth]; } int a2 = (tintColor >> 24) & 0xff; // System.out.println("tint color is " + a2); @@ -1126,8 +1131,8 @@ public class PGraphicsFX2D extends PGraphics { // The target image is opaque, meaning that the source image has no // alpha (is not ARGB), and the tint has no alpha. int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1142,7 +1147,7 @@ public class PGraphicsFX2D extends PGraphics { (((b2 * b1) & 0xff00) >> 8); } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth); } // could this be any slower? // float[] scales = { tintR, tintG, tintB }; @@ -1156,19 +1161,19 @@ public class PGraphicsFX2D extends PGraphics { (tintColor & 0xffffff) == 0xffffff) { int hi = tintColor & 0xff000000; int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF); } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelHeight); } } else { int index = 0; - for (int y = 0; y < source.height; y++) { + for (int y = 0; y < source.pixelHeight; y++) { if (source.format == RGB) { int alpha = tintColor & 0xFF000000; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1179,7 +1184,7 @@ public class PGraphicsFX2D extends PGraphics { (((b2 * b1) & 0xff00) >> 8); } } else if (source.format == ARGB) { - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int a1 = (argb1 >> 24) & 0xff; int r1 = (argb1 >> 16) & 0xff; @@ -1193,14 +1198,14 @@ public class PGraphicsFX2D extends PGraphics { } } else if (source.format == ALPHA) { int lower = tintColor & 0xFFFFFF; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int a1 = source.pixels[index++]; tintedTemp[x] = (((a2 * a1) & 0xff00) << 16) | lower; } } //wr.setDataElements(0, y, source.width, 1, tintedTemp); - pw.setPixels(0, y, source.width, 1, argbFormat, tintedTemp, 0, source.width); + pw.setPixels(0, y, source.pixelWidth, 1, argbFormat, tintedTemp, 0, source.pixelWidth); } } // Not sure why ARGB images take the scales in this order... @@ -1222,8 +1227,8 @@ public class PGraphicsFX2D extends PGraphics { // If no tint, just shove the pixels on in there verbatim //wr.setDataElements(0, 0, source.width, source.height, source.pixels); //System.out.println("moving the big one"); - pw.setPixels(0, 0, source.width, source.height, - argbFormat, source.pixels, 0, source.width); + pw.setPixels(0, 0, source.pixelWidth, source.pixelHeight, + argbFormat, source.pixels, 0, source.pixelWidth); } this.tinted = tint; this.tintedColor = tintColor; From f8bbc3b3fee58849f72fac44a1e0f3096c8eaf52 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 01:41:23 +0100 Subject: [PATCH 17/34] pixelDensity (Java2D): fix pixel operations --- core/src/processing/awt/PGraphicsJava2D.java | 61 ++++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index 22145cfaa..0143772b7 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -1571,8 +1571,8 @@ public class PGraphicsJava2D extends PGraphics { // Nuke the cache if the image was resized if (cash != null) { - if (who.width != cash.image.getWidth() || - who.height != cash.image.getHeight()) { + if (who.pixelWidth != cash.image.getWidth() || + who.pixelHeight != cash.image.getHeight()) { cash = null; } } @@ -1599,12 +1599,17 @@ public class PGraphicsJava2D extends PGraphics { // This might be a PGraphics that hasn't been drawn to yet. // Can't just bail because the cache has been created above. // https://github.com/processing/processing/issues/2208 - who.pixels = new int[who.width * who.height]; + who.pixels = new int[who.pixelWidth * who.pixelHeight]; } cash.update(who, tint, tintColor); who.setModified(false); } + u1 *= who.pixelDensity; + v1 *= who.pixelDensity; + u2 *= who.pixelDensity; + v2 *= who.pixelDensity; + g2.drawImage(((ImageCache) getCache(who)).image, (int) x1, (int) y1, (int) x2, (int) y2, u1, v1, u2, v2, null); @@ -1672,14 +1677,14 @@ public class PGraphicsJava2D extends PGraphics { // in the alpha channel when drawn to the screen. // https://github.com/processing/processing/issues/2030 if (image == null) { - image = new BufferedImage(source.width, source.height, + image = new BufferedImage(source.pixelWidth, source.pixelHeight, BufferedImage.TYPE_INT_ARGB); } WritableRaster wr = image.getRaster(); if (tint) { - if (tintedTemp == null || tintedTemp.length != source.width) { - tintedTemp = new int[source.width]; + if (tintedTemp == null || tintedTemp.length != source.pixelWidth) { + tintedTemp = new int[source.pixelHeight]; } int a2 = (tintColor >> 24) & 0xff; // System.out.println("tint color is " + a2); @@ -1693,8 +1698,8 @@ public class PGraphicsJava2D extends PGraphics { // The target image is opaque, meaning that the source image has no // alpha (is not ARGB), and the tint has no alpha. int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1708,7 +1713,7 @@ public class PGraphicsJava2D extends PGraphics { ((g2 * g1) & 0xff00) | (((b2 * b1) & 0xff00) >> 8); } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } // could this be any slower? // float[] scales = { tintR, tintG, tintB }; @@ -1722,18 +1727,18 @@ public class PGraphicsJava2D extends PGraphics { (tintColor & 0xffffff) == 0xffffff) { int hi = tintColor & 0xff000000; int index = 0; - for (int y = 0; y < source.height; y++) { - for (int x = 0; x < source.width; x++) { + for (int y = 0; y < source.pixelHeight; y++) { + for (int x = 0; x < source.pixelWidth; x++) { tintedTemp[x] = hi | (source.pixels[index++] & 0xFFFFFF); } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } } else { int index = 0; - for (int y = 0; y < source.height; y++) { + for (int y = 0; y < source.pixelHeight; y++) { if (source.format == RGB) { int alpha = tintColor & 0xFF000000; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int r1 = (argb1 >> 16) & 0xff; int g1 = (argb1 >> 8) & 0xff; @@ -1744,7 +1749,7 @@ public class PGraphicsJava2D extends PGraphics { (((b2 * b1) & 0xff00) >> 8); } } else if (source.format == ARGB) { - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int argb1 = source.pixels[index++]; int a1 = (argb1 >> 24) & 0xff; int r1 = (argb1 >> 16) & 0xff; @@ -1758,13 +1763,13 @@ public class PGraphicsJava2D extends PGraphics { } } else if (source.format == ALPHA) { int lower = tintColor & 0xFFFFFF; - for (int x = 0; x < source.width; x++) { + for (int x = 0; x < source.pixelWidth; x++) { int a1 = source.pixels[index++]; tintedTemp[x] = (((a2 * a1) & 0xff00) << 16) | lower; } } - wr.setDataElements(0, y, source.width, 1, tintedTemp); + wr.setDataElements(0, y, source.pixelWidth, 1, tintedTemp); } } // Not sure why ARGB images take the scales in this order... @@ -1784,7 +1789,7 @@ public class PGraphicsJava2D extends PGraphics { // in a PImage and how the high bits will be set. } // If no tint, just shove the pixels on in there verbatim - wr.setDataElements(0, 0, source.width, source.height, source.pixels); + wr.setDataElements(0, 0, source.pixelWidth, source.pixelHeight, source.pixels); } this.tinted = tint; this.tintedColor = tintColor; @@ -2839,12 +2844,6 @@ public class PGraphicsJava2D extends PGraphics { //public PImage get(int x, int y, int w, int h) - @Override - public PImage get() { - return get(0, 0, width, height); - } - - @Override protected void getImpl(int sourceX, int sourceY, int sourceWidth, int sourceHeight, @@ -2855,7 +2854,7 @@ public class PGraphicsJava2D extends PGraphics { // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); WritableRaster raster = getRaster(); - if (sourceWidth == target.width && sourceHeight == target.height) { + if (sourceWidth == target.pixelWidth && sourceHeight == target.pixelHeight) { raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels); // https://github.com/processing/processing/issues/2030 if (raster.getNumBands() == 3) { @@ -2869,7 +2868,7 @@ public class PGraphicsJava2D extends PGraphics { // Copy the temporary output pixels over to the outgoing image int sourceOffset = 0; - int targetOffset = targetY*target.width + targetX; + int targetOffset = targetY*target.pixelWidth + targetX; for (int y = 0; y < sourceHeight; y++) { if (raster.getNumBands() == 3) { for (int i = 0; i < sourceWidth; i++) { @@ -2881,7 +2880,7 @@ public class PGraphicsJava2D extends PGraphics { System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth); } sourceOffset += sourceWidth; - targetOffset += target.width; + targetOffset += target.pixelWidth; } } } @@ -2910,18 +2909,18 @@ public class PGraphicsJava2D extends PGraphics { // ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster(); if ((sourceX == 0) && (sourceY == 0) && - (sourceWidth == sourceImage.width) && - (sourceHeight == sourceImage.height)) { + (sourceWidth == sourceImage.pixelWidth) && + (sourceHeight == sourceImage.pixelHeight)) { // System.out.format("%d %d %dx%d %d%n", targetX, targetY, // sourceImage.width, sourceImage.height, // sourceImage.pixels.length); raster.setDataElements(targetX, targetY, - sourceImage.width, sourceImage.height, + sourceImage.pixelWidth, sourceImage.pixelHeight, sourceImage.pixels); } else { // TODO optimize, incredibly inefficient to reallocate this much memory PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight); - raster.setDataElements(targetX, targetY, temp.width, temp.height, temp.pixels); + raster.setDataElements(targetX, targetY, temp.pixelWidth, temp.pixelHeight, temp.pixels); } } From 9d420740b55b5e9a4ebde86c232f9f6f6ccddb00 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 01:42:34 +0100 Subject: [PATCH 18/34] pixelDensity (OpenGL): fix textures --- core/src/processing/core/PGraphics.java | 7 ++++++- .../src/processing/opengl/PGraphicsOpenGL.java | 18 +++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 02b9919c7..9c8195d7c 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -3879,6 +3879,11 @@ public class PGraphics extends PImage implements PConstants { // fillA = 1; // } + u1 *= img.pixelDensity; + u2 *= img.pixelDensity; + v1 *= img.pixelDensity; + v2 *= img.pixelDensity; + beginShape(QUADS); texture(img); vertex(x1, y1, u1, v1); @@ -7347,7 +7352,7 @@ public class PGraphics extends PImage implements PConstants { * @param image PImage to set as background (must be same size as the sketch window) */ public void background(PImage image) { - if ((image.width != width) || (image.height != height)) { + if ((image.pixelWidth != width) || (image.pixelHeight != height)) { throw new RuntimeException(ERROR_BACKGROUND_IMAGE_SIZE); } if ((image.format != RGB) && (image.format != ARGB)) { diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 2a03b88bc..9ecf2fadc 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -2147,8 +2147,8 @@ public class PGraphicsOpenGL extends PGraphics { } if (textured && textureMode == IMAGE) { - u /= textureImage.width; - v /= textureImage.height; + u /= textureImage.pixelWidth; + v /= textureImage.pixelHeight; } inGeo.addVertex(x, y, z, @@ -5555,10 +5555,10 @@ public class PGraphicsOpenGL extends PGraphics { @Override protected void processImageBeforeAsyncSave(PImage image) { if (image.format == AsyncPixelReader.OPENGL_NATIVE) { - PGL.nativeToJavaARGB(image.pixels, image.width, image.height); + PGL.nativeToJavaARGB(image.pixels, image.pixelWidth, image.pixelHeight); image.format = ARGB; } else if (image.format == AsyncPixelReader.OPENGL_NATIVE_OPAQUE) { - PGL.nativeToJavaRGB(image.pixels, image.width, image.height); + PGL.nativeToJavaRGB(image.pixels, image.pixelWidth, image.pixelHeight); image.format = RGB; } } @@ -6003,7 +6003,7 @@ public class PGraphicsOpenGL extends PGraphics { @Override public void mask(PImage alpha) { updatePixelSize(); - if (alpha.width != pixelWidth || alpha.height != pixelHeight) { + if (alpha.pixelWidth != pixelWidth || alpha.pixelHeight != pixelHeight) { throw new RuntimeException("The PImage used with mask() must be " + "the same size as the applet."); } @@ -6364,8 +6364,8 @@ public class PGraphicsOpenGL extends PGraphics { if (tex == null) return null; if (img.isModified()) { - if (img.width != tex.width || img.height != tex.height) { - tex.init(img.width, img.height); + if (img.pixelWidth != tex.width || img.pixelHeight != tex.height) { + tex.init(img.pixelWidth, img.pixelHeight); } updateTexture(img, tex); } @@ -6491,8 +6491,8 @@ public class PGraphicsOpenGL extends PGraphics { // avoid initializing the pixels array. PImage img = new PImage(); img.parent = parent; - img.width = tex.width; - img.height = tex.height; + img.width = img.pixelWidth = tex.width; + img.height = img.pixelHeight = tex.height; img.format = ARGB; setCache(img, tex); return img; From da291436bba7f7d376b548830c8ff2bf50579353 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 02:49:46 +0100 Subject: [PATCH 19/34] pixelDensity (FX): run with highest density --- core/src/processing/javafx/PSurfaceFX.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index 508040016..b64750a33 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -247,9 +247,15 @@ public class PSurfaceFX implements PSurface { PApplet sketch = surface.sketch; float renderScale = Screen.getMainScreen().getRenderScale(); + if (PApplet.platform == PConstants.MACOSX) { + for (Screen s : Screen.getScreens()) { + renderScale = Math.max(renderScale, s.getRenderScale()); + } + } float uiScale = Screen.getMainScreen().getUIScale(); if (sketch.pixelDensity == 2 && renderScale < 2) { sketch.pixelDensity = 1; + sketch.g.pixelDensity = 1; System.err.println("pixelDensity(2) is not available for this display"); } From 641c32c5f03a7c416c9506cb060ea5415a3348f7 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 03:01:16 +0100 Subject: [PATCH 20/34] pixelDensity (FX): leave the density check up to PSurfaceFX --- core/src/processing/core/PApplet.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 3c4849ee4..406949911 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1212,9 +1212,11 @@ public class PApplet implements PConstants { if (density != 1 && density != 2) { throw new RuntimeException("pixelDensity() can only be 1 or 2"); } - if (density == 2 && displayDensity() == 1) { + if (!FX2D.equals(renderer) && density == 2 && displayDensity() == 1) { + // FX has its own check in PSurfaceFX // Don't throw exception because the sketch should still work - throw new RuntimeException("pixelDensity(2) is not available for this display"); + System.err.println("pixelDensity(2) is not available for this display"); + this.pixelDensity = 1; } else { this.pixelDensity = density; } From 4eb04c4b641fa38286144723add09488d9cb0f5f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 05:47:01 +0100 Subject: [PATCH 21/34] pixelDensity (OpenGL): fix 1x on macOS --- core/src/processing/opengl/PSurfaceJOGL.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 7811cd733..ef080ab5d 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -822,27 +822,33 @@ public class PSurfaceJOGL implements PSurface { public void setSize(final int width, final int height) { if (pgl.presentMode()) return; + boolean changed = sketch.width != width || sketch.height != height; + sketchWidth = width; sketchHeight = height; sketch.setSize(width, height); graphics.setSize(width, height); - if (window.getWidth() != width || window.getHeight() != height) { + if (changed) { window.setSize(width * windowScaleFactor, height * windowScaleFactor); } } public float getPixelScale() { - float result = graphics.pixelDensity; - if (graphics.pixelDensity == 2 && PApplet.platform == PConstants.MACOSX) { + if (graphics.pixelDensity == 1) { + return 1; + } + + if (PApplet.platform == PConstants.MACOSX) { // Even if the graphics are retina, the user might have moved the window // into a non-retina monitor, so we need to check window.getCurrentSurfaceScale(currentPixelScale); - result = currentPixelScale[0]; + return currentPixelScale[0]; } - return result; + + return 2; } @@ -947,8 +953,8 @@ public class PSurfaceJOGL implements PSurface { public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { pgl.resetFBOLayer(); pgl.getGL(drawable); - int pixelScale = (int) getPixelScale(); - setSize(w / pixelScale, h / pixelScale); + window.getCurrentSurfaceScale(currentPixelScale); + setSize((int) (w / currentPixelScale[0]), (int) (h / currentPixelScale[1])); } } From b93f7c2c09bde283b3540db213c0b76ff49c3f09 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 19 Feb 2017 06:00:41 +0100 Subject: [PATCH 22/34] pixelDensity (OpenGL): fix 1x mouse input on macOS --- core/src/processing/opengl/PSurfaceJOGL.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index ef080ab5d..d67c9632f 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1102,9 +1102,15 @@ public class PSurfaceJOGL implements PSurface { peCount = nativeEvent.getClickCount(); } - int pixelScale = (int) getPixelScale(); - int sx = nativeEvent.getX() / pixelScale; - int sy = nativeEvent.getY() / pixelScale; + int scale; + if (PApplet.platform == PConstants.MACOSX) { + window.getCurrentSurfaceScale(currentPixelScale); + scale = (int) currentPixelScale[0]; + } else { + scale = (int) getPixelScale(); + } + int sx = nativeEvent.getX() / scale; + int sy = nativeEvent.getY() / scale; int mx = sx; int my = sy; From d94987cbce9014ba43511d3db4e5fc358e4dfb5b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 12 Apr 2017 18:57:35 +0200 Subject: [PATCH 23/34] pixelDensity (OpenGL): fix 2x on Windows --- core/src/processing/opengl/PSurfaceJOGL.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index d67c9632f..381900a00 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -953,8 +953,8 @@ public class PSurfaceJOGL implements PSurface { public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { pgl.resetFBOLayer(); pgl.getGL(drawable); - window.getCurrentSurfaceScale(currentPixelScale); - setSize((int) (w / currentPixelScale[0]), (int) (h / currentPixelScale[1])); + float scale = getPixelScale(); + setSize((int) (w / scale), (int) (h / scale)); } } From a601323b50169eac818bfcd6ce502beb1c9886ce Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Wed, 12 Apr 2017 18:57:44 +0200 Subject: [PATCH 24/34] pixelDensity (OpenGL): fix 2x present mode on Windows --- core/src/processing/opengl/PSurfaceJOGL.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 381900a00..0d15936e2 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -751,8 +751,9 @@ public class PSurfaceJOGL implements PSurface { public void placePresent(int stopColor) { - pgl.initPresentMode(0.5f * (screenRect.width - sketchWidth), - 0.5f * (screenRect.height - sketchHeight), stopColor); + float scale = getPixelScale(); + pgl.initPresentMode(0.5f * (screenRect.width/scale - sketchWidth), + 0.5f * (screenRect.height/scale - sketchHeight), stopColor); window.setSize(screenRect.width, screenRect.height); PApplet.hideMenuBar(); window.setTopLevelPosition(sketchX + screenRect.x, From b0c5575d2cc18dfb4cb5b4140e3b483f6d1e4ee8 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 13 Apr 2017 15:00:31 +0200 Subject: [PATCH 25/34] pixelDensity (FX): fix fullscreen placement --- core/src/processing/javafx/PSurfaceFX.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index b64750a33..c471a3cbc 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -555,6 +555,7 @@ public class PSurfaceFX implements PSurface { public void placeWindow(int[] location, int[] editorLocation) { if (sketch.sketchFullScreen()) { PApplet.hideMenuBar(); + return; } //Dimension window = setFrameSize(); From 19e7bcf3150261d36521091b35341ef7b331cc3c Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 13 Apr 2017 15:01:05 +0200 Subject: [PATCH 26/34] pixelDensity (FX): clean up placement code --- core/src/processing/javafx/PSurfaceFX.java | 53 ++-------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index c471a3cbc..14938445d 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -301,17 +301,8 @@ public class PSurfaceFX implements PSurface { maxY = Math.max(maxY, bounds.getMaxY()); } } - if (minY < 0) { - // FX can't handle this - System.err.format("FX can't place window at negative Y coordinate " + - "[x=%d, y=%d]. Please make sure that your secondary " + - "display does not extend above the main display.", - (int) minX, (int) minY); - screenRect = primaryScreenRect; - } else { - screenRect = new Rectangle((int) minX, (int) minY, - (int) (maxX - minX), (int) (maxY - minY)); - } + screenRect = new Rectangle((int) minX, (int) minY, + (int) (maxX - minX), (int) (maxY - minY)); } // Set the displayWidth/Height variables inside PApplet, so that they're @@ -558,10 +549,6 @@ public class PSurfaceFX implements PSurface { return; } - //Dimension window = setFrameSize(); -// int contentW = Math.max(sketchWidth, MIN_WINDOW_WIDTH); -// int contentH = Math.max(sketchHeight, MIN_WINDOW_HEIGHT); -// System.out.println("stage size is " + stage.getWidth() + " " + stage.getHeight()); int wide = sketch.width; // stage.getWidth() is NaN here int high = sketch.height; // stage.getHeight() @@ -581,42 +568,10 @@ public class PSurfaceFX implements PSurface { stage.setY(locationY); } else { // doesn't fit -// // if it fits inside the editor window, -// // offset slightly from upper lefthand corner -// // so that it's plunked inside the text area -// locationX = editorLocation[0] + 66; -// locationY = editorLocation[1] + 66; -// -// if ((locationX + stage.getWidth() > sketch.displayWidth - 33) || -// (locationY + stage.getHeight() > sketch.displayHeight - 33)) { -// // otherwise center on screen -// locationX = (int) ((sketch.displayWidth - wide) / 2); -// locationY = (int) ((sketch.displayHeight - high) / 2); -// } - locationX = (sketch.displayWidth - wide) / 2; - locationY = (sketch.displayHeight - high) / 2; - stage.setX(locationX); - stage.setY(locationY); + stage.centerOnScreen(); } } else { // just center on screen - //setFrameCentered(); - } - if (stage.getY() < 0) { - // Windows actually allows you to place frames where they can't be - // closed. Awesome. http://dev.processing.org/bugs/show_bug.cgi?id=1508 - //frame.setLocation(frameLoc.x, 30); - stage.setY(30); - } - - //canvas.setBounds((contentW - sketchWidth)/2, - // (contentH - sketchHeight)/2, - // sketchWidth, sketchHeight); - - // handle frame resizing events - //setupFrameResizeListener(); - - if (sketch.getGraphics().displayable()) { - setVisible(true); + stage.centerOnScreen(); } } From 7a5eac6fdd2cdd2261d58ae155fde098d73db060 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 13 Apr 2017 17:18:05 +0200 Subject: [PATCH 27/34] pixelDensity (OpenGL): fix fullscreen placement on secondary screens --- core/src/processing/opengl/PSurfaceJOGL.java | 126 +++++-------------- 1 file changed, 31 insertions(+), 95 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 0d15936e2..b946f57c0 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -103,8 +103,7 @@ public class PSurfaceJOGL implements PSurface { protected Display display; protected Screen screen; - protected List monitors; - protected MonitorDevice displayDevice; + protected Rectangle displayRect; protected Throwable drawException; private final Object drawExceptionMutex = new Object(); @@ -163,103 +162,35 @@ public class PSurfaceJOGL implements PSurface { protected void initDisplay() { - Display tmpDisplay = NewtFactory.createDisplay(null); - tmpDisplay.addReference(); - Screen tmpScreen = NewtFactory.createScreen(tmpDisplay, 0); - tmpScreen.addReference(); + display = NewtFactory.createDisplay(null); + display.addReference(); + screen = NewtFactory.createScreen(display, 0); + screen.addReference(); - monitors = new ArrayList(); GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] awtDevices = environment.getScreenDevices(); - List newtDevices = tmpScreen.getMonitorDevices(); - // AWT and NEWT name devices in different ways, depending on the platform, - // and also appear to order them in different ways. The following code - // tries to address the differences. - if (PApplet.platform == PConstants.LINUX) { - for (GraphicsDevice device: awtDevices) { - String did = device.getIDstring(); - String[] parts = did.split("\\."); - String id1 = ""; - if (1 < parts.length) { - id1 = parts[1].trim(); - } - MonitorDevice monitor = null; - int id0 = newtDevices.size() > 0 ? newtDevices.get(0).getId() : 0; - for (int i = 0; i < newtDevices.size(); i++) { - MonitorDevice mon = newtDevices.get(i); - String mid = String.valueOf(mon.getId() - id0); - if (id1.equals(mid)) { - monitor = mon; - break; - } - } - if (monitor != null) { - monitors.add(monitor); - } - } - } else if (PApplet.platform == PConstants.WINDOWS) { - // NEWT display id is == (adapterId << 8 | monitorId), - // should be in the same order as AWT - monitors.addAll(newtDevices); - } else { // MAC OSX and others - for (GraphicsDevice device: awtDevices) { - String did = device.getIDstring(); - String[] parts = did.split("Display"); - String id1 = ""; - if (1 < parts.length) { - id1 = parts[1].trim(); - } - MonitorDevice monitor = null; - for (int i = 0; i < newtDevices.size(); i++) { - MonitorDevice mon = newtDevices.get(i); - String mid = String.valueOf(mon.getId()); - if (id1.equals(mid)) { - monitor = mon; - break; - } - } - if (monitor == null) { - // Didn't find a matching monitor, try using less stringent id check - for (int i = 0; i < newtDevices.size(); i++) { - MonitorDevice mon = newtDevices.get(i); - String mid = String.valueOf(mon.getId()); - if (-1 < did.indexOf(mid)) { - monitor = mon; - break; - } - } - } - if (monitor != null) { - monitors.add(monitor); - } - } - } - - displayDevice = null; + GraphicsDevice awtDisplayDevice = null; int displayNum = sketch.sketchDisplay(); if (displayNum > 0) { // if -1, use the default device - if (displayNum <= monitors.size()) { - displayDevice = monitors.get(displayNum - 1); + if (displayNum <= awtDevices.length) { + awtDisplayDevice = awtDevices[displayNum-1]; } else { System.err.format("Display %d does not exist, " + "using the default display instead.%n", displayNum); - for (int i = 0; i < monitors.size(); i++) { - System.err.format("Display %d is %s%n", i+1, monitors.get(i)); + for (int i = 0; i < awtDevices.length; i++) { + System.err.format("Display %d is %s%n", i+1, awtDevices[i]); } } - } else if (0 < monitors.size()) { - displayDevice = monitors.get(0); + } else if (0 < awtDevices.length) { + awtDisplayDevice = awtDevices[0]; } - if (displayDevice != null) { - screen = displayDevice.getScreen(); - display = screen.getDisplay(); - } else { - screen = tmpScreen; - display = tmpDisplay; - displayDevice = screen.getPrimaryMonitor(); + if (awtDisplayDevice == null) { + awtDisplayDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); } + + displayRect = awtDisplayDevice.getDefaultConfiguration().getBounds(); } @@ -340,8 +271,8 @@ public class PSurfaceJOGL implements PSurface { screenRect = spanDisplays ? new Rectangle(0, 0, screen.getWidth(), screen.getHeight()) : new Rectangle(0, 0, - displayDevice.getViewportInWindowUnits().getWidth(), - displayDevice.getViewportInWindowUnits().getHeight()); + (int) displayRect.getWidth(), + (int) displayRect.getHeight()); // Set the displayWidth/Height variables inside PApplet, so that they're // usable and can even be returned by the sketchWidth()/Height() methods. @@ -410,16 +341,16 @@ public class PSurfaceJOGL implements PSurface { window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor); window.setResizable(false); setSize(sketchWidth, sketchHeight); - sketchX = displayDevice.getViewportInWindowUnits().getX(); - sketchY = displayDevice.getViewportInWindowUnits().getY(); + sketchX = (int) displayRect.getX(); + sketchY = (int) displayRect.getY(); if (fullScreen) { PApplet.hideMenuBar(); - window.setTopLevelPosition(sketchX, sketchY); if (spanDisplays) { - window.setFullscreen(monitors); + window.setFullscreen(screen.getMonitorDevices()); } else { - List display = Collections.singletonList(displayDevice); - window.setFullscreen(display); + window.setUndecorated(true); + window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY()); + window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight()); } } } @@ -695,6 +626,11 @@ public class PSurfaceJOGL implements PSurface { @Override public void placeWindow(int[] location, int[] editorLocation) { + + if (sketch.sketchFullScreen()) { + return; + } + int x = window.getX() - window.getInsets().getLeftWidth(); int y = window.getY() - window.getInsets().getTopHeight(); int w = window.getWidth() + window.getInsets().getTotalWidth(); @@ -735,8 +671,8 @@ public class PSurfaceJOGL implements PSurface { } else { // just center on screen // Can't use frame.setLocationRelativeTo(null) because it sends the // frame to the main display, which undermines the --display setting. - int sketchX = displayDevice.getViewportInWindowUnits().getX(); - int sketchY = displayDevice.getViewportInWindowUnits().getY(); + int sketchX = (int) displayRect.getX(); + int sketchY = (int) displayRect.getY(); window.setTopLevelPosition(sketchX + screenRect.x + (screenRect.width - sketchWidth) / 2, sketchY + screenRect.y + (screenRect.height - sketchHeight) / 2); } From 0a6d38e22e44cd1dc34552694a59403408cee36d Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 13 Apr 2017 20:42:35 +0200 Subject: [PATCH 28/34] pixelDensity (OpenGL): fix present mode placement --- core/src/processing/opengl/PSurfaceJOGL.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index b946f57c0..231c2844a 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -690,11 +690,11 @@ public class PSurfaceJOGL implements PSurface { float scale = getPixelScale(); pgl.initPresentMode(0.5f * (screenRect.width/scale - sketchWidth), 0.5f * (screenRect.height/scale - sketchHeight), stopColor); - window.setSize(screenRect.width, screenRect.height); PApplet.hideMenuBar(); - window.setTopLevelPosition(sketchX + screenRect.x, - sketchY + screenRect.y); - window.setFullscreen(true); + + window.setUndecorated(true); + window.setTopLevelPosition((int) displayRect.getX(), (int) displayRect.getY()); + window.setTopLevelSize((int) displayRect.getWidth(), (int) displayRect.getHeight()); } From cf5cfdb334e44a5751d8d8abbd73e880ab405cae Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 13 Apr 2017 20:56:12 +0200 Subject: [PATCH 29/34] pixelDensity (OpenGL): fix stop button in 2x present mode --- core/src/processing/opengl/PSurfaceJOGL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 231c2844a..62dfa379c 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1055,7 +1055,7 @@ public class PSurfaceJOGL implements PSurface { mx -= (int)pgl.presentX; my -= (int)pgl.presentY; if (peAction == KeyEvent.RELEASE && - pgl.insideStopButton(sx, sy - screenRect.height)) { + pgl.insideStopButton(sx, sy - screenRect.height / scale)) { sketch.exit(); } if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) { From 8fa6187d49cfb7def6451c62fd3a059e5db0cc0e Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 14 Apr 2017 19:13:57 +0200 Subject: [PATCH 30/34] pixelDensity (all): allow 2x if windowed or SPAN, and any screen is 2x --- core/src/processing/core/PApplet.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 406949911..60f7e0f60 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -910,6 +910,8 @@ public class PApplet implements PConstants { public int pixelDensity = 1; int suggestedDensity = -1; + boolean present; + String outputPath; OutputStream outputStream; @@ -1127,17 +1129,17 @@ public class PApplet implements PConstants { * @see PApplet#size(int,int) */ public int displayDensity() { - if (display == SPAN) { - // walk through all displays, use lowest common denominator - for (int i = 0; i < displayDevices.length; i++) { - if (displayDensity(i) != 2) { - return 1; - } - } - // If nobody's density is 1 (or != 2, to be exact) then everyone is 2 - return 2; + if (display != SPAN && (fullScreen || present)) { + return displayDensity(display); } - return displayDensity(display); + // walk through all displays, use 2 if any display is 2 + for (int i = 0; i < displayDevices.length; i++) { + if (displayDensity(i+1) == 2) { + return 2; + } + } + // If nobody's density is 2 then everyone is 1 + return 1; } /** @@ -10505,6 +10507,8 @@ public class PApplet implements PConstants { // (most likely set from the PDE based on a system DPI scaling) sketch.suggestedDensity = density; + sketch.present = present; + // For 3.0.1, moved this above handleSettings() so that loadImage() can be // used inside settings(). Sets a terrible precedent, but the alternative // of not being able to size a sketch to an image is driving people loopy. From 6d5cc7a3262c6bc2f1e1e1c117a1b54bb9d7f8bd Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 14 Apr 2017 19:15:19 +0200 Subject: [PATCH 31/34] pixelDensity (OpenGL): fix running 1x on 2x screen on Mac --- core/src/processing/opengl/PSurfaceJOGL.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 62dfa379c..af4dbc2fe 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -779,15 +779,19 @@ public class PSurfaceJOGL implements PSurface { } if (PApplet.platform == PConstants.MACOSX) { - // Even if the graphics are retina, the user might have moved the window - // into a non-retina monitor, so we need to check - window.getCurrentSurfaceScale(currentPixelScale); - return currentPixelScale[0]; + return getCurrentPixelScale(); } return 2; } + private float getCurrentPixelScale() { + // Even if the graphics are retina, the user might have moved the window + // into a non-retina monitor, so we need to check + window.getCurrentSurfaceScale(currentPixelScale); + return currentPixelScale[0]; + } + public Component getComponent() { return canvas; @@ -890,7 +894,8 @@ public class PSurfaceJOGL implements PSurface { public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { pgl.resetFBOLayer(); pgl.getGL(drawable); - float scale = getPixelScale(); + float scale = PApplet.platform == PConstants.MACOSX ? + getCurrentPixelScale() : getPixelScale(); setSize((int) (w / scale), (int) (h / scale)); } } From e457bb3337127531e3269b267caa6aaa8263341f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 14 Apr 2017 19:38:33 +0200 Subject: [PATCH 32/34] pixelDensity (OpenGL): fix stop button on Mac --- core/src/processing/opengl/PSurfaceJOGL.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index af4dbc2fe..44319cefc 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1046,8 +1046,7 @@ public class PSurfaceJOGL implements PSurface { int scale; if (PApplet.platform == PConstants.MACOSX) { - window.getCurrentSurfaceScale(currentPixelScale); - scale = (int) currentPixelScale[0]; + scale = (int) getCurrentPixelScale(); } else { scale = (int) getPixelScale(); } @@ -1060,7 +1059,7 @@ public class PSurfaceJOGL implements PSurface { mx -= (int)pgl.presentX; my -= (int)pgl.presentY; if (peAction == KeyEvent.RELEASE && - pgl.insideStopButton(sx, sy - screenRect.height / scale)) { + pgl.insideStopButton(sx, sy - screenRect.height / windowScaleFactor)) { sketch.exit(); } if (mx < 0 || sketchWidth < mx || my < 0 || sketchHeight < my) { From 0f0731d1e2b966ff292644c845dcd99e27198a4d Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 15 Apr 2017 19:14:09 +0200 Subject: [PATCH 33/34] pixelDensity (OpenGL): tidy up some some variables --- core/src/processing/opengl/PSurfaceJOGL.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 44319cefc..bcec8d551 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -94,8 +94,6 @@ public class PSurfaceJOGL implements PSurface { protected PApplet sketch; protected PGraphics graphics; - protected int sketchX; - protected int sketchY; protected int sketchWidth0; protected int sketchHeight0; protected int sketchWidth; @@ -269,8 +267,8 @@ public class PSurfaceJOGL implements PSurface { boolean spanDisplays = sketch.sketchDisplay() == PConstants.SPAN; screenRect = spanDisplays ? - new Rectangle(0, 0, screen.getWidth(), screen.getHeight()) : - new Rectangle(0, 0, + new Rectangle(screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight()) : + new Rectangle((int) displayRect.getX(), (int) displayRect.getY(), (int) displayRect.getWidth(), (int) displayRect.getHeight()); @@ -341,8 +339,6 @@ public class PSurfaceJOGL implements PSurface { window.setSize(sketchWidth * windowScaleFactor, sketchHeight * windowScaleFactor); window.setResizable(false); setSize(sketchWidth, sketchHeight); - sketchX = (int) displayRect.getX(); - sketchY = (int) displayRect.getY(); if (fullScreen) { PApplet.hideMenuBar(); if (spanDisplays) { @@ -671,10 +667,8 @@ public class PSurfaceJOGL implements PSurface { } else { // just center on screen // Can't use frame.setLocationRelativeTo(null) because it sends the // frame to the main display, which undermines the --display setting. - int sketchX = (int) displayRect.getX(); - int sketchY = (int) displayRect.getY(); - window.setTopLevelPosition(sketchX + screenRect.x + (screenRect.width - sketchWidth) / 2, - sketchY + screenRect.y + (screenRect.height - sketchHeight) / 2); + window.setTopLevelPosition(screenRect.x + (screenRect.width - sketchWidth) / 2, + screenRect.y + (screenRect.height - sketchHeight) / 2); } Point frameLoc = new Point(x, y); From 18e43a9ae0bbec6d6db09048fe767ced5d8aa5a0 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 17 Apr 2017 21:31:59 +0200 Subject: [PATCH 34/34] pixelDensity (all): fix background(PImage) size check --- core/src/processing/core/PGraphics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 9c8195d7c..a4425e1d8 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -7352,7 +7352,7 @@ public class PGraphics extends PImage implements PConstants { * @param image PImage to set as background (must be same size as the sketch window) */ public void background(PImage image) { - if ((image.pixelWidth != width) || (image.pixelHeight != height)) { + if ((image.pixelWidth != pixelWidth) || (image.pixelHeight != pixelHeight)) { throw new RuntimeException(ERROR_BACKGROUND_IMAGE_SIZE); } if ((image.format != RGB) && (image.format != ARGB)) {