OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [examples/] [gnu/] [classpath/] [examples/] [java2d/] [bench.c] - Blame information for rev 781

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 781 jeremybenn
/* bench.c -- native benchmark for Cairo library (meant to test java2d)
2
   Copyright (C) 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath examples.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA. */
20
 
21
#include "bench.h"
22
#include <math.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <gtk/gtk.h>
27
#include <sys/timeb.h>
28
 
29
G_DEFINE_TYPE (Benchmark, benchmark, GTK_TYPE_DRAWING_AREA);
30
 
31
// Needed for the gtk widget, but not used:
32
static void
33
benchmark_class_init (BenchmarkClass *klass)
34
{
35
}
36
 
37
static void
38
benchmark_init (Benchmark *obj)
39
{
40
}
41
 
42
// The Arc2D's PathIterator uses some transforms, so we condense the required
43
// functionality of AffineTransform
44
static void
45
doTransform (double rx, double ry, double theta, double *cvec)
46
{
47
  // Define identity matrix (corresponds to new AffineTransform())
48
  double m00 = 1;
49
  double m10 = 0;
50
  double m01 = 0;
51
  double m11 = 1;
52
  double m02 = 0;
53
  double m12 = 0;
54
 
55
  // AffineTransform.scale(rx, ry)
56
  m00 = m00 * rx;
57
  m01 = m01 * ry;
58
  m10 = m10 * rx;
59
  m11 = m11 * ry;
60
 
61
  // AffineTransform.rotate(theta)
62
  double c = cos(theta);
63
  double s = sin(theta);
64
  double n00 = m00 *  c + m01 * s;
65
  double n01 = m00 * -s + m01 * c;
66
  double n10 = m10 *  c + m11 * s;
67
  double n11 = m10 * -s + m11 * c;
68
 
69
  m00 = n00;
70
  m01 = n01;
71
  m10 = n10;
72
  m11 = n11;
73
 
74
  // AffineTransform.transform(cvec, 0, cvec, 0, 1)
75
  double dstPts[2];
76
  dstPts[0] = (float) (m00 * cvec[0] + m01 * cvec[1] + m02);
77
  dstPts[1] = (float) (m10 * cvec[0] + m11 * cvec[1] + m12);
78
  cvec[0] = dstPts[0];
79
  cvec[1] = dstPts[1];
80
}
81
 
