blob: 118ae2463b80ebe0303fd50cb1f5e8711af2e84c [file] [log] [blame]
/* J2dBenchmark.java -- Benchmarking utility for java2d,
based on the Aicas AWT benchmarker
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath examples.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA. */
package gnu.classpath.examples.java2d;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.QuadCurve2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class J2dBenchmark
extends Panel
{
/**
* Default number of test-iterations.
*/
protected static final int DEFAULT_TEST_SIZE = 1000;
/**
* Default screen size.
*/
protected static final int DEFAULT_SCREEN_WIDTH = 320;
protected static final int DEFAULT_SCREEN_HEIGHT = 240;
/**
* Java2D tests.
*/
protected static final int J2DTEST_ARC = 1 << 0;
protected static final int J2DTEST_CUBICCURVE = 1 << 1;
protected static final int J2DTEST_ELLIPSE = 1 << 2;
protected static final int J2DTEST_GENERALPATH = 1 << 3;
protected static final int J2DTEST_LINE = 1 << 4;
protected static final int J2DTEST_QUADCURVE = 1 << 5;
protected static final int J2DTEST_RECTANGLE = 1 << 6;
protected static final int J2DTEST_ROUNDRECTANGLE = 1 << 7;
protected static final int J2DTEST_IMAGE = 1 << 8;
protected static final int J2DTEST_NONE = 0;
/*
private static final int J2DTEST_ALL = J2DTEST_ARC | J2DTEST_CUBICCURVE
| J2DTEST_ELLIPSE
| J2DTEST_GENERALPATH | J2DTEST_LINE
| J2DTEST_QUADCURVE
| J2DTEST_RECTANGLE
| J2DTEST_ROUNDRECTANGLE
| J2DTEST_IMAGE;
*/
private static final int J2DTEST_ALL = J2DTEST_ARC | J2DTEST_CUBICCURVE
| J2DTEST_ELLIPSE
| J2DTEST_LINE
| J2DTEST_QUADCURVE
| J2DTEST_RECTANGLE
| J2DTEST_ROUNDRECTANGLE
| J2DTEST_IMAGE;
int iterations = 1;
protected int screenWidth = DEFAULT_SCREEN_WIDTH;
protected int screenHeight = DEFAULT_SCREEN_HEIGHT;
protected boolean noClippingFlag = true;
protected boolean withClippingFlag = true;
protected boolean zeroClippingFlag = true;
protected boolean singleBufferFlag = true;
protected boolean doubleBufferFlag = true;
protected boolean gradientFlag = false;
protected String texture = null;
protected boolean strokeFlag = false;
protected float composite = 1;
protected int xtranslate = 0;
protected int ytranslate = 0;
protected double xshear = 0;
protected double yshear = 0;
protected double rotate = 0;
protected boolean antialiasFlag = false;
protected AffineTransform affineTransform = null;
protected int awtTests = J2DTEST_ALL;
protected int testSize = DEFAULT_TEST_SIZE;
private Label testLabel;
private String testContext = "";
Logger logger = Logger.getLogger("J2dGraphicsBenchmark");
private Image pngTestImage;
private Image gifTestImage;
protected BufferedImage textureImage;
protected TestSet testSetMap = new TestSet();
public String init()
{
boolean loadError = false;
pngTestImage = loadImage("aicas.png");
gifTestImage = loadImage("palme.gif");
if (texture != null)
{
textureImage = loadBufferedImage(texture);
if (textureImage == null)
{
logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "init",
"Unable to load texture - defaulting "
+ "to solid colours");
texture = null;
loadError = true;
}
}
setLayout(new BorderLayout());
testLabel = new Label();
add(testLabel, BorderLayout.NORTH);
add(new GraphicsTest(), BorderLayout.CENTER);
if (loadError)
return "Unable to load image";
else
return null;
}
void setTestContext(String testName)
{
logger.logp(Level.INFO, "J2dGraphicsBenchmark", "recordTest",
"--- Starting new test context: " + testName);
testContext = testName;
testLabel.setText(testName);
}
private void recordTest(String testName, long time)
{
logger.logp(Level.INFO, "J2dGraphicsBenchmark", "recordTest",
testContext + ": " + testName + " duration (ms): " + time);
TestRecorder recorder = testSetMap.getTest(testName);
if (recorder == null)
{
recorder = new TestRecorder(testName);
testSetMap.putTest(testName, recorder);
}
recorder.addRun(time);
}
void printReport()
{
for (Iterator i = testSetMap.testIterator(); i.hasNext();)
{
TestRecorder recorder = testSetMap.getTest((String) i.next());
System.out.println("TEST " + recorder.getTestName() + ": average "
+ recorder.getAverage() + "ms ["
+ recorder.getMinTime() + "-"
+ recorder.getMaxTime() + "]");
}
}
void testComplete()
{
System.exit(0);
}
public static void main(String[] args)
{
int awtTests;
int i;
boolean endOfOptionsFlag;
J2dBenchmark speed = new J2dBenchmark();
// Parse arguments.
i = 0;
endOfOptionsFlag = false;
awtTests = J2DTEST_NONE;
while (i < args.length)
{
if (! endOfOptionsFlag)
{
if (args[i].equals("--help") || args[i].equals("-help")
|| args[i].equals("-h"))
{
System.out.println("Usage: J2dBenchmark [<options>] [<test> ...]");
System.out.println("");
System.out.println("Options: -i|--iterations=<n|-1> - number of iterations (-1 is infinite; default "
+ speed.iterations + ")");
System.out.println(" -w|--width=<n> - screen width; default "
+ DEFAULT_SCREEN_WIDTH);
System.out.println(" -h|--height=<n> - screen height; default "
+ DEFAULT_SCREEN_HEIGHT);
System.out.println(" -d|--noDoubleBuffer - disable double-buffering test");
System.out.println(" -s|--testsize=<n> - size of each test; default "
+ DEFAULT_TEST_SIZE);
System.out.println(" -c|--noClipping - disable clipping test");
System.out.println(" -z|--noZeroClipping - disable clipping to zero test");
System.out.println("");
System.out.println("Additional options:");
System.out.println(" --with-gradients - enable gradients (not compatible with --texture)");
System.out.println(" --with-stroking - enable random stroking");
System.out.println(" --texture=<file> - enable texturing with this file (not compatible with --with-gradients)");
System.out.println(" --composite=<n|-1> - set alpha composite level; -1 for random; default 1.0 (no transparency)");
System.out.println(" --anti-alias=<on|off> - set anti-aliasing hint (not all implementations respect this); default off");
System.out.println(" --x-translate=<n> - set x-axis translation; default 0");
System.out.println(" --y-translate=<n> - set y-axis translation; default 0");
System.out.println(" --x-shear=<n> - set x-axis shear; default 0");
System.out.println(" --y-shear=<n> - set y-axis shear; default 0");
System.out.println(" --rotate=<n|-1> - set rotation (radians); -1 for random; default: 0 (none)");
System.out.println("");
System.out.println("Tests: arc");
System.out.println(" cubiccurve");
System.out.println(" ellipse");
// System.out.println(" generalpath");
System.out.println(" line");
System.out.println(" quadcurve");
System.out.println(" rectangle");
System.out.println(" roundrectangle");
System.out.println(" image");
System.exit(1);
}
else if ((args[i].startsWith("-i=") || args[i].startsWith("--iterations=")))
{
speed.iterations = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if ((args[i].equals("-i") || args[i].equals("--iterations")))
{
if ((i + 1) >= args.length)
{
System.err.println("ERROR: No argument given for option '"
+ args[i] + "'!");
System.exit(2);
}
speed.iterations = Integer.parseInt(args[i + 1]);
i += 2;
continue;
}
else if ((args[i].startsWith("-w=") || args[i].startsWith("--width=")))
{
speed.screenWidth = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if ((args[i].equals("-w") || args[i].equals("--width")))
{
if ((i + 1) >= args.length)
{
System.err.println("ERROR: No argument given for option '"
+ args[i] + "'!");
System.exit(2);
}
speed.screenWidth = Integer.parseInt(args[i + 1]);
i += 2;
continue;
}
else if ((args[i].startsWith("-h=") || args[i].startsWith("--height=")))
{
speed.screenHeight = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if ((args[i].equals("-h") || args[i].equals("--height")))
{
if ((i + 1) >= args.length)
{
System.err.println("ERROR: No argument given for option '"
+ args[i] + "'!");
System.exit(2);
}
speed.screenHeight = Integer.parseInt(args[i + 1]);
i += 2;
continue;
}
else if ((args[i].equals("-d") || args[i].equals("--noDoubleBuffer")))
{
speed.doubleBufferFlag = false;
i += 1;
continue;
}
else if ((args[i].startsWith("-s=") || args[i].startsWith("--testsize=")))
{
if ((i + 1) >= args.length)
{
System.err.println("ERROR: No argument given for option '"
+ args[i] + "'!");
System.exit(2);
}
speed.testSize = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if ((args[i].equals("-s") || args[i].equals("--testsize")))
{
if ((i + 1) >= args.length)
{
System.err.println("ERROR: No argument given for option '"
+ args[i] + "'!");
System.exit(2);
}
speed.testSize = Integer.parseInt(args[i + 1]);
i += 2;
continue;
}
else if ((args[i].equals("-c") || args[i].equals("--noClipping")))
{
speed.noClippingFlag = false;
i += 1;
continue;
}
else if ((args[i].equals("-z") || args[i].equals("--noZeroClipping")))
{
speed.zeroClippingFlag = false;
i += 1;
continue;
}
else if (args[i].equals("--with-gradients"))
{
speed.gradientFlag = true;
i += 1;
continue;
}
else if (args[i].equals("--with-stroking"))
{
speed.strokeFlag = true;
i += 1;
continue;
}
else if (args[i].startsWith("--texture="))
{
speed.texture = args[i].substring(args[i].indexOf('=') + 1);
i += 1;
continue;
}
else if (args[i].startsWith("--composite="))
{
speed.composite = Float.parseFloat(args[i].substring(args[i].indexOf('=') + 1));
if (speed.composite != - 1
&& (speed.composite < 0 || speed.composite > 1))
{
System.err.println("ERROR: Invalid value for composite (must be between 0 and 1, or -1 for random)");
System.exit(2);
}
i += 1;
continue;
}
else if (args[i].startsWith("--anti-alias="))
{
speed.antialiasFlag = (args[i].substring(args[i].indexOf('=') + 1).equals("on"));
i += 1;
continue;
}
else if (args[i].startsWith("--x-translate="))
{
speed.xtranslate = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if (args[i].startsWith("--y-translate="))
{
speed.ytranslate = Integer.parseInt(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if (args[i].startsWith("--x-shear="))
{
speed.xshear = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if (args[i].startsWith("--y-shear="))
{
speed.yshear = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if (args[i].startsWith("--rotate="))
{
speed.rotate = Double.parseDouble(args[i].substring(args[i].indexOf('=') + 1));
i += 1;
continue;
}
else if (args[i].equals("--"))
{
endOfOptionsFlag = true;
i += 1;
continue;
}
else if (args[i].startsWith("-"))
{
System.err.println("ERROR: Unknown option '" + args[i] + "'!");
System.exit(2);
}
}
StringTokenizer tokenizer = new StringTokenizer(args[i], " +,");
while (tokenizer.hasMoreTokens())
{
String s = tokenizer.nextToken().toLowerCase();
if (s.equals("arc"))
awtTests |= J2DTEST_ARC;
else if (s.equals("cubiccurve"))
awtTests |= J2DTEST_CUBICCURVE;
else if (s.equals("ellipse"))
awtTests |= J2DTEST_ELLIPSE;
else if (s.equals("generalpath"))
awtTests |= J2DTEST_GENERALPATH;
else if (s.equals("line"))
awtTests |= J2DTEST_LINE;
else if (s.equals("quadcurve"))
awtTests |= J2DTEST_QUADCURVE;
else if (s.equals("rectangle"))
awtTests |= J2DTEST_RECTANGLE;
else if (s.equals("roundrectangle"))
awtTests |= J2DTEST_ROUNDRECTANGLE;
else if (s.equals("image"))
awtTests |= J2DTEST_IMAGE;
else
{
System.err.println("Unknown AWT test '" + s + "'!");
System.exit(2);
}
}
i += 1;
}
if (awtTests != J2DTEST_NONE)
speed.awtTests = awtTests;
// Create graphics.
speed.init();
final Frame frame = new Frame("J2dGraphicsBenchmark");
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
frame.setVisible(false);
System.exit(0);
}
});
frame.add(speed, BorderLayout.CENTER);
frame.setSize(speed.screenWidth, speed.screenHeight);
frame.setVisible(true);
// Insets are correctly set only after the native peer was created.
Insets insets = frame.getInsets();
// The internal size of the frame should be 320x240.
frame.setSize(320 + insets.right + insets.left, 240 + insets.top
+ insets.bottom);
}
private Image loadImage(String imageName)
{
Image result = null;
logger.logp(Level.INFO, "J2dGraphicsBenchmark", "loadImage",
"Loading image: " + imageName);
URL url = getClass().getResource(imageName);
if (url != null)
{
result = Toolkit.getDefaultToolkit().getImage(url);
prepareImage(result, this);
}
else
{
logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "loadImage",
"Could not locate image resource in class path: "
+ imageName);
}
return result;
}
private BufferedImage loadBufferedImage(String imageName)
{
BufferedImage result = null;
logger.logp(Level.INFO, "J2dGraphicsBenchmark", "loadImage",
"Loading image: " + imageName);
// Try to load image out of classpath before trying an absolute filename
URL url = getClass().getResource(imageName);
Image img;
if (url != null)
img = Toolkit.getDefaultToolkit().getImage(url);
else
img = Toolkit.getDefaultToolkit().getImage(imageName);
if (img != null)
{
// Wait for image to load
try
{
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(img, 1);
tracker.waitForAll();
prepareImage(img, this);
result = new BufferedImage(img.getWidth(this), img.getHeight(this),
BufferedImage.TYPE_INT_RGB);
result.createGraphics().drawImage(img, 0, 0, this);
}
catch (InterruptedException e)
{
}
catch (IllegalArgumentException e)
{
}
}
if (result == null)
{
logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "loadBufferedImage",
"Could not locate image resource in class path: "
+ imageName);
}
return result;
}
/**
* Executes the test methods.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
void runTestSet(Graphics2D g, Dimension size)
{
// Any user-specified options (ie set transforms, rendering hints)
prepareGraphics((Graphics2D) g);
if ((awtTests & J2DTEST_ARC) != 0)
{
test_drawArc(g, size);
test_fillArc(g, size);
}
if ((awtTests & J2DTEST_CUBICCURVE) != 0)
{
test_drawCubicCurve(g, size);
}
if ((awtTests & J2DTEST_ELLIPSE) != 0)
{
test_drawEllipse(g, size);
test_fillEllipse(g, size);
}
if ((awtTests & J2DTEST_GENERALPATH) != 0)
{
// Current implementation doesn't work
test_drawGeneralPath(g, size);
test_fillGeneralPath(g, size);
}
if ((awtTests & J2DTEST_LINE) != 0)
{
test_drawLine(g, size);
}
if ((awtTests & J2DTEST_QUADCURVE) != 0)
{
test_drawQuadCurve(g, size);
}
if ((awtTests & J2DTEST_RECTANGLE) != 0)
{
test_drawRectangle(g, size);
test_fillRectangle(g, size);
}
if ((awtTests & J2DTEST_ROUNDRECTANGLE) != 0)
{
test_drawRoundRectangle(g, size);
test_fillRoundRectangle(g, size);
}
if ((awtTests & J2DTEST_IMAGE) != 0)
{
test_drawImage(g, size);
test_drawTransparentImage(g, size);
}
}
/**
* Reset all graphics settings to the standard, default values
*
* @param g the object to apply settings to
*/
private void resetGraphics(Graphics2D g)
{
g.setTransform(new AffineTransform());
g.setStroke(new BasicStroke());
g.setComposite(AlphaComposite.SrcOut);
}
/**
* Sets initial user graphics options
*
* @param g the object to apply settings to
*/
private void prepareGraphics(Graphics2D g)
{
// Transforms
if (affineTransform != null)
g.setTransform(affineTransform);
else if (xtranslate != 0 || ytranslate != 0 || xshear != 0 || yshear != 0)
{
g.translate(xtranslate, ytranslate);
g.shear(xshear, yshear);
}
if (rotate > 0)
g.rotate(rotate * Math.PI, screenWidth / 2, screenHeight / 2);
// Composite (transparency)
if (composite > 0)
{
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
composite));
}
// Textures
if (texture != null)
g.setPaint(new TexturePaint(textureImage,
new Rectangle(0, 0, textureImage.getWidth(),
textureImage.getHeight())));
// Anti-alias setting
if (antialiasFlag)
g.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON));
else
g.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF));
}
/**
* Gets new random settings
*
* @param g the object to set parameters for
* @param size the screen size
*/
private void setRandom(Graphics2D g, Dimension size)
{
// Set colour / paint
if (gradientFlag)
{
Color c1 = new Color((int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1);
Color c2 = new Color((int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1);
g.setPaint(new GradientPaint(0, 0, c1, screenWidth / 5,
screenHeight / 5, c2, true));
}
else if (texture == null)
g.setPaint(new Color((int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1,
(int) (Math.random() * 254) + 1));
// Set stroke width and options
if (strokeFlag)
{
int cap = (int) (Math.random() * 3 + 1);
if (cap == 1)
cap = BasicStroke.CAP_SQUARE;
else if (cap == 2)
cap = BasicStroke.CAP_BUTT;
else
cap = BasicStroke.CAP_ROUND;
int join = (int) (Math.random() * 3 + 1);
if (join == 1)
join = BasicStroke.JOIN_MITER;
else if (join == 2)
join = BasicStroke.JOIN_BEVEL;
else
join = BasicStroke.JOIN_ROUND;
float[] dashes = { 10, 10 };
g.setStroke(new BasicStroke((int) (Math.random() * 10), cap, join, 10f,
dashes, 0));
}
// Composite / transparency
if (composite == - 1)
{
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
(float) Math.random()));
}
// Transformations
if (rotate == - 1)
g.rotate(Math.random() * Math.PI * 2);
}
/**
* Draws random arcs within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawArc(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize;
long startTime;
long endTime;
minSize = 10;
startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - minSize + 1));
int y = (int) (Math.random() * (size.height - minSize + 1));
int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
int startAngle = (int) (Math.random() * 360);
int arcAngle = (int) (Math.random() * 360 - startAngle);
Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle,
Arc2D.OPEN);
g.draw(arc);
}
endTime = System.currentTimeMillis();
recordTest("draw(Arc2D.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random filled arcs within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_fillArc(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize;
long startTime;
long endTime;
minSize = 10;
startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - minSize + 1));
int y = (int) (Math.random() * (size.height - minSize + 1));
int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
int startAngle = (int) (Math.random() * 360);
int arcAngle = (int) (Math.random() * 360);
Arc2D arc = new Arc2D.Double(x, y, width, height, startAngle, arcAngle,
Arc2D.OPEN);
g.fill(arc);
}
endTime = System.currentTimeMillis();
recordTest("fill(Arc2D.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random cubic curves within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawCubicCurve(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int xc1 = (int) (Math.random() * (size.width - minSize));
int yc1 = (int) (Math.random() * (size.height - minSize));
int xc2 = (int) (Math.random() * (size.width - minSize));
int yc2 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
CubicCurve2D curve = new CubicCurve2D.Double(x1, y1, xc1, yc1, xc2,
yc2, x2, y2);
g.draw(curve);
}
long endTime = System.currentTimeMillis();
recordTest("draw(CubicCurve2D.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random ellipses within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawEllipse(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
Ellipse2D ellipse = new Ellipse2D.Double(x1, y1, x2, y2);
g.draw(ellipse);
}
long endTime = System.currentTimeMillis();
recordTest("draw(Ellipse.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random ellipses within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_fillEllipse(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
Ellipse2D ellipse = new Ellipse2D.Double(x1, y1, x2, y2);
g.fill(ellipse);
}
long endTime = System.currentTimeMillis();
recordTest("fill(Ellipse.Double) " + maxTests + " times",
(endTime - startTime));
}
// TODO: fix the GeneralPath methods.
/**
* Draws random polygons within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawGeneralPath(Graphics2D g, Dimension size)
{
int maxTests = testSize;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int points = (int) (Math.random() * 6) + 2;
GeneralPath shape = new GeneralPath();
shape.moveTo((float) Math.random() * (size.width),
(float) Math.random() * (size.height));
for (int j = 0; j < points; j += 1)
{
shape.lineTo((float) (Math.random() * (size.width)),
(float) (Math.random() * (size.height)));
}
g.draw(shape);
}
long endTime = System.currentTimeMillis();
recordTest("draw(GeneralPath) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random filled polygons within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_fillGeneralPath(Graphics2D g, Dimension size)
{
int maxTests = testSize;
long startTime = System.currentTimeMillis();
GeneralPath shape = new GeneralPath();
shape.moveTo((float) Math.random() * (size.width), (float) Math.random()
* (size.height));
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int points = (int) (Math.random() * 6) + 2;
for (int j = 0; j < points; j += 1)
{
shape.lineTo((float) (Math.random() * (size.width)),
(float) (Math.random() * (size.height)));
}
g.fill(shape);
}
long endTime = System.currentTimeMillis();
recordTest("fill(GeneralPath) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random lines within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawLine(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
Line2D line = new Line2D.Double(x1, y1, x2, y2);
g.draw(line);
}
long endTime = System.currentTimeMillis();
recordTest("draw(Line2D.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random quadratic curves within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawQuadCurve(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int xc = (int) (Math.random() * (size.width - minSize));
int yc = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
QuadCurve2D curve = new QuadCurve2D.Double(x1, y1, xc, yc, x2, y2);
g.draw(curve);
}
long endTime = System.currentTimeMillis();
recordTest("draw(QuadCurve2D.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random rectangles within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawRectangle(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
Rectangle2D rect = new Rectangle2D.Double(x1, y1, x2, y2);
g.draw(rect);
}
long endTime = System.currentTimeMillis();
recordTest("draw(Rectangle.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random rectangles within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_fillRectangle(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize = 10;
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x1 = (int) (Math.random() * (size.width - minSize));
int y1 = (int) (Math.random() * (size.height - minSize));
int x2 = (int) (Math.random() * (size.width - minSize));
int y2 = (int) (Math.random() * (size.height - minSize));
Rectangle2D rect = new Rectangle2D.Double(x1, y1, x2, y2);
g.fill(rect);
}
long endTime = System.currentTimeMillis();
recordTest("fill(Rectangle.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random rounded rectangles within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawRoundRectangle(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize;
long startTime;
long endTime;
minSize = 10;
startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - minSize + 1));
int y = (int) (Math.random() * (size.height - minSize + 1));
int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
int arcWidth = (int) (Math.random() * (width - 1) + 1);
int arcHeight = (int) (Math.random() * (height - 1) + 5);
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
height, arcWidth,
arcHeight);
g.draw(rect);
}
endTime = System.currentTimeMillis();
recordTest("draw(RoundRectangle.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random filled rounded rectangles within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_fillRoundRectangle(Graphics2D g, Dimension size)
{
int maxTests = testSize;
int minSize;
long startTime;
long endTime;
minSize = 10;
startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - minSize + 1));
int y = (int) (Math.random() * (size.height - minSize + 1));
int width = (int) (Math.random() * (size.width - x - minSize) + minSize);
int height = (int) (Math.random() * (size.height - y - minSize) + minSize);
int arcWidth = (int) (Math.random() * (width - 1) + 1);
int arcHeight = (int) (Math.random() * (height - 1) + 5);
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width,
height, arcWidth,
arcHeight);
g.fill(rect);
}
endTime = System.currentTimeMillis();
recordTest("fill(RoundRectangle.Double) " + maxTests + " times",
(endTime - startTime));
}
/**
* Draws random images within the given dimensions.
*
* @param g The Graphics2D object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawImage(Graphics2D g, Dimension size)
{
if (gifTestImage == null)
{
logger.logp(Level.WARNING, "J2dGraphicsBenchmark", "runTestSet",
"Skipping 'test_drawImage' due to missing resource.");
return;
}
int maxTests = testSize / 2;
if (maxTests == 0)
maxTests = 1;
int imageWidth = gifTestImage.getWidth(this);
int imageHeight = gifTestImage.getHeight(this);
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - imageWidth + 1));
int y = (int) (Math.random() * (size.height - imageHeight + 1));
g.drawImage(gifTestImage, x, y, this);
}
long endTime = System.currentTimeMillis();
recordTest("drawImage " + maxTests + " times", (endTime - startTime));
}
/**
* Draws random transparent images within the given dimensions.
*
* @param g The Graphics object that is used to paint.
* @param size The size of the canvas.
*/
private void test_drawTransparentImage(Graphics2D g, Dimension size)
{
if (pngTestImage == null)
{
logger.logp(Level.WARNING, "AicasGraphicsBenchmark", "runTestSet",
"Skipping 'drawTransparentImage' due to missing resource.");
return;
}
int maxTests = testSize / 5;
if (maxTests == 0)
maxTests = 1;
int imageWidth = pngTestImage.getWidth(this);
int imageHeight = pngTestImage.getHeight(this);
long startTime = System.currentTimeMillis();
for (int i = 0; i < maxTests; i += 1)
{
setRandom(g, size);
int x = (int) (Math.random() * (size.width - imageWidth + 1));
int y = (int) (Math.random() * (size.height - imageHeight + 1));
g.drawImage(pngTestImage, x, y, this);
}
long endTime = System.currentTimeMillis();
recordTest("draw transparent image " + maxTests + " times",
(endTime - startTime));
}
private class GraphicsTest
extends Canvas
implements Runnable
{
Thread paintThread;
boolean done = false;
boolean doPaint = false;
boolean withClipping = false;
public GraphicsTest()
{
paintThread = new Thread(this);
paintThread.start();
}
public void run()
{
int runCount = 0;
while (! done)
{
runCount++;
try
{
synchronized (this)
{
while (! doPaint)
{
try
{
wait(200);
}
catch (InterruptedException exception)
{
return;
}
}
}
// if (iterations != 0)
// System.out.println("--- run...("
// + runCount
// + "/"
// + iterations
// + ") ------------------------------------------------------");
Graphics g = getGraphics();
Dimension size = getSize();
if (singleBufferFlag)
{
logger.logp(Level.INFO, "J2dGraphicsBenchmark.GraphicsTest",
"run",
"Start testing non-double-buffered drawing");
if (noClippingFlag)
runSet_noClipping((Graphics2D) g, size, runCount);
if (withClippingFlag)
runSet_withClipping((Graphics2D) g, size, runCount);
if (zeroClippingFlag)
runSet_zeroClipping((Graphics2D) g, size, runCount);
g.dispose();
}
if (doubleBufferFlag)
{
logger.logp(Level.INFO, "J2dGraphicsBenchmark.GraphicsTest",
"run", "Start testing double-buffered drawing");
Graphics canvas = getGraphics();
Image doublebuffer = createImage(size.width, size.height);
if (noClippingFlag)
{
g = doublebuffer.getGraphics();
runSet_noClipping((Graphics2D) g, size,
"double buffering", runCount);
g.dispose();
canvas.drawImage(doublebuffer, 0, 0, this);
}
if (withClippingFlag)
{
g = doublebuffer.getGraphics();
runSet_withClipping((Graphics2D) g, size,
"double buffering", runCount);
g.dispose();
canvas.drawImage(doublebuffer, 0, 0, this);
}
if (zeroClippingFlag)
{
g = doublebuffer.getGraphics();
runSet_zeroClipping((Graphics2D) g, size,
"double buffering", runCount);
g.dispose();
canvas.drawImage(doublebuffer, 0, 0, this);
canvas.dispose();
}
}
printReport();
if (iterations != 1)
{
if (iterations != - 1)
iterations--;
}
else
{
// System.out.println("--- done
// --------------------------------------------------------");
synchronized (this)
{
doPaint = false;
}
done = true;
}
}
catch (Error error)
{
System.err.println("Error: " + error);
System.exit(129);
}
}
testComplete();
}
private void runSet_zeroClipping(Graphics2D g, Dimension size, int runCount)
{
runSet_zeroClipping(g, size, "", runCount);
}
private void runSet_zeroClipping(Graphics2D g, Dimension size,
String context, int runCount)
{
int clipped_width;
int clipped_height;
int clipped_x;
int clipped_y;
clipped_width = 0;
clipped_height = 0;
clipped_x = (size.width) / 2;
clipped_y = (size.height) / 2;
// Reset any transforms from past tests
resetGraphics(g);
Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
g.setClip(fullWindow);
g.setPaint(Color.BLACK);
g.fill(fullWindow);
Rectangle windowBorder = new Rectangle(0, 0, size.width - 1,
size.width - 1);
g.setPaint(Color.WHITE);
g.draw(windowBorder);
Rectangle innerBorder = new Rectangle(clipped_x - 1, clipped_y - 1,
clipped_width + 2,
clipped_height + 2);
g.fill(innerBorder);
Rectangle innerBox = new Rectangle(clipped_x, clipped_y, clipped_width,
clipped_height);
g.clip(innerBox);
g.setPaint(Color.BLACK);
g.fill(fullWindow);
if (context.equals(""))
setTestContext("(" + runCount + ") clipping to zero");
else
setTestContext("(" + runCount + ") clipping to zero (" + context + ")");
runTestSet(g, size);
}
private void runSet_withClipping(Graphics2D g, Dimension size, int runCount)
{
runSet_withClipping(g, size, "", runCount);
}
private void runSet_withClipping(Graphics2D g, Dimension size,
String context, int runCount)
{
int clipped_width = 2 * size.width / 3;
int clipped_height = 2 * size.height / 3;
int clipped_x = (size.width - clipped_width) / 2;
int clipped_y = (size.height - clipped_height) / 2;
// Reset any transforms from past tests
resetGraphics(g);
Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
g.setClip(fullWindow);
g.setPaint(Color.BLACK);
g.fill(fullWindow);
Rectangle windowBorder = new Rectangle(0, 0, size.width - 1,
size.height - 1);
g.setPaint(Color.GREEN);
g.draw(windowBorder);
Rectangle innerBorder = new Rectangle(clipped_x - 1, clipped_y - 1,
clipped_width + 2,
clipped_height + 2);
g.setPaint(Color.WHITE);
g.fill(innerBorder);
Rectangle innerBox = new Rectangle(clipped_x, clipped_y, clipped_width,
clipped_height);
g.clip(innerBox);
g.setPaint(Color.BLACK);
g.fill(fullWindow);
if (context.equals(""))
setTestContext("(" + runCount + ") with clipping ");
else
setTestContext("(" + runCount + ") with clipping (" + context + ")");
runTestSet(g, size);
}
private void runSet_noClipping(Graphics2D g, Dimension size, int runCount)
{
runSet_noClipping(g, size, "", runCount);
}
private void runSet_noClipping(Graphics2D g, Dimension size,
String context, int runCount)
{
// Reset any transforms from past tests
resetGraphics(g);
Rectangle fullWindow = new Rectangle(0, 0, size.width, size.height);
g.setPaint(Color.BLACK);
g.fill(fullWindow);
if (context.equals(""))
setTestContext("(" + runCount + ") without clipping");
else
setTestContext("(" + runCount + ") without clipping (" + context + ")");
runTestSet(g, size);
}
public void paint(Graphics g)
{
synchronized (this)
{
doPaint = true;
notify();
}
}
}
}
class TestContext
{
}
class TestSet
{
private Map testsMap = new TreeMap();
public void putTest(String testName, TestRecorder recoder)
{
testsMap.put(testName, recoder);
}
public TestRecorder getTest(String testName)
{
return (TestRecorder) testsMap.get(testName);
}
public Iterator testIterator()
{
return testsMap.keySet().iterator();
}
}
class TestRecorder
{
String test;
long totalTime = 0;
long minTime = Long.MAX_VALUE;
long maxTime = Long.MIN_VALUE;
int runCount = 0;
/**
* @return Returns the maxTime.
*/
public final long getMaxTime()
{
return maxTime;
}
/**
* @return Returns the minTime.
*/
public final long getMinTime()
{
return minTime;
}
/**
* @return Returns the test name.
*/
public final String getTestName()
{
return test;
}
public final long getAverage()
{
return (totalTime / runCount);
}
public TestRecorder(String testName)
{
test = testName;
}
public void addRun(long time)
{
totalTime += time;
if (minTime > time)
minTime = time;
if (maxTime < time)
maxTime = time;
runCount += 1;
}
}