blitters-test.c revision de17ff4a
1/* 2 * Test program, which stresses the use of different color formats and 3 * compositing operations. 4 * 5 * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in 6 * the case of test failure. 7 */ 8#include <stdlib.h> 9#include <stdio.h> 10#include "utils.h" 11 12static pixman_indexed_t rgb_palette[9]; 13static pixman_indexed_t y_palette[9]; 14 15/* The first eight format in the list are by far the most widely 16 * used formats, so we test those more than the others 17 */ 18#define N_MOST_LIKELY_FORMATS 8 19 20/* Create random image for testing purposes */ 21static pixman_image_t * 22create_random_image (pixman_format_code_t *allowed_formats, 23 int max_width, 24 int max_height, 25 int max_extra_stride, 26 pixman_format_code_t *used_fmt) 27{ 28 int n = 0, width, height, stride; 29 pixman_format_code_t fmt; 30 uint32_t *buf; 31 pixman_image_t *img; 32 33 while (allowed_formats[n] != PIXMAN_null) 34 n++; 35 36 if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0) 37 n = N_MOST_LIKELY_FORMATS; 38 fmt = allowed_formats[prng_rand_n (n)]; 39 40 width = prng_rand_n (max_width) + 1; 41 height = prng_rand_n (max_height) + 1; 42 stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + 43 prng_rand_n (max_extra_stride + 1); 44 stride = (stride + 3) & ~3; 45 46 /* do the allocation */ 47 buf = aligned_malloc (64, stride * height); 48 49 if (prng_rand_n (4) == 0) 50 { 51 /* uniform distribution */ 52 prng_randmemset (buf, stride * height, 0); 53 } 54 else 55 { 56 /* significantly increased probability for 0x00 and 0xFF */ 57 prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF); 58 } 59 60 /* test negative stride */ 61 if (prng_rand_n (4) == 0) 62 { 63 buf += (stride / 4) * (height - 1); 64 stride = - stride; 65 } 66 67 img = pixman_image_create_bits (fmt, width, height, buf, stride); 68 69 if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR) 70 { 71 pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)])); 72 } 73 else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY) 74 { 75 pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)])); 76 } 77 78 if (prng_rand_n (16) == 0) 79 pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0); 80 81 image_endian_swap (img); 82 83 if (used_fmt) *used_fmt = fmt; 84 return img; 85} 86 87/* Free random image, and optionally update crc32 based on its data */ 88static uint32_t 89free_random_image (uint32_t initcrc, 90 pixman_image_t *img, 91 pixman_format_code_t fmt) 92{ 93 uint32_t crc32 = 0; 94 uint32_t *data = pixman_image_get_data (img); 95 96 if (fmt != PIXMAN_null) 97 crc32 = compute_crc32_for_image (initcrc, img); 98 99 if (img->bits.rowstride < 0) 100 data += img->bits.rowstride * (img->bits.height - 1); 101 102 pixman_image_unref (img); 103 free (data); 104 105 return crc32; 106} 107 108static pixman_op_t op_list[] = { 109 PIXMAN_OP_SRC, 110 PIXMAN_OP_OVER, 111 PIXMAN_OP_ADD, 112 PIXMAN_OP_CLEAR, 113 PIXMAN_OP_SRC, 114 PIXMAN_OP_DST, 115 PIXMAN_OP_OVER, 116 PIXMAN_OP_OVER_REVERSE, 117 PIXMAN_OP_IN, 118 PIXMAN_OP_IN_REVERSE, 119 PIXMAN_OP_OUT, 120 PIXMAN_OP_OUT_REVERSE, 121 PIXMAN_OP_ATOP, 122 PIXMAN_OP_ATOP_REVERSE, 123 PIXMAN_OP_XOR, 124 PIXMAN_OP_ADD, 125 PIXMAN_OP_SATURATE, 126 PIXMAN_OP_DISJOINT_CLEAR, 127 PIXMAN_OP_DISJOINT_SRC, 128 PIXMAN_OP_DISJOINT_DST, 129 PIXMAN_OP_DISJOINT_OVER, 130 PIXMAN_OP_DISJOINT_OVER_REVERSE, 131 PIXMAN_OP_DISJOINT_IN, 132 PIXMAN_OP_DISJOINT_IN_REVERSE, 133 PIXMAN_OP_DISJOINT_OUT, 134 PIXMAN_OP_DISJOINT_OUT_REVERSE, 135 PIXMAN_OP_DISJOINT_ATOP, 136 PIXMAN_OP_DISJOINT_ATOP_REVERSE, 137 PIXMAN_OP_DISJOINT_XOR, 138 PIXMAN_OP_CONJOINT_CLEAR, 139 PIXMAN_OP_CONJOINT_SRC, 140 PIXMAN_OP_CONJOINT_DST, 141 PIXMAN_OP_CONJOINT_OVER, 142 PIXMAN_OP_CONJOINT_OVER_REVERSE, 143 PIXMAN_OP_CONJOINT_IN, 144 PIXMAN_OP_CONJOINT_IN_REVERSE, 145 PIXMAN_OP_CONJOINT_OUT, 146 PIXMAN_OP_CONJOINT_OUT_REVERSE, 147 PIXMAN_OP_CONJOINT_ATOP, 148 PIXMAN_OP_CONJOINT_ATOP_REVERSE, 149 PIXMAN_OP_CONJOINT_XOR, 150 PIXMAN_OP_MULTIPLY, 151 PIXMAN_OP_SCREEN, 152 PIXMAN_OP_OVERLAY, 153 PIXMAN_OP_DARKEN, 154 PIXMAN_OP_LIGHTEN, 155 PIXMAN_OP_COLOR_DODGE, 156 PIXMAN_OP_COLOR_BURN, 157 PIXMAN_OP_HARD_LIGHT, 158 PIXMAN_OP_DIFFERENCE, 159 PIXMAN_OP_EXCLUSION, 160#if 0 /* these use floating point math and are not always bitexact on different platforms */ 161 PIXMAN_OP_SOFT_LIGHT, 162 PIXMAN_OP_HSL_HUE, 163 PIXMAN_OP_HSL_SATURATION, 164 PIXMAN_OP_HSL_COLOR, 165 PIXMAN_OP_HSL_LUMINOSITY, 166#endif 167}; 168 169static pixman_format_code_t img_fmt_list[] = { 170 PIXMAN_a8r8g8b8, 171 PIXMAN_a8b8g8r8, 172 PIXMAN_x8r8g8b8, 173 PIXMAN_x8b8g8r8, 174 PIXMAN_r5g6b5, 175 PIXMAN_b5g6r5, 176 PIXMAN_a8, 177 PIXMAN_a1, 178 PIXMAN_r3g3b2, 179 PIXMAN_b8g8r8a8, 180 PIXMAN_b8g8r8x8, 181 PIXMAN_r8g8b8a8, 182 PIXMAN_r8g8b8x8, 183 PIXMAN_x14r6g6b6, 184 PIXMAN_r8g8b8, 185 PIXMAN_b8g8r8, 186#if 0 /* These are going to use floating point in the near future */ 187 PIXMAN_x2r10g10b10, 188 PIXMAN_a2r10g10b10, 189 PIXMAN_x2b10g10r10, 190 PIXMAN_a2b10g10r10, 191#endif 192 PIXMAN_a1r5g5b5, 193 PIXMAN_x1r5g5b5, 194 PIXMAN_a1b5g5r5, 195 PIXMAN_x1b5g5r5, 196 PIXMAN_a4r4g4b4, 197 PIXMAN_x4r4g4b4, 198 PIXMAN_a4b4g4r4, 199 PIXMAN_x4b4g4r4, 200 PIXMAN_r3g3b2, 201 PIXMAN_b2g3r3, 202 PIXMAN_a2r2g2b2, 203 PIXMAN_a2b2g2r2, 204 PIXMAN_c8, 205 PIXMAN_g8, 206 PIXMAN_x4c4, 207 PIXMAN_x4g4, 208 PIXMAN_c4, 209 PIXMAN_g4, 210 PIXMAN_g1, 211 PIXMAN_x4a4, 212 PIXMAN_a4, 213 PIXMAN_r1g2b1, 214 PIXMAN_b1g2r1, 215 PIXMAN_a1r1g1b1, 216 PIXMAN_a1b1g1r1, 217 PIXMAN_null 218}; 219 220static pixman_format_code_t mask_fmt_list[] = { 221 PIXMAN_a8r8g8b8, 222 PIXMAN_a8, 223 PIXMAN_a4, 224 PIXMAN_a1, 225 PIXMAN_null 226}; 227 228 229/* 230 * Composite operation with pseudorandom images 231 */ 232uint32_t 233test_composite (int testnum, int verbose) 234{ 235 pixman_image_t *src_img = NULL; 236 pixman_image_t *dst_img = NULL; 237 pixman_image_t *mask_img = NULL; 238 int src_width, src_height; 239 int dst_width, dst_height; 240 int src_stride, dst_stride; 241 int src_x, src_y; 242 int dst_x, dst_y; 243 int mask_x, mask_y; 244 int w, h; 245 pixman_op_t op; 246 pixman_format_code_t src_fmt, dst_fmt, mask_fmt; 247 uint32_t *srcbuf, *maskbuf; 248 uint32_t crc32; 249 int max_width, max_height, max_extra_stride; 250 FLOAT_REGS_CORRUPTION_DETECTOR_START (); 251 252 max_width = max_height = 24 + testnum / 10000; 253 max_extra_stride = 4 + testnum / 1000000; 254 255 if (max_width > 256) 256 max_width = 256; 257 258 if (max_height > 16) 259 max_height = 16; 260 261 if (max_extra_stride > 8) 262 max_extra_stride = 8; 263 264 prng_srand (testnum); 265 266 op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; 267 268 if (prng_rand_n (8)) 269 { 270 /* normal image */ 271 src_img = create_random_image (img_fmt_list, max_width, max_height, 272 max_extra_stride, &src_fmt); 273 } 274 else 275 { 276 /* solid case */ 277 src_img = create_random_image (img_fmt_list, 1, 1, 278 max_extra_stride, &src_fmt); 279 280 pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); 281 } 282 283 dst_img = create_random_image (img_fmt_list, max_width, max_height, 284 max_extra_stride, &dst_fmt); 285 286 src_width = pixman_image_get_width (src_img); 287 src_height = pixman_image_get_height (src_img); 288 src_stride = pixman_image_get_stride (src_img); 289 290 dst_width = pixman_image_get_width (dst_img); 291 dst_height = pixman_image_get_height (dst_img); 292 dst_stride = pixman_image_get_stride (dst_img); 293 294 srcbuf = pixman_image_get_data (src_img); 295 296 src_x = prng_rand_n (src_width); 297 src_y = prng_rand_n (src_height); 298 dst_x = prng_rand_n (dst_width); 299 dst_y = prng_rand_n (dst_height); 300 301 mask_img = NULL; 302 mask_fmt = PIXMAN_null; 303 mask_x = 0; 304 mask_y = 0; 305 maskbuf = NULL; 306 307 if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) && 308 (prng_rand_n (4) == 0)) 309 { 310 /* PIXBUF */ 311 mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8; 312 mask_img = pixman_image_create_bits (mask_fmt, 313 src_width, 314 src_height, 315 srcbuf, 316 src_stride); 317 mask_x = src_x; 318 mask_y = src_y; 319 maskbuf = srcbuf; 320 } 321 else if (prng_rand_n (2)) 322 { 323 if (prng_rand_n (2)) 324 { 325 mask_img = create_random_image (mask_fmt_list, max_width, max_height, 326 max_extra_stride, &mask_fmt); 327 } 328 else 329 { 330 /* solid case */ 331 mask_img = create_random_image (mask_fmt_list, 1, 1, 332 max_extra_stride, &mask_fmt); 333 pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); 334 } 335 336 if (prng_rand_n (2)) 337 pixman_image_set_component_alpha (mask_img, 1); 338 339 mask_x = prng_rand_n (pixman_image_get_width (mask_img)); 340 mask_y = prng_rand_n (pixman_image_get_height (mask_img)); 341 } 342 343 344 w = prng_rand_n (dst_width - dst_x + 1); 345 h = prng_rand_n (dst_height - dst_y + 1); 346 347 if (verbose) 348 { 349 printf ("op=%s\n", operator_name (op)); 350 printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", 351 format_name (src_fmt), format_name (dst_fmt), 352 format_name (mask_fmt)); 353 printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", 354 src_width, src_height, dst_width, dst_height); 355 printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", 356 src_x, src_y, dst_x, dst_y); 357 printf ("src_stride=%d, dst_stride=%d\n", 358 src_stride, dst_stride); 359 printf ("w=%d, h=%d\n", w, h); 360 } 361 362 pixman_image_composite (op, src_img, mask_img, dst_img, 363 src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h); 364 365 if (verbose) 366 print_image (dst_img); 367 368 free_random_image (0, src_img, PIXMAN_null); 369 crc32 = free_random_image (0, dst_img, dst_fmt); 370 371 if (mask_img) 372 { 373 if (srcbuf == maskbuf) 374 pixman_image_unref(mask_img); 375 else 376 free_random_image (0, mask_img, PIXMAN_null); 377 } 378 379 FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); 380 return crc32; 381} 382 383int 384main (int argc, const char *argv[]) 385{ 386 int i; 387 388 prng_srand (0); 389 390 for (i = 1; i <= 8; i++) 391 { 392 initialize_palette (&(rgb_palette[i]), i, TRUE); 393 initialize_palette (&(y_palette[i]), i, FALSE); 394 } 395 396 return fuzzer_test_main("blitters", 2000000, 397 0xE0A07495, 398 test_composite, argc, argv); 399} 400