stress-test.c revision 953d7d37
1953d7d37Smrg#include "utils.h" 2953d7d37Smrg 3953d7d37Smrg#if 0 4953d7d37Smrg#define fence_malloc malloc 5953d7d37Smrg#define fence_free free 6953d7d37Smrg#define make_random_bytes malloc 7953d7d37Smrg#endif 8953d7d37Smrg 9953d7d37Smrgstatic const pixman_format_code_t image_formats[] = 10953d7d37Smrg{ 11953d7d37Smrg PIXMAN_a8r8g8b8, 12953d7d37Smrg PIXMAN_x8r8g8b8, 13953d7d37Smrg PIXMAN_r5g6b5, 14953d7d37Smrg PIXMAN_r3g3b2, 15953d7d37Smrg PIXMAN_a8, 16953d7d37Smrg PIXMAN_a8b8g8r8, 17953d7d37Smrg PIXMAN_x8b8g8r8, 18953d7d37Smrg PIXMAN_b8g8r8a8, 19953d7d37Smrg PIXMAN_b8g8r8x8, 20953d7d37Smrg PIXMAN_x14r6g6b6, 21953d7d37Smrg PIXMAN_r8g8b8, 22953d7d37Smrg PIXMAN_b8g8r8, 23953d7d37Smrg PIXMAN_r5g6b5, 24953d7d37Smrg PIXMAN_b5g6r5, 25953d7d37Smrg PIXMAN_x2r10g10b10, 26953d7d37Smrg PIXMAN_a2r10g10b10, 27953d7d37Smrg PIXMAN_x2b10g10r10, 28953d7d37Smrg PIXMAN_a2b10g10r10, 29953d7d37Smrg PIXMAN_a1r5g5b5, 30953d7d37Smrg PIXMAN_x1r5g5b5, 31953d7d37Smrg PIXMAN_a1b5g5r5, 32953d7d37Smrg PIXMAN_x1b5g5r5, 33953d7d37Smrg PIXMAN_a4r4g4b4, 34953d7d37Smrg PIXMAN_x4r4g4b4, 35953d7d37Smrg PIXMAN_a4b4g4r4, 36953d7d37Smrg PIXMAN_x4b4g4r4, 37953d7d37Smrg PIXMAN_a8, 38953d7d37Smrg PIXMAN_r3g3b2, 39953d7d37Smrg PIXMAN_b2g3r3, 40953d7d37Smrg PIXMAN_a2r2g2b2, 41953d7d37Smrg PIXMAN_a2b2g2r2, 42953d7d37Smrg PIXMAN_c8, 43953d7d37Smrg PIXMAN_g8, 44953d7d37Smrg PIXMAN_x4c4, 45953d7d37Smrg PIXMAN_x4g4, 46953d7d37Smrg PIXMAN_c4, 47953d7d37Smrg PIXMAN_g4, 48953d7d37Smrg PIXMAN_g1, 49953d7d37Smrg PIXMAN_x4a4, 50953d7d37Smrg PIXMAN_a4, 51953d7d37Smrg PIXMAN_r1g2b1, 52953d7d37Smrg PIXMAN_b1g2r1, 53953d7d37Smrg PIXMAN_a1r1g1b1, 54953d7d37Smrg PIXMAN_a1b1g1r1, 55953d7d37Smrg PIXMAN_a1 56953d7d37Smrg}; 57953d7d37Smrg 58953d7d37Smrgstatic pixman_filter_t filters[] = 59953d7d37Smrg{ 60953d7d37Smrg PIXMAN_FILTER_NEAREST, 61953d7d37Smrg PIXMAN_FILTER_BILINEAR, 62953d7d37Smrg PIXMAN_FILTER_FAST, 63953d7d37Smrg PIXMAN_FILTER_GOOD, 64953d7d37Smrg PIXMAN_FILTER_BEST, 65953d7d37Smrg PIXMAN_FILTER_CONVOLUTION 66953d7d37Smrg}; 67953d7d37Smrg 68953d7d37Smrgstatic int 69953d7d37Smrgget_size (void) 70953d7d37Smrg{ 71953d7d37Smrg switch (lcg_rand_n (28)) 72953d7d37Smrg { 73953d7d37Smrg case 0: 74953d7d37Smrg return 1; 75953d7d37Smrg 76953d7d37Smrg case 1: 77953d7d37Smrg return 2; 78953d7d37Smrg 79953d7d37Smrg default: 80953d7d37Smrg case 2: 81953d7d37Smrg return lcg_rand_n (200); 82953d7d37Smrg 83953d7d37Smrg case 4: 84953d7d37Smrg return lcg_rand_n (2000) + 1000; 85953d7d37Smrg 86953d7d37Smrg case 5: 87953d7d37Smrg return 65535; 88953d7d37Smrg 89953d7d37Smrg case 6: 90953d7d37Smrg return 65536; 91953d7d37Smrg 92953d7d37Smrg case 7: 93953d7d37Smrg return lcg_rand_N (64000) + 63000; 94953d7d37Smrg } 95953d7d37Smrg} 96953d7d37Smrg 97953d7d37Smrgstatic void 98953d7d37Smrgdestroy (pixman_image_t *image, void *data) 99953d7d37Smrg{ 100953d7d37Smrg if (image->type == BITS && image->bits.free_me != image->bits.bits) 101953d7d37Smrg { 102953d7d37Smrg uint32_t *bits; 103953d7d37Smrg 104953d7d37Smrg if (image->bits.bits != (void *)0x01) 105953d7d37Smrg { 106953d7d37Smrg bits = image->bits.bits; 107953d7d37Smrg 108953d7d37Smrg if (image->bits.rowstride < 0) 109953d7d37Smrg bits -= (- image->bits.rowstride * (image->bits.height - 1)); 110953d7d37Smrg 111953d7d37Smrg fence_free (bits); 112953d7d37Smrg } 113953d7d37Smrg } 114953d7d37Smrg 115953d7d37Smrg free (data); 116953d7d37Smrg} 117953d7d37Smrg 118953d7d37Smrgstatic uint32_t 119953d7d37Smrgreal_reader (const void *src, int size) 120953d7d37Smrg{ 121953d7d37Smrg switch (size) 122953d7d37Smrg { 123953d7d37Smrg case 1: 124953d7d37Smrg return *(uint8_t *)src; 125953d7d37Smrg case 2: 126953d7d37Smrg return *(uint16_t *)src; 127953d7d37Smrg case 4: 128953d7d37Smrg return *(uint32_t *)src; 129953d7d37Smrg default: 130953d7d37Smrg assert (0); 131953d7d37Smrg break; 132953d7d37Smrg } 133953d7d37Smrg} 134953d7d37Smrg 135953d7d37Smrgstatic void 136953d7d37Smrgreal_writer (void *src, uint32_t value, int size) 137953d7d37Smrg{ 138953d7d37Smrg switch (size) 139953d7d37Smrg { 140953d7d37Smrg case 1: 141953d7d37Smrg *(uint8_t *)src = value; 142953d7d37Smrg break; 143953d7d37Smrg 144953d7d37Smrg case 2: 145953d7d37Smrg *(uint16_t *)src = value; 146953d7d37Smrg break; 147953d7d37Smrg 148953d7d37Smrg case 4: 149953d7d37Smrg *(uint32_t *)src = value; 150953d7d37Smrg break; 151953d7d37Smrg 152953d7d37Smrg default: 153953d7d37Smrg assert (0); 154953d7d37Smrg break; 155953d7d37Smrg } 156953d7d37Smrg} 157953d7d37Smrg 158953d7d37Smrgstatic uint32_t 159953d7d37Smrgfake_reader (const void *src, int size) 160953d7d37Smrg{ 161953d7d37Smrg uint32_t r = lcg_rand_u32 (); 162953d7d37Smrg 163953d7d37Smrg assert (size == 1 || size == 2 || size == 4); 164953d7d37Smrg return r & ((1 << (size * 8)) - 1); 165953d7d37Smrg} 166953d7d37Smrg 167953d7d37Smrgstatic void 168953d7d37Smrgfake_writer (void *src, uint32_t value, int size) 169953d7d37Smrg{ 170953d7d37Smrg assert (size == 1 || size == 2 || size == 4); 171953d7d37Smrg} 172953d7d37Smrg 173953d7d37Smrgstatic int32_t 174953d7d37Smrglog_rand (void) 175953d7d37Smrg{ 176953d7d37Smrg uint32_t mask; 177953d7d37Smrg 178953d7d37Smrg mask = (1 << lcg_rand_n (31)) - 1; 179953d7d37Smrg 180953d7d37Smrg return (lcg_rand () & mask) - (mask >> 1); 181953d7d37Smrg} 182953d7d37Smrg 183953d7d37Smrgstatic pixman_image_t * 184953d7d37Smrgcreate_random_bits_image (void) 185953d7d37Smrg{ 186953d7d37Smrg pixman_format_code_t format; 187953d7d37Smrg pixman_indexed_t *indexed; 188953d7d37Smrg pixman_image_t *image; 189953d7d37Smrg int width, height, stride; 190953d7d37Smrg uint32_t *bits; 191953d7d37Smrg pixman_read_memory_func_t read_func = NULL; 192953d7d37Smrg pixman_write_memory_func_t write_func = NULL; 193953d7d37Smrg pixman_filter_t filter; 194953d7d37Smrg pixman_fixed_t *coefficients = NULL; 195953d7d37Smrg int n_coefficients = 0; 196953d7d37Smrg 197953d7d37Smrg /* format */ 198953d7d37Smrg format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))]; 199953d7d37Smrg 200953d7d37Smrg indexed = NULL; 201953d7d37Smrg if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) 202953d7d37Smrg { 203953d7d37Smrg indexed = malloc (sizeof (pixman_indexed_t)); 204953d7d37Smrg 205953d7d37Smrg initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), TRUE); 206953d7d37Smrg } 207953d7d37Smrg else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY) 208953d7d37Smrg { 209953d7d37Smrg indexed = malloc (sizeof (pixman_indexed_t)); 210953d7d37Smrg 211953d7d37Smrg initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), FALSE); 212953d7d37Smrg } 213953d7d37Smrg else 214953d7d37Smrg { 215953d7d37Smrg indexed = NULL; 216953d7d37Smrg } 217953d7d37Smrg 218953d7d37Smrg /* size */ 219953d7d37Smrg width = get_size (); 220953d7d37Smrg height = get_size (); 221953d7d37Smrg 222953d7d37Smrg if ((uint64_t)width * height > 200000) 223953d7d37Smrg { 224953d7d37Smrg if (lcg_rand_n(2) == 0) 225953d7d37Smrg height = 200000 / width; 226953d7d37Smrg else 227953d7d37Smrg width = 200000 / height; 228953d7d37Smrg } 229953d7d37Smrg 230953d7d37Smrg if (height == 0) 231953d7d37Smrg height = 1; 232953d7d37Smrg if (width == 0) 233953d7d37Smrg width = 1; 234953d7d37Smrg 235953d7d37Smrg /* bits */ 236953d7d37Smrg switch (lcg_rand_n (7)) 237953d7d37Smrg { 238953d7d37Smrg default: 239953d7d37Smrg case 0: 240953d7d37Smrg stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); 241953d7d37Smrg stride = (stride + 3) & (~3); 242953d7d37Smrg bits = (uint32_t *)make_random_bytes (height * stride); 243953d7d37Smrg break; 244953d7d37Smrg 245953d7d37Smrg case 1: 246953d7d37Smrg stride = 0; 247953d7d37Smrg bits = NULL; 248953d7d37Smrg break; 249953d7d37Smrg 250953d7d37Smrg case 2: /* Zero-filled */ 251953d7d37Smrg stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); 252953d7d37Smrg stride = (stride + 3) & (~3); 253953d7d37Smrg bits = fence_malloc (height * stride); 254953d7d37Smrg if (!bits) 255953d7d37Smrg return NULL; 256953d7d37Smrg memset (bits, 0, height * stride); 257953d7d37Smrg break; 258953d7d37Smrg 259953d7d37Smrg case 3: /* Filled with 0xFF */ 260953d7d37Smrg stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); 261953d7d37Smrg stride = (stride + 3) & (~3); 262953d7d37Smrg bits = fence_malloc (height * stride); 263953d7d37Smrg if (!bits) 264953d7d37Smrg return NULL; 265953d7d37Smrg memset (bits, 0xff, height * stride); 266953d7d37Smrg break; 267953d7d37Smrg 268953d7d37Smrg case 4: /* bits is a bad pointer, has read/write functions */ 269953d7d37Smrg stride = 232; 270953d7d37Smrg bits = (void *)0x01; 271953d7d37Smrg read_func = fake_reader; 272953d7d37Smrg write_func = fake_writer; 273953d7d37Smrg break; 274953d7d37Smrg 275953d7d37Smrg case 5: /* bits is a real pointer, has read/write functions */ 276953d7d37Smrg stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17); 277953d7d37Smrg stride = (stride + 3) & (~3); 278953d7d37Smrg bits = fence_malloc (height * stride); 279953d7d37Smrg if (!bits) 280953d7d37Smrg return NULL; 281953d7d37Smrg memset (bits, 0xff, height * stride); 282953d7d37Smrg read_func = real_reader; 283953d7d37Smrg write_func = real_writer; 284953d7d37Smrg break; 285953d7d37Smrg 286953d7d37Smrg case 6: /* bits is a real pointer, stride is negative */ 287953d7d37Smrg stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17)); 288953d7d37Smrg stride = (stride + 3) & (~3); 289953d7d37Smrg bits = (uint32_t *)make_random_bytes (height * stride); 290953d7d37Smrg if (!bits) 291953d7d37Smrg return NULL; 292953d7d37Smrg bits += ((height - 1) * stride) / 4; 293953d7d37Smrg stride = - stride; 294953d7d37Smrg break; 295953d7d37Smrg } 296953d7d37Smrg 297953d7d37Smrg /* Filter */ 298953d7d37Smrg filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))]; 299953d7d37Smrg if (filter == PIXMAN_FILTER_CONVOLUTION) 300953d7d37Smrg { 301953d7d37Smrg int width = lcg_rand_n (17); 302953d7d37Smrg int height = lcg_rand_n (19); 303953d7d37Smrg 304953d7d37Smrg n_coefficients = width * height + 2; 305953d7d37Smrg coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t)); 306953d7d37Smrg 307953d7d37Smrg if (coefficients) 308953d7d37Smrg { 309953d7d37Smrg int i; 310953d7d37Smrg 311953d7d37Smrg for (i = 0; i < width * height; ++i) 312953d7d37Smrg coefficients[i + 2] = lcg_rand_u32(); 313953d7d37Smrg 314953d7d37Smrg coefficients[0] = width << 16; 315953d7d37Smrg coefficients[1] = height << 16; 316953d7d37Smrg } 317953d7d37Smrg else 318953d7d37Smrg { 319953d7d37Smrg filter = PIXMAN_FILTER_BEST; 320953d7d37Smrg } 321953d7d37Smrg } 322953d7d37Smrg 323953d7d37Smrg /* Finally create the image */ 324953d7d37Smrg image = pixman_image_create_bits (format, width, height, bits, stride); 325953d7d37Smrg if (!image) 326953d7d37Smrg return NULL; 327953d7d37Smrg 328953d7d37Smrg pixman_image_set_indexed (image, indexed); 329953d7d37Smrg pixman_image_set_destroy_function (image, destroy, indexed); 330953d7d37Smrg pixman_image_set_accessors (image, read_func, write_func); 331953d7d37Smrg pixman_image_set_filter (image, filter, coefficients, n_coefficients); 332953d7d37Smrg 333953d7d37Smrg return image; 334953d7d37Smrg} 335953d7d37Smrg 336953d7d37Smrgstatic pixman_repeat_t repeats[] = 337953d7d37Smrg{ 338953d7d37Smrg PIXMAN_REPEAT_NONE, 339953d7d37Smrg PIXMAN_REPEAT_NORMAL, 340953d7d37Smrg PIXMAN_REPEAT_REFLECT, 341953d7d37Smrg PIXMAN_REPEAT_PAD 342953d7d37Smrg}; 343953d7d37Smrg 344953d7d37Smrgstatic uint32_t 345953d7d37Smrgabsolute (int32_t i) 346953d7d37Smrg{ 347953d7d37Smrg return i < 0? -i : i; 348953d7d37Smrg} 349953d7d37Smrg 350953d7d37Smrgstatic void 351953d7d37Smrgset_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map) 352953d7d37Smrg{ 353953d7d37Smrg pixman_repeat_t repeat; 354953d7d37Smrg 355953d7d37Smrg /* Set properties that are generic to all images */ 356953d7d37Smrg 357953d7d37Smrg /* Repeat */ 358953d7d37Smrg repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))]; 359953d7d37Smrg pixman_image_set_repeat (image, repeat); 360953d7d37Smrg 361953d7d37Smrg /* Alpha map */ 362953d7d37Smrg if (allow_alpha_map && lcg_rand_n (3) == 0) 363953d7d37Smrg { 364953d7d37Smrg pixman_image_t *alpha_map; 365953d7d37Smrg int16_t x, y; 366953d7d37Smrg 367953d7d37Smrg alpha_map = create_random_bits_image (); 368953d7d37Smrg 369953d7d37Smrg if (alpha_map) 370953d7d37Smrg { 371953d7d37Smrg set_general_properties (alpha_map, FALSE); 372953d7d37Smrg 373953d7d37Smrg x = lcg_rand_N (100000) - 65536; 374953d7d37Smrg y = lcg_rand_N (100000) - 65536; 375953d7d37Smrg 376953d7d37Smrg pixman_image_set_alpha_map (image, alpha_map, x, y); 377953d7d37Smrg 378953d7d37Smrg pixman_image_unref (alpha_map); 379953d7d37Smrg } 380953d7d37Smrg } 381953d7d37Smrg 382953d7d37Smrg /* Component alpha */ 383953d7d37Smrg pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0); 384953d7d37Smrg 385953d7d37Smrg /* Clip region */ 386953d7d37Smrg if (lcg_rand_n (8) != 0) 387953d7d37Smrg { 388953d7d37Smrg pixman_region32_t region; 389953d7d37Smrg int i, n_rects; 390953d7d37Smrg 391953d7d37Smrg pixman_region32_init (®ion); 392953d7d37Smrg 393953d7d37Smrg switch (lcg_rand_n (10)) 394953d7d37Smrg { 395953d7d37Smrg case 0: 396953d7d37Smrg n_rects = 0; 397953d7d37Smrg break; 398953d7d37Smrg 399953d7d37Smrg case 1: case 2: case 3: 400953d7d37Smrg n_rects = 1; 401953d7d37Smrg break; 402953d7d37Smrg 403953d7d37Smrg case 4: case 5: 404953d7d37Smrg n_rects = 2; 405953d7d37Smrg break; 406953d7d37Smrg 407953d7d37Smrg case 6: case 7: 408953d7d37Smrg n_rects = 3; 409953d7d37Smrg 410953d7d37Smrg default: 411953d7d37Smrg n_rects = lcg_rand_n (100); 412953d7d37Smrg break; 413953d7d37Smrg } 414953d7d37Smrg 415953d7d37Smrg for (i = 0; i < n_rects; ++i) 416953d7d37Smrg { 417953d7d37Smrg uint32_t width, height; 418953d7d37Smrg int x, y; 419953d7d37Smrg 420953d7d37Smrg x = log_rand(); 421953d7d37Smrg y = log_rand(); 422953d7d37Smrg width = absolute (log_rand ()) + 1; 423953d7d37Smrg height = absolute (log_rand ()) + 1; 424953d7d37Smrg 425953d7d37Smrg pixman_region32_union_rect ( 426953d7d37Smrg ®ion, ®ion, x, y, width, height); 427953d7d37Smrg } 428953d7d37Smrg 429953d7d37Smrg pixman_image_set_clip_region32 (image, ®ion); 430953d7d37Smrg 431953d7d37Smrg pixman_region32_fini (®ion); 432953d7d37Smrg } 433953d7d37Smrg 434953d7d37Smrg /* Whether source clipping is enabled */ 435953d7d37Smrg pixman_image_set_source_clipping (image, !!lcg_rand_n (2)); 436953d7d37Smrg 437953d7d37Smrg /* Client clip */ 438953d7d37Smrg pixman_image_set_has_client_clip (image, !!lcg_rand_n (2)); 439953d7d37Smrg 440953d7d37Smrg /* Transform */ 441953d7d37Smrg if (lcg_rand_n (5) < 2) 442953d7d37Smrg { 443953d7d37Smrg pixman_transform_t xform; 444953d7d37Smrg int i, j, k; 445953d7d37Smrg uint32_t tx, ty, sx, sy; 446953d7d37Smrg uint32_t c, s; 447953d7d37Smrg 448953d7d37Smrg memset (&xform, 0, sizeof xform); 449953d7d37Smrg xform.matrix[0][0] = pixman_fixed_1; 450953d7d37Smrg xform.matrix[1][1] = pixman_fixed_1; 451953d7d37Smrg xform.matrix[2][2] = pixman_fixed_1; 452953d7d37Smrg 453953d7d37Smrg for (k = 0; k < 3; ++k) 454953d7d37Smrg { 455953d7d37Smrg switch (lcg_rand_n (4)) 456953d7d37Smrg { 457953d7d37Smrg case 0: 458953d7d37Smrg /* rotation */ 459953d7d37Smrg c = lcg_rand_N (2 * 65536) - 65536; 460953d7d37Smrg s = lcg_rand_N (2 * 65536) - 65536; 461953d7d37Smrg pixman_transform_rotate (&xform, NULL, c, s); 462953d7d37Smrg break; 463953d7d37Smrg 464953d7d37Smrg case 1: 465953d7d37Smrg /* translation */ 466953d7d37Smrg tx = lcg_rand_u32(); 467953d7d37Smrg ty = lcg_rand_u32(); 468953d7d37Smrg pixman_transform_translate (&xform, NULL, tx, ty); 469953d7d37Smrg break; 470953d7d37Smrg 471953d7d37Smrg case 2: 472953d7d37Smrg /* scale */ 473953d7d37Smrg sx = lcg_rand_u32(); 474953d7d37Smrg sy = lcg_rand_u32(); 475953d7d37Smrg pixman_transform_scale (&xform, NULL, sx, sy); 476953d7d37Smrg break; 477953d7d37Smrg 478953d7d37Smrg case 3: 479953d7d37Smrg if (lcg_rand_n (16) == 0) 480953d7d37Smrg { 481953d7d37Smrg /* random */ 482953d7d37Smrg for (i = 0; i < 3; ++i) 483953d7d37Smrg for (j = 0; j < 3; ++j) 484953d7d37Smrg xform.matrix[i][j] = lcg_rand_u32(); 485953d7d37Smrg break; 486953d7d37Smrg } 487953d7d37Smrg else if (lcg_rand_n (16) == 0) 488953d7d37Smrg { 489953d7d37Smrg /* zero */ 490953d7d37Smrg memset (&xform, 0, sizeof xform); 491953d7d37Smrg } 492953d7d37Smrg break; 493953d7d37Smrg } 494953d7d37Smrg } 495953d7d37Smrg 496953d7d37Smrg pixman_image_set_transform (image, &xform); 497953d7d37Smrg } 498953d7d37Smrg} 499953d7d37Smrg 500953d7d37Smrgstatic pixman_color_t 501953d7d37Smrgrandom_color (void) 502953d7d37Smrg{ 503953d7d37Smrg pixman_color_t color = 504953d7d37Smrg { 505953d7d37Smrg lcg_rand() & 0xffff, 506953d7d37Smrg lcg_rand() & 0xffff, 507953d7d37Smrg lcg_rand() & 0xffff, 508953d7d37Smrg lcg_rand() & 0xffff, 509953d7d37Smrg }; 510953d7d37Smrg 511953d7d37Smrg return color; 512953d7d37Smrg} 513953d7d37Smrg 514953d7d37Smrg 515953d7d37Smrgstatic pixman_image_t * 516953d7d37Smrgcreate_random_solid_image (void) 517953d7d37Smrg{ 518953d7d37Smrg pixman_color_t color = random_color(); 519953d7d37Smrg pixman_image_t *image = pixman_image_create_solid_fill (&color); 520953d7d37Smrg 521953d7d37Smrg return image; 522953d7d37Smrg} 523953d7d37Smrg 524953d7d37Smrgstatic pixman_gradient_stop_t * 525953d7d37Smrgcreate_random_stops (int *n_stops) 526953d7d37Smrg{ 527953d7d37Smrg pixman_fixed_t step; 528953d7d37Smrg pixman_fixed_t s; 529953d7d37Smrg int i; 530953d7d37Smrg pixman_gradient_stop_t *stops; 531953d7d37Smrg 532953d7d37Smrg *n_stops = lcg_rand_n (50) + 1; 533953d7d37Smrg 534953d7d37Smrg step = pixman_fixed_1 / *n_stops; 535953d7d37Smrg 536953d7d37Smrg stops = malloc (*n_stops * sizeof (pixman_gradient_stop_t)); 537953d7d37Smrg 538953d7d37Smrg s = 0; 539953d7d37Smrg for (i = 0; i < (*n_stops) - 1; ++i) 540953d7d37Smrg { 541953d7d37Smrg stops[i].x = s; 542953d7d37Smrg stops[i].color = random_color(); 543953d7d37Smrg 544953d7d37Smrg s += step; 545953d7d37Smrg } 546953d7d37Smrg 547953d7d37Smrg stops[*n_stops - 1].x = pixman_fixed_1; 548953d7d37Smrg stops[*n_stops - 1].color = random_color(); 549953d7d37Smrg 550953d7d37Smrg return stops; 551953d7d37Smrg} 552953d7d37Smrg 553953d7d37Smrgstatic pixman_point_fixed_t 554953d7d37Smrgcreate_random_point (void) 555953d7d37Smrg{ 556953d7d37Smrg pixman_point_fixed_t p; 557953d7d37Smrg 558953d7d37Smrg p.x = log_rand (); 559953d7d37Smrg p.y = log_rand (); 560953d7d37Smrg 561953d7d37Smrg return p; 562953d7d37Smrg} 563953d7d37Smrg 564953d7d37Smrgstatic pixman_image_t * 565953d7d37Smrgcreate_random_linear_image (void) 566953d7d37Smrg{ 567953d7d37Smrg int n_stops; 568953d7d37Smrg pixman_gradient_stop_t *stops; 569953d7d37Smrg pixman_point_fixed_t p1, p2; 570953d7d37Smrg pixman_image_t *result; 571953d7d37Smrg 572953d7d37Smrg stops = create_random_stops (&n_stops); 573953d7d37Smrg if (!stops) 574953d7d37Smrg return NULL; 575953d7d37Smrg 576953d7d37Smrg p1 = create_random_point (); 577953d7d37Smrg p2 = create_random_point (); 578953d7d37Smrg 579953d7d37Smrg result = pixman_image_create_linear_gradient (&p1, &p2, stops, n_stops); 580953d7d37Smrg 581953d7d37Smrg free (stops); 582953d7d37Smrg 583953d7d37Smrg return result; 584953d7d37Smrg} 585953d7d37Smrg 586953d7d37Smrgstatic pixman_image_t * 587953d7d37Smrgcreate_random_radial_image (void) 588953d7d37Smrg{ 589953d7d37Smrg int n_stops; 590953d7d37Smrg pixman_gradient_stop_t *stops; 591953d7d37Smrg pixman_point_fixed_t inner_c, outer_c; 592953d7d37Smrg pixman_fixed_t inner_r, outer_r; 593953d7d37Smrg pixman_image_t *result; 594953d7d37Smrg 595953d7d37Smrg inner_c = create_random_point(); 596953d7d37Smrg outer_c = create_random_point(); 597953d7d37Smrg inner_r = lcg_rand(); 598953d7d37Smrg outer_r = lcg_rand(); 599953d7d37Smrg 600953d7d37Smrg stops = create_random_stops (&n_stops); 601953d7d37Smrg 602953d7d37Smrg if (!stops) 603953d7d37Smrg return NULL; 604953d7d37Smrg 605953d7d37Smrg result = pixman_image_create_radial_gradient ( 606953d7d37Smrg &inner_c, &outer_c, inner_r, outer_r, stops, n_stops); 607953d7d37Smrg 608953d7d37Smrg free (stops); 609953d7d37Smrg 610953d7d37Smrg return result; 611953d7d37Smrg} 612953d7d37Smrg 613953d7d37Smrgstatic pixman_image_t * 614953d7d37Smrgcreate_random_conical_image (void) 615953d7d37Smrg{ 616953d7d37Smrg pixman_gradient_stop_t *stops; 617953d7d37Smrg int n_stops; 618953d7d37Smrg pixman_point_fixed_t c; 619953d7d37Smrg pixman_fixed_t angle; 620953d7d37Smrg pixman_image_t *result; 621953d7d37Smrg 622953d7d37Smrg c = create_random_point(); 623953d7d37Smrg angle = lcg_rand(); 624953d7d37Smrg 625953d7d37Smrg stops = create_random_stops (&n_stops); 626953d7d37Smrg 627953d7d37Smrg if (!stops) 628953d7d37Smrg return NULL; 629953d7d37Smrg 630953d7d37Smrg result = pixman_image_create_conical_gradient (&c, angle, stops, n_stops); 631953d7d37Smrg 632953d7d37Smrg free (stops); 633953d7d37Smrg 634953d7d37Smrg return result; 635953d7d37Smrg} 636953d7d37Smrg 637953d7d37Smrgstatic pixman_image_t * 638953d7d37Smrgcreate_random_image (void) 639953d7d37Smrg{ 640953d7d37Smrg pixman_image_t *result; 641953d7d37Smrg 642953d7d37Smrg switch (lcg_rand_n (5)) 643953d7d37Smrg { 644953d7d37Smrg default: 645953d7d37Smrg case 0: 646953d7d37Smrg result = create_random_bits_image (); 647953d7d37Smrg break; 648953d7d37Smrg 649953d7d37Smrg case 1: 650953d7d37Smrg result = create_random_solid_image (); 651953d7d37Smrg break; 652953d7d37Smrg 653953d7d37Smrg case 2: 654953d7d37Smrg result = create_random_linear_image (); 655953d7d37Smrg break; 656953d7d37Smrg 657953d7d37Smrg case 3: 658953d7d37Smrg result = create_random_radial_image (); 659953d7d37Smrg break; 660953d7d37Smrg 661953d7d37Smrg case 4: 662953d7d37Smrg result = create_random_conical_image (); 663953d7d37Smrg break; 664953d7d37Smrg } 665953d7d37Smrg 666953d7d37Smrg if (result) 667953d7d37Smrg set_general_properties (result, TRUE); 668953d7d37Smrg 669953d7d37Smrg return result; 670953d7d37Smrg} 671953d7d37Smrg 672953d7d37Smrgstatic const pixman_op_t op_list[] = 673953d7d37Smrg{ 674953d7d37Smrg PIXMAN_OP_SRC, 675953d7d37Smrg PIXMAN_OP_OVER, 676953d7d37Smrg PIXMAN_OP_ADD, 677953d7d37Smrg PIXMAN_OP_CLEAR, 678953d7d37Smrg PIXMAN_OP_SRC, 679953d7d37Smrg PIXMAN_OP_DST, 680953d7d37Smrg PIXMAN_OP_OVER, 681953d7d37Smrg PIXMAN_OP_OVER_REVERSE, 682953d7d37Smrg PIXMAN_OP_IN, 683953d7d37Smrg PIXMAN_OP_IN_REVERSE, 684953d7d37Smrg PIXMAN_OP_OUT, 685953d7d37Smrg PIXMAN_OP_OUT_REVERSE, 686953d7d37Smrg PIXMAN_OP_ATOP, 687953d7d37Smrg PIXMAN_OP_ATOP_REVERSE, 688953d7d37Smrg PIXMAN_OP_XOR, 689953d7d37Smrg PIXMAN_OP_ADD, 690953d7d37Smrg PIXMAN_OP_SATURATE, 691953d7d37Smrg PIXMAN_OP_DISJOINT_CLEAR, 692953d7d37Smrg PIXMAN_OP_DISJOINT_SRC, 693953d7d37Smrg PIXMAN_OP_DISJOINT_DST, 694953d7d37Smrg PIXMAN_OP_DISJOINT_OVER, 695953d7d37Smrg PIXMAN_OP_DISJOINT_OVER_REVERSE, 696953d7d37Smrg PIXMAN_OP_DISJOINT_IN, 697953d7d37Smrg PIXMAN_OP_DISJOINT_IN_REVERSE, 698953d7d37Smrg PIXMAN_OP_DISJOINT_OUT, 699953d7d37Smrg PIXMAN_OP_DISJOINT_OUT_REVERSE, 700953d7d37Smrg PIXMAN_OP_DISJOINT_ATOP, 701953d7d37Smrg PIXMAN_OP_DISJOINT_ATOP_REVERSE, 702953d7d37Smrg PIXMAN_OP_DISJOINT_XOR, 703953d7d37Smrg PIXMAN_OP_CONJOINT_CLEAR, 704953d7d37Smrg PIXMAN_OP_CONJOINT_SRC, 705953d7d37Smrg PIXMAN_OP_CONJOINT_DST, 706953d7d37Smrg PIXMAN_OP_CONJOINT_OVER, 707953d7d37Smrg PIXMAN_OP_CONJOINT_OVER_REVERSE, 708953d7d37Smrg PIXMAN_OP_CONJOINT_IN, 709953d7d37Smrg PIXMAN_OP_CONJOINT_IN_REVERSE, 710953d7d37Smrg PIXMAN_OP_CONJOINT_OUT, 711953d7d37Smrg PIXMAN_OP_CONJOINT_OUT_REVERSE, 712953d7d37Smrg PIXMAN_OP_CONJOINT_ATOP, 713953d7d37Smrg PIXMAN_OP_CONJOINT_ATOP_REVERSE, 714953d7d37Smrg PIXMAN_OP_CONJOINT_XOR, 715953d7d37Smrg PIXMAN_OP_MULTIPLY, 716953d7d37Smrg PIXMAN_OP_SCREEN, 717953d7d37Smrg PIXMAN_OP_OVERLAY, 718953d7d37Smrg PIXMAN_OP_DARKEN, 719953d7d37Smrg PIXMAN_OP_LIGHTEN, 720953d7d37Smrg PIXMAN_OP_COLOR_DODGE, 721953d7d37Smrg PIXMAN_OP_COLOR_BURN, 722953d7d37Smrg PIXMAN_OP_HARD_LIGHT, 723953d7d37Smrg PIXMAN_OP_DIFFERENCE, 724953d7d37Smrg PIXMAN_OP_EXCLUSION, 725953d7d37Smrg PIXMAN_OP_SOFT_LIGHT, 726953d7d37Smrg PIXMAN_OP_HSL_HUE, 727953d7d37Smrg PIXMAN_OP_HSL_SATURATION, 728953d7d37Smrg PIXMAN_OP_HSL_COLOR, 729953d7d37Smrg PIXMAN_OP_HSL_LUMINOSITY, 730953d7d37Smrg}; 731953d7d37Smrg 732953d7d37Smrgstatic void 733953d7d37Smrgrun_test (uint32_t seed) 734953d7d37Smrg{ 735953d7d37Smrg pixman_image_t *source, *mask, *dest; 736953d7d37Smrg pixman_op_t op; 737953d7d37Smrg 738953d7d37Smrg lcg_srand (seed); 739953d7d37Smrg 740953d7d37Smrg source = create_random_image (); 741953d7d37Smrg mask = create_random_image (); 742953d7d37Smrg dest = create_random_bits_image (); 743953d7d37Smrg 744953d7d37Smrg if (source && mask && dest) 745953d7d37Smrg { 746953d7d37Smrg set_general_properties (dest, TRUE); 747953d7d37Smrg 748953d7d37Smrg op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))]; 749953d7d37Smrg 750953d7d37Smrg pixman_image_composite32 (op, 751953d7d37Smrg source, mask, dest, 752953d7d37Smrg log_rand(), log_rand(), 753953d7d37Smrg log_rand(), log_rand(), 754953d7d37Smrg log_rand(), log_rand(), 755953d7d37Smrg absolute (log_rand()), 756953d7d37Smrg absolute (log_rand())); 757953d7d37Smrg } 758953d7d37Smrg if (source) 759953d7d37Smrg pixman_image_unref (source); 760953d7d37Smrg if (mask) 761953d7d37Smrg pixman_image_unref (mask); 762953d7d37Smrg if (dest) 763953d7d37Smrg pixman_image_unref (dest); 764953d7d37Smrg} 765953d7d37Smrg 766953d7d37Smrgstatic pixman_bool_t 767953d7d37Smrgget_int (char *s, uint32_t *i) 768953d7d37Smrg{ 769953d7d37Smrg char *end; 770953d7d37Smrg int p; 771953d7d37Smrg 772953d7d37Smrg p = strtol (s, &end, 0); 773953d7d37Smrg 774953d7d37Smrg if (end != s && *end == 0) 775953d7d37Smrg { 776953d7d37Smrg *i = p; 777953d7d37Smrg return TRUE; 778953d7d37Smrg } 779953d7d37Smrg 780953d7d37Smrg return FALSE; 781953d7d37Smrg} 782953d7d37Smrg 783953d7d37Smrgint 784953d7d37Smrgmain (int argc, char **argv) 785953d7d37Smrg{ 786953d7d37Smrg int verbose = FALSE; 787953d7d37Smrg uint32_t seed = 1; 788953d7d37Smrg uint32_t n_tests = 0xffffffff; 789953d7d37Smrg uint32_t mod = 0; 790953d7d37Smrg uint32_t i; 791953d7d37Smrg 792953d7d37Smrg pixman_disable_out_of_bounds_workaround (); 793953d7d37Smrg 794953d7d37Smrg enable_fp_exceptions(); 795953d7d37Smrg 796953d7d37Smrg if (getenv ("VERBOSE") != NULL) 797953d7d37Smrg verbose = TRUE; 798953d7d37Smrg 799953d7d37Smrg for (i = 1; i < argc; ++i) 800953d7d37Smrg { 801953d7d37Smrg if (strcmp (argv[i], "-v") == 0) 802953d7d37Smrg { 803953d7d37Smrg verbose = TRUE; 804953d7d37Smrg 805953d7d37Smrg if (i + 1 < argc) 806953d7d37Smrg { 807953d7d37Smrg get_int (argv[i + 1], &mod); 808953d7d37Smrg i++; 809953d7d37Smrg } 810953d7d37Smrg } 811953d7d37Smrg else if (strcmp (argv[i], "-s") == 0 && i + 1 < argc) 812953d7d37Smrg { 813953d7d37Smrg get_int (argv[i + 1], &seed); 814953d7d37Smrg i++; 815953d7d37Smrg } 816953d7d37Smrg else if (strcmp (argv[i], "-n") == 0 && i + 1 < argc) 817953d7d37Smrg { 818953d7d37Smrg get_int (argv[i + 1], &n_tests); 819953d7d37Smrg i++; 820953d7d37Smrg } 821953d7d37Smrg else 822953d7d37Smrg { 823953d7d37Smrg if (strcmp (argv[i], "-h") != 0) 824953d7d37Smrg printf ("Unknown option '%s'\n\n", argv[i]); 825953d7d37Smrg 826953d7d37Smrg printf ("Options:\n\n" 827953d7d37Smrg "-n <number> Number of tests to run\n" 828953d7d37Smrg "-s <seed> Seed of first test\n" 829953d7d37Smrg "-v Print out seeds\n" 830953d7d37Smrg "-v <n> Print out every n'th seed\n\n"); 831953d7d37Smrg 832953d7d37Smrg exit (-1); 833953d7d37Smrg } 834953d7d37Smrg } 835953d7d37Smrg 836953d7d37Smrg if (n_tests == 0xffffffff) 837953d7d37Smrg n_tests = 8000; 838953d7d37Smrg 839953d7d37Smrg /* FIXME: seed 2005763 fails in set_lum() with divide by zero */ 840953d7d37Smrg#ifdef USE_OPENMP 841953d7d37Smrg# pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed) 842953d7d37Smrg#endif 843953d7d37Smrg for (i = seed; i < seed + n_tests; ++i) 844953d7d37Smrg { 845953d7d37Smrg if (verbose) 846953d7d37Smrg { 847953d7d37Smrg if (mod == 0 || (i % mod) == 0) 848953d7d37Smrg printf ("Seed %d\n", i); 849953d7d37Smrg } 850953d7d37Smrg 851953d7d37Smrg run_test (i); 852953d7d37Smrg } 853953d7d37Smrg 854953d7d37Smrg return 0; 855953d7d37Smrg} 856