82
// Place an arc on the cairo path, simulating java2d's Arc2D
83
static void
84
setupArc(cairo_t *cr, GtkWidget *bench, int shift)
85
{
86
  double x, y;
87
 
88
  // Normally passed into the Arc2D constructor
89
  x = bench->allocation.x + (rand() % (bench->allocation.width - minSize + 1));
90
  y = bench->allocation.y + (rand() % (bench->allocation.height - minSize + 1));
91
 
92
  int angle = rand() % 360;
93
  int length = (rand() % 360) - angle;
94
  int width = rand() % (int)((bench->allocation.width - x - 10) + 10);
95
  int height = rand() % (int)((bench->allocation.height - y - 10) + 10);
96
 
97
  // This is from the ArcPath iterator
98
  double start = angle * (M_PI / 180);
99
  double extent = length * (M_PI / 180);
100
 
101
  if (extent < 0)
102
    {
103
      extent = -extent;
104
      start = 2 * M_PI - extent + start;
105
    }
106
 
107
  int limit;
108
  if (width < 0 || height < 0)  // We assume type == 0; ie, Arc2D.OPEN
109
    limit = -1;
110
  else if (extent == 0)
111
    limit = 0;
112
  else if (extent <= M_PI / 2.0)
113
    limit = 1;
114
  else if (extent <= M_PI)
115
    limit = 2;
116
  else if (extent <= 3.0 * (M_PI / 2.0))
117
    limit = 3;
118
  else
119
    limit = 4;
120
 
121
  // This is from CairoGraphics2D.walkPath
122
  double xnew = 0;
123
  double ynew = 0;
124
  double coords[6];
125
 
126
  cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
127
  cairo_set_fill_rule(cr, cfillrule);
128
 
129
  // First iteration will move to the starting point
130
  double rx = width / 2;
131
  double ry = height / 2;
132
  double xmid = x + rx;
133
  double ymid = y + ry;
134
  coords[0] = xmid + rx * cos(start);
135
  coords[1] = ymid - ry * sin(start);
136
 
137
  if (shift == 1)
138
    {
139
      xnew = floor(coords[0]) + 0.5;
140
      ynew = floor(coords[1]) + 0.5;
141
    }
142
  else
143
    {
144
      xnew = coords[0];
145
      ynew = coords[1];
146
    }
147
 
148
  cairo_move_to(cr, xnew, ynew);
149
 
150
  // Iterate through segments of the arc  
151
  int current;
152
  for (current = 1; current <= limit; current++)
153
    {
154
      // Back to the ArcPath iterator's getCurrent
155
      double kappa = (sqrt(2.0) - 1.0) * (4.0 / 3.0);
156
      double quad = (M_PI / 2.0);
157
 
158
      double curr_begin = start + (current - 1) * quad;
159
      double curr_extent;
160
 
161
      if (start + extent - curr_begin < quad)
162
        curr_extent = (start + extent) - curr_begin;
163
      else
164
        curr_extent = quad;
165
 
166
      double portion_of_a_quadrant = curr_extent / quad;
167
 
168
      double x0 = xmid + rx * cos(curr_begin);
169
      double y0 = ymid - ry * sin(curr_begin);
170
 
171
      double x1 = xmid + rx * cos(curr_begin + curr_extent);
172
      double y1 = ymid - ry * sin(curr_begin + curr_extent);
173
 
174
      double cvec[2];
175
      double len = kappa * portion_of_a_quadrant;
176
      double angle = curr_begin;
177
 
178
      cvec[0] = 0;
179
      cvec[1] = len;
180
      doTransform(rx, ry, angle, cvec);
181
      coords[0] = x0 + cvec[0];
182
      coords[1] = y0 - cvec[1];
183
 
184
      cvec[0] = 0;
185
      cvec[1] = -len;
186
      doTransform(rx, ry, angle, cvec);
187
      doTransform(1, 1, curr_extent, cvec);
188
      coords[2] = x1 + cvec[0];
189
      coords[3] = y1 - cvec[1];
190
 
191
      coords[4] = x1;
192
      coords[5] = y1;
193
 
194
      // draw it, from CairoGraphics2D.walkPath
195
      if (shift == 1)
196
        {
197
          xnew = floor(coords[4]) + 0.5;
198
          ynew = floor(coords[5]) + 0.5;
199
          cairo_curve_to(cr, floor(coords[0]) + 0.5, floor(coords[1]) + 0.5,
200
                         floor(coords[2]) + 0.5, floor(coords[3]) + 0.5,
201
                         xnew, ynew);
202
        }
203
      else
204
        {
205
          xnew = coords[4];
206
          ynew = coords[5];
207
          cairo_curve_to(cr, coords[0], coords[1], coords[2],
208
                         coords[3], xnew, ynew);
209
        }
210
    }
211
 
212
  // Randomize the colour, just for asthetics =)
213
  cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
214
                       (rand() % 100 / (float)100),
215
                       (rand() % 100 / (float)100));
216
 
217
}
218
 
