diff options
author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2018-07-11 12:10:41 +0200 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2018-11-06 14:25:49 +0100 |
commit | 489fa0df11eef83912932f7be881f35bbe0a1b93 (patch) | |
tree | e8415454e461e4539eea4e3f174a05ac7e31d1a0 /test | |
parent | a4b8a26d2b741e1b3a17b58d34b67bffa17bf15c (diff) | |
download | pixman-489fa0df11eef83912932f7be881f35bbe0a1b93.tar.gz |
pixman: Add tests for (a)rgb floating point formats.
Add some basic tests to ensure that the newly added formats work as
intended.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'test')
-rw-r--r-- | test/alphamap.c | 73 | ||||
-rw-r--r-- | test/stress-test.c | 75 | ||||
-rw-r--r-- | test/utils.c | 76 | ||||
-rw-r--r-- | test/utils.h | 2 |
4 files changed, 186 insertions, 40 deletions
diff --git a/test/alphamap.c b/test/alphamap.c index 4d09076..150d33e 100644 --- a/test/alphamap.c +++ b/test/alphamap.c @@ -10,7 +10,8 @@ static const pixman_format_code_t formats[] = PIXMAN_a8r8g8b8, PIXMAN_a2r10g10b10, PIXMAN_a4r4g4b4, - PIXMAN_a8 + PIXMAN_a8, + PIXMAN_rgba_float, }; static const pixman_format_code_t alpha_formats[] = @@ -18,7 +19,8 @@ static const pixman_format_code_t alpha_formats[] = PIXMAN_null, PIXMAN_a8, PIXMAN_a2r10g10b10, - PIXMAN_a4r4g4b4 + PIXMAN_a4r4g4b4, + PIXMAN_rgba_float, }; static const int origins[] = @@ -41,7 +43,10 @@ make_image (pixman_format_code_t format) uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; pixman_image_t *image; - bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + if (format != PIXMAN_rgba_float) + bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); + else + bits = (uint32_t *)make_random_floats (WIDTH * HEIGHT * bpp); image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); @@ -51,11 +56,11 @@ make_image (pixman_format_code_t format) return image; } -static uint8_t +static float get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) { uint8_t *bits; - uint8_t r; + uint32_t r; if (image->common.alpha_map) { @@ -69,7 +74,7 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) } else { - return 0; + return 0.f; } } @@ -78,28 +83,32 @@ get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) if (image->bits.format == PIXMAN_a8) { r = bits[y * WIDTH + x]; + return r / 255.f; } else if (image->bits.format == PIXMAN_a2r10g10b10) { r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; - r |= r << 2; - r |= r << 4; + return r / 3.f; } else if (image->bits.format == PIXMAN_a8r8g8b8) { r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; + return r / 255.f; } else if (image->bits.format == PIXMAN_a4r4g4b4) { r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; - r |= r << 4; + return r / 15.f; + } + else if (image->bits.format == PIXMAN_rgba_float) + { + return ((float *)bits)[y * WIDTH * 4 + x * 4 + 3]; } else { assert (0); + return 0.f; } - - return r; } static uint16_t @@ -133,6 +142,11 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) r |= r << 4; r |= r << 8; } + else if (image->bits.format == PIXMAN_rgba_float) + { + double tmp = ((float *)bits)[y * WIDTH * 4 + x * 4]; + return tmp * 65535.; + } else { assert (0); @@ -141,6 +155,23 @@ get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) return r; } +static float get_alpha_err(pixman_format_code_t sf, pixman_format_code_t saf, + pixman_format_code_t df, pixman_format_code_t daf) +{ + pixman_format_code_t s = saf != PIXMAN_null ? saf : sf; + pixman_format_code_t d = daf != PIXMAN_null ? daf : df; + + /* There are cases where we go through the 8 bit compositing + * path even with 10bpc and higher formats. + */ + if (PIXMAN_FORMAT_A(s) == PIXMAN_FORMAT_A(d)) + return 1.f / 255.f; + else if (PIXMAN_FORMAT_A(s) > PIXMAN_FORMAT_A(d)) + return 1.f / ((1 << PIXMAN_FORMAT_A(d)) - 1); + else + return 1.f / ((1 << PIXMAN_FORMAT_A(s)) - 1); +} + static int run_test (int s, int d, int sa, int da, int soff, int doff) { @@ -151,15 +182,11 @@ run_test (int s, int d, int sa, int da, int soff, int doff) pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha; pixman_transform_t t1; int j, k; - int n_alpha_bits, n_red_bits; + int n_red_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); - n_red_bits = PIXMAN_FORMAT_R (df); /* Source */ @@ -211,21 +238,25 @@ run_test (int s, int d, int sa, int da, int soff, int doff) { for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) { - uint8_t sa, da, oda, refa; + float sa, da, oda, refa; uint16_t sr, dr, odr, refr; + float err; + + err = get_alpha_err(sf, saf, df, daf); 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) - refa = 255; + if (sa + oda > 1.f) + refa = 1.f; else refa = sa + oda; - if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits)) + if (da - err > refa || + da + err < refa) { - printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", + printf ("\nWrong alpha value at (%d, %d). Should be %g; got %g. Source was %g, original dest was %g\n", k, j, refa, da, sa, oda); printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", diff --git a/test/stress-test.c b/test/stress-test.c index 85d1293..6b4f7d6 100644 --- a/test/stress-test.c +++ b/test/stress-test.c @@ -11,6 +11,8 @@ static const pixman_format_code_t image_formats[] = { + PIXMAN_rgba_float, + PIXMAN_rgb_float, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, PIXMAN_r5g6b5, @@ -100,6 +102,14 @@ get_size (void) } } +static uint32_t +real_reader (const void *src, int size); + +static void *xor_ptr(const void *ptr) +{ + return (void *)(((intptr_t)ptr) ^ (intptr_t)0x8000000080000000); +} + static void destroy (pixman_image_t *image, void *data) { @@ -114,6 +124,9 @@ destroy (pixman_image_t *image, void *data) if (image->bits.rowstride < 0) bits -= (- image->bits.rowstride * (image->bits.height - 1)); + if (image->bits.read_func == real_reader) + bits = xor_ptr(bits); + fence_free (bits); } } @@ -124,6 +137,7 @@ destroy (pixman_image_t *image, void *data) static uint32_t real_reader (const void *src, int size) { + src = xor_ptr(src); switch (size) { case 1: @@ -141,6 +155,7 @@ real_reader (const void *src, int size) static void real_writer (void *src, uint32_t value, int size) { + src = xor_ptr(src); switch (size) { case 1: @@ -247,9 +262,20 @@ create_random_bits_image (alpha_preference_t alpha_preference) pixman_filter_t filter; pixman_fixed_t *coefficients = NULL; int n_coefficients = 0; + int align_add, align_mask; /* format */ format = random_format (alpha_preference); + switch (PIXMAN_FORMAT_BPP (format)) { + case 128: + align_mask = 15; + align_add = align_mask + prng_rand_n (65); + break; + default: + align_mask = 3; + align_add = align_mask + prng_rand_n (17); + break; + } indexed = NULL; if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) @@ -291,9 +317,12 @@ create_random_bits_image (alpha_preference_t alpha_preference) { default: case 0: - stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17); - stride = (stride + 3) & (~3); - bits = (uint32_t *)make_random_bytes (height * stride); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); + if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float) + bits = (uint32_t *)make_random_floats (height * stride); + else + bits = (uint32_t *)make_random_bytes (height * stride); break; case 1: @@ -302,8 +331,8 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 2: /* Zero-filled */ - stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; @@ -311,8 +340,8 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 3: /* Filled with 0xFF */ - stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; @@ -320,27 +349,35 @@ create_random_bits_image (alpha_preference_t alpha_preference) break; case 4: /* bits is a bad pointer, has read/write functions */ - stride = 232; - bits = (void *)0x01; - read_func = fake_reader; - write_func = fake_writer; - break; + if (PIXMAN_FORMAT_BPP (format) <= 32) { + stride = 232; + bits = (void *)0x01; + read_func = fake_reader; + write_func = fake_writer; + break; + } case 5: /* bits is a real pointer, has read/write functions */ - stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17); - stride = (stride + 3) & (~3); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); bits = fence_malloc (height * stride); if (!bits) return NULL; memset (bits, 0xff, height * stride); - read_func = real_reader; - write_func = real_writer; + if (PIXMAN_FORMAT_BPP (format) <= 32) { + bits = xor_ptr(bits); + read_func = real_reader; + write_func = real_writer; + } break; case 6: /* bits is a real pointer, stride is negative */ - stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8 + prng_rand_n (17); - stride = (stride + 3) & (~3); - bits = (uint32_t *)make_random_bytes (height * stride); + stride = (width * PIXMAN_FORMAT_BPP (format) + 7) / 8; + stride = (stride + align_add) & (~align_mask); + if (format == PIXMAN_rgb_float || format == PIXMAN_rgba_float) + bits = (uint32_t *)make_random_floats (height * stride); + else + bits = (uint32_t *)make_random_bytes (height * stride); if (!bits) return NULL; bits += ((height - 1) * stride) / 4; diff --git a/test/utils.c b/test/utils.c index f8e42a5..4eeb068 100644 --- a/test/utils.c +++ b/test/utils.c @@ -595,6 +595,21 @@ make_random_bytes (int n_bytes) return bytes; } +float * +make_random_floats (int n_bytes) +{ + uint8_t *bytes = fence_malloc (n_bytes); + float *vals = (float *)bytes; + + if (!bytes) + return 0; + + for (n_bytes /= 4; n_bytes; vals++, n_bytes--) + *vals = (float)rand() / (float)RAND_MAX; + + return (float *)bytes; +} + void a8r8g8b8_to_rgba_np (uint32_t *dst, uint32_t *src, int n_pixels) { @@ -1180,6 +1195,11 @@ static const format_entry_t format_list[] = * Aliases are not listed by list_formats (). */ +/* 128bpp formats */ + ENTRY (rgba_float), +/* 96bpp formats */ + ENTRY (rgb_float), + /* 32bpp formats */ ENTRY (a8r8g8b8), ALIAS (a8r8g8b8, "8888"), @@ -1914,6 +1934,10 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) checker->format = format; + if (format == PIXMAN_rgba_float || + format == PIXMAN_rgb_float) + return; + switch (PIXMAN_FORMAT_TYPE (format)) { case PIXMAN_TYPE_A: @@ -1970,10 +1994,19 @@ pixel_checker_init (pixel_checker_t *checker, pixman_format_code_t format) checker->bw = PIXMAN_FORMAT_B (format); } +static void +pixel_checker_require_uint32_format (const pixel_checker_t *checker) +{ + assert (checker->format != PIXMAN_rgba_float && + checker->format != PIXMAN_rgb_float); +} + void pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel, int *a, int *r, int *g, int *b) { + pixel_checker_require_uint32_format(checker); + *a = (pixel & checker->am) >> checker->as; *r = (pixel & checker->rm) >> checker->rs; *g = (pixel & checker->gm) >> checker->gs; @@ -1987,6 +2020,8 @@ pixel_checker_get_masks (const pixel_checker_t *checker, uint32_t *gm, uint32_t *bm) { + pixel_checker_require_uint32_format(checker); + if (am) *am = checker->am; if (rm) @@ -2003,6 +2038,8 @@ pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker, { int a, r, g, b; + pixel_checker_require_uint32_format(checker); + pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b); if (checker->am == 0) @@ -2078,6 +2115,8 @@ void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, int *am, int *rm, int *gm, int *bm) { + pixel_checker_require_uint32_format(checker); + get_limits (checker, DEVIATION, color, am, rm, gm, bm); } @@ -2085,6 +2124,8 @@ void pixel_checker_get_min (const pixel_checker_t *checker, color_t *color, int *am, int *rm, int *gm, int *bm) { + pixel_checker_require_uint32_format(checker); + get_limits (checker, - DEVIATION, color, am, rm, gm, bm); } @@ -2096,6 +2137,8 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel, int32_t ai, ri, gi, bi; pixman_bool_t result; + pixel_checker_require_uint32_format(checker); + pixel_checker_get_min (checker, color, &a_lo, &r_lo, &g_lo, &b_lo); pixel_checker_get_max (checker, color, &a_hi, &r_hi, &g_hi, &b_hi); pixel_checker_split_pixel (checker, pixel, &ai, &ri, &gi, &bi); @@ -2108,3 +2151,36 @@ pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel, return result; } + +static void +color_limits (const pixel_checker_t *checker, + double limit, const color_t *color, color_t *out) +{ + if (PIXMAN_FORMAT_A(checker->format)) + out->a = color->a + limit; + else + out->a = 1.; + + out->r = color->r + limit; + out->g = color->g + limit; + out->b = color->b + limit; +} + +pixman_bool_t +pixel_checker_check_color (const pixel_checker_t *checker, + const color_t *actual, const color_t *reference) +{ + color_t min, max; + pixman_bool_t result; + + color_limits(checker, -DEVIATION, reference, &min); + color_limits(checker, DEVIATION, reference, &max); + + result = + actual->a >= min.a && actual->a <= max.a && + actual->r >= min.r && actual->r <= max.r && + actual->g >= min.g && actual->g <= max.g && + actual->b >= min.b && actual->b <= max.b; + + return result; +} diff --git a/test/utils.h b/test/utils.h index e299d1d..e5ac945 100644 --- a/test/utils.h +++ b/test/utils.h @@ -119,6 +119,8 @@ fence_get_page_size (); /* Generate n_bytes random bytes in fence_malloced memory */ uint8_t * make_random_bytes (int n_bytes); +float * +make_random_floats (int n_bytes); /* Return current time in seconds */ double |