[cairo-commit] 8 commits - perf/cairo-perf-compare-backends.c perf/cairo-perf-cover.c perf/cairo-perf-diff-files.c perf/cairo-perf-graph-files.c perf/cairo-perf.h perf/cairo-perf-report.c perf/dragon.c perf/.gitignore perf/Makefile.am src/cairo-scaled-font.c test/fill-image.c test/fill-image.ref.png test/huge-linear.c test/huge-linear.ps3.ref.png test/huge-linear.ref.png test/huge-pattern.c test/huge-pattern.pdf.argb32.ref.png test/huge-pattern.pdf.ref.png test/huge-pattern.pdf.rgb24.ref.png test/huge-pattern.ps3.ref.png test/huge-pattern.ref.png test/huge-radial.c test/huge-radial.ps3.ref.png test/huge-radial.ref.png test/large-source-roi.c test/Makefile.am
Chris Wilson
ickle at kemper.freedesktop.org
Wed Jan 14 08:53:16 PST 2009
dev/null |binary
perf/.gitignore | 1
perf/Makefile.am | 8
perf/cairo-perf-compare-backends.c | 393 +++++++++++++++++++++++++++++++++++++
perf/cairo-perf-cover.c | 80 +++++++
perf/cairo-perf-diff-files.c | 2
perf/cairo-perf-graph-files.c | 2
perf/cairo-perf-report.c | 43 +++-
perf/cairo-perf.h | 9
perf/dragon.c | 42 +++
src/cairo-scaled-font.c | 63 +++--
test/Makefile.am | 13 -
test/fill-image.c | 83 +++++++
test/fill-image.ref.png |binary
test/huge-linear.c | 67 ++++++
test/huge-linear.ps3.ref.png |binary
test/huge-linear.ref.png |binary
test/huge-pattern.c | 65 ------
test/huge-radial.c | 69 ++++++
test/huge-radial.ps3.ref.png |binary
test/huge-radial.ref.png |binary
test/large-source-roi.c | 28 +-
22 files changed, 853 insertions(+), 115 deletions(-)
New commits:
commit 6801f28f6dfeb21eec44052e75156e9d2b82422e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Jan 14 13:59:28 2009 +0000
[perf] Add a utility to compare backends.
A minor variation on cairo-perf-diff-files that compares tests with the
same name for multiple backends.
diff --git a/perf/.gitignore b/perf/.gitignore
index 29ec88d..a5d452f 100644
--- a/perf/.gitignore
+++ b/perf/.gitignore
@@ -1,6 +1,7 @@
TAGS
tags
cairo-perf
+cairo-perf-compare-backends
cairo-perf-diff-files
cairo-perf-graph-files
valgrind-log
diff --git a/perf/Makefile.am b/perf/Makefile.am
index 5dcc0ab..5927199 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -7,7 +7,10 @@ AM_CPPFLAGS = \
-I$(top_builddir)/src \
$(CAIRO_CFLAGS)
-EXTRA_PROGRAMS += cairo-perf cairo-perf-diff-files cairo-perf-graph-files
+EXTRA_PROGRAMS += cairo-perf \
+ cairo-perf-diff-files \
+ cairo-perf-compare-backends \
+ cairo-perf-graph-files
EXTRA_DIST += cairo-perf-diff COPYING
EXTRA_LTLIBRARIES += libcairoperf.la
@@ -70,6 +73,9 @@ libcairoperf_la_SOURCES = \
cairo_perf_diff_files_SOURCES = \
cairo-perf-diff-files.c
+cairo_perf_compare_backends_SOURCES = \
+ cairo-perf-compare-backends.c
+
cairo_perf_graph_files_SOURCES = \
cairo-perf-graph.h \
cairo-perf-graph-files.c \
diff --git a/perf/cairo-perf-compare-backends.c b/perf/cairo-perf-compare-backends.c
new file mode 100644
index 0000000..e6ab37f
--- /dev/null
+++ b/perf/cairo-perf-compare-backends.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Authors: Carl Worth <cworth at cworth.org>
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-perf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+
+typedef struct _cairo_perf_report_options {
+ double min_change;
+ int use_utf;
+ int print_change_bars;
+ int use_ms;
+} cairo_perf_report_options_t;
+
+typedef struct _cairo_perf_diff_files_args {
+ const char **filenames;
+ int num_filenames;
+ cairo_perf_report_options_t options;
+} cairo_perf_diff_files_args_t;
+
+static int
+test_diff_cmp (const void *a, const void *b)
+{
+ const test_diff_t *a_diff = a;
+ const test_diff_t *b_diff = b;
+
+ /* Reverse sort by magnitude of change so larger changes come
+ * first */
+ if (a_diff->change > b_diff->change)
+ return -1;
+
+ if (a_diff->change < b_diff->change)
+ return 1;
+
+ return 0;
+}
+
+#define CHANGE_BAR_WIDTH 70
+static void
+print_change_bar (double change, double max_change, int use_utf)
+{
+ int units_per_cell = (int) ceil (max_change / CHANGE_BAR_WIDTH);
+ static char const *ascii_boxes[8] = {
+ "****","***" ,"***", "**",
+ "**", "*", "*", ""
+ };
+ static char const *utf_boxes[8] = {
+ "â", "â", "â", "â",
+ "â", "â", "â", "â"
+ };
+ char const **boxes = use_utf ? utf_boxes : ascii_boxes;
+
+ /* For a 1.0x speedup we want a zero-size bar to show "no
+ * change". */
+ change -= 1.0;
+
+ while (change > units_per_cell) {
+ printf ("%s", boxes[0]);
+ change -= units_per_cell;
+ }
+
+ change /= units_per_cell;
+
+ if (change > 7.5/8.0)
+ printf ("%s", boxes[0]);
+ else if (change > 6.5/8.0)
+ printf ("%s", boxes[1]);
+ else if (change > 5.5/8.0)
+ printf ("%s", boxes[2]);
+ else if (change > 4.5/8.0)
+ printf ("%s", boxes[3]);
+ else if (change > 3.5/8.0)
+ printf ("%s", boxes[4]);
+ else if (change > 2.5/8.0)
+ printf ("%s", boxes[5]);
+ else if (change > 1.5/8.0)
+ printf ("%s", boxes[6]);
+ else if (change > 0.5/8.0)
+ printf ("%s", boxes[7]);
+
+ printf ("\n");
+}
+
+static void
+test_diff_print (test_diff_t *diff,
+ double max_change,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ double test_time;
+ double change;
+
+ printf ("(%s, size: %d)\n",
+ diff->tests[0]->name,
+ diff->tests[0]->size);
+
+ for (i = 0; i < diff->num_tests; i++) {
+ test_time = diff->tests[i]->stats.min_ticks;
+ if (options->use_ms)
+ test_time /= diff->tests[i]->stats.ticks_per_ms;
+ change = diff->max / test_time;
+ printf ("%8s-%s-%s\t%6.2f: %5.2fx ",
+ diff->tests[i]->backend,
+ diff->tests[i]->content,
+ diff->tests[i]->configuration,
+ diff->tests[i]->stats.min_ticks / diff->tests[i]->stats.ticks_per_ms,
+ change);
+
+ if (options->print_change_bars)
+ print_change_bar (change, max_change, options->use_utf);
+ }
+
+ printf("\n");
+}
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+static void
+cairo_perf_reports_compare (cairo_perf_report_t *reports,
+ int num_reports,
+ cairo_perf_report_options_t *options)
+{
+ int i;
+ test_report_t **tests, *min_test;
+ test_diff_t *diff, *diffs;
+ int num_diffs, max_diffs;
+ double max_change;
+ double test_time;
+ int seen_non_null;
+
+ tests = xmalloc (num_reports * sizeof (test_report_t *));
+
+ max_diffs = reports[0].tests_count;
+ for (i = 0; i < num_reports; i++) {
+ tests[i] = reports[i].tests;
+ if (reports[i].tests_count > max_diffs)
+ max_diffs = reports[i].tests_count;
+ }
+
+ diff = diffs = xmalloc (max_diffs * sizeof (test_diff_t));
+
+ num_diffs = 0;
+ while (1) {
+ int num_tests;
+
+ /* We expect iterations values of 0 when multiple raw reports
+ * for the same test have been condensed into the stats of the
+ * first. So we just skip these later reports that have no
+ * stats. */
+ seen_non_null = 0;
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name && tests[i]->stats.iterations == 0)
+ tests[i]++;
+ if (tests[i]->name)
+ seen_non_null++;
+ }
+ if (! seen_non_null)
+ break;
+
+ /* Find the minimum of all current tests, (we have to do this
+ * in case some reports don't have a particular test). */
+ for (i = 0; i < num_reports; i++) {
+ if (tests[i]->name) {
+ min_test = tests[i];
+ break;
+ }
+ }
+ for (++i; i < num_reports; i++) {
+ if (tests[i]->name && test_report_cmp_name (tests[i], min_test) < 0)
+ min_test = tests[i];
+ }
+
+ num_tests = 0;
+ for (i = 0; i < num_reports; i++) {
+ test_report_t *test;
+ int n = 0;
+
+ test = tests[i];
+ while (test[n].name &&
+ test_report_cmp_name (&test[n], min_test) == 0)
+ {
+ n++;
+ }
+
+ num_tests += n;
+ }
+
+ /* For each report that has the current test, record it into
+ * the diff structure. */
+ diff->num_tests = 0;
+ diff->tests = xmalloc (num_tests * sizeof (test_diff_t));
+ for (i = 0; i < num_reports; i++) {
+ while (tests[i]->name &&
+ test_report_cmp_name (tests[i], min_test) == 0)
+ {
+ test_time = tests[i]->stats.min_ticks;
+ if (options->use_ms)
+ test_time /= tests[i]->stats.ticks_per_ms;
+ if (diff->num_tests == 0) {
+ diff->min = test_time;
+ diff->max = test_time;
+ } else {
+ if (test_time < diff->min)
+ diff->min = test_time;
+ if (test_time > diff->max)
+ diff->max = test_time;
+ }
+ diff->tests[diff->num_tests++] = tests[i];
+ tests[i]++;
+ }
+ }
+ diff->change = diff->max / diff->min;
+
+ diff++;
+ num_diffs++;
+ }
+ if (num_diffs < 2)
+ goto DONE;
+
+ qsort (diffs, num_diffs, sizeof (test_diff_t), test_diff_cmp);
+
+ max_change = 1.0;
+ for (i = 0; i < num_diffs; i++) {
+ if (fabs (diffs[i].change) > max_change)
+ max_change = fabs (diffs[i].change);
+ }
+
+ for (i = 0; i < num_diffs; i++) {
+ diff = &diffs[i];
+
+ /* Discard as uninteresting a change which is less than the
+ * minimum change required, (default may be overriden on
+ * command-line). */
+ if (fabs (diff->change) - 1.0 < options->min_change)
+ continue;
+
+ test_diff_print (diff, max_change, options);
+ }
+
+ DONE:
+ for (i = 0; i < num_diffs; i++)
+ free (diffs[i].tests);
+ free (diffs);
+ free (tests);
+}
+
+static void
+usage (const char *argv0)
+{
+ char const *basename = strrchr(argv0, '/');
+ basename = basename ? basename+1 : argv0;
+ fprintf (stderr,
+ "Usage: %s [options] file [...]\n\n",
+ basename);
+ fprintf (stderr,
+ "Computes significant performance differences for cairo performance reports.\n"
+ "Each file should be the output of the cairo-perf program (or \"make perf\").\n"
+ "The following options are available:\n"
+ "\n"
+ "--no-utf Use ascii stars instead of utf-8 change bars.\n"
+ " Four stars are printed per factor of speedup.\n"
+ "\n"
+ "--no-bars Don't display change bars at all.\n\n"
+ "\n"
+ "--use-ms Use milliseconds to calculate differences.\n"
+ " (instead of ticks which are hardware dependant)\n"
+ "\n"
+ "--min-change threshold[%%]\n"
+ " Suppress all changes below the given threshold.\n"
+ " The default threshold of 0.05 or 5%% ignores any\n"
+ " speedup or slowdown of 1.05 or less. A threshold\n"
+ " of 0 will cause all output to be reported.\n"
+ );
+ exit(1);
+}
+
+static void
+parse_args(int argc,
+ char const **argv,
+ cairo_perf_diff_files_args_t *args)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp (argv[i], "--no-utf") == 0) {
+ args->options.use_utf = 0;
+ }
+ else if (strcmp (argv[i], "--no-bars") == 0) {
+ args->options.print_change_bars = 0;
+ }
+ else if (strcmp (argv[i], "--use-ms") == 0) {
+ args->options.use_ms = 1;
+ }
+ else if (strcmp (argv[i], "--min-change") == 0) {
+ char *end = NULL;
+ i++;
+ if (i >= argc)
+ usage (argv[0]);
+ args->options.min_change = strtod (argv[i], &end);
+ if (*end) {
+ if (*end == '%') {
+ args->options.min_change /= 100;
+ } else {
+ usage (argv[0]);
+ }
+ }
+ }
+ else {
+ args->num_filenames++;
+ args->filenames = xrealloc (args->filenames,
+ args->num_filenames * sizeof (char *));
+ args->filenames[args->num_filenames - 1] = argv[i];
+ }
+ }
+}
+
+int
+main (int argc, const char *argv[])
+{
+ cairo_perf_diff_files_args_t args = {
+ NULL, /* filenames */
+ 0, /* num_filenames */
+ {
+ 0.05, /* min change */
+ 1, /* use UTF-8? */
+ 1, /* display change bars? */
+ }
+ };
+ cairo_perf_report_t *reports;
+ test_report_t *t;
+ int i;
+
+ parse_args (argc, argv, &args);
+
+ if (args.num_filenames < 1)
+ usage (argv[0]);
+
+ reports = xmalloc (args.num_filenames * sizeof (cairo_perf_report_t));
+
+ for (i = 0; i < args.num_filenames; i++) {
+ cairo_perf_report_load (&reports[i], args.filenames[i],
+ test_report_cmp_name);
+ printf ("loaded: %s\n", args.filenames[i]);
+ }
+
+ cairo_perf_reports_compare (reports, args.num_filenames, &args.options);
+
+ /* Pointless memory cleanup, (would be a great place for talloc) */
+ free (args.filenames);
+ for (i = 0; i < args.num_filenames; i++) {
+ for (t = reports[i].tests; t->name; t++) {
+ free (t->samples);
+ free (t->backend);
+ free (t->name);
+ }
+ free (reports[i].tests);
+ free (reports[i].configuration);
+ }
+ free (reports);
+
+ return 0;
+}
diff --git a/perf/cairo-perf-diff-files.c b/perf/cairo-perf-diff-files.c
index 9b9f5f9..adbe69a 100644
--- a/perf/cairo-perf-diff-files.c
+++ b/perf/cairo-perf-diff-files.c
@@ -449,7 +449,7 @@ main (int argc, const char *argv[])
reports = xmalloc (args.num_filenames * sizeof (cairo_perf_report_t));
for (i = 0; i < args.num_filenames; i++ )
- cairo_perf_report_load (&reports[i], args.filenames[i]);
+ cairo_perf_report_load (&reports[i], args.filenames[i], NULL);
cairo_perf_reports_compare (reports, args.num_filenames, &args.options);
diff --git a/perf/cairo-perf-graph-files.c b/perf/cairo-perf-graph-files.c
index 04235d6..0adfabd 100644
--- a/perf/cairo-perf-graph-files.c
+++ b/perf/cairo-perf-graph-files.c
@@ -565,7 +565,7 @@ main (int argc, char *argv[])
reports = xmalloc ((argc-1) * sizeof (cairo_perf_report_t));
for (i = 1; i < argc; i++ )
- cairo_perf_report_load (&reports[i-1], argv[i]);
+ cairo_perf_report_load (&reports[i-1], argv[i], NULL);
cases = test_cases_from_reports (reports, argc-1);
diff --git a/perf/cairo-perf-report.c b/perf/cairo-perf-report.c
index 2f748f4..8a99b9d 100644
--- a/perf/cairo-perf-report.c
+++ b/perf/cairo-perf-report.c
@@ -337,15 +337,47 @@ test_report_cmp_backend_then_name (const void *a, const void *b)
return 0;
}
+int
+test_report_cmp_name (const void *a, const void *b)
+{
+ const test_report_t *a_test = a;
+ const test_report_t *b_test = b;
+
+ int cmp;
+
+ /* A NULL name is a list-termination marker, so force it last. */
+ if (a_test->name == NULL)
+ if (b_test->name == NULL)
+ return 0;
+ else
+ return 1;
+ else if (b_test->name == NULL)
+ return -1;
+
+ cmp = strcmp (a_test->name, b_test->name);
+ if (cmp)
+ return cmp;
+
+ if (a_test->size < b_test->size)
+ return -1;
+ if (a_test->size > b_test->size)
+ return 1;
+
+ return 0;
+}
+
void
-cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report)
+cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report,
+ int (*cmp) (const void*, const void*))
{
test_report_t *base, *next, *last, *t;
+ if (cmp == NULL)
+ cmp = test_report_cmp_backend_then_name;
+
/* First we sort, since the diff needs both lists in the same
* order */
- qsort (report->tests, report->tests_count, sizeof (test_report_t),
- test_report_cmp_backend_then_name);
+ qsort (report->tests, report->tests_count, sizeof (test_report_t), cmp);
/* The sorting also brings all related raw reports together so we
* can condense them and compute the stats.
@@ -384,7 +416,8 @@ cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report)
void
cairo_perf_report_load (cairo_perf_report_t *report,
- const char *filename)
+ const char *filename,
+ int (*cmp) (const void *, const void *))
{
FILE *file;
test_report_status_t status;
@@ -444,7 +477,7 @@ cairo_perf_report_load (cairo_perf_report_t *report,
fclose (file);
- cairo_perf_report_sort_and_compute_stats (report);
+ cairo_perf_report_sort_and_compute_stats (report, cmp);
/* Add one final report with a NULL name to terminate the list. */
if (report->tests_count == report->tests_size) {
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
index 3affcb8..8c44c9a 100644
--- a/perf/cairo-perf.h
+++ b/perf/cairo-perf.h
@@ -144,14 +144,19 @@ typedef enum {
void
cairo_perf_report_load (cairo_perf_report_t *report,
- const char *filename);
+ const char *filename,
+ int (*cmp) (const void *, const void *));
void
-cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report);
+cairo_perf_report_sort_and_compute_stats (cairo_perf_report_t *report,
+ int (*cmp) (const void *, const void *));
int
test_report_cmp_backend_then_name (const void *a, const void *b);
+int
+test_report_cmp_name (const void *a, const void *b);
+
#define CAIRO_PERF_DECL(func) void (func) (cairo_perf_t *perf, cairo_t *cr, int width, int height)
CAIRO_PERF_DECL (fill);
commit 4c79cd480db1cf10b6018bce3ea966587efc6081
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Jan 13 12:52:52 2009 +0000
[perf] Tweak dragon to hit fill_rectangles().
Add a second dragon path that is pixel-aligned and uses a solid pattern,
so that it can be drawn using fill-rectangles.
diff --git a/perf/dragon.c b/perf/dragon.c
index 6d0328e..a6167cb 100644
--- a/perf/dragon.c
+++ b/perf/dragon.c
@@ -65,7 +65,6 @@ direction (int i)
return ! direction (2 * pivot - i);
}
-
static void
path (cairo_t *cr, int step, int dir, int iterations)
{
@@ -159,8 +158,49 @@ do_dragon (cairo_t *cr, int width, int height)
return cairo_perf_timer_elapsed ();
}
+static cairo_perf_ticks_t
+do_dragon_solid (cairo_t *cr, int width, int height)
+{
+ double cx, cy, r;
+
+ cx = cy = .5 * MAX (width, height);
+ r = .5 * MIN (width, height);
+
+ cairo_perf_timer_start ();
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_line_width (cr, 4.);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 0, 2048);
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 1, 2048);
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 2, 2048);
+ cairo_set_source_rgb (cr, 0, 0, 1);
+ cairo_stroke(cr);
+
+ cairo_move_to (cr, cx, cy);
+ path (cr, 12, 3, 2048);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_stroke(cr);
+
+ cairo_perf_timer_stop ();
+
+ return cairo_perf_timer_elapsed ();
+}
+
void
dragon (cairo_perf_t *perf, cairo_t *cr, int width, int height)
{
+ cairo_perf_run (perf, "dragon-solid", do_dragon_solid);
cairo_perf_run (perf, "dragon", do_dragon);
}
commit de9e6b5a3f4e4752e0f99e3ae20ac263a5aae4bb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jan 12 01:00:30 2009 +0000
[perf] Cover linear gradient with 3 stops.
The i915 is able to special case gradients with just 2 color stops to
avoid creating temporary gradient textures, so add a 3 stop linear
gradient to compare the speed difference.
diff --git a/perf/cairo-perf-cover.c b/perf/cairo-perf-cover.c
index eb77ccd..975c766 100644
--- a/perf/cairo-perf-cover.c
+++ b/perf/cairo-perf-cover.c
@@ -225,6 +225,40 @@ set_source_linear_rgba (cairo_t *cr,
}
static void
+set_source_linear3_rgb (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgb (linear, 0.0, 1, 0, 0); /* red */
+ cairo_pattern_add_color_stop_rgb (linear, 0.5, 0, 1, 0); /* green */
+ cairo_pattern_add_color_stop_rgb (linear, 1.0, 0, 0, 1); /* blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
+set_source_linear3_rgba (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_pattern_t *linear;
+
+ linear = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgba (linear, 0.0, 1, 0, 0, 0.5); /* 50% red */
+ cairo_pattern_add_color_stop_rgba (linear, 0.5, 0, 1, 0, 0.0); /* 0% green */
+ cairo_pattern_add_color_stop_rgba (linear, 1.0, 0, 0, 1, 0.5); /* 50% blue */
+
+ cairo_set_source (cr, linear);
+
+ cairo_pattern_destroy (linear);
+}
+
+static void
set_source_radial_rgb (cairo_t *cr,
int width,
int height)
@@ -282,6 +316,8 @@ cairo_perf_cover_sources_and_operators (cairo_perf_t *perf,
{ set_source_similar_surface_rgba_min, "similar_rgba_min" },
{ set_source_linear_rgb, "linear_rgb" },
{ set_source_linear_rgba, "linear_rgba" },
+ { set_source_linear3_rgb, "linear3_rgb" },
+ { set_source_linear3_rgba, "linear3_rgba" },
{ set_source_radial_rgb, "radial_rgb" },
{ set_source_radial_rgba, "radial_rgba" }
};
commit 7cbc55f21624159dfa58a9a50ec004af9368ab3d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Jan 10 00:12:06 2009 +0000
[perf] Add scaled similar surface sources.
Cover the similar source with min/mag scale factors as well, so we can
compare the performance impact with scaled image sources. This is useful
to distinguish between transport overhead and transform cost.
diff --git a/perf/cairo-perf-cover.c b/perf/cairo-perf-cover.c
index 30942d2..eb77ccd 100644
--- a/perf/cairo-perf-cover.c
+++ b/perf/cairo-perf-cover.c
@@ -98,8 +98,8 @@ set_source_image_surface_rgba (cairo_t *cr,
static void
set_source_image_surface_rgba_mag (cairo_t *cr,
- int width,
- int height)
+ int width,
+ int height)
{
cairo_surface_t *source;
@@ -114,8 +114,8 @@ set_source_image_surface_rgba_mag (cairo_t *cr,
static void
set_source_image_surface_rgba_min (cairo_t *cr,
- int width,
- int height)
+ int width,
+ int height)
{
cairo_surface_t *source;
@@ -159,6 +159,40 @@ set_source_similar_surface_rgba (cairo_t *cr,
}
static void
+set_source_similar_surface_rgba_mag (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width/2, height/2);
+ cairo_scale(cr, 2.1, 2.1);
+ init_and_set_source_surface (cr, source, width/2, height/2);
+ cairo_scale(cr, 1/2.1, 1/2.1);
+
+ cairo_surface_destroy (source);
+}
+
+static void
+set_source_similar_surface_rgba_min (cairo_t *cr,
+ int width,
+ int height)
+{
+ cairo_surface_t *source;
+
+ source = cairo_surface_create_similar (cairo_get_group_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width*2, height*2);
+ cairo_scale(cr, 1/1.9, 1/1.9);
+ init_and_set_source_surface (cr, source, width*2, height*2);
+ cairo_scale(cr, 1.9, 1.9);
+
+ cairo_surface_destroy (source);
+}
+
+static void
set_source_linear_rgb (cairo_t *cr,
int width,
int height)
@@ -244,6 +278,8 @@ cairo_perf_cover_sources_and_operators (cairo_perf_t *perf,
{ set_source_image_surface_rgba_min, "image_rgba_min" },
{ set_source_similar_surface_rgb, "similar_rgb" },
{ set_source_similar_surface_rgba, "similar_rgba" },
+ { set_source_similar_surface_rgba_mag, "similar_rgba_mag" },
+ { set_source_similar_surface_rgba_min, "similar_rgba_min" },
{ set_source_linear_rgb, "linear_rgb" },
{ set_source_linear_rgba, "linear_rgba" },
{ set_source_radial_rgb, "radial_rgb" },
commit afce1cfe987eeec6516aed1eb8fd97c2d3b9b07b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jan 9 14:22:36 2009 +0000
[scaled-font] Avoid repeated lookup of the same unicode during text->glyphs
Performing the unicode to index is quite expensive, the
FcFreeTypeCharIndex() taking over 12% in the cairo-perf text benchmarks.
By adding a simple cache of translated unicode indices, we save around 25%
of the lookups during benchmarks, with a relative reduction in runtime.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 013d680..1d5798f 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1534,6 +1534,12 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
cairo_status_t status;
cairo_glyph_t *orig_glyphs;
cairo_text_cluster_t *orig_clusters;
+ struct glyph_lut_elt {
+ uint32_t unicode;
+ unsigned long index;
+ double x_advance;
+ double y_advance;
+ } glyph_lut[256];
status = scaled_font->status;
if (unlikely (status))
@@ -1608,17 +1614,13 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
orig_clusters = clusters ? *clusters : NULL;
if (scaled_font->backend->text_to_glyphs) {
-
status = scaled_font->backend->text_to_glyphs (scaled_font, x, y,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters,
cluster_flags);
-
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-
if (status == CAIRO_STATUS_SUCCESS) {
-
/* The checks here are crude; we only should do them in
* user-font backend, but they don't hurt here. This stuff
* can be hard to get right. */
@@ -1633,7 +1635,6 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
}
if (clusters) {
-
if (*num_clusters < 0) {
status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT);
goto DONE;
@@ -1643,11 +1644,12 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
goto DONE;
}
- /* Dont trust the backend, validate clusters! */
- status = _cairo_validate_text_clusters (utf8, utf8_len,
- *glyphs, *num_glyphs,
- *clusters, *num_clusters,
- *cluster_flags);
+ /* Don't trust the backend, validate clusters! */
+ status =
+ _cairo_validate_text_clusters (utf8, utf8_len,
+ *glyphs, *num_glyphs,
+ *clusters, *num_clusters,
+ *cluster_flags);
}
}
@@ -1675,34 +1677,51 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
*num_clusters = num_chars;
}
+ for (i = 0; i < ARRAY_LENGTH (glyph_lut); i++)
+ glyph_lut[i].unicode = ~0U;
+
p = utf8;
for (i = 0; i < num_chars; i++) {
int num_bytes;
uint32_t unicode;
cairo_scaled_glyph_t *scaled_glyph;
+ struct glyph_lut_elt *glyph_slot;
num_bytes = _cairo_utf8_get_char_validated (p, &unicode);
p += num_bytes;
- (*glyphs)[i].index = (*scaled_font->backend->ucs4_to_index) (scaled_font, unicode);
(*glyphs)[i].x = x;
(*glyphs)[i].y = y;
+ glyph_slot = &glyph_lut[unicode % ARRAY_LENGTH (glyph_lut)];
+ if (glyph_slot->unicode == unicode) {
+ (*glyphs)[i].index = glyph_slot->index;
+ x += glyph_slot->x_advance;
+ y += glyph_slot->y_advance;
+ } else {
+ (*glyphs)[i].index =
+ (*scaled_font->backend->ucs4_to_index) (scaled_font, unicode);
+
+ status = _cairo_scaled_glyph_lookup (scaled_font,
+ (*glyphs)[i].index,
+ CAIRO_SCALED_GLYPH_INFO_METRICS,
+ &scaled_glyph);
+ if (unlikely (status))
+ goto DONE;
+
+ x += scaled_glyph->metrics.x_advance;
+ y += scaled_glyph->metrics.y_advance;
+
+ glyph_slot->unicode = unicode;
+ glyph_slot->index = (*glyphs)[i].index;
+ glyph_slot->x_advance = scaled_glyph->metrics.x_advance;
+ glyph_slot->y_advance = scaled_glyph->metrics.y_advance;
+ }
+
if (clusters) {
(*clusters)[i].num_bytes = num_bytes;
(*clusters)[i].num_glyphs = 1;
}
-
- status = _cairo_scaled_glyph_lookup (scaled_font,
- (*glyphs)[i].index,
- CAIRO_SCALED_GLYPH_INFO_METRICS,
- &scaled_glyph);
- if (unlikely (status)) {
- goto DONE;
- }
-
- x += scaled_glyph->metrics.x_advance;
- y += scaled_glyph->metrics.y_advance;
}
DONE: /* error that should be logged on scaled_font happened */
commit 49eca78a4265432e285af58435219e8b804b38bb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jan 12 12:42:46 2009 +0000
[test] Add a huge-radial test case.
Also test the handling of radial gradients with large radii.
diff --git a/test/Makefile.am b/test/Makefile.am
index 2afda68..8c849ba 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -85,7 +85,8 @@ test_sources = \
gradient-constant-alpha.c \
gradient-zero-stops.c \
group-paint.c \
- huge-pattern.c \
+ huge-linear.c \
+ huge-radial.c \
image-surface-source.c \
infinite-join.c \
in-fill-empty-trapezoid.c \
@@ -610,10 +611,10 @@ REFERENCE_IMAGES = \
gradient-zero-stops.ref.png \
gradient-zero-stops.rgb24.ref.png \
group-paint.ref.png \
- huge-pattern.ref.png \
- huge-pattern.ps3.ref.png \
- huge-pattern.pdf.ref.png \
- huge-pattern.pdf.rgb24.ref.png \
+ huge-linear.ref.png \
+ huge-linear.ps3.ref.png \
+ huge-radial.ref.png \
+ huge-radial.ps3.ref.png \
image-surface-source.ref.png \
image-surface-source.ps2.ref.png \
image-surface-source.ps3.ref.png \
diff --git a/test/huge-linear.c b/test/huge-linear.c
new file mode 100644
index 0000000..304cac4
--- /dev/null
+++ b/test/huge-linear.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2006 Benjamin Otte
+ *
+ * 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: Benjamin Otte <otte at gnome.org>
+ */
+
+#include "cairo-test.h"
+
+/* set this to 0.1 to make this test work */
+#define FACTOR 1
+
+/* XXX poppler-cairo doesn't handle gradients very well... */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat = {
+ 0, -4.5254285714285709 * FACTOR,
+ -2.6398333333333333 * FACTOR, 0,
+ 0, 0
+ };
+
+ pattern = cairo_pattern_create_linear (-16384 * FACTOR, 0,
+ 16384 * FACTOR, 0);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0, 0.376471, 0.533333, 0.27451, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, 1);
+ cairo_pattern_set_matrix (pattern, &mat);
+
+ cairo_scale (cr, 0.05, 0.05);
+ cairo_translate (cr, 6000, 3500);
+
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, -6000, -3500, 12000, 7000);
+ cairo_pattern_destroy (pattern);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (huge_linear,
+ "Test huge linear patterns",
+ "XFAIL=pdf gradient, linear", /* keywords */
+ NULL, /* requirements */
+ 600, 350,
+ NULL, draw)
diff --git a/test/huge-linear.ps3.ref.png b/test/huge-linear.ps3.ref.png
new file mode 100644
index 0000000..d55239b
Binary files /dev/null and b/test/huge-linear.ps3.ref.png differ
diff --git a/test/huge-linear.ref.png b/test/huge-linear.ref.png
new file mode 100644
index 0000000..68f86b4
Binary files /dev/null and b/test/huge-linear.ref.png differ
diff --git a/test/huge-pattern.c b/test/huge-pattern.c
deleted file mode 100644
index 9a74337..0000000
--- a/test/huge-pattern.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright © 2006 Benjamin Otte
- *
- * 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: Benjamin Otte <otte at gnome.org>
- */
-
-#include "cairo-test.h"
-
-/* set this to 0.1 to make this test work */
-#define FACTOR 1
-
-static cairo_test_status_t
-draw (cairo_t *cr, int width, int height)
-{
- cairo_pattern_t *pattern;
- cairo_matrix_t mat = {
- 0, -4.5254285714285709 * FACTOR,
- -2.6398333333333333 * FACTOR, 0,
- 0, 0
- };
-
- pattern = cairo_pattern_create_linear (-16384 * FACTOR, 0,
- 16384 * FACTOR, 0);
- cairo_pattern_add_color_stop_rgba (pattern,
- 0, 0.376471, 0.533333, 0.27451, 1);
- cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, 1);
- cairo_pattern_set_matrix (pattern, &mat);
-
- cairo_scale (cr, 0.05, 0.05);
- cairo_translate (cr, 6000, 3500);
-
- cairo_set_source (cr, pattern);
- cairo_rectangle (cr, -6000, -3500, 12000, 7000);
- cairo_pattern_destroy (pattern);
- cairo_fill (cr);
-
- return CAIRO_TEST_SUCCESS;
-}
-
-CAIRO_TEST (huge_pattern,
- "Test huge linear patterns",
- "gradient", /* keywords */
- NULL, /* requirements */
- 600, 350,
- NULL, draw)
diff --git a/test/huge-pattern.pdf.argb32.ref.png b/test/huge-pattern.pdf.argb32.ref.png
deleted file mode 100644
index 005d4a6..0000000
Binary files a/test/huge-pattern.pdf.argb32.ref.png and /dev/null differ
diff --git a/test/huge-pattern.pdf.ref.png b/test/huge-pattern.pdf.ref.png
deleted file mode 100644
index dfa8c5b..0000000
Binary files a/test/huge-pattern.pdf.ref.png and /dev/null differ
diff --git a/test/huge-pattern.pdf.rgb24.ref.png b/test/huge-pattern.pdf.rgb24.ref.png
deleted file mode 100644
index a950f8b..0000000
Binary files a/test/huge-pattern.pdf.rgb24.ref.png and /dev/null differ
diff --git a/test/huge-pattern.ps3.ref.png b/test/huge-pattern.ps3.ref.png
deleted file mode 100644
index d55239b..0000000
Binary files a/test/huge-pattern.ps3.ref.png and /dev/null differ
diff --git a/test/huge-pattern.ref.png b/test/huge-pattern.ref.png
deleted file mode 100644
index 68f86b4..0000000
Binary files a/test/huge-pattern.ref.png and /dev/null differ
diff --git a/test/huge-radial.c b/test/huge-radial.c
new file mode 100644
index 0000000..0e5aca1
--- /dev/null
+++ b/test/huge-radial.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2006 Benjamin Otte
+ * Copyright © 2009 Chris Wilson
+ *
+ * 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: Benjamin Otte <otte at gnome.org>
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/* set this to 0.1 to make this test work */
+#define FACTOR 1
+
+/* XXX poppler-cairo doesn't handle gradients very well... */
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_pattern_t *pattern;
+ cairo_matrix_t mat = {
+ 0, -4.5254285714285709 * FACTOR,
+ -2.6398333333333333 * FACTOR, 0,
+ 0, 0
+ };
+
+ pattern = cairo_pattern_create_radial (0, 0, 0,
+ 0, 0, 16384 * FACTOR);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0, 0.376471, 0.533333, 0.27451, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, 1);
+ cairo_pattern_set_matrix (pattern, &mat);
+
+ cairo_scale (cr, 0.05, 0.05);
+ cairo_translate (cr, 6000, 3500);
+
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, -6000, -3500, 12000, 7000);
+ cairo_pattern_destroy (pattern);
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (huge_radial,
+ "Test huge radial patterns",
+ "XFAIL=pdf gradient, radial", /* keywords */
+ NULL, /* requirements */
+ 600, 350,
+ NULL, draw)
diff --git a/test/huge-radial.ps3.ref.png b/test/huge-radial.ps3.ref.png
new file mode 100644
index 0000000..c231948
Binary files /dev/null and b/test/huge-radial.ps3.ref.png differ
diff --git a/test/huge-radial.ref.png b/test/huge-radial.ref.png
new file mode 100644
index 0000000..541bb30
Binary files /dev/null and b/test/huge-radial.ref.png differ
commit 7709d1d9d43a42dd8f9293f18141c57c76ca0970
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Jan 7 21:12:21 2009 +0000
[test] Add fill-image.
A filled equivalent of stroke-image, that checks that the pattern
matrices are applied correctly during fills - useful with the
segregation between fills and strokes introduced by spans.
diff --git a/test/Makefile.am b/test/Makefile.am
index 3c0972c..2afda68 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -66,6 +66,7 @@ test_sources = \
fill-and-stroke-alpha.c \
fill-and-stroke-alpha-add.c \
fill-degenerate-sort-order.c \
+ fill-image.c \
fill-missed-stop.c \
fill-rule.c \
filter-bilinear-extents.c \
@@ -519,6 +520,7 @@ REFERENCE_IMAGES = \
fill-degenerate-sort-order.quartz.rgb24.ref.png \
fill-degenerate-sort-order.ref.png \
fill-degenerate-sort-order.rgb24.ref.png \
+ fill-image.ref.png \
fill-missed-stop.ps2.argb32.ref.png \
fill-missed-stop.ps3.argb32.ref.png \
fill-missed-stop.ps2.rgb24.ref.png \
diff --git a/test/fill-image.c b/test/fill-image.c
new file mode 100644
index 0000000..24ee031
--- /dev/null
+++ b/test/fill-image.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2006 Mozilla Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Mozilla Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Mozilla Corporation makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MOZILLA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MOZILLA CORPORATION BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Vladimir Vukicevic <vladimir at pobox.com>
+ */
+
+#include "cairo-test.h"
+
+#define PAD 10
+#define SIZE 100
+#define IMAGE_SIZE (SIZE-PAD*2)
+#define LINE_WIDTH 10
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *image;
+ cairo_t *cr_image;
+
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_paint (cr);
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ IMAGE_SIZE, IMAGE_SIZE);
+ cr_image = cairo_create (image);
+ cairo_surface_destroy (image);
+
+ /* Create the image */
+ cairo_set_source_rgb (cr_image, 0, 0, 0);
+ cairo_paint (cr_image);
+
+ cairo_set_source_rgb (cr_image, 0, 1, 0);
+ cairo_new_sub_path (cr_image);
+ cairo_arc (cr_image, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH, 0, M_PI * 2.0);
+ cairo_close_path (cr_image);
+ cairo_new_sub_path (cr_image);
+ cairo_arc_negative (cr_image, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2, 0, -M_PI * 2.0);
+ cairo_close_path (cr_image);
+ cairo_fill (cr_image);
+
+ /* Now stroke^Wfill with it */
+ cairo_translate (cr, PAD, PAD);
+
+ cairo_set_source_surface (cr, cairo_get_target (cr_image), 0, 0);
+ cairo_destroy (cr_image);
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2 - LINE_WIDTH, 0, M_PI * 2.0);
+ cairo_close_path (cr);
+ cairo_new_sub_path (cr);
+ cairo_arc_negative (cr, IMAGE_SIZE/2, IMAGE_SIZE/2, IMAGE_SIZE/2, 0, -M_PI * 2.0);
+ cairo_close_path (cr);
+
+ cairo_fill (cr);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (fill_image,
+ "Test filling with an image source, with a non-identity CTM",
+ "fill, image, transform", /* keywords */
+ NULL, /* requirements */
+ SIZE, SIZE,
+ NULL, draw)
diff --git a/test/fill-image.ref.png b/test/fill-image.ref.png
new file mode 100644
index 0000000..4e4f450
Binary files /dev/null and b/test/fill-image.ref.png differ
commit 5605e4bfcd0b6e3e34eed3785bc8ae51b24a7385
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Jan 4 11:26:45 2009 +0000
[test] Propagate failure from painting large-source-roi
Use cairo_get_target() to propagate any failure when creating the
large-source.
diff --git a/test/large-source-roi.c b/test/large-source-roi.c
index 097390f..226d97f 100644
--- a/test/large-source-roi.c
+++ b/test/large-source-roi.c
@@ -25,6 +25,24 @@
/* This test attempts to trigger failures in those clone_similar
* backend methods that have size restrictions. */
+static cairo_surface_t *
+create_large_source (int width, int height)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ cairo_set_source_rgb (cr, 1,0,0); /* red */
+ cairo_paint (cr);
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+
+ return surface;
+}
+
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
@@ -35,13 +53,7 @@ draw (cairo_t *cr, int width, int height)
cairo_paint (cr);
/* Create an excessively wide source image, all red. */
- source = cairo_image_surface_create (CAIRO_FORMAT_RGB24, source_width, height);
- {
- cairo_t *cr2 = cairo_create (source);
- cairo_set_source_rgb (cr2, 1,0,0); /* red */
- cairo_paint (cr2);
- cairo_destroy (cr2);
- }
+ source = create_large_source (source_width, height);
/* Set a transform so that the source is scaled down to fit in the
* destination horizontally and then paint the entire source to
@@ -58,7 +70,7 @@ draw (cairo_t *cr, int width, int height)
CAIRO_TEST (large_source_roi,
"Uses a all of a large source image.",
- "stress, source", /* keywords */
+ "XFAIL stress, source", /* keywords */
NULL, /* requirements */
20, 20,
NULL, draw)
More information about the cairo-commit
mailing list