There are many types of composite operation that are useful to benchmark but
which are omitted from the table. Continually having to add extra entries to
the table is a nuisance and is prone to human error, so this patch adds the
ability to break down unknow strings of the format
  <operation>_<src>[_<mask]<dst>[_ca]
where bitmap formats are specified by number of bits of each component
(assumed in ARGB order) or 'n' to indicate a solid source or mask.

The only downside to this approach is that specifying 'all' instead of a
specific operation will remain limited to the set of operations from the
table.
---
 test/lowlevel-blt-bench.c |  144 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
index 3da094a..f0baad1 100644
--- a/test/lowlevel-blt-bench.c
+++ b/test/lowlevel-blt-bench.c
@@ -32,6 +32,7 @@
 
 #define L1CACHE_SIZE (8 * 1024)
 #define L2CACHE_SIZE (128 * 1024)
+#define PAGE_SIZE (4 * 1024)
 
 /* This is applied to both L1 and L2 tests - alternatively, you could
  * parameterise bench_L or split it into two functions. It could be
@@ -51,6 +52,12 @@
 
 #define EXCLUDE_OVERHEAD 1
 
+typedef struct
+{
+    const char *name;
+    uint32_t    number;
+} name_to_number_t;
+
 uint32_t *dst;
 uint32_t *src;
 uint32_t *mask;
@@ -367,14 +374,14 @@ bench_RT (pixman_op_t              op,
 }
 
 void
-bench_composite (char * testname,
-                 int    src_fmt,
-                 int    src_flags,
-                 int    op,
-                 int    mask_fmt,
-                 int    mask_flags,
-                 int    dst_fmt,
-                 double npix)
+bench_composite (const 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;
@@ -719,12 +726,124 @@ tests_tbl[] =
     { "rpixbuf",               PIXMAN_x8b8g8r8,    0, PIXMAN_OP_SRC,     
PIXMAN_a8b8g8r8, 0, PIXMAN_a8b8g8r8 },
 };
 
+static uint32_t
+lookup_name_to_number (const char **string, const name_to_number_t *array, 
size_t entries)
+{
+    size_t entry, i;
+    for (entry = 0; entry < entries; entry++)
+    {
+        for (i = 0; (*string)[i] == array[entry].name[i]; i++)
+        {
+            if ((*string)[i] == 0)
+            {
+                *string += i;
+                return array[entry].number;
+            }
+        }
+        if ((*string)[i] == '_' && array[entry].name[i] == 0)
+        {
+            *string += i;
+            return array[entry].number;
+        }
+    }
+    return 0;
+}
+
+static int
+parse_and_test (const char *pattern)
+{
+    static const name_to_number_t combine_type[] = {
+            { "src",          PIXMAN_OP_SRC },
+            { "over_reverse", PIXMAN_OP_OVER_REVERSE },
+            { "overrev",      PIXMAN_OP_OVER_REVERSE },
+            { "over",         PIXMAN_OP_OVER },
+            { "in_reverse",   PIXMAN_OP_IN_REVERSE },
+            { "inrev",        PIXMAN_OP_IN_REVERSE },
+            { "in",           PIXMAN_OP_IN },
+            { "out_reverse",  PIXMAN_OP_OUT_REVERSE },
+            { "outrev",       PIXMAN_OP_OUT_REVERSE },
+            { "out",          PIXMAN_OP_OUT },
+            { "atop_reverse", PIXMAN_OP_ATOP_REVERSE },
+            { "atoprev",      PIXMAN_OP_ATOP_REVERSE },
+            { "atop",         PIXMAN_OP_ATOP },
+            { "xor",          PIXMAN_OP_XOR },
+            { "add",          PIXMAN_OP_ADD }
+    };
+    static const name_to_number_t format[] = {
+            { "8888",         PIXMAN_a8r8g8b8 },
+            { "x888",         PIXMAN_x8r8g8b8 },
+            { "0565",         PIXMAN_r5g6b5 },
+            { "1555",         PIXMAN_a1r5g5b5 },
+            { "8",            PIXMAN_a8 }
+    };
+
+    const char *p = pattern;
+    int         src_fmt;
+    int         src_flags = 0;
+    int         mask_fmt;
+    int         mask_flags = 0;
+    int         dst_fmt;
+    int         op = lookup_name_to_number(&p, combine_type, sizeof 
combine_type / sizeof *combine_type);
+    if (op == 0 || *p++ != '_')
+        return 0;
+
+    if (p[0] == 'n' && p[1] == '_')
+    {
+        src_fmt = PIXMAN_a8r8g8b8;
+        src_flags = SOLID_FLAG;
+        ++p;
+    }
+    else
+        src_fmt = lookup_name_to_number(&p, format, sizeof format / sizeof 
*format);
+    if (src_fmt == 0 || *p++ != '_')
+        return 0;
+
+    if (p[0] == 'n' && p[1] == '_')
+    {
+        mask_fmt = PIXMAN_a8r8g8b8;
+        mask_flags = SOLID_FLAG;
+        ++p;
+    }
+    else
+        mask_fmt = lookup_name_to_number(&p, format, sizeof format / sizeof 
*format);
+    if (mask_fmt == 0)
+        return 0;
+
+    if (*p == 0)
+    {
+        dst_fmt = mask_fmt;
+        mask_fmt = PIXMAN_null;
+    }
+    else
+    {
+        ++p;
+        dst_fmt = lookup_name_to_number(&p, format, sizeof format / sizeof 
*format);
+        if (strcmp (p, "_ca") == 0)
+            mask_flags |= CA_FLAG;
+        else if (*p != 0)
+            dst_fmt = 0;
+    }
+    if (dst_fmt == 0)
+        return 0;
+
+    bench_composite (pattern,
+                     src_fmt,
+                     src_flags,
+                     op,
+                     mask_fmt,
+                     mask_flags,
+                     dst_fmt,
+                     bandwidth/8);
+    return 1;
+}
+
 int
 main (int argc, char *argv[])
 {
     double x;
     int i;
     const char *pattern = NULL;
+    int matches = 0;
     for (i = 1; i < argc; i++)
     {
        if (argv[i][0] == '-')
@@ -754,7 +873,7 @@ main (int argc, char *argv[])
        return 1;
     }
 
-    src = aligned_malloc (4096, BUFSIZE * 3);
+    src = aligned_malloc (PAGE_SIZE, BUFSIZE * 3);
     memset (src, 0xCC, BUFSIZE * 3);
     dst = src + (BUFSIZE / 4);
     mask = dst + (BUFSIZE / 4);
@@ -805,6 +924,7 @@ main (int argc, char *argv[])
     {
        if (strcmp (pattern, "all") == 0 || strcmp (tests_tbl[i].testname, 
pattern) == 0)
        {
+           ++matches;
            bench_composite (tests_tbl[i].testname,
                             tests_tbl[i].src_fmt,
                             tests_tbl[i].src_flags,
@@ -816,6 +936,12 @@ main (int argc, char *argv[])
        }
     }
 
+    if (matches == 0)
+        matches = parse_and_test (pattern);
+
+    if (matches == 0)
+        printf ("Unrecognised test pattern\n");
+
     free (src);
     return 0;
 }
-- 
1.7.5.4

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to