diff options
Diffstat (limited to 'pixman/test')
-rw-r--r-- | pixman/test/Makefile.sources | 1 | ||||
-rw-r--r-- | pixman/test/blitters-test.c | 31 | ||||
-rw-r--r-- | pixman/test/glyph-test.c | 331 | ||||
-rw-r--r-- | pixman/test/utils.c | 101 | ||||
-rw-r--r-- | pixman/test/utils.h | 7 |
5 files changed, 440 insertions, 31 deletions
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index 99eb705af..fad8c6f69 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/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/pixman/test/blitters-test.c b/pixman/test/blitters-test.c index feea308c2..6a3cc8649 100644 --- a/pixman/test/blitters-test.c +++ b/pixman/test/blitters-test.c @@ -83,39 +83,10 @@ free_random_image (uint32_t initcrc, pixman_format_code_t fmt) { uint32_t crc32 = 0; - int stride = pixman_image_get_stride (img); uint32_t *data = pixman_image_get_data (img); - int height = pixman_image_get_height (img); if (fmt != PIXMAN_null) - { - /* mask unused 'x' part */ - if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) && - PIXMAN_FORMAT_DEPTH (fmt) != 0) - { - int i; - uint32_t *data = pixman_image_get_data (img); - uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1; - - if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA || - PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA) - { - mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt)); - } - - for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++) - mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt)); - - for (i = 0; i < stride * height / 4; i++) - data[i] &= mask; - } - - /* swap endiannes in order to provide identical results on both big - * and litte endian systems - */ - image_endian_swap (img); - crc32 = compute_crc32 (initcrc, data, stride * height); - } + crc32 = compute_crc32_for_image (initcrc, img); pixman_image_unref (img); free (data); diff --git a/pixman/test/glyph-test.c b/pixman/test/glyph-test.c new file mode 100644 index 000000000..9ff2a2bd4 --- /dev/null +++ b/pixman/test/glyph-test.c @@ -0,0 +1,331 @@ +#include <stdlib.h> +#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); +} diff --git a/pixman/test/utils.c b/pixman/test/utils.c index c1bf6dc2c..0abc32c66 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -135,6 +135,107 @@ compute_crc32 (uint32_t in_crc32, return (crc32 ^ 0xFFFFFFFF); } +static uint32_t +compute_crc32_for_image_internal (uint32_t crc32, + pixman_image_t *img, + pixman_bool_t remove_alpha, + pixman_bool_t remove_rgb) +{ + pixman_format_code_t fmt = pixman_image_get_format (img); + uint32_t *data = pixman_image_get_data (img); + int stride = pixman_image_get_stride (img); + int height = pixman_image_get_height (img); + uint32_t mask = 0xffffffff; + int i; + + /* mask unused 'x' part */ + if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) && + PIXMAN_FORMAT_DEPTH (fmt) != 0) + { + uint32_t m = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1; + + if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA || + PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA) + { + m <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt)); + } + + mask &= m; + } + + /* mask alpha channel */ + if (remove_alpha && PIXMAN_FORMAT_A (fmt)) + { + uint32_t m; + + if (PIXMAN_FORMAT_BPP (fmt) == 32) + m = 0xffffffff; + else + m = (1 << PIXMAN_FORMAT_BPP (fmt)) - 1; + + m >>= PIXMAN_FORMAT_A (fmt); + + if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA || + PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA || + PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_A) + { + /* Alpha is at the bottom of the pixel */ + m <<= PIXMAN_FORMAT_A (fmt); + } + + mask &= m; + } + + /* mask rgb channels */ + if (remove_rgb && PIXMAN_FORMAT_RGB (fmt)) + { + uint32_t m = ((uint32_t)~0) >> (32 - PIXMAN_FORMAT_BPP (fmt)); + uint32_t size = PIXMAN_FORMAT_R (fmt) + PIXMAN_FORMAT_G (fmt) + PIXMAN_FORMAT_B (fmt); + + m &= ~((1 << size) - 1); + + if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA || + PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA) + { + /* RGB channels are at the top of the pixel */ + m >>= size; + } + + mask &= m; + } + + for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++) + mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt)); + + for (i = 0; i < stride * height / 4; i++) + data[i] &= mask; + + /* swap endiannes in order to provide identical results on both big + * and litte endian systems + */ + image_endian_swap (img); + + return compute_crc32 (crc32, data, stride * height); +} + +uint32_t +compute_crc32_for_image (uint32_t crc32, + pixman_image_t *img) +{ + if (img->common.alpha_map) + { + crc32 = compute_crc32_for_image_internal (crc32, img, TRUE, FALSE); + crc32 = compute_crc32_for_image_internal ( + crc32, (pixman_image_t *)img->common.alpha_map, FALSE, TRUE); + } + else + { + crc32 = compute_crc32_for_image_internal (crc32, img, FALSE, FALSE); + } + + return crc32; +} + pixman_bool_t is_little_endian (void) { diff --git a/pixman/test/utils.h b/pixman/test/utils.h index 01af316d2..ac2decd11 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -63,7 +63,12 @@ compute_crc32 (uint32_t in_crc32, const void *buf, size_t buf_len); -/* Returns TRUE if running on a little endian system */ +uint32_t +compute_crc32_for_image (uint32_t in_crc32, + pixman_image_t *image); + +/* Returns TRUE if running on a little endian system + */ pixman_bool_t is_little_endian (void); |