219
// Place a beizer curve on the cairo path, simulating java2d's CubicCurve2D
220
static void
221
setupCurve(cairo_t *cr, GtkWidget *bench, int shift)
222
{
223
  // These are options when creating a new curve
224
  int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
225
  int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
226
  int xc1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
227
  int yc1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
228
  int xc2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
229
  int yc2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
230
  int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
231
  int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
232
 
233
  // From CairoGraphics2D.walkPath
234
  double xnew = 0;
235
  double ynew = 0;
236
  double coords[6];
237
 
238
  cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
239
  cairo_set_fill_rule(cr, cfillrule);
240
 
241
  // And into CubicCurve's PathIterator...
242
  // start by moving to the starting coordinate
243
  coords[0] = (float) x1;
244
  coords[1] = (float) y1;
245
 
246
  if (shift == 1)
247
    {
248
      xnew = floor(coords[0]) + 0.5;
249
      ynew = floor(coords[1]) + 0.5;
250
    }
251
  else
252
    {
253
      xnew = coords[0];
254
      ynew = coords[1];
255
    }
256
 
257
  cairo_move_to(cr, xnew, ynew);
258
 
259
  // Now the curve itself
260
  coords[0] = (float) xc1;
261
  coords[1] = (float) yc1;
262
  coords[2] = (float) xc2;
263
  coords[3] = (float) yc2;
264
  coords[4] = (float) x2;
265
  coords[5] = (float) y2;
266
 
267
  if (shift == 1)
268
    {
269
      xnew = floor(coords[4]) + 0.5;
270
      ynew = floor(coords[5]) + 0.5;
271
      cairo_curve_to(cr, floor(coords[0]) + 0.5, floor(coords[1]) + 0.5,
272
                     floor(coords[2]) + 0.5, floor(coords[3]) + 0.5,
273
                     xnew, ynew);
274
    }
275
  else
276
    {
277
      xnew = coords[4];
278
      ynew = coords[5];
279
      cairo_curve_to(cr, coords[0], coords[1], coords[2],
280
                     coords[3], xnew, ynew);
281
    }
282
 
283
  // Randomize colour for asthetics
284
  cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
285
                       (rand() % 100 / (float)100),
286
                       (rand() % 100 / (float)100));
287
}
288
 
289
// Place a line on the cairo path, simulating java2d's Line2D
290
static void
291
setupLine(cairo_t *cr, GtkWidget *bench, int shift)
292
{
293
  // These are set when you create a line
294
  int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
295
  int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
296
  int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
297
  int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
298
 
299
  // This is from CairoGraphics2D.walkPath
300
  double xnew = 0;
301
  double ynew = 0;
302
  double coords[6];
303
 
304
  cairo_fill_rule_t cfillrule = CAIRO_FILL_RULE_WINDING;
305
  cairo_set_fill_rule(cr, cfillrule);
306
 
307
  // And into Line2D's PathIterator
308
  coords[0] = (float) x1;
309
  coords[1] = (float) y1;
310
 
311
  if (shift == 1)
312
    {
313
      xnew = floor(coords[0]) + 0.5;
314
      ynew = floor(coords[1]) + 0.5;
315
    }
316
  else
317
    {
318
      xnew = coords[0];
319
      ynew = coords[1];
320
    }
321
 
322
  cairo_move_to(cr, xnew, ynew);
323
 
324
  coords[0] = (float) x2;
325
  coords[1] = (float) y2;
326
 
327
  if (shift == 1)
328
    {
329
      xnew = floor(coords[0]) + 0.5;
330
      ynew = floor(coords[1]) + 0.5;
331
    }
332
  else
333
    {
334
      xnew = coords[0];
335
      ynew = coords[1];
336
    }
337
 
338
  cairo_line_to(cr, xnew, ynew);
339
 
340
  // Randomize colour for asthetics
341
  cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
342
                       (rand() % 100 / (float)100),
343
                       (rand() % 100 / (float)100));
344
}
345
 
346
// Place a rectangle on the cairo path, simulating java2d's Rectangle2D
347
static void
348
setupRect(cairo_t *cr, GtkWidget *bench, int shift)
349
{
350
  // These are set when you create a rectangle
351
  int x1 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
352
  int y1 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
353
  int x2 = bench->allocation.x + (rand() % (bench->allocation.width - minSize));
354
  int y2 = bench->allocation.y + (rand() % (bench->allocation.height - minSize));
355
 
356
  // draw() and fill() have been optimized to ignore the PathIterator.
357
  // We do the same here.
358
  double xnew = 0;
359
  double ynew = 0;
360
 
361
  if (shift == 1)
362
    {
363
      xnew = floor(x1) + 0.5;
364
      ynew = floor(y1) + 0.5;
365
    }
366
  else
367
    {
368
      xnew = x1;
369
      ynew = y1;
370
    }
371
 
372
  cairo_rectangle(cr, x1, y1, x2, y2);
373
 
374
  // Randomize colour for asthetics
375
  cairo_set_source_rgb(cr, (rand() % 100 / (float)100),
376
                       (rand() % 100 / (float)100),
377
                       (rand() % 100 / (float)100));
378
}
379
 
