2
* Test program, which stresses the use of different color formats and
3
* compositing operations.
5
* Just run it without any command line arguments, and it will report either
6
* "blitters test passed" - everything is ok
7
* "blitters test failed!" - there is some problem
9
* In the case of failure, finding the problem involves the following steps:
10
* 1. Get the reference 'blitters-test' binary. It makes sense to disable all
11
* the cpu specific optimizations in pixman and also configure it with
12
* '--disable-shared' option. Those who are paranoid can also tweak the
13
* sources to disable all fastpath functions. The resulting binary
14
* can be renamed to something like 'blitters-test.ref'.
15
* 2. Compile the buggy binary (also with the '--disable-shared' option).
16
* 3. Run 'ruby blitters-test-bisect.rb ./blitters-test.ref ./blitters-test'
17
* 4. Look at the information about failed case (destination buffer content
18
* will be shown) and try to figure out what is wrong. Loading
19
* test program in gdb, specifying failed test number in the command
20
* line with '-' character prepended and setting breakpoint on
21
* 'pixman_image_composite' function can provide detailed information
22
* about function arguments
30
/* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */
32
static uint32_t lcg_seed;
34
static inline uint32_t
37
lcg_seed = lcg_seed * 1103515245 + 12345;
38
return ((uint32_t)(lcg_seed / 65536) % 32768);
42
lcg_srand (uint32_t seed)
47
static inline uint32_t
50
return lcg_rand () % max;
54
aligned_malloc (size_t align, size_t size)
58
#ifdef HAVE_POSIX_MEMALIGN
59
posix_memalign (&result, align, size);
61
result = malloc (size);
67
/*----------------------------------------------------------------------------*\
68
* CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
70
* This program generates the CRC-32 values for the files named in the
71
* command-line arguments. These are the same CRC-32 values used by GZIP,
72
* PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and
75
* THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE.
77
* Based on the byte-oriented implementation "File Verification Using CRC"
78
* by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67.
80
* v1.0.0: original release.
81
* v1.0.1: fixed printf formats.
82
* v1.0.2: fixed something else.
83
* v1.0.3: replaced CRC constant table by generator function.
84
* v1.0.4: reformatted code, made ANSI C. 1994-12-05.
85
* v2.0.0: rewrote to use memory buffer & static table, 2006-04-29.
86
\*----------------------------------------------------------------------------*/
88
/*----------------------------------------------------------------------------*\
90
* Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer
92
* Computes or accumulates the CRC-32 value for a memory buffer.
93
* The 'inCrc32' gives a previously accumulated CRC-32 value to allow
94
* a CRC to be generated for multiple sequential buffer-fuls of data.
95
* The 'inCrc32' for the first buffer must be zero.
97
* inCrc32 - accumulated CRC-32 value, must be 0 on first call
98
* buf - buffer to compute CRC-32 value for
99
* bufLen - number of bytes in buffer
101
* crc32 - computed CRC-32 value
103
* (no errors are possible)
104
\*----------------------------------------------------------------------------*/
107
compute_crc32 (uint32_t in_crc32,
111
static const uint32_t crc_table[256] = {
112
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
113
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
114
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
115
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
116
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
117
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
118
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
119
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
120
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
121
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
122
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
123
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
124
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
125
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
126
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
127
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
128
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
129
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
130
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
131
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
132
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
133
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
134
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
135
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
136
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
137
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
138
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
139
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
140
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
141
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
142
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
143
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
144
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
145
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
146
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
147
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
148
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
149
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
150
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
151
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
152
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
153
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
154
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
158
unsigned char * byte_buf;
161
/* accumulate crc32 for buffer */
162
crc32 = in_crc32 ^ 0xFFFFFFFF;
163
byte_buf = (unsigned char*) buf;
165
for (i = 0; i < buf_len; i++)
166
crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF];
168
return (crc32 ^ 0xFFFFFFFF);
171
/* perform endian conversion of pixel data */
173
image_endian_swap (pixman_image_t *img, int bpp)
175
int stride = pixman_image_get_stride (img);
176
uint32_t *data = pixman_image_get_data (img);
177
int height = pixman_image_get_height (img);;
180
/* swap bytes only on big endian systems */
181
volatile uint16_t endian_check_var = 0x1234;
182
if (*(volatile uint8_t *)&endian_check_var != 0x12)
185
for (i = 0; i < height; i++)
187
uint8_t *line_data = (uint8_t *)data + stride * i;
188
/* swap bytes only for 16, 24 and 32 bpp for now */
192
for (j = 0; j < stride; j++)
195
((line_data[j] & 0x80) >> 7) |
196
((line_data[j] & 0x40) >> 5) |
197
((line_data[j] & 0x20) >> 3) |
198
((line_data[j] & 0x10) >> 1) |
199
((line_data[j] & 0x08) << 1) |
200
((line_data[j] & 0x04) << 3) |
201
((line_data[j] & 0x02) << 5) |
202
((line_data[j] & 0x01) << 7);
206
for (j = 0; j < stride; j++)
208
line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4);
212
for (j = 0; j + 2 <= stride; j += 2)
214
char t1 = line_data[j + 0];
215
char t2 = line_data[j + 1];
217
line_data[j + 1] = t1;
218
line_data[j + 0] = t2;
222
for (j = 0; j + 3 <= stride; j += 3)
224
char t1 = line_data[j + 0];
225
char t2 = line_data[j + 1];
226
char t3 = line_data[j + 2];
228
line_data[j + 2] = t1;
229
line_data[j + 1] = t2;
230
line_data[j + 0] = t3;
234
for (j = 0; j + 4 <= stride; j += 4)
236
char t1 = line_data[j + 0];
237
char t2 = line_data[j + 1];
238
char t3 = line_data[j + 2];
239
char t4 = line_data[j + 3];
241
line_data[j + 3] = t1;
242
line_data[j + 2] = t2;
243
line_data[j + 1] = t3;
244
line_data[j + 0] = t4;
253
/* Create random image for testing purposes */
254
static pixman_image_t *
255
create_random_image (pixman_format_code_t *allowed_formats,
258
int max_extra_stride,
259
pixman_format_code_t *used_fmt)
261
int n = 0, i, width, height, stride;
262
pixman_format_code_t fmt;
266
while (allowed_formats[n] != -1)
268
fmt = allowed_formats[lcg_rand_n (n)];
269
width = lcg_rand_n (max_width) + 1;
270
height = lcg_rand_n (max_height) + 1;
271
stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
272
lcg_rand_n (max_extra_stride + 1);
273
stride = (stride + 3) & ~3;
275
/* do the allocation */
276
buf = aligned_malloc (64, stride * height);
278
/* initialize image with random data */
279
for (i = 0; i < stride * height; i++)
281
/* generation is biased to having more 0 or 255 bytes as
282
* they are more likely to be special-cased in code
284
*((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
285
(lcg_rand_n (2) ? 0 : 255);
288
img = pixman_image_create_bits (fmt, width, height, buf, stride);
290
image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
292
if (used_fmt) *used_fmt = fmt;
296
/* Free random image, and optionally update crc32 based on its data */
298
free_random_image (uint32_t initcrc,
300
pixman_format_code_t fmt)
303
int stride = pixman_image_get_stride (img);
304
uint32_t *data = pixman_image_get_data (img);
305
int height = pixman_image_get_height (img);;
309
/* mask unused 'x' part */
310
if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
311
PIXMAN_FORMAT_DEPTH (fmt) != 0)
314
uint32_t *data = pixman_image_get_data (img);
315
uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
317
if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA)
318
mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
320
for (i = 0; i < 32; i++)
321
mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
323
for (i = 0; i < stride * height / 4; i++)
327
/* swap endiannes in order to provide identical results on both big
328
* and litte endian systems
330
image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt));
331
crc32 = compute_crc32 (initcrc, data, stride * height);
334
pixman_image_unref (img);
340
static pixman_op_t op_list[] = {
348
PIXMAN_OP_OVER_REVERSE,
350
PIXMAN_OP_IN_REVERSE,
352
PIXMAN_OP_OUT_REVERSE,
354
PIXMAN_OP_ATOP_REVERSE,
358
PIXMAN_OP_DISJOINT_CLEAR,
359
PIXMAN_OP_DISJOINT_SRC,
360
PIXMAN_OP_DISJOINT_DST,
361
PIXMAN_OP_DISJOINT_OVER,
362
PIXMAN_OP_DISJOINT_OVER_REVERSE,
363
PIXMAN_OP_DISJOINT_IN,
364
PIXMAN_OP_DISJOINT_IN_REVERSE,
365
PIXMAN_OP_DISJOINT_OUT,
366
PIXMAN_OP_DISJOINT_OUT_REVERSE,
367
PIXMAN_OP_DISJOINT_ATOP,
368
PIXMAN_OP_DISJOINT_ATOP_REVERSE,
369
PIXMAN_OP_DISJOINT_XOR,
370
PIXMAN_OP_CONJOINT_CLEAR,
371
PIXMAN_OP_CONJOINT_SRC,
372
PIXMAN_OP_CONJOINT_DST,
373
PIXMAN_OP_CONJOINT_OVER,
374
PIXMAN_OP_CONJOINT_OVER_REVERSE,
375
PIXMAN_OP_CONJOINT_IN,
376
PIXMAN_OP_CONJOINT_IN_REVERSE,
377
PIXMAN_OP_CONJOINT_OUT,
378
PIXMAN_OP_CONJOINT_OUT_REVERSE,
379
PIXMAN_OP_CONJOINT_ATOP,
380
PIXMAN_OP_CONJOINT_ATOP_REVERSE,
381
PIXMAN_OP_CONJOINT_XOR,
387
PIXMAN_OP_COLOR_DODGE,
388
PIXMAN_OP_COLOR_BURN,
389
PIXMAN_OP_HARD_LIGHT,
390
PIXMAN_OP_DIFFERENCE,
392
#if 0 /* these use floating point math and are not always bitexact on different platforms */
393
PIXMAN_OP_SOFT_LIGHT,
395
PIXMAN_OP_HSL_SATURATION,
397
PIXMAN_OP_HSL_LUMINOSITY,
401
static pixman_format_code_t img_fmt_list[] = {
432
#if 0 /* using these crashes the test */
451
static pixman_format_code_t mask_fmt_list[] = {
461
* Composite operation with pseudorandom images
464
test_composite (uint32_t initcrc, int testnum, int verbose)
467
pixman_image_t *src_img = NULL;
468
pixman_image_t *dst_img = NULL;
469
pixman_image_t *mask_img = NULL;
470
int src_width, src_height;
471
int dst_width, dst_height;
472
int src_stride, dst_stride;
477
pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
480
int max_width, max_height, max_extra_stride;
482
max_width = max_height = 24 + testnum / 10000;
483
max_extra_stride = 4 + testnum / 1000000;
491
if (max_extra_stride > 8)
492
max_extra_stride = 8;
496
op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];
501
src_img = create_random_image (img_fmt_list, max_width, max_height,
502
max_extra_stride, &src_fmt);
507
src_img = create_random_image (img_fmt_list, 1, 1,
508
max_extra_stride, &src_fmt);
510
pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
513
dst_img = create_random_image (img_fmt_list, max_width, max_height,
514
max_extra_stride, &dst_fmt);
523
mask_img = create_random_image (mask_fmt_list, max_width, max_height,
524
max_extra_stride, &mask_fmt);
529
mask_img = create_random_image (mask_fmt_list, 1, 1,
530
max_extra_stride, &mask_fmt);
531
pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
535
pixman_image_set_component_alpha (mask_img, 1);
538
src_width = pixman_image_get_width (src_img);
539
src_height = pixman_image_get_height (src_img);
540
src_stride = pixman_image_get_stride (src_img);
542
dst_width = pixman_image_get_width (dst_img);
543
dst_height = pixman_image_get_height (dst_img);
544
dst_stride = pixman_image_get_stride (dst_img);
546
dstbuf = pixman_image_get_data (dst_img);
548
src_x = lcg_rand_n (src_width);
549
src_y = lcg_rand_n (src_height);
550
dst_x = lcg_rand_n (dst_width);
551
dst_y = lcg_rand_n (dst_height);
553
w = lcg_rand_n (dst_width - dst_x + 1);
554
h = lcg_rand_n (dst_height - dst_y + 1);
558
printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
559
op, src_fmt, dst_fmt, mask_fmt);
560
printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
561
src_width, src_height, dst_width, dst_height);
562
printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
563
src_x, src_y, dst_x, dst_y);
564
printf ("src_stride=%d, dst_stride=%d\n",
565
src_stride, dst_stride);
566
printf ("w=%d, h=%d\n", w, h);
569
pixman_image_composite (op, src_img, mask_img, dst_img,
570
src_x, src_y, src_x, src_y, dst_x, dst_y, w, h);
577
for (i = 0; i < dst_height; i++)
579
for (j = 0; j < dst_stride; j++)
581
if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
584
printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
591
free_random_image (initcrc, src_img, -1);
592
crc32 = free_random_image (initcrc, dst_img, dst_fmt);
595
free_random_image (initcrc, mask_img, -1);
601
main (int argc, char *argv[])
603
int i, n1 = 1, n2 = 0;
605
int verbose = getenv ("VERBOSE") != NULL;
624
crc = test_composite (0, abs (n2), 1);
625
printf ("crc32=%08X\n", crc);
629
for (i = n1; i <= n2; i++)
631
crc = test_composite (crc, i, 0);
634
printf ("%d: %08X\n", i, crc);
636
printf ("crc32=%08X\n", crc);
640
/* Predefined value for running with all the fastpath functions
641
disabled. It needs to be updated every time when changes are
642
introduced to this program or behavior of pixman changes! */
643
if (crc == 0x06D8EDB6)
645
printf ("blitters test passed\n");
649
printf ("blitters test failed!\n");