aboutsummaryrefslogtreecommitdiff
path: root/pixman/test/composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'pixman/test/composite.c')
-rw-r--r--pixman/test/composite.c261
1 files changed, 135 insertions, 126 deletions
diff --git a/pixman/test/composite.c b/pixman/test/composite.c
index 426a887e3..e8a7e94dc 100644
--- a/pixman/test/composite.c
+++ b/pixman/test/composite.c
@@ -1,6 +1,8 @@
/*
* Copyright © 2005 Eric Anholt
* Copyright © 2009 Chris Wilson
+ * Copyright © 2010 Soeren Sandmann
+ * Copyright © 2010 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -20,15 +22,14 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-
+#define PIXMAN_USE_INTERNAL_API
#include <pixman.h>
#include <stdio.h>
#include <stdlib.h> /* abort() */
#include <math.h>
#include <config.h>
-
-#define FALSE 0
-#define TRUE !FALSE
+#include <time.h>
+#include "utils.h"
#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
#define min(a,b) ((a) <= (b) ? (a) : (b))
@@ -50,14 +51,15 @@ struct format_t
const char *name;
};
-static color_t colors[] =
+static const color_t colors[] =
{
- /* these are premultiplied in main() */
{ 1.0, 1.0, 1.0, 1.0 },
+ { 1.0, 1.0, 1.0, 0.0 },
+ { 0.0, 0.0, 0.0, 1.0 },
+ { 0.0, 0.0, 0.0, 0.0 },
{ 1.0, 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 1.0, 1.0 },
- { 0.0, 0.0, 0.0, 1.0 },
{ 0.5, 0.0, 0.0, 0.5 },
};
@@ -82,62 +84,66 @@ compute_pixman_color (const color_t *color,
out->alpha = _color_double_to_short (color->a);
}
+#define REPEAT 0x01000000
+#define FLAGS 0xff000000
+
+static const int sizes[] =
+{
+ 0,
+ 1,
+ 1 | REPEAT,
+ 10
+};
+
static const format_t formats[] =
{
#define P(x) { PIXMAN_##x, #x }
- P(a8),
- /* 32bpp formats */
+ /* 32 bpp formats */
P(a8r8g8b8),
P(x8r8g8b8),
P(a8b8g8r8),
P(x8b8g8r8),
P(b8g8r8a8),
P(b8g8r8x8),
-
- /* XXX: and here the errors begin! */
-#if 0
P(x2r10g10b10),
- P(a2r10g10b10),
P(x2b10g10r10),
+ P(a2r10g10b10),
P(a2b10g10r10),
- /* 24bpp formats */
+ /* 24 bpp formats */
P(r8g8b8),
P(b8g8r8),
-
- /* 16bpp formats */
P(r5g6b5),
P(b5g6r5),
- P(a1r5g5b5),
+ /* 16 bpp formats */
P(x1r5g5b5),
- P(a1b5g5r5),
P(x1b5g5r5),
- P(a4r4g4b4),
- P(x4r4g4b4),
+ P(a1r5g5b5),
+ P(a1b5g5r5),
P(a4b4g4r4),
P(x4b4g4r4),
+ P(a4r4g4b4),
+ P(x4r4g4b4),
- /* 8bpp formats */
+ /* 8 bpp formats */
P(a8),
P(r3g3b2),
P(b2g3r3),
P(a2r2g2b2),
P(a2b2g2r2),
-
P(x4a4),
- /* 4bpp formats */
+ /* 4 bpp formats */
P(a4),
P(r1g2b1),
P(b1g2r1),
P(a1r1g1b1),
P(a1b1g1r1),
- /* 1bpp formats */
+ /* 1 bpp formats */
P(a1)
-#endif
#undef P
};
@@ -482,8 +488,9 @@ static void
color_correct (pixman_format_code_t format,
color_t *color)
{
-#define round_pix(pix, mask) \
- ((int)((pix) * (mask) + .5) / (double) (mask))
+#define MASK(x) ((1 << (x)) - 1)
+#define round_pix(pix, m) \
+ ((int)((pix) * (MASK(m)) + .5) / (double) (MASK(m)))
if (PIXMAN_FORMAT_R (format) == 0)
{
@@ -504,6 +511,7 @@ color_correct (pixman_format_code_t format,
color->a = round_pix (color->a, PIXMAN_FORMAT_A (format));
#undef round_pix
+#undef MASK
}
static void
@@ -594,18 +602,15 @@ get_pixel (pixman_image_t *image,
}
static double
-eval_diff (color_t *expected, color_t *test)
+eval_diff (color_t *expected, color_t *test, pixman_format_code_t format)
{
double rscale, gscale, bscale, ascale;
double rdiff, gdiff, bdiff, adiff;
- /* XXX: Need to be provided mask shifts so we can produce useful error
- * values.
- */
- rscale = 1.0 * (1 << 5);
- gscale = 1.0 * (1 << 6);
- bscale = 1.0 * (1 << 5);
- ascale = 1.0 * 32;
+ rscale = 1.0 * ((1 << PIXMAN_FORMAT_R (format)) - 1);
+ gscale = 1.0 * ((1 << PIXMAN_FORMAT_G (format)) - 1);
+ bscale = 1.0 * ((1 << PIXMAN_FORMAT_B (format)) - 1);
+ ascale = 1.0 * ((1 << PIXMAN_FORMAT_A (format)) - 1);
rdiff = fabs (test->r - expected->r) * rscale;
bdiff = fabs (test->g - expected->g) * gscale;
@@ -699,7 +704,12 @@ composite_test (image_t *dst,
&expected, component_alpha);
color_correct (dst->format->format, &expected);
- diff = eval_diff (&expected, &result);
+ diff = eval_diff (&expected, &result, dst->format->format);
+
+ /* FIXME: We should find out what deviation is acceptable. 3.0
+ * is clearly absurd for 2 bit formats for example. On the other
+ * hand currently 1.0 does not work.
+ */
if (diff > 3.0)
{
char buf[40];
@@ -717,7 +727,7 @@ composite_test (image_t *dst,
result.r, result.g, result.b, result.a,
*(unsigned long *) pixman_image_get_data (dst->image),
expected.r, expected.g, expected.b, expected.a);
-
+
if (mask != NULL)
{
printf ("src color: %.2f %.2f %.2f %.2f\n"
@@ -751,9 +761,6 @@ composite_test (image_t *dst,
return success;
}
-#define REPEAT 0x01000000
-#define FLAGS 0xff000000
-
static void
image_init (image_t *info,
int color,
@@ -766,7 +773,7 @@ image_init (image_t *info,
compute_pixman_color (info->color, &fill);
info->format = &formats[format];
- info->size = size & ~FLAGS;
+ info->size = sizes[size] & ~FLAGS;
info->repeat = PIXMAN_REPEAT_NONE;
if (info->size)
@@ -800,103 +807,105 @@ image_fini (image_t *info)
pixman_image_unref (info->image);
}
-int
-main (void)
+static int
+random_size (void)
+{
+ return lcg_rand_n (ARRAY_LENGTH (sizes));
+}
+
+static int
+random_color (void)
{
- pixman_bool_t ok, group_ok = TRUE, ca;
- int i, d, m, s;
- int tests_passed = 0, tests_total = 0;
- int sizes[] = { 1, 1 | REPEAT, 10 };
- int num_tests;
+ return lcg_rand_n (ARRAY_LENGTH (colors));
+}
+
+static int
+random_format (void)
+{
+ return lcg_rand_n (ARRAY_LENGTH (formats));
+}
+
+static pixman_bool_t
+run_test (uint32_t seed)
+{
+ image_t src, mask, dst;
+ const operator_t *op;
+ int ca;
+ int ok;
+
+ lcg_srand (seed);
+
+ image_init (&dst, random_color(), random_format(), 1);
+ image_init (&src, random_color(), random_format(), random_size());
+ image_init (&mask, random_color(), random_format(), random_size());
+
+ op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]);
+
+ ca = lcg_rand_n (3);
- for (i = 0; i < ARRAY_LENGTH (colors); i++)
+ switch (ca)
{
- colors[i].r *= colors[i].a;
- colors[i].g *= colors[i].a;
- colors[i].b *= colors[i].a;
+ case 0:
+ ok = composite_test (&dst, op, &src, NULL, FALSE);
+ break;
+ case 1:
+ ok = composite_test (&dst, op, &src, &mask, FALSE);
+ break;
+ case 2:
+ ok = composite_test (&dst, op, &src, &mask,
+ mask.size? TRUE : FALSE);
+ break;
+ default:
+ ok = FALSE;
+ break;
}
- num_tests = ARRAY_LENGTH (colors) * ARRAY_LENGTH (formats);
+ image_fini (&src);
+ image_fini (&mask);
+ image_fini (&dst);
- for (d = 0; d < num_tests; d++)
- {
- image_t dst;
+ return ok;
+}
- image_init (
- &dst, d / ARRAY_LENGTH (formats), d % ARRAY_LENGTH (formats), 1);
+int
+main (int argc, char **argv)
+{
+#define N_TESTS (8 * 1024 * 1024)
+ int result = 0;
+ int i;
+ if (argc > 1)
+ {
+ char *end;
+
+ i = strtol (argv[1], &end, 0);
- for (s = -ARRAY_LENGTH (colors);
- s < ARRAY_LENGTH (sizes) * num_tests;
- s++)
+ if (end != argv[1])
{
- image_t src;
-
- if (s < 0)
- {
- image_init (&src, -s - 1, 0, 0);
- }
+ if (!run_test (i))
+ return 1;
else
- {
- image_init (&src,
- s / ARRAY_LENGTH (sizes) / ARRAY_LENGTH (formats),
- s / ARRAY_LENGTH (sizes) % ARRAY_LENGTH (formats),
- sizes[s % ARRAY_LENGTH (sizes)]);
- }
-
- for (m = -ARRAY_LENGTH (colors);
- m < ARRAY_LENGTH (sizes) * num_tests;
- m++)
- {
- image_t mask;
-
- if (m < 0)
- {
- image_init (&mask, -m - 1, 0, 0);
- }
- else
- {
- image_init (
- &mask,
- m / ARRAY_LENGTH (sizes) / ARRAY_LENGTH (formats),
- m / ARRAY_LENGTH (sizes) % ARRAY_LENGTH (formats),
- sizes[m % ARRAY_LENGTH (sizes)]);
- }
-
- for (ca = -1; ca <= 1; ca++)
- {
- for (i = 0; i < ARRAY_LENGTH (operators); i++)
- {
- const operator_t *op = &operators[i];
-
- switch (ca)
- {
- case -1:
- ok = composite_test (&dst, op, &src, NULL, FALSE);
- break;
- case 0:
- ok = composite_test (&dst, op, &src, &mask, FALSE);
- break;
- case 1:
- ok = composite_test (&dst, op, &src, &mask,
- mask.size? TRUE : FALSE);
- break;
- default:
- ok = FALSE; /* Silence GCC */
- break;
- }
- group_ok = group_ok && ok;
- tests_passed += ok;
- tests_total++;
- }
- }
-
- image_fini (&mask);
- }
- image_fini (&src);
+ return 0;
+ }
+ else
+ {
+ printf ("Usage:\n\n %s <number>\n\n", argv[0]);
+ return -1;
}
- image_fini (&dst);
}
- return group_ok == FALSE;
+#ifdef USE_OPENMP
+# pragma omp parallel for default(none) shared(result) shared(argv)
+#endif
+ for (i = 1; i <= N_TESTS; ++i)
+ {
+ if (!result && !run_test (i))
+ {
+ printf ("Test %d failed.\n", i);
+
+ result = i;
+ }
+ }
+
+ return result;
}