[Pixman] [PATCH 2/2] pixman: Add tests for xrgb/argb formats.
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Mon Aug 27 12:39:24 UTC 2018
Hey,
Op 01-08-18 om 14:41 schreef Maarten Lankhorst:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> ---
> test/alphamap.c | 73 +++++++++++++++++++++++++++++++-------------
> test/stress-test.c | 75 +++++++++++++++++++++++++++++++++------------
> test/utils.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
> test/utils.h | 2 ++
> 4 files changed, 186 insertions(+), 40 deletions(-)
>
> diff --git a/test/alphamap.c b/test/alphamap.c
> index 4d09076fbcf3..150d33eed5b5 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 85d12932c9aa..6b4f7d606f72 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 f8e42a5d3f3d..4eeb068497ec 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 e299d1d066ed..e5ac945ab3f8 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
There hasn't been any movement on reviewing this series since i posted this.
Can I assume there are no objections, and I can push this to pixman next week?
~Maarten
More information about the Pixman
mailing list