380
// The real work gets done here: this function is called when the widget
381
// is drawn on screen.
382
static void
383
draw (GtkWidget *bench, cairo_t *cr)
384
{
385
  // Setup
386
  struct timeb t1, t2;
387
  int i, timeElapsed;
388
 
389
  cairo_set_line_width(cr, lineWidth);
390
 
391
  if (antialias == 0)
392
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
393
  else
394
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_GRAY);
395
 
396
  // Tell the user what's going on
397
  printf("Testing native cairo drawing..\n");
398
  printf("  Screen size is %d x %d \n", screenWidth, screenHeight);
399
  printf("  Line width is %d\n", lineWidth);
400
  printf("  Test size: %d\n", testSize);
401
 
402
  if (antialias == 0)
403
    printf("  Anti-alias is off\n");
404
  else
405
    printf("  Anti-alias is on\n");
406
 
407
  printf("\n");
408
  fflush(stdout);
409
 
410
  // Draw & fill Arc
411
  if (arcTest == 1)
412
    {
413
      // Draw
414
      ftime(&t1);
415
      for (i = 0; i < testSize; i++)
416
        {
417
          setupArc(cr, bench, 1);
418
          cairo_stroke (cr);
419
        }
420
 
421
      ftime(&t2);
422
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
423
      printf("Draw arc: %d ms\n", timeElapsed);
424
      fflush(stdout);
425
 
426
      // Fill
427
      ftime(&t1);
428
      for (i = 0; i < testSize; i++)
429
        {
430
          setupArc(cr, bench, 0);
431
          cairo_fill (cr);
432
        }
433
 
434
      ftime(&t2);
435
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
436
      printf("Fill arc: %d ms\n", timeElapsed);
437
    }
438
 
439
  // Draw cubic curve
440
  if (curveTest == 1)
441
    {
442
      ftime(&t1);
443
      for (i = 0; i < testSize; i++)
444
        {
445
          setupCurve(cr, bench, 1);
446
          cairo_stroke (cr);
447
        }
448
 
449
      ftime(&t2);
450
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
451
      printf("Draw cubic curve: %d ms\n", timeElapsed);
452
    }
453
 
454
  // Ellipse: skip; this is just a special case of arc
455
  // General path: skip; this doesn't even work in java2d
456
 
457
  // Draw Line
458
  if (lineTest == 1)
459
    {
460
      ftime(&t1);
461
      for (i = 0; i < testSize; i++)
462
        {
463
          setupLine(cr, bench, 1);
464
          cairo_stroke (cr);
465
        }
466
 
467
      ftime(&t2);
468
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
469
      printf("Draw line: %d ms\n", timeElapsed);
470
    }
471
 
472
  // Draw & fill Rectangle
473
  if (rectTest == 1)
474
    {
475
      // Draw
476
      ftime(&t1);
477
      for (i = 0; i < testSize; i++)
478
        {
479
          setupRect(cr, bench, 1);
480
          cairo_stroke (cr);
481
        }
482
 
483
      ftime(&t2);
484
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
485
      printf("Draw rectangle: %d ms\n", timeElapsed);
486
 
487
      // Fill
488
      ftime(&t1);
489
      for (i = 0; i < testSize; i++)
490
        {
491
          setupRect(cr, bench, 0);
492
          cairo_fill (cr);
493
        }
494
 
495
      ftime(&t2);
496
      timeElapsed = 1000 * (t2.time - t1.time) + (t2.millitm - t1.millitm);
497
      printf("Fill rectangle: %d ms\n", timeElapsed);
498
    }
