16ba797d6Smrg/* Based loosely on scaling-test */ 26ba797d6Smrg 36ba797d6Smrg#include <stdlib.h> 46ba797d6Smrg#include <stdio.h> 56ba797d6Smrg#include "utils.h" 66ba797d6Smrg 76ba797d6Smrg#define MAX_SRC_WIDTH 48 86ba797d6Smrg#define MAX_SRC_HEIGHT 48 96ba797d6Smrg#define MAX_DST_WIDTH 48 106ba797d6Smrg#define MAX_DST_HEIGHT 48 116ba797d6Smrg#define MAX_STRIDE 4 126ba797d6Smrg 136ba797d6Smrgstatic pixman_format_code_t formats[] = 146ba797d6Smrg{ 156ba797d6Smrg PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4 166ba797d6Smrg}; 176ba797d6Smrg 186ba797d6Smrgstatic pixman_format_code_t mask_formats[] = 196ba797d6Smrg{ 206ba797d6Smrg PIXMAN_a1, PIXMAN_a4, PIXMAN_a8, 216ba797d6Smrg}; 226ba797d6Smrg 236ba797d6Smrgstatic pixman_op_t operators[] = 246ba797d6Smrg{ 256ba797d6Smrg PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN 266ba797d6Smrg}; 276ba797d6Smrg 286ba797d6Smrg#define RANDOM_ELT(array) \ 29f4f78bb6Smrg ((array)[prng_rand_n(ARRAY_LENGTH((array)))]) 306ba797d6Smrg 316ba797d6Smrgstatic void 326ba797d6Smrgdestroy_bits (pixman_image_t *image, void *data) 336ba797d6Smrg{ 346ba797d6Smrg fence_free (data); 356ba797d6Smrg} 366ba797d6Smrg 376ba797d6Smrgstatic pixman_fixed_t 386ba797d6Smrgrandom_fixed (int n) 396ba797d6Smrg{ 40f4f78bb6Smrg return prng_rand_n (n << 16); 416ba797d6Smrg} 426ba797d6Smrg 436ba797d6Smrg/* 446ba797d6Smrg * Composite operation with pseudorandom images 456ba797d6Smrg */ 466ba797d6Smrguint32_t 476ba797d6Smrgtest_composite (int testnum, 486ba797d6Smrg int verbose) 496ba797d6Smrg{ 506ba797d6Smrg int i; 516ba797d6Smrg pixman_image_t * src_img; 526ba797d6Smrg pixman_image_t * dst_img; 536ba797d6Smrg pixman_region16_t clip; 546ba797d6Smrg int dst_width, dst_height; 556ba797d6Smrg int dst_stride; 566ba797d6Smrg int dst_x, dst_y; 576ba797d6Smrg int dst_bpp; 586ba797d6Smrg pixman_op_t op; 596ba797d6Smrg uint32_t * dst_bits; 606ba797d6Smrg uint32_t crc32; 616ba797d6Smrg pixman_format_code_t mask_format, dst_format; 626ba797d6Smrg pixman_trapezoid_t *traps; 636ba797d6Smrg int src_x, src_y; 646ba797d6Smrg int n_traps; 656ba797d6Smrg 666ba797d6Smrg static pixman_color_t colors[] = 676ba797d6Smrg { 686ba797d6Smrg { 0xffff, 0xffff, 0xffff, 0xffff }, 696ba797d6Smrg { 0x0000, 0x0000, 0x0000, 0x0000 }, 706ba797d6Smrg { 0xabcd, 0xabcd, 0x0000, 0xabcd }, 716ba797d6Smrg { 0x0000, 0x0000, 0x0000, 0xffff }, 726ba797d6Smrg { 0x0101, 0x0101, 0x0101, 0x0101 }, 736ba797d6Smrg { 0x7777, 0x6666, 0x5555, 0x9999 }, 746ba797d6Smrg }; 756ba797d6Smrg 766ba797d6Smrg FLOAT_REGS_CORRUPTION_DETECTOR_START (); 776ba797d6Smrg 78f4f78bb6Smrg prng_srand (testnum); 796ba797d6Smrg 806ba797d6Smrg op = RANDOM_ELT (operators); 816ba797d6Smrg mask_format = RANDOM_ELT (mask_formats); 826ba797d6Smrg 836ba797d6Smrg /* Create source image */ 846ba797d6Smrg 85f4f78bb6Smrg if (prng_rand_n (4) == 0) 866ba797d6Smrg { 876ba797d6Smrg src_img = pixman_image_create_solid_fill ( 88f4f78bb6Smrg &(colors[prng_rand_n (ARRAY_LENGTH (colors))])); 896ba797d6Smrg 906ba797d6Smrg src_x = 10; 916ba797d6Smrg src_y = 234; 926ba797d6Smrg } 936ba797d6Smrg else 946ba797d6Smrg { 956ba797d6Smrg pixman_format_code_t src_format = RANDOM_ELT(formats); 966ba797d6Smrg int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8; 97f4f78bb6Smrg int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1; 98f4f78bb6Smrg int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1; 99f4f78bb6Smrg int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp; 100de17ff4aSmrg uint32_t *bits, *orig; 1016ba797d6Smrg 102f4f78bb6Smrg src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2); 103f4f78bb6Smrg src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2); 1046ba797d6Smrg 1056ba797d6Smrg src_stride = (src_stride + 3) & ~3; 1066ba797d6Smrg 107de17ff4aSmrg orig = bits = (uint32_t *)make_random_bytes (src_stride * src_height); 1086ba797d6Smrg 109de17ff4aSmrg if (prng_rand_n (2) == 0) 110de17ff4aSmrg { 111de17ff4aSmrg bits += (src_stride / 4) * (src_height - 1); 112de17ff4aSmrg src_stride = - src_stride; 113de17ff4aSmrg } 114de17ff4aSmrg 1156ba797d6Smrg src_img = pixman_image_create_bits ( 1166ba797d6Smrg src_format, src_width, src_height, bits, src_stride); 1176ba797d6Smrg 118de17ff4aSmrg pixman_image_set_destroy_function (src_img, destroy_bits, orig); 1196ba797d6Smrg 120f4f78bb6Smrg if (prng_rand_n (8) == 0) 1216ba797d6Smrg { 1226ba797d6Smrg pixman_box16_t clip_boxes[2]; 123f4f78bb6Smrg int n = prng_rand_n (2) + 1; 1246ba797d6Smrg 1256ba797d6Smrg for (i = 0; i < n; i++) 1266ba797d6Smrg { 127f4f78bb6Smrg clip_boxes[i].x1 = prng_rand_n (src_width); 128f4f78bb6Smrg clip_boxes[i].y1 = prng_rand_n (src_height); 1296ba797d6Smrg clip_boxes[i].x2 = 130f4f78bb6Smrg clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1); 1316ba797d6Smrg clip_boxes[i].y2 = 132f4f78bb6Smrg clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1); 1336ba797d6Smrg 1346ba797d6Smrg if (verbose) 1356ba797d6Smrg { 1366ba797d6Smrg printf ("source clip box: [%d,%d-%d,%d]\n", 1376ba797d6Smrg clip_boxes[i].x1, clip_boxes[i].y1, 1386ba797d6Smrg clip_boxes[i].x2, clip_boxes[i].y2); 1396ba797d6Smrg } 1406ba797d6Smrg } 1416ba797d6Smrg 1426ba797d6Smrg pixman_region_init_rects (&clip, clip_boxes, n); 1436ba797d6Smrg pixman_image_set_clip_region (src_img, &clip); 1446ba797d6Smrg pixman_image_set_source_clipping (src_img, 1); 1456ba797d6Smrg pixman_region_fini (&clip); 1466ba797d6Smrg } 1476ba797d6Smrg 1486ba797d6Smrg image_endian_swap (src_img); 1496ba797d6Smrg } 1506ba797d6Smrg 1516ba797d6Smrg /* Create destination image */ 1526ba797d6Smrg { 1536ba797d6Smrg dst_format = RANDOM_ELT(formats); 1546ba797d6Smrg dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8; 155f4f78bb6Smrg dst_width = prng_rand_n (MAX_DST_WIDTH) + 1; 156f4f78bb6Smrg dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1; 157f4f78bb6Smrg dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp; 1586ba797d6Smrg dst_stride = (dst_stride + 3) & ~3; 1596ba797d6Smrg 1606ba797d6Smrg dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height); 1616ba797d6Smrg 162de17ff4aSmrg if (prng_rand_n (2) == 0) 163de17ff4aSmrg { 164de17ff4aSmrg dst_bits += (dst_stride / 4) * (dst_height - 1); 165de17ff4aSmrg dst_stride = - dst_stride; 166de17ff4aSmrg } 167de17ff4aSmrg 168f4f78bb6Smrg dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2); 169f4f78bb6Smrg dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2); 1706ba797d6Smrg 1716ba797d6Smrg dst_img = pixman_image_create_bits ( 1726ba797d6Smrg dst_format, dst_width, dst_height, dst_bits, dst_stride); 1736ba797d6Smrg 1746ba797d6Smrg image_endian_swap (dst_img); 1756ba797d6Smrg } 1766ba797d6Smrg 1776ba797d6Smrg /* Create traps */ 1786ba797d6Smrg { 1796ba797d6Smrg int i; 1806ba797d6Smrg 181f4f78bb6Smrg n_traps = prng_rand_n (25); 1826ba797d6Smrg traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t)); 1836ba797d6Smrg 1846ba797d6Smrg for (i = 0; i < n_traps; ++i) 1856ba797d6Smrg { 1866ba797d6Smrg pixman_trapezoid_t *t = &(traps[i]); 1876ba797d6Smrg 1886ba797d6Smrg t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2; 1896ba797d6Smrg t->bottom = t->top + random_fixed (MAX_DST_HEIGHT); 1906ba797d6Smrg t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; 1916ba797d6Smrg t->left.p1.y = t->top - random_fixed (50); 1926ba797d6Smrg t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; 1936ba797d6Smrg t->left.p2.y = t->bottom + random_fixed (50); 1946ba797d6Smrg t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH); 1956ba797d6Smrg t->right.p1.y = t->top - random_fixed (50); 1966ba797d6Smrg t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH); 1976ba797d6Smrg t->right.p2.y = t->bottom - random_fixed (50); 1986ba797d6Smrg } 1996ba797d6Smrg } 2006ba797d6Smrg 201f4f78bb6Smrg if (prng_rand_n (8) == 0) 2026ba797d6Smrg { 2036ba797d6Smrg pixman_box16_t clip_boxes[2]; 204f4f78bb6Smrg int n = prng_rand_n (2) + 1; 2056ba797d6Smrg for (i = 0; i < n; i++) 2066ba797d6Smrg { 207f4f78bb6Smrg clip_boxes[i].x1 = prng_rand_n (dst_width); 208f4f78bb6Smrg clip_boxes[i].y1 = prng_rand_n (dst_height); 2096ba797d6Smrg clip_boxes[i].x2 = 210f4f78bb6Smrg clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1); 2116ba797d6Smrg clip_boxes[i].y2 = 212f4f78bb6Smrg clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1); 2136ba797d6Smrg 2146ba797d6Smrg if (verbose) 2156ba797d6Smrg { 2166ba797d6Smrg printf ("destination clip box: [%d,%d-%d,%d]\n", 2176ba797d6Smrg clip_boxes[i].x1, clip_boxes[i].y1, 2186ba797d6Smrg clip_boxes[i].x2, clip_boxes[i].y2); 2196ba797d6Smrg } 2206ba797d6Smrg } 2216ba797d6Smrg pixman_region_init_rects (&clip, clip_boxes, n); 2226ba797d6Smrg pixman_image_set_clip_region (dst_img, &clip); 2236ba797d6Smrg pixman_region_fini (&clip); 2246ba797d6Smrg } 2256ba797d6Smrg 2266ba797d6Smrg pixman_composite_trapezoids (op, src_img, dst_img, mask_format, 2276ba797d6Smrg src_x, src_y, dst_x, dst_y, n_traps, traps); 2286ba797d6Smrg 229de17ff4aSmrg crc32 = compute_crc32_for_image (0, dst_img); 2306ba797d6Smrg 2316ba797d6Smrg if (verbose) 232de17ff4aSmrg print_image (dst_img); 2336ba797d6Smrg 234de17ff4aSmrg if (dst_stride < 0) 235de17ff4aSmrg dst_bits += (dst_stride / 4) * (dst_height - 1); 236de17ff4aSmrg 2376ba797d6Smrg fence_free (dst_bits); 2386ba797d6Smrg 2396ba797d6Smrg pixman_image_unref (src_img); 2406ba797d6Smrg pixman_image_unref (dst_img); 2416ba797d6Smrg fence_free (traps); 2426ba797d6Smrg 2436ba797d6Smrg FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); 2446ba797d6Smrg return crc32; 2456ba797d6Smrg} 2466ba797d6Smrg 2476ba797d6Smrgint 2486ba797d6Smrgmain (int argc, const char *argv[]) 2496ba797d6Smrg{ 250de17ff4aSmrg return fuzzer_test_main("composite traps", 40000, 0xAF41D210, 2516ba797d6Smrg test_composite, argc, argv); 2526ba797d6Smrg} 253