From: Søren Sandmann Pedersen Date: Sun, 27 May 2012 22:23:20 +0000 (-0400) Subject: test: Add glyph-test X-Git-Tag: pixman-0.27.2~57 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9710442b4b2294e1ccd1594c54ca8a4feda2ac5;p=platform%2Fupstream%2Fpixman.git test: Add glyph-test This test tests the new glyph cache and compositing API. Much of this test is intending to making sure that clipping and alpha map handling survive any optimizations that may be added to the glyph compositing. V2: Evaluating lcg_rand_n() multiple times in an argument list lead to undefined behavior. --- diff --git a/test/Makefile.sources b/test/Makefile.sources index 99eb705..fad8c6f 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -16,6 +16,7 @@ TESTPROGRAMS = \ stress-test \ composite-traps-test \ blitters-test \ + glyph-test \ scaling-test \ affine-test \ composite \ diff --git a/test/glyph-test.c b/test/glyph-test.c new file mode 100644 index 0000000..9ff2a2b --- /dev/null +++ b/test/glyph-test.c @@ -0,0 +1,331 @@ +#include +#include "utils.h" + +static const pixman_format_code_t glyph_formats[] = +{ + PIXMAN_a8r8g8b8, + PIXMAN_a8, + PIXMAN_a4, + PIXMAN_a1, + PIXMAN_x8r8g8b8, + PIXMAN_r3g3b2, + PIXMAN_null, +}; + +static const pixman_format_code_t formats[] = +{ + PIXMAN_a8r8g8b8, + PIXMAN_a8b8g8r8, + PIXMAN_x8r8g8b8, + PIXMAN_x8b8g8r8, + PIXMAN_r5g6b5, + PIXMAN_b5g6r5, + PIXMAN_a8, + PIXMAN_a1, + PIXMAN_r3g3b2, + PIXMAN_b8g8r8a8, + PIXMAN_b8g8r8x8, + PIXMAN_r8g8b8a8, + PIXMAN_r8g8b8x8, + PIXMAN_x14r6g6b6, + PIXMAN_r8g8b8, + PIXMAN_b8g8r8, + PIXMAN_x2r10g10b10, + PIXMAN_a2r10g10b10, + PIXMAN_x2b10g10r10, + PIXMAN_a2b10g10r10, + PIXMAN_a1r5g5b5, + PIXMAN_x1r5g5b5, + PIXMAN_a1b5g5r5, + PIXMAN_x1b5g5r5, + PIXMAN_a4r4g4b4, + PIXMAN_x4r4g4b4, + PIXMAN_a4b4g4r4, + PIXMAN_x4b4g4r4, + PIXMAN_r3g3b2, + PIXMAN_b2g3r3, + PIXMAN_a2r2g2b2, + PIXMAN_a2b2g2r2, + PIXMAN_x4a4, + PIXMAN_a4, + PIXMAN_r1g2b1, + PIXMAN_b1g2r1, + PIXMAN_a1r1g1b1, + PIXMAN_a1b1g1r1, + PIXMAN_null, +}; + +static const pixman_op_t operators[] = +{ + PIXMAN_OP_SRC, + PIXMAN_OP_OVER, + PIXMAN_OP_ADD, + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD +}; + +enum +{ + ALLOW_CLIPPED = (1 << 0), + ALLOW_ALPHA_MAP = (1 << 1), + ALLOW_SOURCE_CLIPPING = (1 << 2), + ALLOW_REPEAT = (1 << 3), + ALLOW_SOLID = (1 << 4), + ALLOW_FENCED_MEMORY = (1 << 5), +}; + +static void +destroy_fenced (pixman_image_t *image, void *data) +{ + fence_free (data); +} + +static void +destroy_malloced (pixman_image_t *image, void *data) +{ + free (data); +} + +static pixman_format_code_t +random_format (const pixman_format_code_t *formats) +{ + int i; + i = 0; + while (formats[i] != PIXMAN_null) + ++i; + return formats[lcg_rand_n (i)]; +} + +static pixman_image_t * +create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) +{ + int width, height; + pixman_image_t *image; + pixman_format_code_t format; + uint32_t *data; + int bpp; + int stride; + int i; + pixman_image_destroy_func_t destroy; + + if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0) + { + pixman_color_t color; + + color.alpha = lcg_rand_u32(); + color.red = lcg_rand_u32(); + color.green = lcg_rand_u32(); + color.blue = lcg_rand_u32(); + + return pixman_image_create_solid_fill (&color); + } + + width = lcg_rand_n (max_size) + 1; + height = lcg_rand_n (max_size) + 1; + format = random_format (formats); + + bpp = PIXMAN_FORMAT_BPP (format); + stride = (width * bpp + 7) / 8 + lcg_rand_n (17); + stride = (stride + 3) & ~3; + + if (lcg_rand_n (64) == 0) + { + if (!(data = (uint32_t *)make_random_bytes (stride * height))) + { + fprintf (stderr, "Out of memory\n"); + abort (); + } + destroy = destroy_fenced; + } + else + { + data = malloc (stride * height); + for (i = 0; i < height * stride / 4; ++i) + data[i] = lcg_rand_u32(); + + destroy = destroy_malloced; + } + + image = pixman_image_create_bits (format, width, height, data, stride); + pixman_image_set_destroy_function (image, destroy, data); + + if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0) + { + pixman_box16_t clip_boxes[8]; + pixman_region16_t clip; + int n = lcg_rand_n (8) + 1; + + for (i = 0; i < n; i++) + { + clip_boxes[i].x1 = lcg_rand_n (width); + clip_boxes[i].y1 = lcg_rand_n (height); + clip_boxes[i].x2 = + clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1); + clip_boxes[i].y2 = + clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1); + } + + pixman_region_init_rects (&clip, clip_boxes, n); + pixman_image_set_clip_region (image, &clip); + pixman_region_fini (&clip); + } + + if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0) + { + pixman_image_set_source_clipping (image, TRUE); + pixman_image_set_has_client_clip (image, TRUE); + } + + if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0) + { + pixman_image_t *alpha_map; + int alpha_x, alpha_y; + + alpha_x = lcg_rand_n (width); + alpha_y = lcg_rand_n (height); + alpha_map = + create_image (max_size, formats, (flags & ~ALLOW_ALPHA_MAP)); + pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y); + pixman_image_unref (alpha_map); + } + + if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0) + pixman_image_set_repeat (image, lcg_rand_n (4)); + + image_endian_swap (image); + + return image; +} + +#define KEY1(p) ((void *)(((unsigned long)p) ^ (0xa7e23dfaUL))) +#define KEY2(p) ((void *)(((unsigned long)p) ^ (0xabcd9876UL))) + +#define MAX_GLYPHS 32 + +uint32_t +test_glyphs (int testnum, int verbose) +{ + pixman_image_t *glyph_images[MAX_GLYPHS]; + pixman_glyph_t glyphs[4 * MAX_GLYPHS]; + uint32_t crc32 = 0; + pixman_image_t *source, *dest; + int n_glyphs, i; + pixman_glyph_cache_t *cache; + + lcg_srand (testnum); + + cache = pixman_glyph_cache_create (); + + source = create_image (300, formats, + ALLOW_CLIPPED | ALLOW_ALPHA_MAP | + ALLOW_SOURCE_CLIPPING | + ALLOW_REPEAT | ALLOW_SOLID); + + dest = create_image (128, formats, + ALLOW_CLIPPED | ALLOW_ALPHA_MAP | + ALLOW_SOURCE_CLIPPING); + + pixman_glyph_cache_freeze (cache); + + n_glyphs = lcg_rand_n (MAX_GLYPHS); + for (i = 0; i < n_glyphs; ++i) + glyph_images[i] = create_image (32, glyph_formats, 0); + + for (i = 0; i < 4 * n_glyphs; ++i) + { + int g = lcg_rand_n (n_glyphs); + pixman_image_t *glyph_img = glyph_images[g]; + void *key1 = KEY1 (glyph_img); + void *key2 = KEY2 (glyph_img); + const void *glyph; + + if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2))) + { + glyph = + pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img); + } + + glyphs[i].glyph = glyph; + glyphs[i].x = lcg_rand_n (128); + glyphs[i].y = lcg_rand_n (128); + } + + if (lcg_rand_n (2) == 0) + { + int src_x = lcg_rand_n (300) - 150; + int src_y = lcg_rand_n (300) - 150; + int mask_x = lcg_rand_n (64) - 32; + int mask_y = lcg_rand_n (64) - 32; + int dest_x = lcg_rand_n (64) - 32; + int dest_y = lcg_rand_n (64) - 32; + int width = lcg_rand_n (64); + int height = lcg_rand_n (64); + pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; + pixman_format_code_t format = random_format (glyph_formats); + + pixman_composite_glyphs ( + op, + source, dest, format, + src_x, src_y, + mask_x, mask_y, + dest_x, dest_y, + width, height, + cache, 4 * n_glyphs, glyphs); + } + else + { + pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; + int src_x = lcg_rand_n (300) - 150; + int src_y = lcg_rand_n (300) - 150; + int dest_x = lcg_rand_n (64) - 32; + int dest_y = lcg_rand_n (64) - 32; + + pixman_composite_glyphs_no_mask ( + op, source, dest, + src_x, src_y, + dest_x, dest_y, + cache, 4 * n_glyphs, glyphs); + } + + pixman_glyph_cache_thaw (cache); + + for (i = 0; i < n_glyphs; ++i) + { + pixman_image_t *img = glyph_images[i]; + void *key1, *key2; + + key1 = KEY1 (img); + key2 = KEY2 (img); + + pixman_glyph_cache_remove (cache, key1, key2); + pixman_image_unref (glyph_images[i]); + } + + crc32 = compute_crc32_for_image (0, dest); + + pixman_image_unref (source); + pixman_image_unref (dest); + + pixman_glyph_cache_destroy (cache); + + return crc32; +} + +int +main (int argc, const char *argv[]) +{ + return fuzzer_test_main ("glyph", 30000, + 0xA2B67F99, + test_glyphs, argc, argv); +}