[Pixman] [PATCH 2/5] Update and extend the alphamap test

Søren Sandmann sandmann at daimi.au.dk
Tue Sep 14 06:18:19 PDT 2010


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

- Test many more combinations of formats

- Test destination alpha maps

- Test various different alpha origins

Also add a transformation to the destination, but comment it out
because it is actually broken at the moment (and pretty difficult to
fix).
---
 test/Makefile.am |    2 +-
 test/alphamap.c  |  243 ++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 218 insertions(+), 27 deletions(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index 3d98e17..f3b2b58 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,9 +13,9 @@ TESTPROGRAMS =			\
 	window-test		\
 	gradient-crash-test	\
 	trap-crasher		\
-	alphamap		\
 	alpha-loop		\
 	scaling-crash-test	\
+	alphamap		\
 	blitters-test		\
 	scaling-test		\
 	composite
diff --git a/test/alphamap.c b/test/alphamap.c
index e6a25ef..09de387 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -2,47 +2,238 @@
 #include <stdlib.h>
 #include "utils.h"
 
-#define WIDTH 400
-#define HEIGHT 200
+#define WIDTH 100
+#define HEIGHT 100
 
-int
-main (int argc, char **argv)
+static const pixman_format_code_t formats[] =
+{
+    PIXMAN_a8r8g8b8,
+    PIXMAN_a2r10g10b10,
+    PIXMAN_a4r4g4b4,
+    PIXMAN_a8
+};
+
+static const pixman_format_code_t alpha_formats[] =
+{
+    PIXMAN_null,
+    PIXMAN_a8,
+    PIXMAN_a2r10g10b10,
+    PIXMAN_a4r4g4b4
+};
+
+static const int origins[] =
 {
-    uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
-    uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-    uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-    int i;
+    0, 10, -100
+};
 
-    pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
-    pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+static const char *
+format_name (pixman_format_code_t format)
+{
+    if (format == PIXMAN_a8)
+	return "a8";
+    else if (format == PIXMAN_a2r10g10b10)
+	return "a2r10g10b10";
+    else if (format == PIXMAN_a8r8g8b8)
+	return "a8r8g8b8";
+    else if (format == PIXMAN_a4r4g4b4)
+	return "a4r4g4b4";
+    else if (format == PIXMAN_null)
+	return "none";
+    else
+	assert (0);
 
-    for (i = 0; i < 2; ++i)
+    return "<unknown - bug in alphamap.c>";
+}
+
+static pixman_image_t *
+make_image (pixman_format_code_t format)
+{
+    uint32_t *bits;
+    uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
+
+    bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
+
+    return pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
+}
+
+static pixman_image_t *
+create_image (pixman_format_code_t format, pixman_format_code_t alpha_format,
+	      int alpha_origin_x, int alpha_origin_y)
+{
+    pixman_image_t *image = make_image (format);
+
+    if (alpha_format != PIXMAN_null)
     {
-	pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : PIXMAN_a2r10g10b10;
-	pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, src, WIDTH * 4);
-	int j, k;
+	pixman_image_t *alpha = make_image (alpha_format);
 
-	pixman_image_set_alpha_map (s, a, 0, 0);
+	pixman_image_set_alpha_map (image, alpha,
+				    alpha_origin_x, alpha_origin_y);
+    }
 
-	pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+    return image;
+}
 