499
 
500
  // Round rectangle: skip, it's just a combination of lines and curves
501
  // Image: skip?
502
 
503
  printf("\n");
504
}
505
 
506
GtkWidget *
507
benchmark_new (void)
508
{
509
  return g_object_new (BENCHMARK_TYPE, NULL);
510
}
511
 
512
int
513
main (int argc, char **argv)
514
{
515
  // Set defaults
516
  minSize = 10;
517
  arcTest = 0;
518
  curveTest = 0;
519
  lineTest = 0;
520
  rectTest = 0;
521
  screenWidth = 320;
522
  screenHeight = 240;
523
  testSize = 1000;
524
  antialias = 0;
525
  lineWidth = 1;
526
 
527
  // Process any command-line user options
528
  int i;
529
  for (i = 1; i < argc; i++)
530
    {
531
      // Process options first
532
      if (!strcmp(argv[i], "-a"))
533
        antialias = 1;
534
      else if (!strcmp(argv[i], "-h"))
535
        screenHeight = atoi(argv[++i]);
536
      else if (!strcmp(argv[i], "-l"))
537
        lineWidth = atoi(argv[++i]);
538
      else if (!strcmp(argv[i], "-t"))
539
        testSize = atoi(argv[++i]);
540
      else if (!strcmp(argv[i], "-w"))
541
        screenWidth = atoi(argv[++i]);
542
      else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--h")
543
               || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help"))
544
        {
545
          printf("Cairo benchmarker, meant to measure JNI overhead\n");
546
          printf("Usage: bench [-a] [-h height] [-t test size] [-w width] [tests...]\n");
547
          printf("\n");
548
          printf("  Valid options: -a   turn on anti-aliasing (default off)\n");
549
          printf("                 -h   set screen height (default 240)\n");
550
          printf("                 -l   set stroke line width (default 1)\n");
551
          printf("                 -t   set test size (default 1000)\n");
552
          printf("                 -w   set screen width (default 320)\n");
553
          printf("                 -h | --help\n");
554
          printf("  Valid tests: arc\n");
555
          printf("               curve\n");
556
          printf("               line\n");
557
          printf("               rect\n");
558
          printf("               (default: run all)\n");
559
          exit (0);
560
        }
561
 
562
      // Process tests
563
      else if (!strcmp(argv[i], "arc"))
564
        arcTest = 1;
565
      else if (!strcmp(argv[i], "curve"))
566
        curveTest = 1;
567
      else if (!strcmp(argv[i], "line"))
568
        lineTest = 1;
569
      else if (!strcmp(argv[i], "rect"))
570
        rectTest = 1;
571
    }
572
 
573
  // If no tests were specified, we default to running all of them
574
  if (arcTest == 0 && curveTest == 0 && lineTest == 0 && rectTest == 0)
575
    {
576
      arcTest = 1;
577
      curveTest = 1;
578
      lineTest = 1;
579
      rectTest = 1;
580
    }
581
 
582
  // Set up gtk widget
583
  GtkWidget *window, *bench;
584
  gtk_init (&argc, &argv);
585
 
586
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
587
  gtk_window_resize(GTK_WINDOW(window), screenWidth, screenHeight);
588
  gtk_window_set_title(GTK_WINDOW(window), "cairo benchmark");
589
 
590
  // Set up benchmkar and cairo surface
591
  bench = benchmark_new ();
592
  gtk_container_add (GTK_CONTAINER (window), bench);
593
  gtk_widget_show_all (window);
594
 
595
  cairo_t *cr;
596
  cr = gdk_cairo_create (bench->window);
597
 
598
  // Run tests
599
  draw (bench, cr);
600
 
601
  // Hold output on screen until user exits.
602
  printf("Press any key to exit.\n");
603
  getchar();
604
  exit(0);
605
gtk_main();
606
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.