[Pixman] [PATCH] Add a lowlevel blitter benchmark

Dmitri Vorobiev dmitri.vorobiev at movial.com
Wed Sep 15 05:37:41 PDT 2010


From: Jonathan Morton <jonathan.morton at movial.com>

This test is a modified version of Siarhei's compositor throughput
benchmark.  It's expanded with explicit reporting of memory bandwidth
consumption for the M-test, and with an additional 8x8-random test
intended to determine peak ops/sec capability.  There are also quite a
lot more operations tested for.

We try to be portable as much as we can, and take care of systems
that do not support gettimeofday() or memalign() calls. For this
reason, we add checking for these calls, and update test utils to
fall back to time() or malloc(), respectively.
---
 configure.ac              |   17 +-
 test/Makefile.am          |    6 +-
 test/blitters-test.c      |   15 -
 test/lowlevel-blt-bench.c |  713 +++++++++++++++++++++++++++++++++++++++++++++
 test/utils.c              |   52 ++++
 test/utils.h              |    8 +
 6 files changed, 794 insertions(+), 17 deletions(-)
 create mode 100644 test/lowlevel-blt-bench.c

diff --git a/configure.ac b/configure.ac
index dbff2a6..a6f4d95 100644
--- a/configure.ac
+++ b/configure.ac
@@ -606,7 +606,7 @@ AC_SUBST(DEP_CFLAGS)
 AC_SUBST(DEP_LIBS)
 
 dnl =====================================
-dnl posix_memalign, sigaction, alarm
+dnl posix_memalign, sigaction, alarm, gettimeofday, memalign
 
 AC_CHECK_FUNC(posix_memalign, have_posix_memalign=yes, have_posix_memalign=no)
 if test x$have_posix_memalign = xyes; then
@@ -623,6 +623,21 @@ if test x$have_alarm = xyes; then
    AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()])
 fi
 
+AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
+if test x$have_gettimeofday = xyes; then
+   AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Whether we have gettimeofday()])
+fi
+
+AC_CHECK_FUNC(time, have_time=yes, have_time=no)
+if test x$have_time = xyes; then
+   AC_DEFINE(HAVE_TIME, 1, [Whether we have time()])
+fi
+
+AC_CHECK_FUNC(memalign, have_memalign=yes, have_memalign=no)
+if test x$have_memalign = xyes; then
+   AC_DEFINE(HAVE_MEMALIGN, 1, [Whether we have memalign()])
+fi
+
 dnl =====================================
 dnl Thread local storage
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 3d98e17..8f3fdaf 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -18,7 +18,8 @@ TESTPROGRAMS =			\
 	scaling-crash-test	\
 	blitters-test		\
 	scaling-test		\
-	composite
+	composite		\
+	lowlevel-blt-bench
 
 a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
@@ -45,6 +46,9 @@ alphamap_SOURCES = alphamap.c utils.c utils.h
 alpha_loop_LDADD = $(TEST_LDADD)
 alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
 
+lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h
+lowlevel_blt_bench_LDADD = $(TEST_LDADD)
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 9dd9163..7ba80eb 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -14,21 +14,6 @@
 static pixman_indexed_t rgb_palette[9];
 static pixman_indexed_t y_palette[9];
 
