From ae77548f0d9ca95a86a466fc4ff099e000716067 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Sun, 29 Aug 2010 16:59:02 -0400 Subject: [PATCH] Update and extend the alphamap test - 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 #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 ""; +} + +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; -- 2.7.4