summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly Biggs <vektor@freedesktop.org>2005-08-19 03:33:19 +0000
committerBilly Biggs <vektor@freedesktop.org>2005-08-19 03:33:19 +0000
commitb66126652fb511e0c28d8686a772fb17f8708d02 (patch)
treeb4ad6dafbb8e36b0b4b0f924a1a370118a6c4904
Initial revision
-rw-r--r--Makefile48
-rw-r--r--add.c88
-rw-r--r--curves.c71
-rw-r--r--downsample-bilinear.c88
-rw-r--r--downsample-nearest.c88
-rw-r--r--gradients-linear.c71
-rw-r--r--lines.c84
-rw-r--r--memcpy-helper.c32
-rw-r--r--multiple-clip-rectangles.c12
-rw-r--r--over-clipped.c90
-rw-r--r--over.c88
-rw-r--r--setup.h17
-rw-r--r--textpath.c89
-rw-r--r--texturedtext.c91
-rw-r--r--tools.c117
-rw-r--r--tools.h12
-rw-r--r--upsample-bilinear.c88
-rw-r--r--upsample-nearest.c88
18 files changed, 1262 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5983da4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,48 @@
+
+BENCHMARKS= \
+ over \
+ over-xlib \
+ over-clipped \
+ over-clipped-xlib \
+ add \
+ add-xlib \
+ upsample-bilinear \
+ upsample-bilinear-xlib \
+ upsample-nearest \
+ upsample-nearest-xlib \
+ downsample-bilinear \
+ downsample-bilinear-xlib \
+ downsample-nearest \
+ downsample-nearest-xlib \
+ lines \
+ lines-xlib \
+ curves \
+ curves-xlib \
+ gradients-linear \
+ gradients-linear-xlib \
+ textpath \
+ textpath-xlib \
+ texturedtext \
+ texturedtext-xlib
+
+MYCFLAGS=-Wall `pkg-config --cflags cairo libpng12`
+MYLDFLAGS=`pkg-config --libs cairo libpng12`
+
+MYOBJS=tools.o
+
+all: $(MYOBJS) $(BENCHMARKS)
+
+memcpy-helper: memcpy-helper.c
+ $(CC) -Wall -fPIC -shared -o memcpy-helper.so memcpy-helper.c -ldl
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) $(CPPFLAGS) ${MYCFLAGS} $< -o $@
+
+%-xlib: %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) ${MYCFLAGS} ${MYLDFLAGS} ${MYOBJS} $^ -o $@
+
+%: %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) ${MYCFLAGS} ${MYLDFLAGS} ${MYOBJS} $^ -o $@
+
+clean:
+ rm -f ${BENCHMARKS} *.o *.so *-out.png
diff --git a/add.c b/add.c
new file mode 100644
index 0000000..e88b6af
--- /dev/null
+++ b/add.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 640;
+static int height = 480;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (image);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "640x480-empty",
+ "640x480-opaque",
+ "640x480-shapes",
+ "640x480-text",
+ "640x480-transparentshapes"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-over-transparent-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/curves.c b/curves.c
new file mode 100644
index 0000000..be0224e
--- /dev/null
+++ b/curves.c
@@ -0,0 +1,71 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 512;
+static int height = 512;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface)
+{
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+
+ rdtscll (before);
+ for (i = 0; i < width + 1; i += 8) {
+ cairo_move_to (cr, i + 0.5, (height / 2) + 0.5);
+ cairo_curve_to (cr, i + 4.5, (i * 2) + 0.5,
+ i + 4.5, height - (i * 2) - 0.5,
+ i + 8.5, (height / 2) + 0.5);
+ cairo_stroke (cr);
+ }
+ rdtscll (after);
+
+ cairo_destroy (cr);
+
+ return (int) (after - before);
+}
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int j;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ fprintf (stderr, "Testing curves...\n");
+ test (surface);
+ cairo_surface_write_to_png (surface, "curves-out.png");
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/downsample-bilinear.c b/downsample-bilinear.c
new file mode 100644
index 0000000..d7f7287
--- /dev/null
+++ b/downsample-bilinear.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 64;
+static int height = 64;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_scale (cr, 1.0 / 8.0, 1.0 / 8.0);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "512x512-lenna",
+ "512x512-primrose",
+ "512x512-redsquare",
+ "512x512-transparent"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-downsample-bilinear-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy (surface);
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/downsample-nearest.c b/downsample-nearest.c
new file mode 100644
index 0000000..319ce8d
--- /dev/null
+++ b/downsample-nearest.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 64;
+static int height = 64;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_scale (cr, 1.0 / 8.0, 1.0 / 8.0);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "512x512-lenna",
+ "512x512-primrose",
+ "512x512-redsquare",
+ "512x512-transparent"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-downsample-nearest-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy (surface);
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/gradients-linear.c b/gradients-linear.c
new file mode 100644
index 0000000..777a631
--- /dev/null
+++ b/gradients-linear.c
@@ -0,0 +1,71 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 512;
+static int height = 512;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface)
+{
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_linear (0.0, 0.0, width, height);
+ cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, 1);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int j;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ fprintf (stderr, "Testing gradients-linear...\n");
+ test (surface);
+ cairo_surface_write_to_png (surface, "gradients-linear-out.png");
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/lines.c b/lines.c
new file mode 100644
index 0000000..975ce94
--- /dev/null
+++ b/lines.c
@@ -0,0 +1,84 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 512;
+static int height = 512;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface)
+{
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+
+ rdtscll (before);
+ for (i = 0; i < width + 1; i += 16) {
+ cairo_move_to (cr, 0.5, i + 0.5);
+ cairo_line_to (cr, i + 0.5, height - 0.5);
+ cairo_stroke (cr);
+ }
+ for (i = 0; i < width + 1; i += 16) {
+ cairo_move_to (cr, i + 0.5, height - 0.5);
+ cairo_line_to (cr, width - 0.5, height - i - 0.5);
+ cairo_stroke (cr);
+ }
+ for (i = 0; i < width + 1; i += 16) {
+ cairo_move_to (cr, width - 0.5, height - i - 0.5);
+ cairo_line_to (cr, width - i - 0.5, 0.5);
+ cairo_stroke (cr);
+ }
+ for (i = 0; i < width + 1; i += 16) {
+ cairo_move_to (cr, width - i - 0.5, 0.5);
+ cairo_line_to (cr, 0.5, i + 0.5);
+ cairo_stroke (cr);
+ }
+ rdtscll (after);
+
+ cairo_destroy (cr);
+
+ return (int) (after - before);
+}
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int j;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ fprintf (stderr, "Testing lines...\n");
+ test (surface);
+ cairo_surface_write_to_png (surface, "lines-out.png");
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/memcpy-helper.c b/memcpy-helper.c
new file mode 100644
index 0000000..20d6b5c
--- /dev/null
+++ b/memcpy-helper.c
@@ -0,0 +1,32 @@
+
+#include <stdio.h>
+#define __USE_GNU
+#include <dlfcn.h>
+
+static size_t memcpy_size = 0;
+static size_t last_checkpoint = 0;
+
+void *memcpy (void *dest, const void *src, size_t n)
+{
+ static void * (*real_memcpy) (void *, const void *, size_t) = 0;
+
+ if (!real_memcpy) {
+ real_memcpy = dlsym (RTLD_NEXT, "memcpy");
+ }
+
+ memcpy_size += n;
+
+ if (memcpy_size - last_checkpoint > (1024*1024)) {
+asm("int3");
+ fprintf (stderr, "memcpy total: %d\n", memcpy_size);
+ last_checkpoint = memcpy_size;
+ }
+ return real_memcpy (dest, src, n);
+/*
+ unsigned char *d = dest;
+ unsigned char *s = src;
+ while (n--) *d++ = *s++;
+ return dest;
+*/
+}
+
diff --git a/multiple-clip-rectangles.c b/multiple-clip-rectangles.c
new file mode 100644
index 0000000..8685b3d
--- /dev/null
+++ b/multiple-clip-rectangles.c
@@ -0,0 +1,12 @@
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_identity_matrix (cr);
+ cairo_rectangle (cr, 0.0, 0.0, width, height);
+ cairo_rectangle (cr, 200.0, 200.0, 100.0, 100.0);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+
+ cairo_translate (cr, 0, 0);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+ cairo_fill (cr);
+
diff --git a/over-clipped.c b/over-clipped.c
new file mode 100644
index 0000000..f17c084
--- /dev/null
+++ b/over-clipped.c
@@ -0,0 +1,90 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 640;
+static int height = 480;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_set_source (cr, pattern);
+
+ cairo_rectangle (cr, 128, 128, 128, 128);
+ cairo_clip (cr);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "640x480-empty",
+ "640x480-opaque",
+ "640x480-shapes",
+ "640x480-text",
+ "640x480-transparentshapes"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-over-transparent-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/over.c b/over.c
new file mode 100644
index 0000000..4f628af
--- /dev/null
+++ b/over.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 640;
+static int height = 480;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (image);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "640x480-empty",
+ "640x480-opaque",
+ "640x480-shapes",
+ "640x480-text",
+ "640x480-transparentshapes"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-over-transparent-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/setup.h b/setup.h
new file mode 100644
index 0000000..4e9e46c
--- /dev/null
+++ b/setup.h
@@ -0,0 +1,17 @@
+
+#ifndef SETUP_H_INCLUDED
+#define SETUP_H_INCLUDED
+
+/**
+ * Number of times to go for. Set this nice and high if you want to get
+ * a good oprofile sample.
+ */
+#define NUM_RUNS 256
+
+/**
+ * Set this to 1 to use realtime priority. Dangerous! This will hang your
+ * machine for the duration of the test! Infinite loop and you must reboot!
+ */
+#define USE_REALTIME_PRIORITY 0
+
+#endif /* SETUP_H_INCLUDED */
diff --git a/textpath.c b/textpath.c
new file mode 100644
index 0000000..497b6d7
--- /dev/null
+++ b/textpath.c
@@ -0,0 +1,89 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 512;
+static int height = 512;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+const char *text[] = {
+ "Cairo provides a stateful",
+ "user-level API with",
+ "capabilities similar to the",
+ "PDF 1.4 imaging model.",
+ "Cairo provides operations",
+ "including stroking and",
+ "filling Bezier cubic",
+ "splines, transforming",
+ "and compositing",
+ "translucent images, and",
+ "antialiased text rendering." };
+
+static int test (cairo_surface_t *surface)
+{
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_set_line_width (cr, 0.8);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+
+ cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 32.0);
+
+ rdtscll (before);
+ for (i = 0; i < sizeof (text) / sizeof (const char *); i++) {
+ cairo_move_to (cr, 10.5, 40.5 + (i * 45));
+ cairo_text_path (cr, text [i]);
+ cairo_set_source_rgb (cr, 0.85, 0.85, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_stroke (cr);
+ }
+ rdtscll (after);
+
+ cairo_destroy (cr);
+
+ return (int) (after - before);
+}
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int j;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ fprintf (stderr, "Testing textpath...\n");
+ test (surface);
+ cairo_surface_write_to_png (surface, "textpath-out.png");
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/texturedtext.c b/texturedtext.c
new file mode 100644
index 0000000..9897381
--- /dev/null
+++ b/texturedtext.c
@@ -0,0 +1,91 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 512;
+static int height = 512;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+const char *text[] = {
+ "C41r0",
+ "r0x0rz",
+ "!!11!" };
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+ int i;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 130.0);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ for (i = 0; i < sizeof (text) / sizeof (const char *); i++) {
+ cairo_text_extents_t extents;
+ double x;
+
+ cairo_text_extents (cr, text [i], &extents);
+ x = ((width - extents.width) / 2.0) + 0.5;
+
+ cairo_move_to (cr, x, 196.5 + (i * 128));
+ cairo_text_path (cr, text [i]);
+ cairo_set_source (cr, pattern);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_stroke (cr);
+ }
+ rdtscll (after);
+
+ cairo_destroy (cr);
+
+ return (int) (after - before);
+}
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int j;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ fprintf (stderr, "Testing texturedtext...\n");
+ test (surface, "256x256-darkgnome.png");
+ cairo_surface_write_to_png (surface, "texturedtext-out.png");
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, "256x256-darkgnome.png");
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+
+ cairo_surface_destroy( surface );
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/tools.c b/tools.c
new file mode 100644
index 0000000..10f30ad
--- /dev/null
+++ b/tools.c
@@ -0,0 +1,117 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sched.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <cairo-xlib-xrender.h>
+#include "tools.h"
+#include "setup.h"
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int mhz_calculated = 0;
+double mhz;
+
+static double cpuinfo_get_speed( void )
+{
+ uint64_t tsc_start, tsc_end;
+ struct timeval tv_start, tv_end;
+ int usec_delay;
+
+ rdtscll( tsc_start );
+ gettimeofday( &tv_start, 0 );
+ usleep( 100000 );
+ rdtscll( tsc_end );
+ gettimeofday( &tv_end, 0 );
+
+ usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec) +
+ (tv_end.tv_usec - tv_start.tv_usec);
+
+ return (((double) (tsc_end - tsc_start)) / ((double) usec_delay));
+}
+
+int set_realtime_priority( int max )
+{
+ struct sched_param schp;
+
+ memset( &schp, 0, sizeof( schp ) );
+ if( max ) schp.sched_priority = sched_get_priority_max( SCHED_FIFO );
+ else schp.sched_priority = sched_get_priority_max( SCHED_FIFO ) - 1;
+
+ if( sched_setscheduler( 0, SCHED_FIFO, &schp ) != 0 ) {
+ return 0;
+ }
+
+ return 1;
+}
+
+double get_milliseconds( int cycles )
+{
+ if( !mhz_calculated ) {
+ mhz = cpuinfo_get_speed();
+ mhz_calculated = 1;
+ }
+ return ((double) cycles) / (mhz * 1000.0);
+}
+
+static Display *dpy;
+static Pixmap pixmap;
+static int xlib = 0;
+
+static cairo_surface_t *create_xlib_surface (int width, int height)
+{
+ cairo_surface_t *surface;
+ XRenderPictFormat *xrender_format;
+
+ dpy = XOpenDisplay (0);
+
+ xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ width, height, xrender_format->depth);
+
+ surface = cairo_xlib_surface_create_with_xrender_format (dpy, pixmap,
+ DefaultScreenOfDisplay (dpy), xrender_format, width, height);
+ return surface;
+}
+
+static void cleanup_xlib (void)
+{
+ XFreePixmap (dpy, pixmap);
+ XCloseDisplay (dpy);
+}
+
+static uint8_t *data = 0;
+
+cairo_surface_t *output_create_surface (const char *appname, int width,
+ int height)
+{
+ if (USE_REALTIME_PRIORITY) {
+ if (!set_realtime_priority (0)) {
+ fprintf (stderr, "Cannot set realtime priority (need root)\n");
+ }
+ }
+
+ if (strstr (appname, "xlib")) {
+ return create_xlib_surface (width, height);
+ } else {
+ data = malloc (width * height * 4);
+ return cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
+ width, height, width * 4);
+ }
+}
+
+void output_cleanup (void)
+{
+ if (xlib) {
+ cleanup_xlib ();
+ } else {
+ free (data);
+ }
+}
+
+
diff --git a/tools.h b/tools.h
new file mode 100644
index 0000000..8f0bc3b
--- /dev/null
+++ b/tools.h
@@ -0,0 +1,12 @@
+
+#ifndef TOOLS_H_INCLUDED
+#define TOOLS_H_INCLUDED
+
+#include <cairo.h>
+
+double get_milliseconds( int cycles );
+cairo_surface_t *output_create_surface (const char *appname, int width,
+ int height);
+void output_cleanup (void);
+
+#endif /* TOOLS_H_INCLUDED */
diff --git a/upsample-bilinear.c b/upsample-bilinear.c
new file mode 100644
index 0000000..db0ba9d
--- /dev/null
+++ b/upsample-bilinear.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 384;
+static int height = 384;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_scale (cr, 8.0, 8.0);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "48x48-brokenlock",
+ "48x48-mail",
+ "48x48-script",
+ "48x48-todo"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-upsample-bilinear-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2f ms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy (surface);
+ output_cleanup ();
+ return 0;
+}
+
diff --git a/upsample-nearest.c b/upsample-nearest.c
new file mode 100644
index 0000000..0fb8220
--- /dev/null
+++ b/upsample-nearest.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <cairo.h>
+#include "tools.h"
+#include "setup.h"
+
+static int width = 384;
+static int height = 384;
+
+#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static int test (cairo_surface_t *surface, const char *png_filename)
+{
+ cairo_surface_t *image = cairo_image_surface_create_from_png (png_filename);
+ cairo_pattern_t *pattern;
+ uint64_t before = 0;
+ uint64_t after = 0;
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+
+ cairo_scale (cr, 8.0, 8.0);
+
+ pattern = cairo_pattern_create_for_surface (image);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+ cairo_set_source (cr, pattern);
+
+ rdtscll (before);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+ rdtscll (after);
+
+ cairo_destroy (cr);
+ cairo_pattern_destroy (pattern);
+
+ return (int) (after - before);
+}
+
+static const char *filenames[] = {
+ "48x48-brokenlock",
+ "48x48-mail",
+ "48x48-script",
+ "48x48-todo"
+};
+
+int main( int argc, char **argv )
+{
+ cairo_surface_t *surface;
+ int i;
+
+ surface = output_create_surface (argv [0], width, height);
+
+ for (i = 0; i < sizeof (filenames) / sizeof (const char *); i++) {
+ char input_filename [1024];
+ char output_filename [1024];
+ int j;
+
+ fprintf (stderr, "Testing %s...\n", filenames [i]);
+ sprintf (input_filename, "%s.png", filenames [i]);
+ sprintf (output_filename, "%s-upsample-nearest-out.png",
+ filenames [i]);
+
+ test (surface, input_filename);
+ cairo_surface_write_to_png (surface, output_filename);
+
+ for (j = 0; j < NUM_RUNS; j++) {
+ int cur = test (surface, input_filename);
+ fprintf (stderr, "\t%d: %d (%.2fms)\n", j, cur,
+ get_milliseconds (cur));
+ }
+ }
+
+ cairo_surface_destroy (surface);
+ output_cleanup ();
+ return 0;
+}
+