blitters-test.c revision a450e446
1a450e446Smrg/* 2a450e446Smrg * Test program, which stresses the use of different color formats and 3a450e446Smrg * compositing operations. 4a450e446Smrg * 5a450e446Smrg * Just run it without any command line arguments, and it will report either 6a450e446Smrg * "blitters test passed" - everything is ok 7a450e446Smrg * "blitters test failed!" - there is some problem 8a450e446Smrg * 9a450e446Smrg * In the case of failure, finding the problem involves the following steps: 10a450e446Smrg * 1. Get the reference 'blitters-test' binary. It makes sense to disable all 11a450e446Smrg * the cpu specific optimizations in pixman and also configure it with 12a450e446Smrg * '--disable-shared' option. Those who are paranoid can also tweak the 13a450e446Smrg * sources to disable all fastpath functions. The resulting binary 14a450e446Smrg * can be renamed to something like 'blitters-test.ref'. 15a450e446Smrg * 2. Compile the buggy binary (also with the '--disable-shared' option). 16a450e446Smrg * 3. Run 'ruby blitters-test-bisect.rb ./blitters-test.ref ./blitters-test' 17a450e446Smrg * 4. Look at the information about failed case (destination buffer content 18a450e446Smrg * will be shown) and try to figure out what is wrong. Loading 19a450e446Smrg * test program in gdb, specifying failed test number in the command 20a450e446Smrg * line with '-' character prepended and setting breakpoint on 21a450e446Smrg * 'pixman_image_composite' function can provide detailed information 22a450e446Smrg * about function arguments 23a450e446Smrg */ 24a450e446Smrg#include <assert.h> 25a450e446Smrg#include <stdlib.h> 26a450e446Smrg#include <stdio.h> 27a450e446Smrg#include <config.h> 28a450e446Smrg#include "pixman.h" 29a450e446Smrg 30a450e446Smrg/* A primitive pseudorandom number generator, taken from POSIX.1-2001 example */ 31a450e446Smrg 32a450e446Smrgstatic uint32_t lcg_seed; 33a450e446Smrg 34a450e446Smrgstatic inline uint32_t 35a450e446Smrglcg_rand (void) 36a450e446Smrg{ 37a450e446Smrg lcg_seed = lcg_seed * 1103515245 + 12345; 38a450e446Smrg return ((uint32_t)(lcg_seed / 65536) % 32768); 39a450e446Smrg} 40a450e446Smrg 41a450e446Smrgstatic inline void 42a450e446Smrglcg_srand (uint32_t seed) 43a450e446Smrg{ 44a450e446Smrg lcg_seed = seed; 45a450e446Smrg} 46a450e446Smrg 47a450e446Smrgstatic inline uint32_t 48a450e446Smrglcg_rand_n (int max) 49a450e446Smrg{ 50a450e446Smrg return lcg_rand () % max; 51a450e446Smrg} 52a450e446Smrg 53a450e446Smrgstatic void * 54a450e446Smrgaligned_malloc (size_t align, size_t size) 55a450e446Smrg{ 56a450e446Smrg void *result; 57a450e446Smrg 58a450e446Smrg#ifdef HAVE_POSIX_MEMALIGN 59a450e446Smrg posix_memalign (&result, align, size); 60a450e446Smrg#else 61a450e446Smrg result = malloc (size); 62a450e446Smrg#endif 63a450e446Smrg 64a450e446Smrg return result; 65a450e446Smrg} 66a450e446Smrg 67a450e446Smrg/*----------------------------------------------------------------------------*\ 68a450e446Smrg * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29. 69a450e446Smrg * 70a450e446Smrg * This program generates the CRC-32 values for the files named in the 71a450e446Smrg * command-line arguments. These are the same CRC-32 values used by GZIP, 72a450e446Smrg * PKZIP, and ZMODEM. The Crc32_ComputeBuf () can also be detached and 73a450e446Smrg * used independently. 74a450e446Smrg * 75a450e446Smrg * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE. 76a450e446Smrg * 77a450e446Smrg * Based on the byte-oriented implementation "File Verification Using CRC" 78a450e446Smrg * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67. 79a450e446Smrg * 80a450e446Smrg * v1.0.0: original release. 81a450e446Smrg * v1.0.1: fixed printf formats. 82a450e446Smrg * v1.0.2: fixed something else. 83a450e446Smrg * v1.0.3: replaced CRC constant table by generator function. 84a450e446Smrg * v1.0.4: reformatted code, made ANSI C. 1994-12-05. 85a450e446Smrg * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29. 86a450e446Smrg\*----------------------------------------------------------------------------*/ 87a450e446Smrg 88a450e446Smrg/*----------------------------------------------------------------------------*\ 89a450e446Smrg * NAME: 90a450e446Smrg * Crc32_ComputeBuf () - computes the CRC-32 value of a memory buffer 91a450e446Smrg * DESCRIPTION: 92a450e446Smrg * Computes or accumulates the CRC-32 value for a memory buffer. 93a450e446Smrg * The 'inCrc32' gives a previously accumulated CRC-32 value to allow 94a450e446Smrg * a CRC to be generated for multiple sequential buffer-fuls of data. 95a450e446Smrg * The 'inCrc32' for the first buffer must be zero. 96a450e446Smrg * ARGUMENTS: 97a450e446Smrg * inCrc32 - accumulated CRC-32 value, must be 0 on first call 98a450e446Smrg * buf - buffer to compute CRC-32 value for 99a450e446Smrg * bufLen - number of bytes in buffer 100a450e446Smrg * RETURNS: 101a450e446Smrg * crc32 - computed CRC-32 value 102a450e446Smrg * ERRORS: 103a450e446Smrg * (no errors are possible) 104a450e446Smrg\*----------------------------------------------------------------------------*/ 105a450e446Smrg 106a450e446Smrgstatic uint32_t 107a450e446Smrgcompute_crc32 (uint32_t in_crc32, 108a450e446Smrg const void *buf, 109a450e446Smrg size_t buf_len) 110a450e446Smrg{ 111a450e446Smrg static const uint32_t crc_table[256] = { 112a450e446Smrg 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 113a450e446Smrg 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 114a450e446Smrg 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 115a450e446Smrg 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 116a450e446Smrg 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 117a450e446Smrg 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 118a450e446Smrg 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 119a450e446Smrg 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 120a450e446Smrg 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 121a450e446Smrg 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 122a450e446Smrg 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 123a450e446Smrg 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 124a450e446Smrg 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 125a450e446Smrg 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 126a450e446Smrg 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 127a450e446Smrg 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 128a450e446Smrg 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 129a450e446Smrg 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 130a450e446Smrg 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 131a450e446Smrg 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 132a450e446Smrg 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 133a450e446Smrg 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 134a450e446Smrg 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 135a450e446Smrg 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 136a450e446Smrg 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 137a450e446Smrg 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 138a450e446Smrg 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 139a450e446Smrg 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 140a450e446Smrg 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 141a450e446Smrg 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 142a450e446Smrg 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 143a450e446Smrg 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 144a450e446Smrg 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 145a450e446Smrg 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 146a450e446Smrg 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 147a450e446Smrg 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 148a450e446Smrg 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 149a450e446Smrg 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 150a450e446Smrg 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 151a450e446Smrg 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 152a450e446Smrg 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 153a450e446Smrg 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 154a450e446Smrg 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 155a450e446Smrg }; 156a450e446Smrg 157a450e446Smrg uint32_t crc32; 158a450e446Smrg unsigned char * byte_buf; 159a450e446Smrg size_t i; 160a450e446Smrg 161a450e446Smrg /* accumulate crc32 for buffer */ 162a450e446Smrg crc32 = in_crc32 ^ 0xFFFFFFFF; 163a450e446Smrg byte_buf = (unsigned char*) buf; 164a450e446Smrg 165a450e446Smrg for (i = 0; i < buf_len; i++) 166a450e446Smrg crc32 = (crc32 >> 8) ^ crc_table[(crc32 ^ byte_buf[i]) & 0xFF]; 167a450e446Smrg 168a450e446Smrg return (crc32 ^ 0xFFFFFFFF); 169a450e446Smrg} 170a450e446Smrg 171a450e446Smrg/* perform endian conversion of pixel data */ 172a450e446Smrgstatic void 173a450e446Smrgimage_endian_swap (pixman_image_t *img, int bpp) 174a450e446Smrg{ 175a450e446Smrg int stride = pixman_image_get_stride (img); 176a450e446Smrg uint32_t *data = pixman_image_get_data (img); 177a450e446Smrg int height = pixman_image_get_height (img);; 178a450e446Smrg int i, j; 179a450e446Smrg 180a450e446Smrg /* swap bytes only on big endian systems */ 181a450e446Smrg volatile uint16_t endian_check_var = 0x1234; 182a450e446Smrg if (*(volatile uint8_t *)&endian_check_var != 0x12) 183a450e446Smrg return; 184a450e446Smrg 185a450e446Smrg for (i = 0; i < height; i++) 186a450e446Smrg { 187a450e446Smrg uint8_t *line_data = (uint8_t *)data + stride * i; 188a450e446Smrg /* swap bytes only for 16, 24 and 32 bpp for now */ 189a450e446Smrg switch (bpp) 190a450e446Smrg { 191a450e446Smrg case 1: 192a450e446Smrg for (j = 0; j < stride; j++) 193a450e446Smrg { 194a450e446Smrg line_data[j] = 195a450e446Smrg ((line_data[j] & 0x80) >> 7) | 196a450e446Smrg ((line_data[j] & 0x40) >> 5) | 197a450e446Smrg ((line_data[j] & 0x20) >> 3) | 198a450e446Smrg ((line_data[j] & 0x10) >> 1) | 199a450e446Smrg ((line_data[j] & 0x08) << 1) | 200a450e446Smrg ((line_data[j] & 0x04) << 3) | 201a450e446Smrg ((line_data[j] & 0x02) << 5) | 202a450e446Smrg ((line_data[j] & 0x01) << 7); 203a450e446Smrg } 204a450e446Smrg break; 205a450e446Smrg case 4: 206a450e446Smrg for (j = 0; j < stride; j++) 207a450e446Smrg { 208a450e446Smrg line_data[j] = (line_data[j] >> 4) | (line_data[j] << 4); 209a450e446Smrg } 210a450e446Smrg break; 211a450e446Smrg case 16: 212a450e446Smrg for (j = 0; j + 2 <= stride; j += 2) 213a450e446Smrg { 214a450e446Smrg char t1 = line_data[j + 0]; 215a450e446Smrg char t2 = line_data[j + 1]; 216a450e446Smrg 217a450e446Smrg line_data[j + 1] = t1; 218a450e446Smrg line_data[j + 0] = t2; 219a450e446Smrg } 220a450e446Smrg break; 221a450e446Smrg case 24: 222a450e446Smrg for (j = 0; j + 3 <= stride; j += 3) 223a450e446Smrg { 224a450e446Smrg char t1 = line_data[j + 0]; 225a450e446Smrg char t2 = line_data[j + 1]; 226a450e446Smrg char t3 = line_data[j + 2]; 227a450e446Smrg 228a450e446Smrg line_data[j + 2] = t1; 229a450e446Smrg line_data[j + 1] = t2; 230a450e446Smrg line_data[j + 0] = t3; 231a450e446Smrg } 232a450e446Smrg break; 233a450e446Smrg case 32: 234a450e446Smrg for (j = 0; j + 4 <= stride; j += 4) 235a450e446Smrg { 236a450e446Smrg char t1 = line_data[j + 0]; 237a450e446Smrg char t2 = line_data[j + 1]; 238a450e446Smrg char t3 = line_data[j + 2]; 239a450e446Smrg char t4 = line_data[j + 3]; 240a450e446Smrg 241a450e446Smrg line_data[j + 3] = t1; 242a450e446Smrg line_data[j + 2] = t2; 243a450e446Smrg line_data[j + 1] = t3; 244a450e446Smrg line_data[j + 0] = t4; 245a450e446Smrg } 246a450e446Smrg break; 247a450e446Smrg default: 248a450e446Smrg break; 249a450e446Smrg } 250a450e446Smrg } 251a450e446Smrg} 252a450e446Smrg 253a450e446Smrg/* Create random image for testing purposes */ 254a450e446Smrgstatic pixman_image_t * 255a450e446Smrgcreate_random_image (pixman_format_code_t *allowed_formats, 256a450e446Smrg int max_width, 257a450e446Smrg int max_height, 258a450e446Smrg int max_extra_stride, 259a450e446Smrg pixman_format_code_t *used_fmt) 260a450e446Smrg{ 261a450e446Smrg int n = 0, i, width, height, stride; 262a450e446Smrg pixman_format_code_t fmt; 263a450e446Smrg uint32_t *buf; 264a450e446Smrg pixman_image_t *img; 265a450e446Smrg 266a450e446Smrg while (allowed_formats[n] != -1) 267a450e446Smrg n++; 268a450e446Smrg fmt = allowed_formats[lcg_rand_n (n)]; 269a450e446Smrg width = lcg_rand_n (max_width) + 1; 270a450e446Smrg height = lcg_rand_n (max_height) + 1; 271a450e446Smrg stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 + 272a450e446Smrg lcg_rand_n (max_extra_stride + 1); 273a450e446Smrg stride = (stride + 3) & ~3; 274a450e446Smrg 275a450e446Smrg /* do the allocation */ 276a450e446Smrg buf = aligned_malloc (64, stride * height); 277a450e446Smrg 278a450e446Smrg /* initialize image with random data */ 279a450e446Smrg for (i = 0; i < stride * height; i++) 280a450e446Smrg { 281a450e446Smrg /* generation is biased to having more 0 or 255 bytes as 282a450e446Smrg * they are more likely to be special-cased in code 283a450e446Smrg */ 284a450e446Smrg *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) : 285a450e446Smrg (lcg_rand_n (2) ? 0 : 255); 286a450e446Smrg } 287a450e446Smrg 288a450e446Smrg img = pixman_image_create_bits (fmt, width, height, buf, stride); 289a450e446Smrg 290a450e446Smrg image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt)); 291a450e446Smrg 292a450e446Smrg if (used_fmt) *used_fmt = fmt; 293a450e446Smrg return img; 294a450e446Smrg} 295a450e446Smrg 296a450e446Smrg/* Free random image, and optionally update crc32 based on its data */ 297a450e446Smrgstatic uint32_t 298a450e446Smrgfree_random_image (uint32_t initcrc, 299a450e446Smrg pixman_image_t *img, 300a450e446Smrg pixman_format_code_t fmt) 301a450e446Smrg{ 302a450e446Smrg uint32_t crc32 = 0; 303a450e446Smrg int stride = pixman_image_get_stride (img); 304a450e446Smrg uint32_t *data = pixman_image_get_data (img); 305a450e446Smrg int height = pixman_image_get_height (img);; 306a450e446Smrg 307a450e446Smrg if (fmt != -1) 308a450e446Smrg { 309a450e446Smrg /* mask unused 'x' part */ 310a450e446Smrg if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) && 311a450e446Smrg PIXMAN_FORMAT_DEPTH (fmt) != 0) 312a450e446Smrg { 313a450e446Smrg int i; 314a450e446Smrg uint32_t *data = pixman_image_get_data (img); 315a450e446Smrg uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1; 316a450e446Smrg 317a450e446Smrg if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA) 318a450e446Smrg mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt)); 319a450e446Smrg 320a450e446Smrg for (i = 0; i < 32; i++) 321a450e446Smrg mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt)); 322a450e446Smrg 323a450e446Smrg for (i = 0; i < stride * height / 4; i++) 324a450e446Smrg data[i] &= mask; 325a450e446Smrg } 326a450e446Smrg 327a450e446Smrg /* swap endiannes in order to provide identical results on both big 328a450e446Smrg * and litte endian systems 329a450e446Smrg */ 330a450e446Smrg image_endian_swap (img, PIXMAN_FORMAT_BPP (fmt)); 331a450e446Smrg crc32 = compute_crc32 (initcrc, data, stride * height); 332a450e446Smrg } 333a450e446Smrg 334a450e446Smrg pixman_image_unref (img); 335a450e446Smrg free (data); 336a450e446Smrg 337a450e446Smrg return crc32; 338a450e446Smrg} 339a450e446Smrg 340a450e446Smrgstatic pixman_op_t op_list[] = { 341a450e446Smrg PIXMAN_OP_SRC, 342a450e446Smrg PIXMAN_OP_OVER, 343a450e446Smrg PIXMAN_OP_ADD, 344a450e446Smrg PIXMAN_OP_CLEAR, 345a450e446Smrg PIXMAN_OP_SRC, 346a450e446Smrg PIXMAN_OP_DST, 347a450e446Smrg PIXMAN_OP_OVER, 348a450e446Smrg PIXMAN_OP_OVER_REVERSE, 349a450e446Smrg PIXMAN_OP_IN, 350a450e446Smrg PIXMAN_OP_IN_REVERSE, 351a450e446Smrg PIXMAN_OP_OUT, 352a450e446Smrg PIXMAN_OP_OUT_REVERSE, 353a450e446Smrg PIXMAN_OP_ATOP, 354a450e446Smrg PIXMAN_OP_ATOP_REVERSE, 355a450e446Smrg PIXMAN_OP_XOR, 356a450e446Smrg PIXMAN_OP_ADD, 357a450e446Smrg PIXMAN_OP_SATURATE, 358a450e446Smrg PIXMAN_OP_DISJOINT_CLEAR, 359a450e446Smrg PIXMAN_OP_DISJOINT_SRC, 360a450e446Smrg PIXMAN_OP_DISJOINT_DST, 361a450e446Smrg PIXMAN_OP_DISJOINT_OVER, 362a450e446Smrg PIXMAN_OP_DISJOINT_OVER_REVERSE, 363a450e446Smrg PIXMAN_OP_DISJOINT_IN, 364a450e446Smrg PIXMAN_OP_DISJOINT_IN_REVERSE, 365a450e446Smrg PIXMAN_OP_DISJOINT_OUT, 366a450e446Smrg PIXMAN_OP_DISJOINT_OUT_REVERSE, 367a450e446Smrg PIXMAN_OP_DISJOINT_ATOP, 368a450e446Smrg PIXMAN_OP_DISJOINT_ATOP_REVERSE, 369a450e446Smrg PIXMAN_OP_DISJOINT_XOR, 370a450e446Smrg PIXMAN_OP_CONJOINT_CLEAR, 371a450e446Smrg PIXMAN_OP_CONJOINT_SRC, 372a450e446Smrg PIXMAN_OP_CONJOINT_DST, 373a450e446Smrg PIXMAN_OP_CONJOINT_OVER, 374a450e446Smrg PIXMAN_OP_CONJOINT_OVER_REVERSE, 375a450e446Smrg PIXMAN_OP_CONJOINT_IN, 376a450e446Smrg PIXMAN_OP_CONJOINT_IN_REVERSE, 377a450e446Smrg PIXMAN_OP_CONJOINT_OUT, 378a450e446Smrg PIXMAN_OP_CONJOINT_OUT_REVERSE, 379a450e446Smrg PIXMAN_OP_CONJOINT_ATOP, 380a450e446Smrg PIXMAN_OP_CONJOINT_ATOP_REVERSE, 381a450e446Smrg PIXMAN_OP_CONJOINT_XOR, 382a450e446Smrg PIXMAN_OP_MULTIPLY, 383a450e446Smrg PIXMAN_OP_SCREEN, 384a450e446Smrg PIXMAN_OP_OVERLAY, 385a450e446Smrg PIXMAN_OP_DARKEN, 386a450e446Smrg PIXMAN_OP_LIGHTEN, 387a450e446Smrg PIXMAN_OP_COLOR_DODGE, 388a450e446Smrg PIXMAN_OP_COLOR_BURN, 389a450e446Smrg PIXMAN_OP_HARD_LIGHT, 390a450e446Smrg PIXMAN_OP_DIFFERENCE, 391a450e446Smrg PIXMAN_OP_EXCLUSION, 392a450e446Smrg#if 0 /* these use floating point math and are not always bitexact on different platforms */ 393a450e446Smrg PIXMAN_OP_SOFT_LIGHT, 394a450e446Smrg PIXMAN_OP_HSL_HUE, 395a450e446Smrg PIXMAN_OP_HSL_SATURATION, 396a450e446Smrg PIXMAN_OP_HSL_COLOR, 397a450e446Smrg PIXMAN_OP_HSL_LUMINOSITY, 398a450e446Smrg#endif 399a450e446Smrg}; 400a450e446Smrg 401a450e446Smrgstatic pixman_format_code_t img_fmt_list[] = { 402a450e446Smrg PIXMAN_a8r8g8b8, 403a450e446Smrg PIXMAN_x8r8g8b8, 404a450e446Smrg PIXMAN_r5g6b5, 405a450e446Smrg PIXMAN_r3g3b2, 406a450e446Smrg PIXMAN_a8, 407a450e446Smrg PIXMAN_a8b8g8r8, 408a450e446Smrg PIXMAN_x8b8g8r8, 409a450e446Smrg PIXMAN_b8g8r8a8, 410a450e446Smrg PIXMAN_b8g8r8x8, 411a450e446Smrg PIXMAN_r8g8b8, 412a450e446Smrg PIXMAN_b8g8r8, 413a450e446Smrg PIXMAN_r5g6b5, 414a450e446Smrg PIXMAN_b5g6r5, 415a450e446Smrg PIXMAN_x2r10g10b10, 416a450e446Smrg PIXMAN_a2r10g10b10, 417a450e446Smrg PIXMAN_x2b10g10r10, 418a450e446Smrg PIXMAN_a2b10g10r10, 419a450e446Smrg PIXMAN_a1r5g5b5, 420a450e446Smrg PIXMAN_x1r5g5b5, 421a450e446Smrg PIXMAN_a1b5g5r5, 422a450e446Smrg PIXMAN_x1b5g5r5, 423a450e446Smrg PIXMAN_a4r4g4b4, 424a450e446Smrg PIXMAN_x4r4g4b4, 425a450e446Smrg PIXMAN_a4b4g4r4, 426a450e446Smrg PIXMAN_x4b4g4r4, 427a450e446Smrg PIXMAN_a8, 428a450e446Smrg PIXMAN_r3g3b2, 429a450e446Smrg PIXMAN_b2g3r3, 430a450e446Smrg PIXMAN_a2r2g2b2, 431a450e446Smrg PIXMAN_a2b2g2r2, 432a450e446Smrg#if 0 /* using these crashes the test */ 433a450e446Smrg PIXMAN_c8, 434a450e446Smrg PIXMAN_g8, 435a450e446Smrg PIXMAN_x4c4, 436a450e446Smrg PIXMAN_x4g4, 437a450e446Smrg PIXMAN_c4, 438a450e446Smrg PIXMAN_g4, 439a450e446Smrg PIXMAN_g1, 440a450e446Smrg#endif 441a450e446Smrg PIXMAN_x4a4, 442a450e446Smrg PIXMAN_a4, 443a450e446Smrg PIXMAN_r1g2b1, 444a450e446Smrg PIXMAN_b1g2r1, 445a450e446Smrg PIXMAN_a1r1g1b1, 446a450e446Smrg PIXMAN_a1b1g1r1, 447a450e446Smrg PIXMAN_a1, 448a450e446Smrg -1 449a450e446Smrg}; 450a450e446Smrg 451a450e446Smrgstatic pixman_format_code_t mask_fmt_list[] = { 452a450e446Smrg PIXMAN_a8r8g8b8, 453a450e446Smrg PIXMAN_a8, 454a450e446Smrg PIXMAN_a4, 455a450e446Smrg PIXMAN_a1, 456a450e446Smrg -1 457a450e446Smrg}; 458a450e446Smrg 459a450e446Smrg 460a450e446Smrg/* 461a450e446Smrg * Composite operation with pseudorandom images 462a450e446Smrg */ 463a450e446Smrguint32_t 464a450e446Smrgtest_composite (uint32_t initcrc, int testnum, int verbose) 465a450e446Smrg{ 466a450e446Smrg int i; 467a450e446Smrg pixman_image_t *src_img = NULL; 468a450e446Smrg pixman_image_t *dst_img = NULL; 469a450e446Smrg pixman_image_t *mask_img = NULL; 470a450e446Smrg int src_width, src_height; 471a450e446Smrg int dst_width, dst_height; 472a450e446Smrg int src_stride, dst_stride; 473a450e446Smrg int src_x, src_y; 474a450e446Smrg int dst_x, dst_y; 475a450e446Smrg int w, h; 476a450e446Smrg int op; 477a450e446Smrg pixman_format_code_t src_fmt, dst_fmt, mask_fmt; 478a450e446Smrg uint32_t *dstbuf; 479a450e446Smrg uint32_t crc32; 480a450e446Smrg int max_width, max_height, max_extra_stride; 481a450e446Smrg 482a450e446Smrg max_width = max_height = 24 + testnum / 10000; 483a450e446Smrg max_extra_stride = 4 + testnum / 1000000; 484a450e446Smrg 485a450e446Smrg if (max_width > 256) 486a450e446Smrg max_width = 256; 487a450e446Smrg 488a450e446Smrg if (max_height > 16) 489a450e446Smrg max_height = 16; 490a450e446Smrg 491a450e446Smrg if (max_extra_stride > 8) 492a450e446Smrg max_extra_stride = 8; 493a450e446Smrg 494a450e446Smrg lcg_srand (testnum); 495a450e446Smrg 496a450e446Smrg op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))]; 497a450e446Smrg 498a450e446Smrg if (lcg_rand_n (8)) 499a450e446Smrg { 500a450e446Smrg /* normal image */ 501a450e446Smrg src_img = create_random_image (img_fmt_list, max_width, max_height, 502a450e446Smrg max_extra_stride, &src_fmt); 503a450e446Smrg } 504a450e446Smrg else 505a450e446Smrg { 506a450e446Smrg /* solid case */ 507a450e446Smrg src_img = create_random_image (img_fmt_list, 1, 1, 508a450e446Smrg max_extra_stride, &src_fmt); 509a450e446Smrg 510a450e446Smrg pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL); 511a450e446Smrg } 512a450e446Smrg 513a450e446Smrg dst_img = create_random_image (img_fmt_list, max_width, max_height, 514a450e446Smrg max_extra_stride, &dst_fmt); 515a450e446Smrg 516a450e446Smrg mask_img = NULL; 517a450e446Smrg mask_fmt = -1; 518a450e446Smrg 519a450e446Smrg if (lcg_rand_n (2)) 520a450e446Smrg { 521a450e446Smrg if (lcg_rand_n (2)) 522a450e446Smrg { 523a450e446Smrg mask_img = create_random_image (mask_fmt_list, max_width, max_height, 524a450e446Smrg max_extra_stride, &mask_fmt); 525a450e446Smrg } 526a450e446Smrg else 527a450e446Smrg { 528a450e446Smrg /* solid case */ 529a450e446Smrg mask_img = create_random_image (mask_fmt_list, 1, 1, 530a450e446Smrg max_extra_stride, &mask_fmt); 531a450e446Smrg pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL); 532a450e446Smrg } 533a450e446Smrg 534a450e446Smrg if (lcg_rand_n (2)) 535a450e446Smrg pixman_image_set_component_alpha (mask_img, 1); 536a450e446Smrg } 537a450e446Smrg 538a450e446Smrg src_width = pixman_image_get_width (src_img); 539a450e446Smrg src_height = pixman_image_get_height (src_img); 540a450e446Smrg src_stride = pixman_image_get_stride (src_img); 541a450e446Smrg 542a450e446Smrg dst_width = pixman_image_get_width (dst_img); 543a450e446Smrg dst_height = pixman_image_get_height (dst_img); 544a450e446Smrg dst_stride = pixman_image_get_stride (dst_img); 545a450e446Smrg 546a450e446Smrg dstbuf = pixman_image_get_data (dst_img); 547a450e446Smrg 548a450e446Smrg src_x = lcg_rand_n (src_width); 549a450e446Smrg src_y = lcg_rand_n (src_height); 550a450e446Smrg dst_x = lcg_rand_n (dst_width); 551a450e446Smrg dst_y = lcg_rand_n (dst_height); 552a450e446Smrg 553a450e446Smrg w = lcg_rand_n (dst_width - dst_x + 1); 554a450e446Smrg h = lcg_rand_n (dst_height - dst_y + 1); 555a450e446Smrg 556a450e446Smrg if (verbose) 557a450e446Smrg { 558a450e446Smrg printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n", 559a450e446Smrg op, src_fmt, dst_fmt, mask_fmt); 560a450e446Smrg printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", 561a450e446Smrg src_width, src_height, dst_width, dst_height); 562a450e446Smrg printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", 563a450e446Smrg src_x, src_y, dst_x, dst_y); 564a450e446Smrg printf ("src_stride=%d, dst_stride=%d\n", 565a450e446Smrg src_stride, dst_stride); 566a450e446Smrg printf ("w=%d, h=%d\n", w, h); 567a450e446Smrg } 568a450e446Smrg 569a450e446Smrg pixman_image_composite (op, src_img, mask_img, dst_img, 570a450e446Smrg src_x, src_y, src_x, src_y, dst_x, dst_y, w, h); 571a450e446Smrg 572a450e446Smrg if (verbose) 573a450e446Smrg { 574a450e446Smrg int j; 575a450e446Smrg 576a450e446Smrg printf ("---\n"); 577a450e446Smrg for (i = 0; i < dst_height; i++) 578a450e446Smrg { 579a450e446Smrg for (j = 0; j < dst_stride; j++) 580a450e446Smrg { 581a450e446Smrg if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8) 582a450e446Smrg printf ("| "); 583a450e446Smrg 584a450e446Smrg printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j)); 585a450e446Smrg } 586a450e446Smrg printf ("\n"); 587a450e446Smrg } 588a450e446Smrg printf ("---\n"); 589a450e446Smrg } 590a450e446Smrg 591a450e446Smrg free_random_image (initcrc, src_img, -1); 592a450e446Smrg crc32 = free_random_image (initcrc, dst_img, dst_fmt); 593a450e446Smrg 594a450e446Smrg if (mask_img) 595a450e446Smrg free_random_image (initcrc, mask_img, -1); 596a450e446Smrg 597a450e446Smrg return crc32; 598a450e446Smrg} 599a450e446Smrg 600a450e446Smrgint 601a450e446Smrgmain (int argc, char *argv[]) 602a450e446Smrg{ 603a450e446Smrg int i, n1 = 1, n2 = 0; 604a450e446Smrg uint32_t crc = 0; 605a450e446Smrg int verbose = getenv ("VERBOSE") != NULL; 606a450e446Smrg 607a450e446Smrg if (argc >= 3) 608a450e446Smrg { 609a450e446Smrg n1 = atoi (argv[1]); 610a450e446Smrg n2 = atoi (argv[2]); 611a450e446Smrg } 612a450e446Smrg else if (argc >= 2) 613a450e446Smrg { 614a450e446Smrg n2 = atoi (argv[1]); 615a450e446Smrg } 616a450e446Smrg else 617a450e446Smrg { 618a450e446Smrg n1 = 1; 619a450e446Smrg n2 = 2000000; 620a450e446Smrg } 621a450e446Smrg 622a450e446Smrg if (n2 < 0) 623a450e446Smrg { 624a450e446Smrg crc = test_composite (0, abs (n2), 1); 625a450e446Smrg printf ("crc32=%08X\n", crc); 626a450e446Smrg } 627a450e446Smrg else 628a450e446Smrg { 629a450e446Smrg for (i = n1; i <= n2; i++) 630a450e446Smrg { 631a450e446Smrg crc = test_composite (crc, i, 0); 632a450e446Smrg 633a450e446Smrg if (verbose) 634a450e446Smrg printf ("%d: %08X\n", i, crc); 635a450e446Smrg } 636a450e446Smrg printf ("crc32=%08X\n", crc); 637a450e446Smrg 638a450e446Smrg if (n2 == 2000000) 639a450e446Smrg { 640a450e446Smrg /* Predefined value for running with all the fastpath functions 641a450e446Smrg disabled. It needs to be updated every time when changes are 642a450e446Smrg introduced to this program or behavior of pixman changes! */ 643a450e446Smrg if (crc == 0x06D8EDB6) 644a450e446Smrg { 645a450e446Smrg printf ("blitters test passed\n"); 646a450e446Smrg } 647a450e446Smrg else 648a450e446Smrg { 649a450e446Smrg printf ("blitters test failed!\n"); 650a450e446Smrg return 1; 651a450e446Smrg } 652a450e446Smrg } 653a450e446Smrg } 654a450e446Smrg return 0; 655a450e446Smrg} 656