1a450e446Smrg/* 2a450e446Smrg * Test program, which stresses the use of different color formats and 3a450e446Smrg * compositing operations. 4a450e446Smrg * 51b18d63aSmrg * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in 61b18d63aSmrg * the case of test failure. 7a450e446Smrg */ 8a450e446Smrg#include <stdlib.h> 9a450e446Smrg#include <stdio.h> 10952204abSmrg#include "utils.h" 11a450e446Smrg 121b18d63aSmrgstatic pixman_indexed_t rgb_palette[9]; 131b18d63aSmrgstatic pixman_indexed_t y_palette[9]; 14a450e446Smrg 156ba797d6Smrg/* The first eight format in the list are by far the most widely 166ba797d6Smrg * used formats, so we test those more than the others 176ba797d6Smrg */ 186ba797d6Smrg#define N_MOST_LIKELY_FORMATS 8 196ba797d6Smrg 20a450e446Smrg/* Create random image for testing purposes */ 21a450e446Smrgstatic pixman_image_t * 22a450e446Smrgcreate_random_image (pixman_format_code_t *allowed_formats, 23a450e446Smrg int max_width, 24a450e446Smrg int max_height, 25a450e446Smrg int max_extra_stride, 26a450e446Smrg pixman_format_code_t *used_fmt) 27a450e446Smrg{ 28f4f78bb6Smrg int n = 0, width, height, stride; 29a450e446Smrg pixman_format_code_t fmt; 30a450e446Smrg uint32_t *buf; 31a450e446Smrg pixman_image_t *img; 32a450e446Smrg 336ba797d6Smrg while (allowed_formats[n] != PIXMAN_null) 34a450e446Smrg n++; 356ba797d6Smrg 36f4f78bb6Smrg if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0) 376ba797d6Smrg n = N_MOST_LIKELY_FORMATS; 38f4f78bb6Smrg fmt = allowed_formats[prng_rand_n (n)]; 39952204abSmrg 40f4f78bb6Smrg width = prng_rand_n (max_width) + 1; 41f4f78bb6Smrg height = prng_rand_n (max_height) + 1; 42a450e446Smrg stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + 43f4f78bb6Smrg prng_rand_n (max_extra_stride + 1); 44a450e446Smrg stride = (stride + 3) & ~3; 45a450e446Smrg 46a450e446Smrg /* do the allocation */ 47a450e446Smrg buf = aligned_malloc (64, stride * height); 48a450e446Smrg 49f4f78bb6Smrg if (prng_rand_n (4) == 0) 50a450e446Smrg { 51f4f78bb6Smrg /* uniform distribution */ 52f4f78bb6Smrg prng_randmemset (buf, stride * height, 0); 53f4f78bb6Smrg } 54f4f78bb6Smrg else 55f4f78bb6Smrg { 56f4f78bb6Smrg /* significantly increased probability for 0x00 and 0xFF */ 57f4f78bb6Smrg prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF); 58a450e446Smrg } 59a450e446Smrg 60de17ff4aSmrg /* test negative stride */ 61de17ff4aSmrg if (prng_rand_n (4) == 0) 62de17ff4aSmrg { 63de17ff4aSmrg buf += (stride / 4) * (height - 1); 64de17ff4aSmrg stride = - stride; 65de17ff4aSmrg } 66de17ff4aSmrg 67a450e446Smrg img = pixman_image_create_bits (fmt, width, height, buf, stride); 68a450e446Smrg 691b18d63aSmrg if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) 701b18d63aSmrg { 711b18d63aSmrg pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)])); 721b18d63aSmrg } 731b18d63aSmrg else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) 74952204abSmrg { 751b18d63aSmrg pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); 76952204abSmrg } 77952204abSmrg 78f4f78bb6Smrg if (prng_rand_n (16) == 0) 799ad247e8Sjmcneill pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0); 809ad247e8Sjmcneill 816ba797d6Smrg image_endian_swap (img); 82a450e446Smrg 83a450e446Smrg if (used_fmt) *used_fmt = fmt; 84a450e446Smrg return img; 85a450e446Smrg} 86a450e446Smrg 87a450e446Smrg/* Free random image, and optionally update crc32 based on its data */ 88a450e446Smrgstatic uint32_t 89a450e446Smrgfree_random_image (uint32_t initcrc, 90a450e446Smrg pixman_image_t *img, 91a450e446Smrg pixman_format_code_t fmt) 92a450e446Smrg{ 93a450e446Smrg uint32_t crc32 = 0; 94a450e446Smrg uint32_t *data = pixman_image_get_data (img); 95a450e446Smrg 966ba797d6Smrg if (fmt != PIXMAN_null) 979ad247e8Sjmcneill crc32 = compute_crc32_for_image (initcrc, img); 98a450e446Smrg 99de17ff4aSmrg if (img->bits.rowstride < 0) 100de17ff4aSmrg data += img->bits.rowstride * (img->bits.height - 1); 101de17ff4aSmrg 102a450e446Smrg pixman_image_unref (img); 103a450e446Smrg free (data); 104a450e446Smrg 105a450e446Smrg return crc32; 106a450e446Smrg} 107a450e446Smrg 108a450e446Smrgstatic pixman_op_t op_list[] = { 109a450e446Smrg PIXMAN_OP_SRC, 110a450e446Smrg PIXMAN_OP_OVER, 111a450e446Smrg PIXMAN_OP_ADD, 112a450e446Smrg PIXMAN_OP_CLEAR, 113a450e446Smrg PIXMAN_OP_SRC, 114a450e446Smrg PIXMAN_OP_DST, 115a450e446Smrg PIXMAN_OP_OVER, 116a450e446Smrg PIXMAN_OP_OVER_REVERSE, 117a450e446Smrg PIXMAN_OP_IN, 118a450e446Smrg PIXMAN_OP_IN_REVERSE, 119a450e446Smrg PIXMAN_OP_OUT, 120a450e446Smrg PIXMAN_OP_OUT_REVERSE, 121a450e446Smrg PIXMAN_OP_ATOP, 122a450e446Smrg PIXMAN_OP_ATOP_REVERSE, 123a450e446Smrg PIXMAN_OP_XOR, 124a450e446Smrg PIXMAN_OP_ADD, 1256ca29ff0Smrg PIXMAN_OP_MULTIPLY, 1266ca29ff0Smrg PIXMAN_OP_SCREEN, 1276ca29ff0Smrg PIXMAN_OP_OVERLAY, 1286ca29ff0Smrg PIXMAN_OP_DARKEN, 1296ca29ff0Smrg PIXMAN_OP_LIGHTEN, 1306ca29ff0Smrg PIXMAN_OP_HARD_LIGHT, 1316ca29ff0Smrg PIXMAN_OP_DIFFERENCE, 1326ca29ff0Smrg PIXMAN_OP_EXCLUSION, 1336ca29ff0Smrg#if 0 /* these use floating point math and are not always bitexact on different platforms */ 134a450e446Smrg PIXMAN_OP_SATURATE, 135a450e446Smrg PIXMAN_OP_DISJOINT_CLEAR, 136a450e446Smrg PIXMAN_OP_DISJOINT_SRC, 137a450e446Smrg PIXMAN_OP_DISJOINT_DST, 138a450e446Smrg PIXMAN_OP_DISJOINT_OVER, 139a450e446Smrg PIXMAN_OP_DISJOINT_OVER_REVERSE, 140a450e446Smrg PIXMAN_OP_DISJOINT_IN, 141a450e446Smrg PIXMAN_OP_DISJOINT_IN_REVERSE, 142a450e446Smrg PIXMAN_OP_DISJOINT_OUT, 143a450e446Smrg PIXMAN_OP_DISJOINT_OUT_REVERSE, 144a450e446Smrg PIXMAN_OP_DISJOINT_ATOP, 145a450e446Smrg PIXMAN_OP_DISJOINT_ATOP_REVERSE, 146a450e446Smrg PIXMAN_OP_DISJOINT_XOR, 147a450e446Smrg PIXMAN_OP_CONJOINT_CLEAR, 148a450e446Smrg PIXMAN_OP_CONJOINT_SRC, 149a450e446Smrg PIXMAN_OP_CONJOINT_DST, 150a450e446Smrg PIXMAN_OP_CONJOINT_OVER, 151a450e446Smrg PIXMAN_OP_CONJOINT_OVER_REVERSE, 152a450e446Smrg PIXMAN_OP_CONJOINT_IN, 153a450e446Smrg PIXMAN_OP_CONJOINT_IN_REVERSE, 154a450e446Smrg PIXMAN_OP_CONJOINT_OUT, 155a450e446Smrg PIXMAN_OP_CONJOINT_OUT_REVERSE, 156a450e446Smrg PIXMAN_OP_CONJOINT_ATOP, 157a450e446Smrg PIXMAN_OP_CONJOINT_ATOP_REVERSE, 158a450e446Smrg PIXMAN_OP_CONJOINT_XOR, 159a450e446Smrg PIXMAN_OP_COLOR_DODGE, 160a450e446Smrg PIXMAN_OP_COLOR_BURN, 161a450e446Smrg PIXMAN_OP_SOFT_LIGHT, 162a450e446Smrg PIXMAN_OP_HSL_HUE, 163a450e446Smrg PIXMAN_OP_HSL_SATURATION, 164a450e446Smrg PIXMAN_OP_HSL_COLOR, 165a450e446Smrg PIXMAN_OP_HSL_LUMINOSITY, 166a450e446Smrg#endif 167a450e446Smrg}; 168a450e446Smrg 169a450e446Smrgstatic pixman_format_code_t img_fmt_list[] = { 170a450e446Smrg PIXMAN_a8r8g8b8, 1716ba797d6Smrg PIXMAN_a8b8g8r8, 172a450e446Smrg PIXMAN_x8r8g8b8, 1736ba797d6Smrg PIXMAN_x8b8g8r8, 174a450e446Smrg PIXMAN_r5g6b5, 1756ba797d6Smrg PIXMAN_b5g6r5, 176a450e446Smrg PIXMAN_a8, 1776ba797d6Smrg PIXMAN_a1, 1786ba797d6Smrg PIXMAN_r3g3b2, 179a450e446Smrg PIXMAN_b8g8r8a8, 180a450e446Smrg PIXMAN_b8g8r8x8, 1816ba797d6Smrg PIXMAN_r8g8b8a8, 1826ba797d6Smrg PIXMAN_r8g8b8x8, 1831b18d63aSmrg PIXMAN_x14r6g6b6, 184a450e446Smrg PIXMAN_r8g8b8, 185a450e446Smrg PIXMAN_b8g8r8, 1869ad247e8Sjmcneill#if 0 /* These are going to use floating point in the near future */ 187a450e446Smrg PIXMAN_x2r10g10b10, 188a450e446Smrg PIXMAN_a2r10g10b10, 189a450e446Smrg PIXMAN_x2b10g10r10, 190a450e446Smrg PIXMAN_a2b10g10r10, 1919ad247e8Sjmcneill#endif 192a450e446Smrg PIXMAN_a1r5g5b5, 193a450e446Smrg PIXMAN_x1r5g5b5, 194a450e446Smrg PIXMAN_a1b5g5r5, 195a450e446Smrg PIXMAN_x1b5g5r5, 196a450e446Smrg PIXMAN_a4r4g4b4, 197a450e446Smrg PIXMAN_x4r4g4b4, 198a450e446Smrg PIXMAN_a4b4g4r4, 199a450e446Smrg PIXMAN_x4b4g4r4, 200a450e446Smrg PIXMAN_r3g3b2, 201a450e446Smrg PIXMAN_b2g3r3, 202a450e446Smrg PIXMAN_a2r2g2b2, 203a450e446Smrg PIXMAN_a2b2g2r2, 204a450e446Smrg PIXMAN_c8, 205a450e446Smrg PIXMAN_g8, 206a450e446Smrg PIXMAN_x4c4, 207a450e446Smrg PIXMAN_x4g4, 208a450e446Smrg PIXMAN_c4, 209a450e446Smrg PIXMAN_g4, 210a450e446Smrg PIXMAN_g1, 211a450e446Smrg PIXMAN_x4a4, 212a450e446Smrg PIXMAN_a4, 213a450e446Smrg PIXMAN_r1g2b1, 214a450e446Smrg PIXMAN_b1g2r1, 215a450e446Smrg PIXMAN_a1r1g1b1, 216a450e446Smrg PIXMAN_a1b1g1r1, 2176ba797d6Smrg PIXMAN_null 218a450e446Smrg}; 219a450e446Smrg 220a450e446Smrgstatic pixman_format_code_t mask_fmt_list[] = { 221a450e446Smrg PIXMAN_a8r8g8b8, 222a450e446Smrg PIXMAN_a8, 223a450e446Smrg PIXMAN_a4, 224a450e446Smrg PIXMAN_a1, 2256ba797d6Smrg PIXMAN_null 226a450e446Smrg}; 227a450e446Smrg 228a450e446Smrg 229a450e446Smrg/* 230a450e446Smrg * Composite operation with pseudorandom images 231a450e446Smrg */ 232a450e446Smrguint32_t 2331b18d63aSmrgtest_composite (int testnum, int verbose) 234a450e446Smrg{ 235a450e446Smrg pixman_image_t *src_img = NULL; 236a450e446Smrg pixman_image_t *dst_img = NULL; 237a450e446Smrg pixman_image_t *mask_img = NULL; 238a450e446Smrg int src_width, src_height; 239a450e446Smrg int dst_width, dst_height; 240a450e446Smrg int src_stride, dst_stride; 241a450e446Smrg int src_x, src_y; 242a450e446Smrg int dst_x, dst_y; 243952204abSmrg int mask_x, mask_y; 244a450e446Smrg int w, h; 2456ba797d6Smrg pixman_op_t op; 246a450e446Smrg pixman_format_code_t src_fmt, dst_fmt, mask_fmt; 247de17ff4aSmrg uint32_t *srcbuf, *maskbuf; 248a450e446Smrg uint32_t crc32; 249a450e446Smrg int max_width, max_height, max_extra_stride; 2501b18d63aSmrg FLOAT_REGS_CORRUPTION_DETECTOR_START (); 251a450e446Smrg 252a450e446Smrg max_width = max_height = 24 + testnum / 10000; 253a450e446Smrg max_extra_stride = 4 + testnum / 1000000; 254a450e446Smrg 255a450e446Smrg if (max_width > 256) 256a450e446Smrg max_width = 256; 257a450e446Smrg 258a450e446Smrg if (max_height > 16) 259a450e446Smrg max_height = 16; 260a450e446Smrg 261a450e446Smrg if (max_extra_stride > 8) 262a450e446Smrg max_extra_stride = 8; 263a450e446Smrg 264f4f78bb6Smrg prng_srand (testnum); 265a450e446Smrg 266f4f78bb6Smrg op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; 267a450e446Smrg 268f4f78bb6Smrg if (prng_rand_n (8)) 269a450e446Smrg { 270a450e446Smrg /* normal image */ 271a450e446Smrg src_img = create_random_image (img_fmt_list, max_width, max_height, 272a450e446Smrg max_extra_stride, &src_fmt); 273a450e446Smrg } 274a450e446Smrg else 275a450e446Smrg { 276a450e446Smrg /* solid case */ 277a450e446Smrg src_img = create_random_image (img_fmt_list, 1, 1, 278a450e446Smrg max_extra_stride, &src_fmt); 279a450e446Smrg 280a450e446Smrg pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); 281a450e446Smrg } 282a450e446Smrg 283a450e446Smrg dst_img = create_random_image (img_fmt_list, max_width, max_height, 284a450e446Smrg max_extra_stride, &dst_fmt); 285a450e446Smrg 286952204abSmrg src_width = pixman_image_get_width (src_img); 287952204abSmrg src_height = pixman_image_get_height (src_img); 288952204abSmrg src_stride = pixman_image_get_stride (src_img); 289952204abSmrg 290952204abSmrg dst_width = pixman_image_get_width (dst_img); 291952204abSmrg dst_height = pixman_image_get_height (dst_img); 292952204abSmrg dst_stride = pixman_image_get_stride (dst_img); 293952204abSmrg 294952204abSmrg srcbuf = pixman_image_get_data (src_img); 295952204abSmrg 296f4f78bb6Smrg src_x = prng_rand_n (src_width); 297f4f78bb6Smrg src_y = prng_rand_n (src_height); 298f4f78bb6Smrg dst_x = prng_rand_n (dst_width); 299f4f78bb6Smrg dst_y = prng_rand_n (dst_height); 300952204abSmrg 301a450e446Smrg mask_img = NULL; 3026ba797d6Smrg mask_fmt = PIXMAN_null; 303952204abSmrg mask_x = 0; 304952204abSmrg mask_y = 0; 305952204abSmrg maskbuf = NULL; 306a450e446Smrg 307952204abSmrg if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) && 308f4f78bb6Smrg (prng_rand_n (4) == 0)) 309952204abSmrg { 310952204abSmrg /* PIXBUF */ 311f4f78bb6Smrg mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; 312952204abSmrg mask_img = pixman_image_create_bits (mask_fmt, 313952204abSmrg src_width, 314952204abSmrg src_height, 315952204abSmrg srcbuf, 316952204abSmrg src_stride); 317952204abSmrg mask_x = src_x; 318952204abSmrg mask_y = src_y; 319952204abSmrg maskbuf = srcbuf; 320952204abSmrg } 321f4f78bb6Smrg else if (prng_rand_n (2)) 322a450e446Smrg { 323f4f78bb6Smrg if (prng_rand_n (2)) 324a450e446Smrg { 325a450e446Smrg mask_img = create_random_image (mask_fmt_list, max_width, max_height, 326a450e446Smrg max_extra_stride, &mask_fmt); 327a450e446Smrg } 328a450e446Smrg else 329a450e446Smrg { 330a450e446Smrg /* solid case */ 331a450e446Smrg mask_img = create_random_image (mask_fmt_list, 1, 1, 332a450e446Smrg max_extra_stride, &mask_fmt); 333a450e446Smrg pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); 334a450e446Smrg } 335a450e446Smrg 336f4f78bb6Smrg if (prng_rand_n (2)) 337a450e446Smrg pixman_image_set_component_alpha (mask_img, 1); 338a450e446Smrg 339f4f78bb6Smrg mask_x = prng_rand_n (pixman_image_get_width (mask_img)); 340f4f78bb6Smrg mask_y = prng_rand_n (pixman_image_get_height (mask_img)); 341952204abSmrg } 342a450e446Smrg 343a450e446Smrg 344f4f78bb6Smrg w = prng_rand_n (dst_width - dst_x + 1); 345f4f78bb6Smrg h = prng_rand_n (dst_height - dst_y + 1); 346a450e446Smrg 347a450e446Smrg if (verbose) 348a450e446Smrg { 349f4f78bb6Smrg printf ("op=%s\n", operator_name (op)); 350f4f78bb6Smrg printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", 351f4f78bb6Smrg format_name (src_fmt), format_name (dst_fmt), 352f4f78bb6Smrg format_name (mask_fmt)); 353a450e446Smrg printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", 354a450e446Smrg src_width, src_height, dst_width, dst_height); 355a450e446Smrg printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", 356a450e446Smrg src_x, src_y, dst_x, dst_y); 357a450e446Smrg printf ("src_stride=%d, dst_stride=%d\n", 358a450e446Smrg src_stride, dst_stride); 359a450e446Smrg printf ("w=%d, h=%d\n", w, h); 360a450e446Smrg } 361a450e446Smrg 362a450e446Smrg pixman_image_composite (op, src_img, mask_img, dst_img, 363952204abSmrg src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); 364a450e446Smrg 365a450e446Smrg if (verbose) 366de17ff4aSmrg print_image (dst_img); 367a450e446Smrg 3686ba797d6Smrg free_random_image (0, src_img, PIXMAN_null); 3691b18d63aSmrg crc32 = free_random_image (0, dst_img, dst_fmt); 370a450e446Smrg 371a450e446Smrg if (mask_img) 372952204abSmrg { 373952204abSmrg if (srcbuf == maskbuf) 374952204abSmrg pixman_image_unref(mask_img); 375952204abSmrg else 3766ba797d6Smrg free_random_image (0, mask_img, PIXMAN_null); 377952204abSmrg } 378952204abSmrg 3791b18d63aSmrg FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); 380a450e446Smrg return crc32; 381a450e446Smrg} 382a450e446Smrg 3831b18d63aSmrgint 3841b18d63aSmrgmain (int argc, const char *argv[]) 3851b18d63aSmrg{ 3861b18d63aSmrg int i; 387a450e446Smrg 388f4f78bb6Smrg prng_srand (0); 389f4f78bb6Smrg 3901b18d63aSmrg for (i = 1; i <= 8; i++) 3911b18d63aSmrg { 392953d7d37Smrg initialize_palette (&(rgb_palette[i]), i, TRUE); 393953d7d37Smrg initialize_palette (&(y_palette[i]), i, FALSE); 394a450e446Smrg } 3951b18d63aSmrg 3961b18d63aSmrg return fuzzer_test_main("blitters", 2000000, 3976ca29ff0Smrg 0xCC21DDF0, 3981b18d63aSmrg test_composite, argc, argv); 399a450e446Smrg} 400