-	for (j = 0; j < HEIGHT; ++j)
+static uint8_t
+get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
+{
+    uint8_t *bits;
+    uint8_t r;
+
+    if (image->common.alpha_map)
+    {
+	if (x - orig_x >= 0 && x - orig_x < WIDTH &&
+	    y - orig_y >= 0 && y - orig_y < HEIGHT)
+	{
+	    image = (pixman_image_t *)image->common.alpha_map;
+
+	    x -= orig_x;
+	    y -= orig_y;
+	}
+	else
 	{
-	    for (k = 0; k < WIDTH; ++k)
+	    return 0;
+	}
+    }
+
+    bits = (uint8_t *)image->bits.bits;
+
+    if (image->bits.format == PIXMAN_a8)
+    {
+	r = bits[y * WIDTH + x];
+    }
+    else if (image->bits.format == PIXMAN_a2r10g10b10)
+    {
+	r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
+	r |= r << 2;
+	r |= r << 4;
+    }
+    else if (image->bits.format == PIXMAN_a8r8g8b8)
+    {
+	r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
+    }
+    else if (image->bits.format == PIXMAN_a4r4g4b4)
+    {
+	r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
+	r |= r << 4;
+    }
+    else
+    {
+	assert (0);
+    }
+
+    return r;
+}
+
+#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
+
+static int
+run_test (int s, int d, int sa, int da, int soff, int doff)
+{
+    pixman_format_code_t sf = formats[s];
+    pixman_format_code_t df = formats[d];
+    pixman_format_code_t saf = alpha_formats[sa];
+    pixman_format_code_t daf = alpha_formats[da];
+    pixman_image_t *src, *dst, *orig_dst;
+    pixman_transform_t t1;
+    int j, k;
+    int n_alpha_bits;
+
+    soff = origins[soff];
+    doff = origins[doff];
+
+    n_alpha_bits = PIXMAN_FORMAT_A (df);
+    if (daf != PIXMAN_null)
+	n_alpha_bits = PIXMAN_FORMAT_A (daf);
+
+
+    src = create_image (sf, saf, soff, soff);
+    orig_dst = create_image (df, daf, doff, doff);
+    dst = create_image (df, daf, doff, doff);
+
+    /* Transformations on destinations should be ignored, so just set some
+     * random one.
+     */
+    pixman_transform_init_identity (&t1);
+    pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
+    pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
+    pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
+
+#if 0
+    /* Unfortunately, this is actually broken at the moment, so we can't
+     * actually turn it on
+     */
+    pixman_image_set_transform (dst, &t1);
+#endif
+
+    pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+    pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+    for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
+    {
+	for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
+	{
+	    uint8_t sa, da, oda, ref;
+
+	    sa = get_alpha (src, k, j, soff, soff);
+	    da = get_alpha (dst, k, j, doff, doff);
+	    oda = get_alpha (orig_dst, k, j, doff, doff);
+
+	    if (sa + oda > 255)
+		ref = 255;
+	    else
+		ref = sa + oda;
+
+	    if (da >> (8 - n_alpha_bits) != ref >> (8 - n_alpha_bits))
 	    {
-		uint8_t ap = ((uint8_t *)alpha)[j * WIDTH + k];
-		uint32_t dap = (dest[j * WIDTH + k] >> 24);
-		uint32_t sap = (src[j * WIDTH + k] >> 24);
+		printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
+			k, j, ref, da, sa, oda);
+
+		printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
+			format_name (sf),
+			format_name (saf),
+			soff, soff,
+			format_name (df),
+			format_name (daf),
+			doff, doff);
+		return 1;
+	    }
+	}
+    }
+
+    pixman_image_unref (src);
+    pixman_image_unref (dst);
+    pixman_image_unref (orig_dst);
+
+    return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+    int i, j, a, b, x, y;
 
-		if (ap != dap)
+    for (i = 0; i < ARRAY_LENGTH (formats); ++i)
+    {
+	for (j = 0; j < ARRAY_LENGTH (formats); ++j)
+	{
+	    for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
+	    {
+		for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
 		{
-		    printf ("Wrong alpha value at (%d, %d). Should be %d; got %d (src was %d)\n", k, j, ap, dap, sap);
-		    return 1;
+		    for (x = 0; x < ARRAY_LENGTH (origins); ++x)
+		    {
+			for (y = 0; y < ARRAY_LENGTH (origins); ++y)
+			{
+			    if (run_test (i, j, a, b, x, y) != 0)
+				return 1;
+			}
+		    }
 		}
 	    }
 	}
-
-	pixman_image_unref (s);
     }
 
     return 0;
-- 
1.7.1.1



More information about the Pixman mailing list