aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c')
-rw-r--r--gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c606
1 files changed, 606 insertions, 0 deletions
diff --git a/gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c b/gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c
new file mode 100644
index 000000000..e5b45aa1c
--- /dev/null
+++ b/gcc-4.4.3/libjava/classpath/examples/gnu/classpath/examples/java2d/bench.c
@@ -0,0 +1,606 @@
+/* bench.c -- native benchmark for Cairo library (meant to test java2d)
+ 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. */
+
+#include "bench.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <sys/timeb.h>
+
+G_DEFINE_TYPE (Benchmark, benchmark, GTK_TYPE_DRAWING_AREA);
+
+// Needed for the gtk widget, but not used:
+static void
+benchmark_class_init (BenchmarkClass *klass)
+{
+}
+
+static void
+benchmark_init (Benchmark *obj)
+{
+}
+
+// The Arc2D's PathIterator uses some transforms, so we condense the required
+// functionality of AffineTransform
+static void
+doTransform (double rx, double ry, double theta, double *cvec)
+{
+ // Define identity matrix (corresponds to new AffineTransform())
+ double m00 = 1;
+ double m10 = 0;
+ double m01 = 0;
+ double m11 = 1;
+ double m02 = 0;
+ double m12 = 0;
+
+ // AffineTransform.scale(rx, ry)
+ m00 = m00 * rx;
+ m01 = m01 * ry;
+ m10 = m10 * rx;
+ m11 = m11 * ry;
+
+ // AffineTransform.rotate(theta)
+ double c = cos(theta);
+ double s = sin(theta);
+ double n00 = m00 * c + m01 * s;
+ double n01 = m00 * -s + m01 * c;
+ double n10 = m10 * c + m11 * s;
+ double n11 = m10 * -s + m11 * c;
+
+ m00 = n00;
+ m01 = n01;
+ m10 = n10;
+ m11 = n11;
+
+ // AffineTransform.transform(cvec, 0, cvec, 0, 1)
+ double dstPts[2];
+ dstPts[0] = (float) (m00 * cvec[0] + m01 * cvec[1] + m02);
+ dstPts[1] = (float) (m10 * cvec[0] + m11 * cvec[1] + m12);
+ cvec[0] = dstPts[0];
+ cvec[1] = dstPts[1];
+}
+
+// Place an arc on the cairo path, simulating java2d's Arc2D
+static void
+setupArc(cairo_t *cr, GtkWidget *bench, int shift)
+{
+ double x, y;
+
+ // Normally passed into the Arc2D constructor
+ x = bench->allocation.x + (rand() % (bench->allocation.width - minSize + 1));
+ y = bench->allocation.y + (rand() % (bench->allocation.height - minSize + 1));
+
+ int angle = rand() % 360;
+ int length = (rand() % 360) - angle;
+ int width = rand() % (int)((bench->allocation.width - x - 10) + 10);
+ int height = rand() % (int)((bench->allocation.height - y - 10) + 10);
+
+ // This is from the ArcPath iterator
+ double start = angle * (M_PI / 180);
+ double extent = length * (M_PI / 180);
+
+ if (extent < 0)
+ {
+ extent = -extent;
+ start = 2 * M_PI - extent + start;
+ }
+
+ int limit;
+ if (width < 0 || height < 0) // We assume type == 0; ie, Arc2D.OPEN
+ limit = -1;
+ else if (extent == 0)
+ limit = 0;
+ else if (extent <= M_PI / 2.0)
+ limit = 1;
+ else if (extent <= M_PI)
+ limit = 2;
+ else if (extent <= 3.0 * (M_PI / 2.0))
+ limit = 3;
+ else
+ limit = 4;
+
+ // This is from CairoGraphics2D.walkPath
+ double xnew = 0;
+ double ynew = 0;
+ double coords[6];
+
+ cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
+ cairo_set_fill_rule(cr, cfillrule);
+
+ // First iteration will move to the starting point
+ double rx = width / 2;
+ double ry = height / 2;
+ double xmid = x + rx;
+ double ymid = y + ry;
+ coords[0] = xmid + rx * cos(start);
+ coords[1] = ymid - ry * sin(start);
+
+ if (shift == 1)
+ {
+ xnew = floor(coords[0]) + 0.5;
+ ynew = floor(coords[1]) + 0.5;
+ }
+ else
+ {
+ xnew = coords[0];
+ ynew = coords[1];
+ }
+
+ cairo_move_to(cr, xnew, ynew);
+
+ // Iterate through segments of the arc
+ int current;
+ for (current = 1; current <= limit; current++)
+ {
+ // Back to the ArcPath iterator's getCurrent
+ double kappa = (sqrt(2.0) - 1.0) * (4.0 / 3.0);
+ double quad = (M_PI / 2.0);
+
+ double curr_begin = start + (current - 1) * quad;
+ double curr_extent;
+
+ if (start + extent - curr_begin < quad)
+ curr_extent = (start + extent) - curr_begin;
+ else
+ curr_extent = quad;
+
+ double portion_of_a_quadrant = curr_extent / quad;
+
+ double x0 = xmid + rx * cos(curr_begin);
+ double y0 = ymid - ry * sin(curr_begin);
+
+ double x1 = xmid + rx * cos(curr_begin + curr_extent);
+ double y1 = ymid - ry * sin(curr_begin + curr_extent);
+
+ double cvec[2];
+ double len = kappa * portion_of_a_quadrant;
+ double angle = curr_begin;
+
+ cvec[0] = 0;
+ cvec[1] = len;
+ doTransform(rx, ry, angle, cvec);
+ coords[0] = x0 + cvec[0];
+ coords[1] = y0 - cvec[1];
+
+ cvec[0] = 0;
+ cvec[1] = -len;
+ doTransform(rx, ry, angle, cvec);
+ doTransform(1, 1, curr_extent, cvec);
+ coords[2] = x1 + cvec[0];
+ coords[3] = y1 - cvec[1];
+
+ coords[4] = x1;
+ coords[5] = y1;
+
+ // draw it, from CairoGraphics2D.walkPath
+ if (shift == 1)
+ {
+ xnew = floor(coords[4]) + 0.5;
+ ynew = floor(coords[5]) + 0.5;
+ cairo_curve_to(cr, floor(coords[0]) + 0.5, floor(coords[1]) + 0.5,
+ floor(coords[2]) + 0.5, floor(coords[3]) + 0.5,
+ xnew, ynew);
+ }
+ else
+ {
+ xnew = coords[4];
+ ynew = coords[5];
+ cairo_curve_to(cr, coords[0], coords[1], coords[2],
+ coords[3], xnew, ynew);
+ }
+ }
+
+ // Randomize the colour, just for asthetics =)
+ cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100));
+
+}
+
+// Place a beizer curve on the cairo path, simulating java2d's CubicCurve2D
+static void
+setupCurve(cairo_t *cr, GtkWidget *bench, int shift)
+{
+ // These are options when creating a new curve
+ int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+ int xc1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int yc1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+ int xc2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int yc2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+ int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+
+ // From CairoGraphics2D.walkPath
+ double xnew = 0;
+ double ynew = 0;
+ double coords[6];
+
+ cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
+ cairo_set_fill_rule(cr, cfillrule);
+
+ // And into CubicCurve's PathIterator...
+ // start by moving to the starting coordinate
+ coords[0] = (float) x1;
+ coords[1] = (float) y1;
+
+ if (shift == 1)
+ {
+ xnew = floor(coords[0]) + 0.5;
+ ynew = floor(coords[1]) + 0.5;
+ }
+ else
+ {
+ xnew = coords[0];
+ ynew = coords[1];
+ }
+
+ cairo_move_to(cr, xnew, ynew);
+
+ // Now the curve itself
+ coords[0] = (float) xc1;
+ coords[1] = (float) yc1;
+ coords[2] = (float) xc2;
+ coords[3] = (float) yc2;
+ coords[4] = (float) x2;
+ coords[5] = (float) y2;
+
+ if (shift == 1)
+ {
+ xnew = floor(coords[4]) + 0.5;
+ ynew = floor(coords[5]) + 0.5;
+ cairo_curve_to(cr, floor(coords[0]) + 0.5, floor(coords[1]) + 0.5,
+ floor(coords[2]) + 0.5, floor(coords[3]) + 0.5,
+ xnew, ynew);
+ }
+ else
+ {
+ xnew = coords[4];
+ ynew = coords[5];
+ cairo_curve_to(cr, coords[0], coords[1], coords[2],
+ coords[3], xnew, ynew);
+ }
+
+ // Randomize colour for asthetics
+ cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100));
+}
+
+// Place a line on the cairo path, simulating java2d's Line2D
+static void
+setupLine(cairo_t *cr, GtkWidget *bench, int shift)
+{
+ // These are set when you create a line
+ int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+ int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+
+ // This is from CairoGraphics2D.walkPath
+ double xnew = 0;
+ double ynew = 0;
+ double coords[6];
+
+ cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
+ cairo_set_fill_rule(cr, cfillrule);
+
+ // And into Line2D's PathIterator
+ coords[0] = (float) x1;
+ coords[1] = (float) y1;
+
+ if (shift == 1)
+ {
+ xnew = floor(coords[0]) + 0.5;
+ ynew = floor(coords[1]) + 0.5;
+ }
+ else
+ {
+ xnew = coords[0];
+ ynew = coords[1];
+ }
+
+ cairo_move_to(cr, xnew, ynew);
+
+ coords[0] = (float) x2;
+ coords[1] = (float) y2;
+
+ if (shift == 1)
+ {
+ xnew = floor(coords[0]) + 0.5;
+ ynew = floor(coords[1]) + 0.5;
+ }
+ else
+ {
+ xnew = coords[0];
+ ynew = coords[1];
+ }
+
+ cairo_line_to(cr, xnew, ynew);
+
+ // Randomize colour for asthetics
+ cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100));
+}
+
+// Place a rectangle on the cairo path, simulating java2d's Rectangle2D
+static void
+setupRect(cairo_t *cr, GtkWidget *bench, int shift)
+{
+ // These are set when you create a rectangle
+ int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+ int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
+ int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
+
+ // draw() and fill() have been optimized to ignore the PathIterator.
+ // We do the same here.
+ double xnew = 0;
+ double ynew = 0;
+
+ if (shift == 1)
+ {
+ xnew = floor(x1) + 0.5;
+ ynew = floor(y1) + 0.5;
+ }
+ else
+ {
+ xnew = x1;
+ ynew = y1;
+ }
+
+ cairo_rectangle(cr, x1, y1, x2, y2);
+
+ // Randomize colour for asthetics
+ cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100),
+ (rand() % 100 / (float)100));
+}
+
+// The real work gets done here: this function is called when the widget
+// is drawn on screen.
+static void
+draw (GtkWidget *bench, cairo_t *cr)
+{
+ // Setup
+ struct timeb t1, t2;
+ int i, timeElapsed;
+
+ cairo_set_line_width(cr, lineWidth);
+
+ if (antialias == 0)
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ else
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_GRAY);
+
+ // Tell the user what's going on
+ printf("Testing native cairo drawing..\n");
+ printf(" Screen size is %d x %d \n", screenWidth, screenHeight);
+ printf(" Line width is %d\n", lineWidth);
+ printf(" Test size: %d\n", testSize);
+
+ if (antialias == 0)
+ printf(" Anti-alias is off\n");
+ else
+ printf(" Anti-alias is on\n");
+
+ printf("\n");
+ fflush(stdout);
+
+ // Draw & fill Arc
+ if (arcTest == 1)
+ {
+ // Draw
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupArc(cr, bench, 1);
+ cairo_stroke (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Draw arc: %d ms\n", timeElapsed);
+ fflush(stdout);
+
+ // Fill
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupArc(cr, bench, 0);
+ cairo_fill (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Fill arc: %d ms\n", timeElapsed);
+ }
+
+ // Draw cubic curve
+ if (curveTest == 1)
+ {
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupCurve(cr, bench, 1);
+ cairo_stroke (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Draw cubic curve: %d ms\n", timeElapsed);
+ }
+
+ // Ellipse: skip; this is just a special case of arc
+ // General path: skip; this doesn't even work in java2d
+
+ // Draw Line
+ if (lineTest == 1)
+ {
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupLine(cr, bench, 1);
+ cairo_stroke (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Draw line: %d ms\n", timeElapsed);
+ }
+
+ // Draw & fill Rectangle
+ if (rectTest == 1)
+ {
+ // Draw
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupRect(cr, bench, 1);
+ cairo_stroke (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Draw rectangle: %d ms\n", timeElapsed);
+
+ // Fill
+ ftime(&t1);
+ for (i = 0; i < testSize; i++)
+ {
+ setupRect(cr, bench, 0);
+ cairo_fill (cr);
+ }
+
+ ftime(&t2);
+ timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
+ printf("Fill rectangle: %d ms\n", timeElapsed);
+ }
+
+ // Round rectangle: skip, it's just a combination of lines and curves
+ // Image: skip?
+
+ printf("\n");
+}
+
+GtkWidget *
+benchmark_new (void)
+{
+ return g_object_new (BENCHMARK_TYPE, NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+ // Set defaults
+ minSize = 10;
+ arcTest = 0;
+ curveTest = 0;
+ lineTest = 0;
+ rectTest = 0;
+ screenWidth = 320;
+ screenHeight = 240;
+ testSize = 1000;
+ antialias = 0;
+ lineWidth = 1;
+
+ // Process any command-line user options
+ int i;
+ for (i = 1; i < argc; i++)
+ {
+ // Process options first
+ if (!strcmp(argv[i], "-a"))
+ antialias = 1;
+ else if (!strcmp(argv[i], "-h"))
+ screenHeight = atoi(argv[++i]);
+ else if (!strcmp(argv[i], "-l"))
+ lineWidth = atoi(argv[++i]);
+ else if (!strcmp(argv[i], "-t"))
+ testSize = atoi(argv[++i]);
+ else if (!strcmp(argv[i], "-w"))
+ screenWidth = atoi(argv[++i]);
+ else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--h")
+ || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help"))
+ {
+ printf("Cairo benchmarker, meant to measure JNI overhead\n");
+ printf("Usage: bench [-a] [-h height] [-t test size] [-w width] [tests...]\n");
+ printf("\n");
+ printf(" Valid options: -a turn on anti-aliasing (default off)\n");
+ printf(" -h set screen height (default 240)\n");
+ printf(" -l set stroke line width (default 1)\n");
+ printf(" -t set test size (default 1000)\n");
+ printf(" -w set screen width (default 320)\n");
+ printf(" -h | --help\n");
+ printf(" Valid tests: arc\n");
+ printf(" curve\n");
+ printf(" line\n");
+ printf(" rect\n");
+ printf(" (default: run all)\n");
+ exit (0);
+ }
+
+ // Process tests
+ else if (!strcmp(argv[i], "arc"))
+ arcTest = 1;
+ else if (!strcmp(argv[i], "curve"))
+ curveTest = 1;
+ else if (!strcmp(argv[i], "line"))
+ lineTest = 1;
+ else if (!strcmp(argv[i], "rect"))
+ rectTest = 1;
+ }
+
+ // If no tests were specified, we default to running all of them
+ if (arcTest == 0 && curveTest == 0 && lineTest == 0 && rectTest == 0)
+ {
+ arcTest = 1;
+ curveTest = 1;
+ lineTest = 1;
+ rectTest = 1;
+ }
+
+ // Set up gtk widget
+ GtkWidget *window, *bench;
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_resize(GTK_WINDOW(window), screenWidth, screenHeight);
+ gtk_window_set_title(GTK_WINDOW(window), "cairo benchmark");
+
+ // Set up benchmkar and cairo surface
+ bench = benchmark_new ();
+ gtk_container_add (GTK_CONTAINER (window), bench);
+ gtk_widget_show_all (window);
+
+ cairo_t *cr;
+ cr = gdk_cairo_create (bench->window);
+
+ // Run tests
+ draw (bench, cr);
+
+ // Hold output on screen until user exits.
+ printf("Press any key to exit.\n");
+ getchar();
+ exit(0);
+gtk_main();
+}