adding in-progress work for on canvas, retina, etc

This commit is contained in:
benfry
2013-01-10 15:59:50 +00:00
parent cb373ab45c
commit 38005496d7
4 changed files with 427 additions and 31 deletions
+103 -31
View File
@@ -59,6 +59,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
Canvas canvas;
// boolean useCanvas = true;
boolean useCanvas = false;
// boolean useRetina = true;
// boolean useOffscreen = true; // ~40fps
boolean useOffscreen = false;
public Graphics2D g2;
protected BufferedImage offscreen;
@@ -154,6 +157,8 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
// parent.setLayout(new BorderLayout());
// parent.add(canvas, BorderLayout.CENTER);
parent.add(canvas);
// canvas.validate();
// parent.doLayout();
if (canvas.getWidth() != width || canvas.getHeight() != height) {
PApplet.debug("PGraphicsJava2D comp size being set to " + width + "x" + height);
@@ -171,14 +176,31 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
// using a compatible image here doesn't seem to provide any performance boost
// Needs to be RGB otherwise there's a major performance hit [0204]
// http://code.google.com/p/processing/issues/detail?id=729
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
if (useOffscreen) {
// Needs to be RGB otherwise there's a major performance hit [0204]
// http://code.google.com/p/processing/issues/detail?id=729
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
// image = gc.createCompatibleImage(width, height);
offscreen = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
offscreen = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// offscreen = gc.createCompatibleImage(width, height);
g2 = (Graphics2D) offscreen.getGraphics();
g2 = (Graphics2D) offscreen.getGraphics();
} else {
// System.out.println("hopefully faster " + width + " " + height);
// new Exception().printStackTrace(System.out);
GraphicsConfiguration gc = parent.getGraphicsConfiguration();
// If not realized (off-screen, i.e the Color Selector Tool),
// gc will be null.
if (gc == null) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
}
image = gc.createCompatibleImage(width, height);
g2 = (Graphics2D) image.getGraphics();
}
}
} else {
// Since this buffer's offscreen anyway, no need for the extra offscreen
@@ -187,9 +209,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) image.getGraphics();
}
if (!useCanvas) {
defaultComposite = g2.getComposite();
}
// if (!useCanvas) {
// defaultComposite = g2.getComposite();
// }
// can't un-set this because this may be only a resize
// http://dev.processing.org/bugs/show_bug.cgi?id=463
@@ -226,6 +248,21 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
@Override
public void beginDraw() {
if (primarySurface && !useOffscreen) {
GraphicsConfiguration gc = parent.getGraphicsConfiguration();
if (false) {
if (image == null || ((VolatileImage) image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
image = gc.createCompatibleVolatileImage(width, height);
}
} else {
if (image == null) {
image = gc.createCompatibleImage(width, height);
//System.out.println("image type is " + image);
}
}
g2 = (Graphics2D) image.getGraphics();
}
if (useCanvas && primarySurface) {
if (parent.frameCount == 0) {
canvas.createBufferStrategy(2);
@@ -275,9 +312,12 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
// alternate version
//canvas.repaint(); // ?? what to do for swapping buffers
// System.out.println("endDraw() frameCount is " + parent.frameCount);
// if (parent.frameCount != 0) {
redraw();
// }
} else {
} else if (useOffscreen) {
// don't copy the pixels/data elements of the buffered image directly,
// since it'll disable the nice speedy pipeline stuff, sending all drawing
// into a world of suck that's rough 6 trillion times slower.
@@ -285,6 +325,10 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
//System.out.println("inside j2d sync");
image.getGraphics().drawImage(offscreen, 0, 0, null);
}
} else {
g2.dispose();
// System.out.println("not doing anything special in endDraw()");
}
} else {
// TODO this is probably overkill for most tasks...
@@ -353,7 +397,13 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
//protected void checkSettings()
//protected void defaultSettings()
@Override
protected void defaultSettings() {
if (!useCanvas) {
defaultComposite = g2.getComposite();
}
super.defaultSettings();
}
//protected void reapplySettings()
@@ -2056,20 +2106,25 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
int[] clearPixels;
protected void clearPixels(int color) {
// On a hi-res display, image may be larger than width/height
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
// Create a small array that can be used to set the pixels several times.
// Using a single-pixel line of length 'width' is a tradeoff between
// speed (setting each pixel individually is too slow) and memory
// (an array for width*height would waste lots of memory if it stayed
// resident, and would terrify the gc if it were re-created on each trip
// to background().
WritableRaster raster = ((BufferedImage) image).getRaster();
// WritableRaster raster = ((BufferedImage) image).getRaster();
// WritableRaster raster = image.getRaster();
if ((clearPixels == null) || (clearPixels.length < width)) {
clearPixels = new int[width];
WritableRaster raster = getRaster();
if ((clearPixels == null) || (clearPixels.length < imageWidth)) {
clearPixels = new int[imageWidth];
}
Arrays.fill(clearPixels, backgroundColor);
for (int i = 0; i < height; i++) {
raster.setDataElements(0, i, width, 1, clearPixels);
Arrays.fill(clearPixels, 0, imageWidth, backgroundColor);
for (int i = 0; i < imageHeight; i++) {
raster.setDataElements(0, i, imageWidth, 1, clearPixels);
}
}
@@ -2101,7 +2156,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
pushMatrix();
resetMatrix();
g2.setColor(bgColor); //, backgroundAlpha));
g2.fillRect(0, 0, width, height);
// g2.fillRect(0, 0, width, height);
// On a hi-res display, image may be larger than width/height
g2.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
popMatrix();
g2.setComposite(oldComposite);
@@ -2200,15 +2257,31 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
// getImage, setCache, getCache, removeCache, isModified, setModified
protected WritableRaster getRaster() {
if (primarySurface) {
// 'offscreen' will probably be removed in the next release
if (useOffscreen) {
return ((BufferedImage) offscreen).getRaster();
}
// when possible, we'll try VolatileImage
if (image instanceof VolatileImage) {
return ((VolatileImage) image).getSnapshot().getRaster();
}
}
return ((BufferedImage) image).getRaster();
//((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
}
@Override
public void loadPixels() {
if ((pixels == null) || (pixels.length != width * height)) {
pixels = new int[width * height];
}
//((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width);
WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = image.getRaster();
raster.getDataElements(0, 0, width, height, pixels);
getRaster().getDataElements(0, 0, width, height, pixels);
}
@@ -2221,9 +2294,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
@Override
public void updatePixels() {
//updatePixels(0, 0, width, height);
WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = image.getRaster();
raster.setDataElements(0, 0, width, height, pixels);
getRaster().setDataElements(0, 0, width, height, pixels);
}
@@ -2255,9 +2328,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
public int get(int x, int y) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0;
//return ((BufferedImage) image).getRGB(x, y);
WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = image.getRaster();
raster.getDataElements(x, y, getset);
getRaster().getDataElements(x, y, getset);
return getset[0];
}
@@ -2272,8 +2345,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
PImage target, int targetX, int targetY) {
// last parameter to getRGB() is the scan size of the *target* buffer
//((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w);
WritableRaster raster =
((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster =
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
WritableRaster raster = getRaster();
if (sourceWidth == target.width && sourceHeight == target.height) {
raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels);
@@ -2306,9 +2380,9 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return;
// ((BufferedImage) image).setRGB(x, y, argb);
getset[0] = argb;
WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
// WritableRaster raster = image.getRaster();
raster.setDataElements(x, y, getset);
getRaster().setDataElements(x, y, getset);
}
@@ -2320,8 +2394,8 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
int sourceX, int sourceY,
int sourceWidth, int sourceHeight,
int targetX, int targetY) {
WritableRaster raster =
((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
WritableRaster raster = getRaster();
// ((BufferedImage) (useOffscreen && primarySurface ? offscreen : image)).getRaster();
if ((sourceX == 0) && (sourceY == 0) &&
(sourceWidth == sourceImage.width) &&
@@ -2380,8 +2454,6 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
public void copy(int sx, int sy, int sw, int sh,
int dx, int dy, int dw, int dh) {
if ((sw != dw) || (sh != dh)) {
// Image img = primarySurface ? offscreen : image;
// g2.drawImage(img, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
g2.drawImage(image, dx, dy, dx + dw, dy + dh, sx, sy, sx + sw, sy + sh, null);
} else {
@@ -0,0 +1,318 @@
package processing.core;
import java.awt.*;
import java.awt.image.*;
public class PGraphicsRetina2D extends PGraphicsJava2D {
//////////////////////////////////////////////////////////////
// INTERNAL
public PGraphicsRetina2D() { }
@Override
protected void allocate() {
// parent.setIgnoreRepaint(true);
// g2 = (Graphics2D) parent.getGraphics();
/*
if (primarySurface) {
if (useCanvas) {
if (canvas != null) {
parent.removeListeners(canvas);
parent.remove(canvas);
}
canvas = new Canvas();
canvas.setIgnoreRepaint(true);
// parent.setLayout(new BorderLayout());
// parent.add(canvas, BorderLayout.CENTER);
parent.add(canvas);
if (canvas.getWidth() != width || canvas.getHeight() != height) {
PApplet.debug("PGraphicsJava2D comp size being set to " + width + "x" + height);
canvas.setSize(width, height);
} else {
PApplet.debug("PGraphicsJava2D comp size already " + width + "x" + height);
}
parent.addListeners(canvas);
// canvas.createBufferStrategy(1);
// g2 = (Graphics2D) canvas.getGraphics();
} else {
parent.updateListeners(parent); // in case they're already there
// using a compatible image here doesn't seem to provide any performance boost
// Needs to be RGB otherwise there's a major performance hit [0204]
// http://code.google.com/p/processing/issues/detail?id=729
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// GraphicsConfiguration gc = parent.getGraphicsConfiguration();
// image = gc.createCompatibleImage(width, height);
offscreen = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// offscreen = gc.createCompatibleImage(width, height);
g2 = (Graphics2D) offscreen.getGraphics();
}
} else {
// Since this buffer's offscreen anyway, no need for the extra offscreen
// buffer. However, unlike the primary surface, this feller needs to be
// ARGB so that blending ("alpha" compositing) will work properly.
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) image.getGraphics();
}
*/
}
//////////////////////////////////////////////////////////////
// FRAME
@Override
public void beginDraw() {
// g2 = (Graphics2D) parent.getGraphics();
GraphicsConfiguration gc = parent.getGraphicsConfiguration();
if (false) {
if (image == null || ((VolatileImage) image).validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
image = gc.createCompatibleVolatileImage(width*2, height*2);
}
} else {
if (image == null) {
image = gc.createCompatibleImage(width*2, height*2);
// System.out.println("image type is " + image);
}
}
g2 = (Graphics2D) image.getGraphics();
// g2.scale(2, 2);
// if (bimage == null ||
// bimage.getWidth() != width ||
// bimage.getHeight() != height) {
// PApplet.debug("PGraphicsJava2D creating new image");
// bimage = gc.createCompatibleImage(width, height);
checkSettings();
resetMatrix(); // reset model matrix
// inserted here for retina
g2.scale(2, 2);
vertexCount = 0;
}
@Override
public void endDraw() {
g2.dispose();
/*
// hm, mark pixels as changed, because this will instantly do a full
// copy of all the pixels to the surface.. so that's kind of a mess.
//updatePixels();
if (primarySurface) {
//if (canvas != null) {
if (useCanvas) {
//System.out.println(canvas);
// alternate version
//canvas.repaint(); // ?? what to do for swapping buffers
redraw();
} else {
// don't copy the pixels/data elements of the buffered image directly,
// since it'll disable the nice speedy pipeline stuff, sending all drawing
// into a world of suck that's rough 6 trillion times slower.
synchronized (image) {
//System.out.println("inside j2d sync");
image.getGraphics().drawImage(offscreen, 0, 0, null);
}
}
} else {
// TODO this is probably overkill for most tasks...
loadPixels();
}
// Marking as modified, and then calling updatePixels() in
// the super class, which just sets the mx1, my1, mx2, my2
// coordinates of the modified area. This avoids doing the
// full copy of the pixels to the surface in this.updatePixels().
setModified();
super.updatePixels();
*/
}
//////////////////////////////////////////////////////////////
// BACKGROUND
// @Override
// public void backgroundImpl() {
// if (backgroundAlpha) {
// clearPixels(backgroundColor);
//
// } else {
// Color bgColor = new Color(backgroundColor);
// // seems to fire an additional event that causes flickering,
// // like an extra background erase on OS X
//// if (canvas != null) {
//// canvas.setBackground(bgColor);
//// }
// //new Exception().printStackTrace(System.out);
// // in case people do transformations before background(),
// // need to handle this with a push/reset/pop
// Composite oldComposite = g2.getComposite();
// g2.setComposite(defaultComposite);
//
// pushMatrix();
// resetMatrix();
// g2.setColor(bgColor); //, backgroundAlpha));
// g2.fillRect(0, 0, width, height);
// popMatrix();
//
// g2.setComposite(oldComposite);
// }
// }
//////////////////////////////////////////////////////////////
/*
@Override
public void loadPixels() {
nope("loadPixels");
}
@Override
public void updatePixels() {
nope("updatePixels");
}
@Override
public void updatePixels(int x, int y, int c, int d) {
nope("updatePixels");
}
//
@Override
public int get(int x, int y) {
nope("get");
return 0; // not reached
}
@Override
public PImage get(int x, int y, int c, int d) {
nope("get");
return null; // not reached
}
@Override
public PImage get() {
nope("get");
return null; // not reached
}
@Override
public void set(int x, int y, int argb) {
nope("set");
}
@Override
public void set(int x, int y, PImage image) {
nope("set");
}
//
@Override
public void mask(int alpha[]) {
nope("mask");
}
@Override
public void mask(PImage alpha) {
nope("mask");
}
//
@Override
public void filter(int kind) {
nope("filter");
}
@Override
public void filter(int kind, float param) {
nope("filter");
}
//
@Override
public void copy(int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2) {
nope("copy");
}
@Override
public void copy(PImage src,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2) {
nope("copy");
}
//
public void blend(int sx, int sy, int dx, int dy, int mode) {
nope("blend");
}
public void blend(PImage src,
int sx, int sy, int dx, int dy, int mode) {
nope("blend");
}
@Override
public void blend(int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2, int mode) {
nope("blend");
}
@Override
public void blend(PImage src,
int sx1, int sy1, int sx2, int sy2,
int dx1, int dy1, int dx2, int dy2, int mode) {
nope("blend");
}
//
@Override
public boolean save(String filename) {
nope("save");
return false;
}
*/
//////////////////////////////////////////////////////////////
protected void nope(String function) {
throw new RuntimeException("No " + function + "() for PGraphicsRetina2D");
}
}
+4
View File
@@ -39,6 +39,8 @@ A P3D sketches failing to run
A http://code.google.com/p/processing/issues/detail?id=1500
A transparent pixels are not set on multisampled offscreen GL surfaces
A http://code.google.com/p/processing/issues/detail?id=1516
A clean-up PShape API
A http://code.google.com/p/processing/issues/detail?id=1518
cleaning/earlier
C textureWrap() CLAMP and REPEAT now added
@@ -114,6 +116,8 @@ _ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey()
_ and how it should be handled with hash/dict
_ right now using hasKey().. in JSONObject
_ add randomGaussian()
_ OpenGL/P3D sketches show graphical corruption
_ http://code.google.com/p/processing/issues/detail?id=1452
+2
View File
@@ -41,6 +41,8 @@ o do command line to run through all examples?
X remove Quaqua
X http://code.google.com/p/processing/issues/detail?id=1509
X remove separate launch of QT movie creator
X Don't open Changes page on the Wiki from command line
X http://code.google.com/p/processing/issues/detail?id=1520
manindra
M bug that was causing the Debugger to point to wrong break point line numbers