[Pixman] [PATCH 04/10] Add combiner test

Søren Sandmann sandmann at cs.au.dk
Wed Sep 26 13:43:57 PDT 2012


From: Søren Sandmann Pedersen <ssp at redhat.com>

This test runs the new floating point combiners on random input with
divide-by-zero exceptions turned on.

With the floating point combiners the only thing we guarantee is that
divide-by-zero exceptions are not generated, so change
enable_fp_exceptions() to only enable those, and rename accordingly.
---
 demos/radial-test.c        |    2 +-
 pixman/pixman-private.h    |    6 ++
 pixman/pixman-utils.c      |    9 +++
 test/Makefile.sources      |    1 +
 test/combiner-test.c       |  151 ++++++++++++++++++++++++++++++++++++++++++++
 test/gradient-crash-test.c |    2 +-
 test/pdf-op-test.c         |    2 +-
 test/stress-test.c         |    2 +-
 test/utils.c               |   14 +----
 test/utils.h               |    2 +-
 10 files changed, 174 insertions(+), 17 deletions(-)
 create mode 100644 test/combiner-test.c

diff --git a/demos/radial-test.c b/demos/radial-test.c
index 35e90d7..e64f357 100644
--- a/demos/radial-test.c
+++ b/demos/radial-test.c
@@ -133,7 +133,7 @@ main (int argc, char **argv)
     pixman_image_t *src_img, *dest_img;
     int i, j;
 
-    enable_fp_exceptions ();
+    enable_divbyzero_exceptions ();
 
     dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
 					 WIDTH, HEIGHT,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 949d384..c82316f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -764,6 +764,12 @@ get_implementation (void)
     return global_implementation;
 }
 
+/* This function is exported for the sake of the test suite and not part
+ * of the ABI.
+ */
+PIXMAN_EXPORT pixman_implementation_t *
+_pixman_internal_only_get_implementation (void);
+
 /* Memory allocation helpers */
 void *
 pixman_malloc_ab (unsigned int n, unsigned int b);
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 5633f8f..e4a9730 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -262,6 +262,15 @@ pixman_region32_copy_from_region16 (pixman_region32_t *dst,
     return retval;
 }
 
+/* This function is exported for the sake of the test suite and not part
+ * of the ABI.
+ */
+PIXMAN_EXPORT pixman_implementation_t *
+_pixman_internal_only_get_implementation (void)
+{
+    return get_implementation ();
+}
+
 #ifdef DEBUG
 
 void
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 0f34411..0778971 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -4,6 +4,7 @@ TESTPROGRAMS =			\
 	pdf-op-test		\
 	region-test		\
 	region-translate-test	\
+	combiner-test		\
 	fetch-test		\
 	rotate-test		\
 	oob-test		\
