Skip to content

Commit 964f31a

Browse files
committed
back in business, but still not nuts about current performance/complexity
1 parent 8bce710 commit 964f31a

File tree

8 files changed

+162
-71
lines changed

8 files changed

+162
-71
lines changed

core/src/processing/core/PApplet.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424

2525
package processing.core;
2626

27-
import java.awt.Canvas;
2827
// used for setting bg colors and whatnot
2928
import java.awt.Color;
29+
// Component is further up the chain than Canvas
30+
import java.awt.Component;
3031
// use for the link() command (and maybe open()?)
3132
import java.awt.Desktop;
3233
import java.awt.EventQueue;
@@ -1811,7 +1812,10 @@ public void handleDraw() {
18111812
return;
18121813
}
18131814

1815+
// Store the quality setting in case it's changed during draw and the
1816+
// drawing context needs to be re-built before the next frame.
18141817
int pquality = g.quality;
1818+
18151819
insideDraw = true;
18161820
g.beginDraw();
18171821
if (recorder != null) {
@@ -9644,10 +9648,10 @@ protected PSurface initSurface(Color backgroundColor, int displayIndex,
96449648
* // add the canvas object to your project and validate() it
96459649
* sketch.init() // start the animation thread
96469650
*/
9647-
public Canvas getCanvas() {
9651+
public Component getComponent() {
96489652
g = createPrimaryGraphics();
96499653
surface = g.createSurface();
9650-
return surface.initCanvas(this);
9654+
return surface.initComponent(this);
96519655
}
96529656

96539657

core/src/processing/core/PGraphicsJava2D.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,18 @@ public boolean canDraw() {
276276

277277
public Graphics2D checkImage() {
278278
if (image == null ||
279-
((BufferedImage) image).getWidth() != width ||
280-
((BufferedImage) image).getHeight() != height) {
279+
((BufferedImage) image).getWidth() != width*pixelFactor ||
280+
((BufferedImage) image).getHeight() != height*pixelFactor) {
281+
// ((VolatileImage) image).getWidth() != width ||
282+
// ((VolatileImage) image).getHeight() != height) {
281283
// image = new BufferedImage(width * pixelFactor, height * pixelFactor
282284
// format == RGB ? BufferedImage.TYPE_INT_ARGB);
285+
283286
GraphicsConfiguration gc = null;
284287
if (surface != null) {
285288
Component comp = surface.getComponent();
286289
if (comp == null) {
290+
// System.out.println("component null, but parent.frame is " + parent.frame);
287291
comp = parent.frame;
288292
}
289293
if (comp != null) {
@@ -292,7 +296,7 @@ public Graphics2D checkImage() {
292296
}
293297
// If not realized (off-screen, i.e the Color Selector Tool), gc will be null.
294298
if (gc == null) {
295-
//System.err.println("GraphicsConfiguration null in initImage()");
299+
System.err.println("GraphicsConfiguration null in initImage()");
296300
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
297301
gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
298302
}
@@ -301,7 +305,10 @@ public Graphics2D checkImage() {
301305
// not, but we may as well create a compatible image; it won't hurt, right?
302306
int wide = width * pixelFactor;
303307
int high = height * pixelFactor;
308+
// System.out.println("re-creating image");
304309
image = gc.createCompatibleImage(wide, high);
310+
// image = gc.createCompatibleVolatileImage(wide, high);
311+
//image = surface.getComponent().createImage(width, height);
305312
}
306313
return (Graphics2D) image.getGraphics();
307314
}

core/src/processing/core/PSurface.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
package processing.core;
2424

25-
import java.awt.Canvas;
2625
import java.awt.Color;
2726
import java.awt.Component;
2827
import java.awt.Frame;
@@ -47,7 +46,7 @@ public interface PSurface {
4746
// renderer that doesn't draw to the screen
4847
public void initOffscreen(PApplet sketch);
4948

50-
public Canvas initCanvas(PApplet sketch);
49+
public Component initComponent(PApplet sketch);
5150

5251
public Frame initFrame(PApplet sketch, Color backgroundColor,
5352
int deviceIndex, boolean fullScreen, boolean spanDisplays);

core/src/processing/core/PSurfaceAWT.java

Lines changed: 128 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ public class PSurfaceAWT extends PSurfaceBasic {
4848
// Note that x and y may not be zero, depending on the display configuration
4949
Rectangle screenRect;
5050

51-
// disabled on retina inside init()
52-
boolean useActive = true;
53-
// boolean useActive = false;
54-
// boolean useStrategy = true;
55-
boolean useStrategy = false;
56-
Canvas canvas;
51+
// 3.0a5 didn't use strategy, and active was shut off during init() w/ retina
52+
boolean useStrategy = true;
53+
54+
// Canvas canvas;
55+
Component canvas;
5756

5857
PGraphics graphics;
5958

@@ -65,22 +64,31 @@ public PSurfaceAWT(PGraphics graphics) {
6564
this.graphics = graphics;
6665

6766
if (checkRetina()) {
67+
// System.out.println("retina in use");
68+
6869
// The active-mode rendering seems to be 2x slower, so disable it
6970
// with retina. On a non-retina machine, however, useActive seems
7071
// the only (or best) way to handle the rendering.
71-
useActive = false;
72+
// useActive = false;
73+
// canvas = new JPanel(true) {
74+
// @Override
75+
// public void paint(Graphics screen) {
76+
//// if (!sketch.insideDraw) {
77+
// screen.drawImage(PSurfaceAWT.this.graphics.image, 0, 0, sketchWidth, sketchHeight, null);
78+
//// }
79+
// }
80+
// };
81+
// Under 1.8 and the current 3.0a6 threading regime, active mode w/o
82+
// strategy is far faster, but perhaps only because it's blitting with
83+
// flicker--pushing pixels out before the screen has finished rendering.
84+
// useStrategy = false;
7285
}
73-
74-
createCanvas();
75-
addListeners();
76-
}
77-
78-
79-
void createCanvas() {
8086
canvas = new SmoothCanvas();
81-
canvas.setIgnoreRepaint(true); // ??
87+
if (useStrategy) {
88+
canvas.setIgnoreRepaint(true);
89+
}
8290

83-
// send tab keys through to the PApplet
91+
// Pass tab key to the sketch, rather than moving between components
8492
canvas.setFocusTraversalKeysEnabled(false);
8593

8694
canvas.addComponentListener(new ComponentAdapter() {
@@ -91,6 +99,7 @@ public void componentResized(ComponentEvent e) {
9199
}
92100
}
93101
});
102+
addListeners();
94103
}
95104

96105

@@ -177,28 +186,48 @@ public void update(Graphics g) {
177186

178187

179188
@Override
180-
public void paint(Graphics g) {
189+
public void paint(Graphics screen) {
181190
// System.out.println("painting");
182191
// validate();
183-
render();
192+
if (useStrategy) {
193+
render();
194+
195+
} else {
196+
// new Exception("painting").printStackTrace(System.out);
197+
// if (graphics.image != null) { // && !sketch.insideDraw) {
198+
if (onscreen != null) {
199+
// synchronized (graphics.image) {
200+
// Needs the width/height to be set so that retina images are properly scaled down
201+
// screen.drawImage(graphics.image, 0, 0, sketchWidth, sketchHeight, null);
202+
synchronized (offscreenLock) {
203+
screen.drawImage(onscreen, 0, 0, sketchWidth, sketchHeight, null);
204+
}
205+
}
206+
}
184207
}
185208

186209

210+
/*
187211
@Override
188212
public void addNotify() {
189213
// System.out.println("adding notify");
190214
super.addNotify();
191215
// prior to Java 7 on OS X, this no longer works [121222]
192216
// createBufferStrategy(2);
193217
}
218+
*/
194219

195220

196221
protected synchronized void render() {
222+
//System.out.println("render() top");
223+
224+
/*
197225
if (!EventQueue.isDispatchThread()) {
198226
//throw new IllegalStateException("render() called outside the EDT");
199227
//System.err.println("render() called outside the EDT");
200228
new Exception("render() called outside the EDT").printStackTrace();
201229
}
230+
*/
202231
// if (canvas == null) {
203232
// removeListeners(this);
204233
// canvas = new Canvas();
@@ -225,12 +254,13 @@ protected synchronized void render() {
225254
return;
226255
}
227256

257+
Canvas c = (Canvas) canvas;
228258
// System.out.println("render(), canvas bounds are " + canvas.getBounds());
229-
if (canvas.getBufferStrategy() == null) { // whole block [121222]
259+
if (c.getBufferStrategy() == null) { // whole block [121222]
230260
// System.out.println("creating a strategy");
231-
canvas.createBufferStrategy(2);
261+
c.createBufferStrategy(2);
232262
}
233-
BufferStrategy strategy = canvas.getBufferStrategy();
263+
BufferStrategy strategy = c.getBufferStrategy();
234264
// System.out.println(strategy);
235265
if (strategy == null) {
236266
return;
@@ -240,10 +270,27 @@ protected synchronized void render() {
240270
// The following loop ensures that the contents of the drawing buffer
241271
// are consistent in case the underlying surface was recreated
242272
do {
243-
Graphics draw = strategy.getDrawGraphics();
273+
Graphics2D draw = (Graphics2D) strategy.getDrawGraphics();
244274
//draw.drawImage(pg.image, 0, 0, sketch.width, sketch.height, null);
275+
//System.out.println("render() drawing image");
276+
/*
277+
while (sketch.insideDraw) {
278+
System.out.println("render() yielding because inside draw");
279+
//Thread.yield();
280+
try {
281+
Thread.sleep(1);
282+
} catch (InterruptedException e) { }
283+
}
284+
*/
285+
286+
// this wasn't any faster than setting the image size while drawing
287+
// if (graphics.pixelFactor == 2) {
288+
// draw.scale(0.5, 0.5);
289+
// }
290+
245291
// draw to width/height, since this may be a 2x image
246292
draw.drawImage(graphics.image, 0, 0, sketchWidth, sketchHeight, null);
293+
// draw.drawImage(graphics.image, 0, 0, null);
247294
draw.dispose();
248295

249296
// Repeat the rendering if the drawing buffer contents
@@ -259,20 +306,56 @@ protected synchronized void render() {
259306
// System.out.println("lost " + strategy.contentsLost());
260307
// System.out.println();
261308
} while (strategy.contentsLost());
309+
//System.out.println("render() bottom");
262310
}
263311
}
264312

265313

314+
Object offscreenLock = new Object();
315+
BufferedImage offscreen;
316+
BufferedImage onscreen;
317+
// Graphics off;
318+
266319
@Override
267320
public void blit() {
268-
// Other folks taht call render() (i.e. paint()) are already on the EDT.
321+
// Other folks that call render() (i.e. paint()) are already on the EDT.
269322
// We need to be using the EDT since we're messing with the Canvas
270323
// object and BufferStrategy and friends.
271-
EventQueue.invokeLater(new Runnable() {
272-
public void run() {
273-
((SmoothCanvas) canvas).render();
324+
//EventQueue.invokeLater(new Runnable() {
325+
//public void run() {
326+
//((SmoothCanvas) canvas).render();
327+
//}
328+
//});
329+
330+
if (useStrategy) {
331+
// Not necessary to be on the EDT to update BufferStrategy
332+
((SmoothCanvas) canvas).render();
333+
} else {
334+
if (graphics.image != null) {
335+
BufferedImage graphicsImage = (BufferedImage) graphics.image;
336+
if (offscreen == null ||
337+
offscreen.getWidth() != graphicsImage.getWidth() ||
338+
offscreen.getHeight() != graphicsImage.getHeight()) {
339+
System.out.println("creating new image");
340+
offscreen = (BufferedImage)
341+
canvas.createImage(graphicsImage.getWidth(),
342+
graphicsImage.getHeight());
343+
// off = offscreen.getGraphics();
344+
}
345+
// synchronized (offscreen) {
346+
Graphics2D off = (Graphics2D) offscreen.getGraphics();
347+
// off.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1));
348+
off.drawImage(graphicsImage, 0, 0, null);
349+
// }
350+
off.dispose();
351+
synchronized (offscreenLock) {
352+
BufferedImage temp = onscreen;
353+
onscreen = offscreen;
354+
offscreen = temp;
355+
}
356+
canvas.repaint();
274357
}
275-
});
358+
}
276359
}
277360

278361

@@ -292,7 +375,7 @@ public Frame initOffscreen() {
292375
*/
293376

294377
@Override
295-
public Canvas initCanvas(PApplet sketch) {
378+
public Component initComponent(PApplet sketch) {
296379
this.sketch = sketch;
297380

298381
// needed for getPreferredSize() et al
@@ -727,39 +810,25 @@ public void setSmooth(int level) {
727810

728811
private boolean checkRetina() {
729812
if (PApplet.platform == PConstants.MACOSX) {
730-
// This should probably be reset each time there's a display change.
731-
// A 5-minute search didn't turn up any such event in the Java API.
732-
// Also, should we use the Toolkit associated with the editor window?
813+
// This should probably be reset each time there's a display change.
814+
// A 5-minute search didn't turn up any such event in the Java 7 API.
815+
// Also, should we use the Toolkit associated with the editor window?
733816
final String javaVendor = System.getProperty("java.vendor");
734-
if (javaVendor.contains("Apple")) {
735-
Float prop = (Float)
736-
canvas.getToolkit().getDesktopProperty("apple.awt.contentScaleFactor");
737-
if (prop != null) {
738-
return prop == 2;
739-
}
740-
} else if (javaVendor.contains("Oracle")) {
741-
String version = System.getProperty("java.version"); // 1.7.0_40
742-
String[] m = PApplet.match(version, "1.(\\d).*_(\\d+)");
743-
744-
// Make sure this is Oracle Java 7u40 or later
745-
if (m != null &&
746-
PApplet.parseInt(m[1]) >= 7 &&
747-
PApplet.parseInt(m[1]) >= 40) {
748-
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
749-
GraphicsDevice device = env.getDefaultScreenDevice();
750-
751-
try {
752-
Field field = device.getClass().getDeclaredField("scale");
753-
if (field != null) {
754-
field.setAccessible(true);
755-
Object scale = field.get(device);
756-
757-
if (scale instanceof Integer && ((Integer)scale).intValue() == 2) {
758-
return true;
759-
}
817+
if (javaVendor.contains("Oracle")) {
818+
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
819+
GraphicsDevice device = env.getDefaultScreenDevice();
820+
821+
try {
822+
Field field = device.getClass().getDeclaredField("scale");
823+
if (field != null) {
824+
field.setAccessible(true);
825+
Object scale = field.get(device);
826+
827+
if (scale instanceof Integer && ((Integer)scale).intValue() == 2) {
828+
return true;
760829
}
761-
} catch (Exception ignore) { }
762-
}
830+
}
831+
} catch (Exception ignore) { }
763832
}
764833
}
765834
return false;

0 commit comments

Comments
 (0)