-static void *
-aligned_malloc (size_t align, size_t size)
-{
-    void *result;
-
-#ifdef HAVE_POSIX_MEMALIGN
-    if (posix_memalign (&result, align, size) != 0)
-      result = NULL;
-#else
-    result = malloc (size);
-#endif
-
-    return result;
-}
-
 /* Create random image for testing purposes */
 static pixman_image_t *
 create_random_image (pixman_format_code_t *allowed_formats,
diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
new file mode 100644
index 0000000..ac1a67c
--- /dev/null
+++ b/test/lowlevel-blt-bench.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright © 2010 Movial Creative Technologies Oy
+ *
+ * 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 ARM Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  ARM Ltd makes 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.
+ *
+ * Author:  Jonathan Morton (jonathan.morton at movial.com)
+ *
+ * Based on the code by Siarhei Siamashka <siarhei.siamashka at gmail.com>
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+#include "utils.h"
+
+#define SOLID_FLAG 1
+#define CA_FLAG    2
+
+#define L1CACHE_SIZE (8 * 1024)
+#define L2CACHE_SIZE (128 * 1024)
+
+#define WIDTH  1920
+#define HEIGHT 1080
+#define BUFSIZE (WIDTH * HEIGHT * 4)
+#define XWIDTH 256
+#define XHEIGHT 256
+#define TILEWIDTH 32
+#define TINYWIDTH 8
+
+#define EXCLUDE_OVERHEAD 1
+
+uint32_t *dst;
+uint32_t *src;
+uint32_t *mask;
+
+double bandwidth = 0;
+
+double
+bench_memcpy ()
+{
+    int64_t n = 0, total;
+    double  t1, t2;
+    int     x = 0;
+
+    t1 = gettime ();
+    while (1)
+    {
+	memcpy (dst, src, BUFSIZE - 64);
+	memcpy (src, dst, BUFSIZE - 64);
+	n += 4 * (BUFSIZE - 64);
+	t2 = gettime ();
+	if (t2 - t1 > 0.5)
+	    break;
+    }
+    n = total = n * 5;
+    t1 = gettime ();
+    while (n > 0)
+    {
+	if (++x >= 64)
+	    x = 0;
+	memcpy ((char *)dst + 1, (char *)src + x, BUFSIZE - 64);
+	memcpy ((char *)src + 1, (char *)dst + x, BUFSIZE - 64);
+	n -= 4 * (BUFSIZE - 64);
+    }
+    t2 = gettime ();
+    return (double)total / (t2 - t1);
+}
+
+static void
+pixman_image_composite_wrapper (pixman_implementation_t *impl,
+                                pixman_op_t              op,
+                                pixman_image_t *         src_image,
+                                pixman_image_t *         mask_image,
+                                pixman_image_t *         dst_image,
+                                int32_t                  src_x,
+                                int32_t                  src_y,
+                                int32_t                  mask_x,
+                                int32_t                  mask_y,
+                                int32_t                  dest_x,
+                                int32_t                  dest_y,
+                                int32_t                  width,
+                                int32_t                  height)
+{
+    pixman_image_composite (op, src_image, mask_image, dst_image, src_x,
+                            src_y, mask_x, mask_y, dest_x, dest_y, width, height);
+}
+
+static void
+pixman_image_composite_empty (pixman_implementation_t *impl,
+                              pixman_op_t              op,
+                              pixman_image_t *         src_image,
+                              pixman_image_t *         mask_image,
+                              pixman_image_t *         dst_image,
+                              int32_t                  src_x,
+                              int32_t                  src_y,
+                              int32_t                  mask_x,
+                              int32_t                  mask_y,
+                              int32_t                  dest_x,
+                              int32_t                  dest_y,
+                              int32_t                  width,
+                              int32_t                  height)
+{
+    pixman_image_composite (op, src_image, mask_image, dst_image, 0,
+                            0, 0, 0, 0, 0, 1, 1);
+}
+
+void __attribute__((noinline))
+bench_L  (pixman_op_t              op,
+          pixman_image_t *         src_img,
+          pixman_image_t *         mask_img,
+          pixman_image_t *         dst_img,
+          int64_t                  n,
+          pixman_composite_func_t  func,
+          int                      width,
+          int                      lines_count)
+{
+    int64_t      i, j;
+    int          x = 0;
+    int          q = 0;
+    volatile int qx;
+
+    for (i = 0; i < n; i++)
+    {
+	/* touch destination buffer to fetch it into L1 cache */
+	for (j = 0; j < width + 64; j += 16) {
+	    q += dst[j];
+	    q += src[j];
+	}
+	if (++x >= 64)
+	    x = 0;
+	func (0, op, src_img, mask_img, dst_img, x, 0, x, 0, 63 - x, 0, width, lines_count);
+    }
+    qx = q;
+}
+
+void __attribute__((noinline))
+bench_M (pixman_op_t              op,
+         pixman_image_t *         src_img,
+         pixman_image_t *         mask_img,
+         pixman_image_t *         dst_img,
+         int64_t                  n,
+         pixman_composite_func_t  func)
+{
+    int64_t i;
+    int     x = 0;
+
+    for (i = 0; i < n; i++)
+    {
+	if (++x >= 64)
+	    x = 0;
+	func (0, op, src_img, mask_img, dst_img, x, 0, x, 0, 1, 0, WIDTH - 64, HEIGHT);
+    }
+}
+
+double __attribute__((noinline))
+bench_HT (pixman_op_t              op,
+          pixman_image_t *         src_img,
+          pixman_image_t *         mask_img,
+          pixman_image_t *         dst_img,
+          int64_t                  n,
+          pixman_composite_func_t  func)
+{
+    double  pix_cnt = 0;
+    int     x = 0;
+    int     y = 0;
+    int64_t i;
+
+    srand (0);
+    for (i = 0; i < n; i++)
+    {
+	int w = (rand () % (TILEWIDTH * 2)) + 1;
+	int h = (rand () % (TILEWIDTH * 2)) + 1;
+	if (x + w > WIDTH)
+	{
+	    x = 0;
+	    y += TILEWIDTH * 2;
+	}
+	if (y + h > HEIGHT)
+	{
+	    y = 0;
+	}
+	func (0, op, src_img, mask_img, dst_img, x, y, x, y, x, y, w, h);
+	x += w;
+	pix_cnt += w * h;
+    }
+    return pix_cnt;
+}
+
+double __attribute__((noinline))
+bench_VT (pixman_op_t              op,
+          pixman_image_t *         src_img,
+          pixman_image_t *         mask_img,
+          pixman_image_t *         dst_img,
+          int64_t                  n,
+          pixman_composite_func_t  func)
+{
+    double  pix_cnt = 0;
+    int     x = 0;
+    int     y = 0;
+    int64_t i;
+
+    srand (0);
+    for (i = 0; i < n; i++)
+    {
+	int w = (rand () % (TILEWIDTH * 2)) + 1;
+	int h = (rand () % (TILEWIDTH * 2)) + 1;
+	if (y + h > HEIGHT)
+	{
+	    y = 0;
+	    x += TILEWIDTH * 2;
+	}
+	if (x + w > WIDTH)
+	{
+	    x = 0;
+	}
+	func (0, op, src_img, mask_img, dst_img, x, y, x, y, x, y, w, h);
+	y += h;
+	pix_cnt += w * h;
+    }
+    return pix_cnt;
+}
+
+double __attribute__((noinline))
+bench_R (pixman_op_t              op,
+         pixman_image_t *         src_img,
+         pixman_image_t *         mask_img,
+         pixman_image_t *         dst_img,
+         int64_t                  n,
+         pixman_composite_func_t  func,
+         int                      maxw,
+         int                      maxh)
+{
+    double  pix_cnt = 0;
+    int64_t i;
+
+    if (maxw <= TILEWIDTH * 2 || maxh <= TILEWIDTH * 2)
+    {
+	printf("error: maxw <= TILEWIDTH * 2 || maxh <= TILEWIDTH * 2\n");
+        return 0;
+    }
+
+    srand (0);
+    for (i = 0; i < n; i++)
+    {
+	int w = (rand () % (TILEWIDTH * 2)) + 1;
+	int h = (rand () % (TILEWIDTH * 2)) + 1;
+	int sx = rand () % (maxw - TILEWIDTH * 2);
+	int sy = rand () % (maxh - TILEWIDTH * 2);
+	int dx = rand () % (maxw - TILEWIDTH * 2);
+	int dy = rand () % (maxh - TILEWIDTH * 2);
+	func (0, op, src_img, mask_img, dst_img, sx, sy, sx, sy, dx, dy, w, h);
+	pix_cnt += w * h;
+    }
+    return pix_cnt;
+}
+
+double __attribute__((noinline))
+bench_RT (pixman_op_t              op,
+          pixman_image_t *         src_img,
+          pixman_image_t *         mask_img,
+          pixman_image_t *         dst_img,
+          int64_t                  n,
+          pixman_composite_func_t  func,
+          int                      maxw,
+          int                      maxh)
+{
+    double  pix_cnt = 0;
+    int64_t i;
+
+    if (maxw <= TINYWIDTH * 2 || maxh <= TINYWIDTH * 2)
+    {
+	printf("error: maxw <= TINYWIDTH * 2 || maxh <= TINYWIDTH * 2\n");
+        return 0;
+    }
+
+    srand (0);
+    for (i = 0; i < n; i++)
+    {
+	int w = (rand () % (TINYWIDTH * 2)) + 1;
+	int h = (rand () % (TINYWIDTH * 2)) + 1;
+	int sx = rand () % (maxw - TINYWIDTH * 2);
+	int sy = rand () % (maxh - TINYWIDTH * 2);
+	int dx = rand () % (maxw - TINYWIDTH * 2);
+	int dy = rand () % (maxh - TINYWIDTH * 2);
+	func (0, op, src_img, mask_img, dst_img, sx, sy, sx, sy, dx, dy, w, h);
+	pix_cnt += w * h;
+    }
+    return pix_cnt;
+}
+
+void
+bench_composite (char * testname,
+                 int    src_fmt,
+                 int    src_flags,
+                 int    op,
+                 int    mask_fmt,
+                 int    mask_flags,
+                 int    dst_fmt,
+                 double npix)
+{
+    pixman_image_t *                src_img;
+    pixman_image_t *                dst_img;
+    pixman_image_t *                mask_img;
+    pixman_image_t *                xsrc_img;
+    pixman_image_t *                xdst_img;
+    pixman_image_t *                xmask_img;
+    double                          t1, t2, t3, pix_cnt;
+    int64_t                         n, l1test_width, nlines;
+    double                             bytes_per_pix = 0;
+
+    pixman_composite_func_t func = pixman_image_composite_wrapper;
+
+    if (!(src_flags & SOLID_FLAG))
+    {
+        bytes_per_pix += (src_fmt >> 24) / 8.0;
+        src_img = pixman_image_create_bits (src_fmt,
+                                            WIDTH, HEIGHT,
+                                            src,
+                                            WIDTH * 4);
+        xsrc_img = pixman_image_create_bits (src_fmt,
+                                             XWIDTH, XHEIGHT,
+                                             src,
+                                             XWIDTH * 4);
+    }
+    else
+    {
+        src_img = pixman_image_create_bits (src_fmt,
+                                            1, 1,
+                                            src,
+                                            4);
+        xsrc_img = pixman_image_create_bits (src_fmt,
+                                             1, 1,
+                                             src,
+                                             4);
+        pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
+        pixman_image_set_repeat (xsrc_img, PIXMAN_REPEAT_NORMAL);
+    }
+
+    bytes_per_pix += (dst_fmt >> 24) / 8.0;
+    dst_img = pixman_image_create_bits (dst_fmt,
+                                        WIDTH, HEIGHT,
+                                        dst,
+                                        WIDTH * 4);
+
+    mask_img = NULL;
+    xmask_img = NULL;
+    if (!(mask_flags & SOLID_FLAG) && mask_fmt != PIXMAN_null)
+    {
+        bytes_per_pix += (mask_fmt >> 24) / ((op == PIXMAN_OP_SRC) ? 8.0 : 4.0);
+        mask_img = pixman_image_create_bits (mask_fmt,
+                                             WIDTH, HEIGHT,
+                                             mask,
+                                             WIDTH * 4);
+        xmask_img = pixman_image_create_bits (mask_fmt,
+                                             XWIDTH, XHEIGHT,
+                                             mask,
+                                             XWIDTH * 4);
+    }
+    else if (mask_fmt != PIXMAN_null)
+    {
+        mask_img = pixman_image_create_bits (mask_fmt,
+                                             1, 1,
+                                             mask,
+                                             4);
+        xmask_img = pixman_image_create_bits (mask_fmt,
+                                             1, 1,
+                                             mask,
+                                             4 * 4);
+       pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
+       pixman_image_set_repeat (xmask_img, PIXMAN_REPEAT_NORMAL);
+    }
+    if ((mask_flags & CA_FLAG) && mask_fmt != PIXMAN_null)
+    {
+       pixman_image_set_component_alpha (mask_img, 1);
+    }
+    xdst_img = pixman_image_create_bits (dst_fmt,
+                                         XWIDTH, XHEIGHT,
+                                         dst,
+                                         XWIDTH * 4);
+
+
+    printf ("%24s %c", testname, func != pixman_image_composite_wrapper ?
+            '-' : '=');
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    l1test_width = L1CACHE_SIZE / 8 - 64;
+    if (l1test_width < 1)
+	l1test_width = 1;
+    if (l1test_width > WIDTH - 64)
+	l1test_width = WIDTH - 64;
+    n = 1 + npix / (l1test_width * 8);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, 1);
+#endif
+    t2 = gettime ();
+    bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, 1);
+    t3 = gettime ();
+    printf ("  L1:%7.2f", (double)n * l1test_width * 1 /
+            ((t3 - t2) - (t2 - t1)) / 1000000.);
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    nlines = (L2CACHE_SIZE / l1test_width) /
+	((PIXMAN_FORMAT_BPP(src_fmt) + PIXMAN_FORMAT_BPP(dst_fmt)) / 8);
+    if (nlines < 1)
+	nlines = 1;
+    n = 1 + npix / (l1test_width * nlines);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    bench_L (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, l1test_width, nlines);
+#endif
+    t2 = gettime ();
+    bench_L (op, src_img, mask_img, dst_img, n, func, l1test_width, nlines);
+    t3 = gettime ();
+    printf ("  L2:%7.2f", (double)n * l1test_width * nlines /
+            ((t3 - t2) - (t2 - t1)) / 1000000.);
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    n = 1 + npix / (WIDTH * HEIGHT);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    bench_M (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
+#endif
+    t2 = gettime ();
+    bench_M (op, src_img, mask_img, dst_img, n, func);
+    t3 = gettime ();
+    printf ("  M:%6.2f (%6.2f%%)",
+        ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1))) / 1000000.,
+        ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) );
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
+#endif
+    t2 = gettime ();
+    pix_cnt = bench_HT (op, src_img, mask_img, dst_img, n, func);
+    t3 = gettime ();
+    printf ("  HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty);
+#endif
+    t2 = gettime ();
+    pix_cnt = bench_VT (op, src_img, mask_img, dst_img, n, func);
+    t3 = gettime ();
+    printf ("  VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, WIDTH, HEIGHT);
+#endif
+    t2 = gettime ();
+    pix_cnt = bench_R (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
+    t3 = gettime ();
+    printf ("  R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
+    fflush (stdout);
+
+    memcpy (src, dst, BUFSIZE);
+    memcpy (dst, src, BUFSIZE);
+
+    n = 1 + npix / (16 * TINYWIDTH * TINYWIDTH);
+    t1 = gettime ();
+#if EXCLUDE_OVERHEAD
+    pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, pixman_image_composite_empty, WIDTH, HEIGHT);
+#endif
+    t2 = gettime ();
+    pix_cnt = bench_RT (op, src_img, mask_img, dst_img, n, func, WIDTH, HEIGHT);
+    t3 = gettime ();
+    printf ("  RT:%6.2f (%4.0fKops/s)\n", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000., (double) n / ((t3 - t2) * 1000));
+
+    if (mask_img) {
+	pixman_image_unref (mask_img);
+	pixman_image_unref (xmask_img);
+    }
+    pixman_image_unref (src_img);
+    pixman_image_unref (dst_img);
+    pixman_image_unref (xsrc_img);
+    pixman_image_unref (xdst_img);
+}
+
+#define PIXMAN_OP_OUT_REV (PIXMAN_OP_OUT_REVERSE)
+
+struct
+{
+    char *testname;
+    int   src_fmt;
+    int   src_flags;
+    int   op;
+    int   mask_fmt;
+    int   mask_flags;
+    int   dst_fmt;
+}
+tests_tbl[] =
+{
+    { "add_8_8_8",             PIXMAN_a8,          0, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a8 },
+    { "add_n_8_8000",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a8 },
+    { "add_n_8_8888",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "add_n_8_x888",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "add_n_8_0565",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "add_n_8_1555",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a1r5g5b5 },
+    { "add_n_8_4444",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a4r4g4b4 },
+    { "add_n_8_2222",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a2r2g2b2 },
+    { "add_n_8_2x10",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_x2r10g10b10 },
+    { "add_n_8_2a10",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_a8,       0, PIXMAN_a2r10g10b10 },
+    { "add_n_8000",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a8 },
+    { "add_n_8888",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "add_n_x888",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "add_n_0565",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "add_n_1555",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "add_n_4444",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a4r4g4b4 },
+    { "add_n_2222",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a2r2g2b2 },
+    { "add_n_2x10",            PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_x2r10g10b10 },
+    { "add_n_2a10",            PIXMAN_a2r10g10b10, 1, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a2r10g10b10 },
+    { "add_8000_8000",         PIXMAN_a8,          0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a8 },
+    { "add_x888_x888",         PIXMAN_x8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "add_8888_8888",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "add_8888_0565",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "add_8888_1555",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "add_8888_4444",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a4r4g4b4 },
+    { "add_8888_2222",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a2r2g2b2 },
+    { "add_0565_0565",         PIXMAN_r5g6b5,      0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "add_1555_1555",         PIXMAN_a1r5g5b5,    0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "add_0565_2x10",         PIXMAN_r5g6b5,      0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_x2r10g10b10 },
+    { "add_2a10_2a10",         PIXMAN_a2r10g10b10, 0, PIXMAN_OP_ADD,     PIXMAN_null,     0, PIXMAN_a2r10g10b10 },
+    { "src_n_2222",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "src_n_0565",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "src_n_1555",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "src_n_4444",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "src_n_x888",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "src_n_8888",            PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "src_n_2x10",            PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_x2r10g10b10 },
+    { "src_n_2a10",            PIXMAN_a2r10g10b10, 1, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a2r10g10b10 },
+    { "src_8888_0565",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "src_8888_4444",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a4r4g4b4 },
+    { "src_8888_2222",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a2r2g2b2 },
+    { "src_8888_2x10",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_x2r10g10b10 },
+    { "src_8888_2a10",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a2r10g10b10 },
+    { "src_0888_0565",         PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "src_0888_8888",         PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "src_0888_x888",         PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "src_x888_x888",         PIXMAN_x8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "src_x888_8888",         PIXMAN_x8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "src_8888_8888",         PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "src_0565_0565",         PIXMAN_r5g6b5,      0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "src_1555_0565",         PIXMAN_a1r5g5b5,    0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "src_0565_1555",         PIXMAN_r5g6b5,      0, PIXMAN_OP_SRC,     PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "src_n_8_0565",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "src_n_8_1555",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a1r5g5b5 },
+    { "src_n_8_4444",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a4r4g4b4 },
+    { "src_n_8_2222",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a2r2g2b2 },
+    { "src_n_8_x888",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "src_n_8_8888",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "src_n_8_2x10",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_x2r10g10b10 },
+    { "src_n_8_2a10",          PIXMAN_a8r8g8b8,    1, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a2r10g10b10 },
+    { "src_8888_8_0565",       PIXMAN_a8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "src_0888_8_0565",       PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "src_0888_8_8888",       PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "src_0888_8_x888",       PIXMAN_r8g8b8,      0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "src_x888_8_x888",       PIXMAN_x8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "src_x888_8_8888",       PIXMAN_x8r8g8b8,    0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "src_0565_8_0565",       PIXMAN_r5g6b5,      0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "src_1555_8_0565",       PIXMAN_a1r5g5b5,    0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "src_0565_8_1555",       PIXMAN_r5g6b5,      0, PIXMAN_OP_SRC,     PIXMAN_a8,       0, PIXMAN_a1r5g5b5 },
+    { "over_n_x888",           PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "over_n_8888",           PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_a8r8g8b8 },
+    { "over_n_0565",           PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "over_n_1555",           PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_a1r5g5b5 },
+    { "over_8888_0565",        PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_r5g6b5 },
+    { "over_8888_x888",        PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_null,     0, PIXMAN_x8r8g8b8 },
+    { "over_n_8_0565",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "over_n_8_1555",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_a1r5g5b5 },
+    { "over_n_8_4444",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_a4r4g4b4 },
+    { "over_n_8_2222",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_a2r2g2b2 },
+    { "over_n_8_x888",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "over_n_8_8888",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "over_n_8_2x10",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_x2r10g10b10 },
+    { "over_n_8_2a10",         PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8,       0, PIXMAN_a2r10g10b10 },
+    { "over_n_8888_8888_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 },
+    { "over_n_8888_x888_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 },
+    { "over_n_8888_0565_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_r5g6b5 },
+    { "over_n_8888_1555_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 },
+    { "over_n_8888_4444_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_a4r4g4b4 },
+    { "over_n_8888_2222_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_a2r2g2b2 },
+    { "over_n_8888_2x10_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_x2r10g10b10 },
+    { "over_n_8888_2a10_ca",   PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OVER,    PIXMAN_a8r8g8b8, 2, PIXMAN_a2r10g10b10 },
+    { "over_8888_n_8888",      PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_a8,       1, PIXMAN_a8r8g8b8 },
+    { "over_8888_n_x888",      PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_a8,       1, PIXMAN_x8r8g8b8 },
+    { "over_8888_n_0565",      PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_a8,       1, PIXMAN_r5g6b5 },
+    { "over_8888_n_1555",      PIXMAN_a8r8g8b8,    0, PIXMAN_OP_OVER,    PIXMAN_a8,       1, PIXMAN_a1r5g5b5 },
+    { "outrev_n_8_0565",       PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8,       0, PIXMAN_r5g6b5 },
+    { "outrev_n_8_1555",       PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8,       0, PIXMAN_a1r5g5b5 },
+    { "outrev_n_8_x888",       PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8,       0, PIXMAN_x8r8g8b8 },
+    { "outrev_n_8_8888",       PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8,       0, PIXMAN_a8r8g8b8 },
+    { "outrev_n_8888_0565_ca", PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_r5g6b5 },
+    { "outrev_n_8888_1555_ca", PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a1r5g5b5 },
+    { "outrev_n_8888_x888_ca", PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_x8r8g8b8 },
+    { "outrev_n_8888_8888_ca", PIXMAN_a8r8g8b8,    1, PIXMAN_OP_OUT_REV, PIXMAN_a8r8g8b8, 2, PIXMAN_a8r8g8b8 },
+};
+
+int
+main (int argc, char *argv[])
+{
+    double x;
+    int i;
+    char *pattern = argc > 1 ? argv[1] : "all";
+
+    src = aligned_malloc (4096, BUFSIZE * 3);
+    memset (src, 0xCC, BUFSIZE * 3);
+    dst = src + (BUFSIZE / 4);
+    mask = dst + (BUFSIZE / 4);
+
+    printf ("Benchmark for a set of most commonly used functions\n");
+    printf ("---\n");
+    printf ("All results are presented in millions of pixels per second\n");
+    printf ("L1  - small Xx1 rectangle (fitting L1 cache), always blitted at the same\n");
+    printf ("      memory location with small drift in horizontal direction\n");
+    printf ("L2  - small XxY rectangle (fitting L2 cache), always blitted at the same\n");
+    printf ("      memory location with small drift in horizontal direction\n");
+    printf ("M   - large %dx%d rectangle, always blitted at the same\n",
+            WIDTH - 64, HEIGHT);
+    printf ("      memory location with small drift in horizontal direction\n");
+    printf ("HT  - random rectangles with %dx%d average size are copied from\n",
+            TILEWIDTH, TILEWIDTH);
+    printf ("      one %dx%d buffer to another, traversing from left to right\n",
+            WIDTH, HEIGHT);
+    printf ("      and from top to bottom\n");
+    printf ("VT  - random rectangles with %dx%d average size are copied from\n",
+            TILEWIDTH, TILEWIDTH);
+    printf ("      one %dx%d buffer to another, traversing from top to bottom\n",
+            WIDTH, HEIGHT);
+    printf ("      and from left to right\n");
+    printf ("R   - random rectangles with %dx%d average size are copied from\n",
+            TILEWIDTH, TILEWIDTH);
+    printf ("      random locations of one %dx%d buffer to another\n",
+            WIDTH, HEIGHT);
+    printf ("RT  - as R, but %dx%d average sized rectangles are copied\n",
+            TINYWIDTH, TINYWIDTH);
+    printf ("---\n");
+    bandwidth = x = bench_memcpy ();
+    printf ("reference memcpy speed = %.1fMB/s (%.1fMP/s for 32bpp fills)\n",
+            x / 1000000., x / 4000000);
+    printf ("---\n");
+
+    for (i = 0; i < sizeof(tests_tbl) / sizeof(tests_tbl[0]); i++)
+    {
+	if (strcmp (pattern, "all") == 0 || strstr (tests_tbl[i].testname, pattern))
+	{
+	    bench_composite (tests_tbl[i].testname,
+			     tests_tbl[i].src_fmt,
+			     tests_tbl[i].src_flags,
+			     tests_tbl[i].op,
+			     tests_tbl[i].mask_fmt,
+			     tests_tbl[i].mask_flags,
+			     tests_tbl[i].dst_fmt,
+			     bandwidth/8);
+	}
+    }
+
+    free (src);
+    return 0;
+}
diff --git a/test/utils.c b/test/utils.c
index d95cbc2..0ebd8c4 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -5,6 +5,18 @@
 #include <unistd.h>
 #endif
 
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#elif HAVE_TIME
+#include <time.h>
+#else
+#error I can't measure time on this system
+#endif
+
+#if !defined(HAVE_POSIX_MEMLALIGN) && !defined(HAVE_MEMALIGN)
+#include <malloc.h>
+#endif
+
 /* Random number seed
  */
 
@@ -352,3 +364,43 @@ fail_after (int seconds, const char *msg)
 #endif
 #endif
 }
+
+/*
+ * This is needed for benchmarking code. We try two options here, namely
+ * gettimeofday() and time(), which, we believe, would cover all systems
+ * we could be running on.
+ */
+
+double
+gettime ()
+{
+#ifdef HAVE_GETTIMEOFDAY
+    struct timeval tv;
+
+    gettimeofday (&tv, NULL);
+    return (double)((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) / 1000000.;
+#elif HAVE_TIME
+    return (double)time();
+#endif
+}
+
+/*
+ * Try hard to get aligned memory chunk.
+ */
+
+void *
+aligned_malloc (size_t align, size_t size)
+{
+    void *result;
+
+#ifdef HAVE_POSIX_MEMALIGN
+    if (posix_memalign (&result, align, size) != 0)
+      result = NULL;
+#elif HAVE_MEMALIGN
+    result = memalign (align, size);
+#else
+    result = malloc (size);
+#endif
+
+    return result;
+}
diff --git a/test/utils.h b/test/utils.h
index a39af02..5a15ba9 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -55,6 +55,14 @@ image_endian_swap (pixman_image_t *img, int bpp);
 uint8_t *
 make_random_bytes (int n_bytes);
 
+/* Return time since the Epoch in seconds */
+double
+gettime (void);
+
+/* Get aligned memory chunk */
+void *
+aligned_malloc (size_t align, size_t size);
+
 /* main body of the fuzzer test */
 int
 fuzzer_test_main (const char *test_name,
-- 
1.6.3.3



More information about the Pixman mailing list