[cairo-commit] 3 commits - perf/cairo-perf.c perf/cairo-perf-diff perf/cairo-perf.h perf/intersections.c perf/Makefile.am perf/spiral.c

M. Joonas Pihlaja joonas at kemper.freedesktop.org
Sat Dec 6 03:56:12 PST 2008


 perf/Makefile.am     |    4 -
 perf/cairo-perf-diff |    2 
 perf/cairo-perf.c    |    2 
 perf/cairo-perf.h    |    2 
 perf/intersections.c |   97 ++++++++++++++++++++++++
 perf/spiral.c        |  200 +++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 305 insertions(+), 2 deletions(-)

New commits:
commit 0c0f4862c52d68776024f125b003ade455044b27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 6 13:32:37 2008 +0200

    [perf-diff] Fix cairo-perf-diff for git 1.6
    
    Since git 1.6 the plumbing commands aren't installed in the user's
    path by default.  This patch fixes cairo-perf-diff to find the
    git-sh-setup command from git's lib dir.

diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff
index 50cd1f2..718cdc5 100755
--- a/perf/cairo-perf-diff
+++ b/perf/cairo-perf-diff
@@ -89,7 +89,7 @@ fi
 
 git_setup() {
     SUBDIRECTORY_OK='Yes'
-    . git-sh-setup
+    . "$(git --exec-path)/git-sh-setup"
     CAIRO_DIR=`dirname $GIT_DIR`
     if [ "$CAIRO_DIR" = "." ]; then
 	CAIRO_DIR=`pwd`
commit afba0c312958852586b846ec615cff1bd3e5cde7
Author: M Joonas Pihlaja <jpihlaja at cc.helsinki.fi>
Date:   Fri Sep 12 17:41:45 2008 +0300

    [perf] Add perf tests to hit rectilinear code paths.
    
    These tests look at the differences in code paths
    hit by filling paths that are rectilinear (or not) and
    pixel aligned (or not) with the even-odd and non-zero
    fill rules.  The paths are not simple, so they don't
    hit the special case quad/triangle tessellator.

diff --git a/perf/Makefile.am b/perf/Makefile.am
index b85d732..5dcc0ab 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -44,7 +44,8 @@ cairo_perf_SOURCES =		\
 	long-dashed-lines.c	\
 	dragon.c		\
 	pythagoras-tree.c	\
-	intersections.c
+	intersections.c		\
+	spiral.c
 
 if CAIRO_HAS_WIN32_SURFACE
 cairo_perf_SOURCES += cairo-perf-win32.c
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index f419f05..6bb48f1 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -466,5 +466,6 @@ const cairo_perf_case_t perf_cases[] = {
     { dragon, 1024, 1024 },
     { pythagoras_tree, 768, 768 },
     { intersections, 512, 512 },
+    { spiral, 512, 512 },
     { NULL }
 };
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
index 91e38de..3affcb8 100644
--- a/perf/cairo-perf.h
+++ b/perf/cairo-perf.h
@@ -176,5 +176,6 @@ CAIRO_PERF_DECL (twin);
 CAIRO_PERF_DECL (dragon);
 CAIRO_PERF_DECL (pythagoras_tree);
 CAIRO_PERF_DECL (intersections);
+CAIRO_PERF_DECL (spiral);
 
 #endif
diff --git a/perf/spiral.c b/perf/spiral.c
new file mode 100644
index 0000000..f26d0a2
--- /dev/null
+++ b/perf/spiral.c
@@ -0,0 +1,200 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2008  M Joonas Pihlaja
+ *
+ * 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.
+ */
+#include <assert.h>
+#include "cairo-perf.h"
+
+#define MAX_SEGMENTS 2560
+
+typedef enum {
+    PIXALIGN,                   /* pixel aligned path */
+    NONALIGN                    /* unaligned path. */
+} align_t;
+
+typedef enum {
+    RECTCLOSE,                  /* keeps the path rectilinear */
+    DIAGCLOSE                   /* forces a diagonal */
+} close_t;
+
+static cairo_perf_ticks_t
+draw_spiral (cairo_t *cr,
+             cairo_fill_rule_t fill_rule,
+             align_t align,
+             close_t close,
+             int width, int height)
+{
+    int i;
+    int n=0;
+    double x[MAX_SEGMENTS];
+    double y[MAX_SEGMENTS];
+    int step = 3;
+    int side = width < height ? width : height;
+
+    assert(5*(side/step/2+1)+2 < MAX_SEGMENTS);
+
+#define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++)
+#define M(x_,y_) L(x_,y_)
+#define v(t) L(x[n-1], y[n-1] + (t))
+#define h(t) L(x[n-1] + (t), y[n-1])
+
+    switch (align) {
+    case PIXALIGN: M(0,0); break;
+    case NONALIGN: M(0.1415926, 0.7182818); break;
+    }
+
+    while (side >= step && side >= 0) {
+        v(side);
+        h(side);
+        v(-side);
+        h(-side+step);
+        v(step);
+        side -= 2*step;
+    }
+
+    switch (close) {
+    case RECTCLOSE: L(x[n-1],y[0]); break;
+    case DIAGCLOSE: L(x[0],y[0]); break;
+    }
+
+    assert(n < MAX_SEGMENTS);
+
+    cairo_save (cr);
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    cairo_paint (cr);
+
+    cairo_translate (cr, 1, 1);
+    cairo_set_fill_rule (cr, fill_rule);
+    cairo_set_source_rgb (cr, 1, 0, 0);
+
+    cairo_perf_timer_start (); {
+
+        cairo_move_to (cr, x[0], y[0]);
+        for (i = 1; i < n; i++) {
+            cairo_line_to (cr, x[i], y[i]);
+        }
+        cairo_close_path (cr);
+
+        cairo_fill (cr);
+    }
+    cairo_perf_timer_stop ();
+
+    cairo_restore (cr);
+
+    return cairo_perf_timer_elapsed ();
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_pa_re (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_EVEN_ODD,
+                        PIXALIGN,
+                        RECTCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_pa_re (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_WINDING,
+                        PIXALIGN,
+                        RECTCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_na_re (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_EVEN_ODD,
+                        NONALIGN,
+                        RECTCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_na_re (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_WINDING,
+                        NONALIGN,
+                        RECTCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_pa_di (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_EVEN_ODD,
+                        PIXALIGN,
+                        DIAGCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_pa_di (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_WINDING,
+                        PIXALIGN,
+                        DIAGCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_eo_na_di (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_EVEN_ODD,
+                        NONALIGN,
+                        DIAGCLOSE,
+                        width, height);
+}
+
+static cairo_perf_ticks_t
+draw_spiral_nz_na_di (cairo_t *cr, int width, int height)
+{
+    return draw_spiral (cr,
+                        CAIRO_FILL_RULE_WINDING,
+                        NONALIGN,
+                        DIAGCLOSE,
+                        width, height);
+}
+
+void
+spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+    cairo_perf_run (perf, "spiral-diag-nonalign-evenodd-fill", draw_spiral_eo_na_di);
+    cairo_perf_run (perf, "spiral-diag-nonalign-nonzero-fill", draw_spiral_nz_na_di);
+    cairo_perf_run (perf, "spiral-diag-pixalign-evenodd-fill", draw_spiral_eo_pa_di);
+    cairo_perf_run (perf, "spiral-diag-pixalign-nonzero-fill", draw_spiral_nz_pa_di);
+    cairo_perf_run (perf, "spiral-rect-nonalign-evenodd-fill", draw_spiral_eo_na_re);
+    cairo_perf_run (perf, "spiral-rect-nonalign-nonzero-fill", draw_spiral_nz_na_re);
+    cairo_perf_run (perf, "spiral-rect-pixalign-evenodd-fill", draw_spiral_eo_pa_re);
+    cairo_perf_run (perf, "spiral-rect-pixalign-nonzero-fill", draw_spiral_nz_pa_re);
+}
commit 8ec58113df417e1ec1d331ab65267c34e6d32096
Author: M Joonas Pihlaja <jpihlaja at cc.helsinki.fi>
Date:   Fri Sep 12 17:32:40 2008 +0300

    [perf] Explicitly test rendering a path with lots of intersections.
    
    We don't have one just for this purpose.  The only other
    path with many intersections that gets actually rendered is zrusin-another,
    but that might be sped up in the future (say by identifying
    collinearities up front or something like that.)

diff --git a/perf/Makefile.am b/perf/Makefile.am
index ae39dbc..b85d732 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -43,7 +43,8 @@ cairo_perf_SOURCES =		\
 	zrusin-another.h	\
 	long-dashed-lines.c	\
 	dragon.c		\
-	pythagoras-tree.c
+	pythagoras-tree.c	\
+	intersections.c
 
 if CAIRO_HAS_WIN32_SURFACE
 cairo_perf_SOURCES += cairo-perf-win32.c
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index c96e6c2..f419f05 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -465,5 +465,6 @@ const cairo_perf_case_t perf_cases[] = {
     { twin, 800, 800},
     { dragon, 1024, 1024 },
     { pythagoras_tree, 768, 768 },
+    { intersections, 512, 512 },
     { NULL }
 };
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
index d18be03..91e38de 100644
--- a/perf/cairo-perf.h
+++ b/perf/cairo-perf.h
@@ -175,5 +175,6 @@ CAIRO_PERF_DECL (composite_checker);
 CAIRO_PERF_DECL (twin);
 CAIRO_PERF_DECL (dragon);
 CAIRO_PERF_DECL (pythagoras_tree);
+CAIRO_PERF_DECL (intersections);
 
 #endif
diff --git a/perf/intersections.c b/perf/intersections.c
new file mode 100644
index 0000000..5e41036
--- /dev/null
+++ b/perf/intersections.c
@@ -0,0 +1,97 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright (c) 2008  M Joonas Pihlaja
+ *
+ * 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.
+ */
+#include "cairo-perf.h"
+
+#define NUM_SEGMENTS 256
+
+static unsigned state;
+static double
+uniform_random (double minval, double maxval)
+{
+    static unsigned const poly = 0x9a795537U;
+    unsigned n = 32;
+    while (n-->0)
+	state = 2*state < state ? (2*state ^ poly) : 2*state;
+    return minval + state * (maxval - minval) / 4294967296.0;
+}
+
+static cairo_perf_ticks_t
+draw_random (cairo_t *cr, cairo_fill_rule_t fill_rule, int width, int height)
+{
+    int i;
+    double x[NUM_SEGMENTS];
+    double y[NUM_SEGMENTS];
+
+    cairo_save (cr);
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    cairo_paint (cr);
+
+    for (i = 0; i < NUM_SEGMENTS; i++) {
+         x[i] = uniform_random (0, width);
+         y[i] = uniform_random (0, height);
+    }
+
+    state = 0x12345678;
+    cairo_translate (cr, 1, 1);
+    cairo_set_fill_rule (cr, fill_rule);
+    cairo_set_source_rgb (cr, 1, 0, 0);
+
+    cairo_perf_timer_start (); {
+
+        cairo_move_to (cr, 0, 0);
+        for (i = 0; i < NUM_SEGMENTS; i++) {
+            cairo_line_to (cr, x[i], y[i]);
+        }
+        cairo_close_path (cr);
+
+        cairo_fill (cr);
+    }
+    cairo_perf_timer_stop ();
+
+    cairo_restore (cr);
+
+    return cairo_perf_timer_elapsed ();
+}
+
+static cairo_perf_ticks_t
+random_eo (cairo_t *cr, int width, int height)
+{
+    return draw_random (cr, CAIRO_FILL_RULE_EVEN_ODD, width, height);
+}
+
+static cairo_perf_ticks_t
+random_nz (cairo_t *cr, int width, int height)
+{
+    return draw_random (cr, CAIRO_FILL_RULE_WINDING, width, height);
+}
+
+void
+intersections (cairo_perf_t *perf, cairo_t *cr, int width, int height)
+{
+    cairo_perf_run (perf, "intersections-nz-fill", random_nz);
+    cairo_perf_run (perf, "intersections-eo-fill", random_eo);
+}


More information about the cairo-commit mailing list