diff --git a/perf/Makefile.am b/perf/Makefile.am index 7e53420df..0d5f2446a 100644 --- a/perf/Makefile.am +++ b/perf/Makefile.am @@ -21,6 +21,7 @@ cairo_perf_SOURCES = \ cairo-stats.h \ box-outline.c \ fill.c \ + long-lines.c \ paint.c \ stroke.c \ subimage_copy.c \ diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index 1b6363550..0708ed952 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -327,5 +327,6 @@ cairo_perf_case_t perf_cases[] = { { world_map, 800, 800}, { box_outline, 100, 100}, { mosaic, 800, 800 }, + { long_lines, 100, 100}, { NULL } }; diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h index bf56e8b4d..2bfd66519 100644 --- a/perf/cairo-perf.h +++ b/perf/cairo-perf.h @@ -103,5 +103,6 @@ CAIRO_PERF_DECL (zrusin); CAIRO_PERF_DECL (world_map); CAIRO_PERF_DECL (box_outline); CAIRO_PERF_DECL (mosaic); +CAIRO_PERF_DECL (long_lines); #endif diff --git a/perf/long-lines.c b/perf/long-lines.c new file mode 100644 index 000000000..62e8e16f9 --- /dev/null +++ b/perf/long-lines.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2006 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Carl D. Worth + */ + +#include "cairo-perf.h" + +/* This test case is designed to illustrate a performance bug in + * drawing very long lines, where most of the line is out of bounds of + * the destination surface, (but some portion of the line is + * visibile). These results are in the "long-lines-uncropped" report. + * + * For comparison, this test also renders the visible portions of the + * same lines, (this is the "long-lines-cropped" report). + */ + +typedef enum { LONG_LINES_UNCROPPED, LONG_LINES_CROPPED } long_lines_crop_t; +#define NUM_LINES 20 +#define LONG_FACTOR 50.0 + +static cairo_perf_ticks_t +do_long_lines (cairo_t *cr, int width, int height, long_lines_crop_t crop) +{ + int i; + double x, y, dx, dy, min_x, min_y, max_x, max_y; + double outer_width, outer_height; + + cairo_save (cr); + + cairo_translate (cr, width / 2, height / 2); + + if (crop == LONG_LINES_UNCROPPED) { + outer_width = LONG_FACTOR * width; + outer_height = LONG_FACTOR * height; + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* red */ + } else { + outer_width = width; + outer_height = height; + cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); /* green */ + } + + min_x = x = - outer_width / 2.0; + min_y = y = - outer_height / 2.0; + max_x = outer_width / 2.0; + max_y = outer_width / 2.0; + dx = outer_width / NUM_LINES; + dy = outer_height / NUM_LINES; + + cairo_perf_timer_start (); + + for (i = 0; i < NUM_LINES; i++) { + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, x, min_y); + cairo_stroke (cr); + + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, x, max_y); + cairo_stroke (cr); + + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, min_x, y); + cairo_stroke (cr); + + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, max_x, y); + cairo_stroke (cr); + + x += dx; + y += dy; + } + + cairo_perf_timer_stop (); + + cairo_restore (cr); + + return cairo_perf_timer_elapsed (); +} + +static cairo_perf_ticks_t +long_lines_uncropped (cairo_t *cr, int width, int height) +{ + return do_long_lines (cr, width, height, LONG_LINES_UNCROPPED); +} + +static cairo_perf_ticks_t +long_lines_cropped (cairo_t *cr, int width, int height) +{ + return do_long_lines (cr, width, height, LONG_LINES_CROPPED); +} + +void +long_lines (cairo_perf_t *perf, cairo_t *cr, int width, int height) +{ + cairo_perf_run (perf, "long-lines-uncropped", long_lines_uncropped); + cairo_perf_run (perf, "long-lines-cropped", long_lines_cropped); +}