diff --git a/test/combiner-test.c b/test/combiner-test.c
new file mode 100644
index 0000000..c438ae6
--- /dev/null
+++ b/test/combiner-test.c
@@ -0,0 +1,151 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+#include <sys/types.h>
+#include "pixman-private.h"
+
+static const pixman_op_t op_list[] =
+{
+    PIXMAN_OP_SRC,
+    PIXMAN_OP_OVER,
+    PIXMAN_OP_ADD,
+    PIXMAN_OP_CLEAR,
+    PIXMAN_OP_SRC,
+    PIXMAN_OP_DST,
+    PIXMAN_OP_OVER,
+    PIXMAN_OP_OVER_REVERSE,
+    PIXMAN_OP_IN,
+    PIXMAN_OP_IN_REVERSE,
+    PIXMAN_OP_OUT,
+    PIXMAN_OP_OUT_REVERSE,
+    PIXMAN_OP_ATOP,
+    PIXMAN_OP_ATOP_REVERSE,
+    PIXMAN_OP_XOR,
+    PIXMAN_OP_ADD,
+    PIXMAN_OP_SATURATE,
+    PIXMAN_OP_DISJOINT_CLEAR,
+    PIXMAN_OP_DISJOINT_SRC,
+    PIXMAN_OP_DISJOINT_DST,
+    PIXMAN_OP_DISJOINT_OVER,
+    PIXMAN_OP_DISJOINT_OVER_REVERSE,
+    PIXMAN_OP_DISJOINT_IN,
+    PIXMAN_OP_DISJOINT_IN_REVERSE,
+    PIXMAN_OP_DISJOINT_OUT,
+    PIXMAN_OP_DISJOINT_OUT_REVERSE,
+    PIXMAN_OP_DISJOINT_ATOP,
+    PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+    PIXMAN_OP_DISJOINT_XOR,
+    PIXMAN_OP_CONJOINT_CLEAR,
+    PIXMAN_OP_CONJOINT_SRC,
+    PIXMAN_OP_CONJOINT_DST,
+    PIXMAN_OP_CONJOINT_OVER,
+    PIXMAN_OP_CONJOINT_OVER_REVERSE,
+    PIXMAN_OP_CONJOINT_IN,
+    PIXMAN_OP_CONJOINT_IN_REVERSE,
+    PIXMAN_OP_CONJOINT_OUT,
+    PIXMAN_OP_CONJOINT_OUT_REVERSE,
+    PIXMAN_OP_CONJOINT_ATOP,
+    PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+    PIXMAN_OP_CONJOINT_XOR,
+    PIXMAN_OP_MULTIPLY,
+    PIXMAN_OP_SCREEN,
+    PIXMAN_OP_OVERLAY,
+    PIXMAN_OP_DARKEN,
+    PIXMAN_OP_LIGHTEN,
+    PIXMAN_OP_COLOR_DODGE,
+    PIXMAN_OP_COLOR_BURN,
+    PIXMAN_OP_HARD_LIGHT,
+    PIXMAN_OP_DIFFERENCE,
+    PIXMAN_OP_EXCLUSION,
+    PIXMAN_OP_SOFT_LIGHT,
+    PIXMAN_OP_HSL_HUE,
+    PIXMAN_OP_HSL_SATURATION,
+    PIXMAN_OP_HSL_COLOR,
+    PIXMAN_OP_HSL_LUMINOSITY,
+};
+
+static float
+rand_float (void)
+{
+    uint32_t u = lcg_rand_u32();
+
+    return *(float *)&u;
+}
+
+static void
+random_floats (argb_t *argb, int width)
+{
+    int i;
+
+    for (i = 0; i < width; ++i)
+    {
+	argb_t *p = argb + i;
+
+	p->a = rand_float();
+	p->r = rand_float();
+	p->g = rand_float();
+	p->b = rand_float();
+    }
+}
+
+#define WIDTH	512
+
+static pixman_combine_float_func_t
+lookup_combiner (pixman_implementation_t *imp, pixman_op_t op,
+		 pixman_bool_t component_alpha)
+{
+    pixman_combine_float_func_t f;
+
+    do
+    {
+	if (component_alpha)
+	    f = imp->combine_float_ca[op];
+	else
+	    f = imp->combine_float[op];
+	
+	imp = imp->fallback;
+    }
+    while (!f);
+
+    return f;
+}
+
+int
+main ()
+{
+    pixman_implementation_t *impl;
+    argb_t *src_bytes = malloc (WIDTH * sizeof (argb_t));
+    argb_t *mask_bytes = malloc (WIDTH * sizeof (argb_t));
+    argb_t *dest_bytes = malloc (WIDTH * sizeof (argb_t));
+    int i;
+
+    enable_divbyzero_exceptions();
+    
+    impl = _pixman_internal_only_get_implementation();
+    
+    lcg_srand (0);
+
+    for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
+    {
+	pixman_op_t op = op_list[i];
+	pixman_combine_float_func_t combiner;
+	int ca;
+
+	for (ca = 0; ca < 2; ++ca)
+	{
+	    combiner = lookup_combiner (impl, op, ca);
+
+	    random_floats (src_bytes, WIDTH);
+	    random_floats (mask_bytes, WIDTH);
+	    random_floats (dest_bytes, WIDTH);
+
+	    combiner (impl, op,
+		      (float *)dest_bytes,
+		      (float *)mask_bytes,
+		      (float *)src_bytes,
+		      WIDTH);
+	}
+    }	
+
+    return 0;
+}
diff --git a/test/gradient-crash-test.c b/test/gradient-crash-test.c
index 73e5bbc..962d1cb 100644
--- a/test/gradient-crash-test.c
+++ b/test/gradient-crash-test.c
@@ -85,7 +85,7 @@ main (int argc, char **argv)
     pixman_fixed_t r_inner;
     pixman_fixed_t r_outer;
 
-    enable_fp_exceptions();
+    enable_divbyzero_exceptions();
     
     for (i = 0; i < WIDTH * HEIGHT; ++i)
 	dest[i] = 0x4f00004f; /* pale blue */
diff --git a/test/pdf-op-test.c b/test/pdf-op-test.c
index 99cb7df..dcb3a60 100644
--- a/test/pdf-op-test.c
+++ b/test/pdf-op-test.c
@@ -36,7 +36,7 @@ main ()
 {
     int o, s, m, d;
 
-    enable_fp_exceptions();
+    enable_divbyzero_exceptions();
 
     for (o = 0; o < ARRAY_LENGTH (pdf_ops); ++o)
     {
diff --git a/test/stress-test.c b/test/stress-test.c
index edcfe09..059250d 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -850,7 +850,7 @@ main (int argc, char **argv)
 
     pixman_disable_out_of_bounds_workaround ();
 
-    enable_fp_exceptions();
+    enable_divbyzero_exceptions();
 
     if (getenv ("VERBOSE") != NULL)
 	verbose = TRUE;
diff --git a/test/utils.c b/test/utils.c
index c922ae5..716bb75 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -723,21 +723,11 @@ fail_after (int seconds, const char *msg)
 }
 
 void
-enable_fp_exceptions (void)
+enable_divbyzero_exceptions (void)
 {
 #ifdef HAVE_FENV_H
 #ifdef HAVE_FEENABLEEXCEPT
-    /* Note: we don't enable the FE_INEXACT trap because
-     * that happens quite commonly. It is possible that
-     * over- and underflow should similarly be considered
-     * okay, but for now the test suite passes with them
-     * enabled, and it's useful to know if they start
-     * occuring.
-     */
-    feenableexcept (FE_DIVBYZERO	|
-		    FE_INVALID		|
-		    FE_OVERFLOW		|
-		    FE_UNDERFLOW);
+    feenableexcept (FE_DIVBYZERO);
 #endif
 #endif
 }
diff --git a/test/utils.h b/test/utils.h
index faf427f..f7ea34c 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -110,7 +110,7 @@ void
 fail_after (int seconds, const char *msg);
 
 /* If possible, enable traps for floating point exceptions */
-void enable_fp_exceptions(void);
+void enable_divbyzero_exceptions(void);
 
 /* Converts a8r8g8b8 pixels to pixels that
  *  - are not premultiplied,
-- 
1.7.4



More information about the Pixman mailing list