16ca29ff0Smrg/* 26ca29ff0Smrg * Copyright © 2015 RISC OS Open Ltd 36ca29ff0Smrg * 46ca29ff0Smrg * Permission to use, copy, modify, distribute, and sell this software and its 56ca29ff0Smrg * documentation for any purpose is hereby granted without fee, provided that 66ca29ff0Smrg * the above copyright notice appear in all copies and that both that 76ca29ff0Smrg * copyright notice and this permission notice appear in supporting 86ca29ff0Smrg * documentation, and that the name of the copyright holders not be used in 96ca29ff0Smrg * advertising or publicity pertaining to distribution of the software without 106ca29ff0Smrg * specific, written prior permission. The copyright holders make no 116ca29ff0Smrg * representations about the suitability of this software for any purpose. It 126ca29ff0Smrg * is provided "as is" without express or implied warranty. 136ca29ff0Smrg * 146ca29ff0Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 156ca29ff0Smrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 166ca29ff0Smrg * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 176ca29ff0Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 186ca29ff0Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 196ca29ff0Smrg * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 206ca29ff0Smrg * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 216ca29ff0Smrg * SOFTWARE. 226ca29ff0Smrg * 236ca29ff0Smrg * Author: Ben Avison (bavison@riscosopen.org) 246ca29ff0Smrg * 256ca29ff0Smrg */ 266ca29ff0Smrg 276ca29ff0Smrg/* 286ca29ff0Smrg * This test aims to verify both numerical correctness and the honouring of 296ca29ff0Smrg * array bounds for scaled plots (both nearest-neighbour and bilinear) at or 306ca29ff0Smrg * close to the boundary conditions for applicability of "cover" type fast paths 316ca29ff0Smrg * and iter fetch routines. 326ca29ff0Smrg * 336ca29ff0Smrg * It has a secondary purpose: by setting the env var EXACT (to any value) it 346ca29ff0Smrg * will only test plots that are exactly on the boundary condition. This makes 356ca29ff0Smrg * it possible to ensure that "cover" routines are being used to the maximum, 366ca29ff0Smrg * although this requires the use of a debugger or code instrumentation to 376ca29ff0Smrg * verify. 386ca29ff0Smrg */ 396ca29ff0Smrg 406ca29ff0Smrg#include "utils.h" 416ca29ff0Smrg#include <stdlib.h> 426ca29ff0Smrg#include <stdio.h> 436ca29ff0Smrg 446ca29ff0Smrg/* Approximate limits for random scale factor generation - these ensure we can 456ca29ff0Smrg * get at least 8x reduction and 8x enlargement. 466ca29ff0Smrg */ 476ca29ff0Smrg#define LOG2_MAX_FACTOR (3) 486ca29ff0Smrg 496ca29ff0Smrg/* 1/sqrt(2) (or sqrt(0.5), or 2^-0.5) as a 0.32 fixed-point number */ 506ca29ff0Smrg#define INV_SQRT_2_0POINT32_FIXED (0xB504F334u) 516ca29ff0Smrg 526ca29ff0Smrg/* The largest increment that can be generated by random_scale_factor(). 536ca29ff0Smrg * This occurs when the "mantissa" part is 0xFFFFFFFF and the "exponent" 546ca29ff0Smrg * part is -LOG2_MAX_FACTOR. 556ca29ff0Smrg */ 566ca29ff0Smrg#define MAX_INC ((pixman_fixed_t) \ 576ca29ff0Smrg (INV_SQRT_2_0POINT32_FIXED >> (31 - 16 - LOG2_MAX_FACTOR))) 586ca29ff0Smrg 596ca29ff0Smrg/* Minimum source width (in pixels) based on a typical page size of 4K and 606ca29ff0Smrg * maximum colour depth of 32bpp. 616ca29ff0Smrg */ 626ca29ff0Smrg#define MIN_SRC_WIDTH (4096 / 4) 636ca29ff0Smrg 646ca29ff0Smrg/* Derive the destination width so that at max increment we fit within source */ 656ca29ff0Smrg#define DST_WIDTH (MIN_SRC_WIDTH * pixman_fixed_1 / MAX_INC) 666ca29ff0Smrg 676ca29ff0Smrg/* Calculate heights the other way round. 686ca29ff0Smrg * No limits due to page alignment here. 696ca29ff0Smrg */ 706ca29ff0Smrg#define DST_HEIGHT 3 716ca29ff0Smrg#define SRC_HEIGHT ((DST_HEIGHT * MAX_INC + pixman_fixed_1 - 1) / pixman_fixed_1) 726ca29ff0Smrg 736ca29ff0Smrg/* At the time of writing, all the scaled fast paths use SRC, OVER or ADD 746ca29ff0Smrg * Porter-Duff operators. XOR is included in the list to ensure good 756ca29ff0Smrg * representation of iter scanline fetch routines. 766ca29ff0Smrg */ 776ca29ff0Smrgstatic const pixman_op_t op_list[] = { 786ca29ff0Smrg PIXMAN_OP_SRC, 796ca29ff0Smrg PIXMAN_OP_OVER, 806ca29ff0Smrg PIXMAN_OP_ADD, 816ca29ff0Smrg PIXMAN_OP_XOR, 826ca29ff0Smrg}; 836ca29ff0Smrg 846ca29ff0Smrg/* At the time of writing, all the scaled fast paths use a8r8g8b8, x8r8g8b8 856ca29ff0Smrg * or r5g6b5, or red-blue swapped versions of the same. When a mask channel is 866ca29ff0Smrg * used, it is always a8 (and so implicitly not component alpha). a1r5g5b5 is 876ca29ff0Smrg * included because it is the only other format to feature in any iters. */ 886ca29ff0Smrgstatic const pixman_format_code_t img_fmt_list[] = { 896ca29ff0Smrg PIXMAN_a8r8g8b8, 906ca29ff0Smrg PIXMAN_x8r8g8b8, 916ca29ff0Smrg PIXMAN_r5g6b5, 926ca29ff0Smrg PIXMAN_a1r5g5b5 936ca29ff0Smrg}; 946ca29ff0Smrg 956ca29ff0Smrg/* This is a flag reflecting the environment variable EXACT. It can be used 966ca29ff0Smrg * to ensure that source coordinates corresponding exactly to the "cover" limits 976ca29ff0Smrg * are used, rather than any "near misses". This can, for example, be used in 986ca29ff0Smrg * conjunction with a debugger to ensure that only COVER fast paths are used. 996ca29ff0Smrg */ 1006ca29ff0Smrgstatic int exact; 1016ca29ff0Smrg 1026ca29ff0Smrgstatic pixman_image_t * 1036ca29ff0Smrgcreate_src_image (pixman_format_code_t fmt) 1046ca29ff0Smrg{ 1056ca29ff0Smrg pixman_image_t *tmp_img, *img; 1066ca29ff0Smrg 1076ca29ff0Smrg /* We need the left-most and right-most MIN_SRC_WIDTH pixels to have 1086ca29ff0Smrg * predictable values, even though fence_image_create_bits() may allocate 1096ca29ff0Smrg * an image somewhat larger than that, by an amount that varies depending 1106ca29ff0Smrg * upon the page size on the current platform. The solution is to create a 1116ca29ff0Smrg * temporary non-fenced image that is exactly MIN_SRC_WIDTH wide and blit it 1126ca29ff0Smrg * into the fenced image. 1136ca29ff0Smrg */ 1146ca29ff0Smrg tmp_img = pixman_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT, 1156ca29ff0Smrg NULL, 0); 1166ca29ff0Smrg if (tmp_img == NULL) 1176ca29ff0Smrg return NULL; 1186ca29ff0Smrg 1196ca29ff0Smrg img = fence_image_create_bits (fmt, MIN_SRC_WIDTH, SRC_HEIGHT, TRUE); 1206ca29ff0Smrg if (img == NULL) 1216ca29ff0Smrg { 1226ca29ff0Smrg pixman_image_unref (tmp_img); 1236ca29ff0Smrg return NULL; 1246ca29ff0Smrg } 1256ca29ff0Smrg 1266ca29ff0Smrg prng_randmemset (tmp_img->bits.bits, 1276ca29ff0Smrg tmp_img->bits.rowstride * SRC_HEIGHT * sizeof (uint32_t), 1286ca29ff0Smrg 0); 1296ca29ff0Smrg image_endian_swap (tmp_img); 1306ca29ff0Smrg 1316ca29ff0Smrg pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img, 1326ca29ff0Smrg 0, 0, 0, 0, 0, 0, 1336ca29ff0Smrg MIN_SRC_WIDTH, SRC_HEIGHT); 1346ca29ff0Smrg pixman_image_composite (PIXMAN_OP_SRC, tmp_img, NULL, img, 1356ca29ff0Smrg 0, 0, 0, 0, img->bits.width - MIN_SRC_WIDTH, 0, 1366ca29ff0Smrg MIN_SRC_WIDTH, SRC_HEIGHT); 1376ca29ff0Smrg 1386ca29ff0Smrg pixman_image_unref (tmp_img); 1396ca29ff0Smrg 1406ca29ff0Smrg return img; 1416ca29ff0Smrg} 1426ca29ff0Smrg 1436ca29ff0Smrgstatic pixman_fixed_t 1446ca29ff0Smrgrandom_scale_factor(void) 1456ca29ff0Smrg{ 1466ca29ff0Smrg /* Get a random number with top bit set. */ 1476ca29ff0Smrg uint32_t f = prng_rand () | 0x80000000u; 1486ca29ff0Smrg 1496ca29ff0Smrg /* In log(2) space, this is still approximately evenly spread between 31 1506ca29ff0Smrg * and 32. Divide by sqrt(2) to centre the distribution on 2^31. 1516ca29ff0Smrg */ 1526ca29ff0Smrg f = ((uint64_t) f * INV_SQRT_2_0POINT32_FIXED) >> 32; 1536ca29ff0Smrg 1546ca29ff0Smrg /* Now shift right (ie divide by an integer power of 2) to spread the 1556ca29ff0Smrg * distribution between centres at 2^(16 +/- LOG2_MAX_FACTOR). 1566ca29ff0Smrg */ 1576ca29ff0Smrg f >>= 31 - 16 + prng_rand_n (2 * LOG2_MAX_FACTOR + 1) - LOG2_MAX_FACTOR; 1586ca29ff0Smrg 1596ca29ff0Smrg return f; 1606ca29ff0Smrg} 1616ca29ff0Smrg 1626ca29ff0Smrgstatic pixman_fixed_t 1636ca29ff0Smrgcalc_translate (int dst_size, 1646ca29ff0Smrg int src_size, 1656ca29ff0Smrg pixman_fixed_t scale, 1666ca29ff0Smrg pixman_bool_t low_align, 1676ca29ff0Smrg pixman_bool_t bilinear) 1686ca29ff0Smrg{ 1696ca29ff0Smrg pixman_fixed_t ref_src, ref_dst, scaled_dst; 1706ca29ff0Smrg 1716ca29ff0Smrg if (low_align) 1726ca29ff0Smrg { 1736ca29ff0Smrg ref_src = bilinear ? pixman_fixed_1 / 2 : pixman_fixed_e; 1746ca29ff0Smrg ref_dst = pixman_fixed_1 / 2; 1756ca29ff0Smrg } 1766ca29ff0Smrg else 1776ca29ff0Smrg { 1786ca29ff0Smrg ref_src = pixman_int_to_fixed (src_size) - 1796ca29ff0Smrg bilinear * pixman_fixed_1 / 2; 1806ca29ff0Smrg ref_dst = pixman_int_to_fixed (dst_size) - pixman_fixed_1 / 2; 1816ca29ff0Smrg } 1826ca29ff0Smrg 1836ca29ff0Smrg scaled_dst = ((uint64_t) ref_dst * scale + pixman_fixed_1 / 2) / 1846ca29ff0Smrg pixman_fixed_1; 1856ca29ff0Smrg 1866ca29ff0Smrg /* We need the translation to be set such that when ref_dst is fed through 1876ca29ff0Smrg * the transformation matrix, we get ref_src as the result. 1886ca29ff0Smrg */ 1896ca29ff0Smrg return ref_src - scaled_dst; 1906ca29ff0Smrg} 1916ca29ff0Smrg 1926ca29ff0Smrgstatic pixman_fixed_t 1936ca29ff0Smrgrandom_offset (void) 1946ca29ff0Smrg{ 1956ca29ff0Smrg pixman_fixed_t offset = 0; 1966ca29ff0Smrg 1976ca29ff0Smrg /* Ensure we test the exact case quite a lot */ 1986ca29ff0Smrg if (prng_rand_n (2)) 1996ca29ff0Smrg return offset; 2006ca29ff0Smrg 2016ca29ff0Smrg /* What happens when we are close to the edge of the first 2026ca29ff0Smrg * interpolation step? 2036ca29ff0Smrg */ 2046ca29ff0Smrg if (prng_rand_n (2)) 2056ca29ff0Smrg offset += (pixman_fixed_1 >> BILINEAR_INTERPOLATION_BITS) - 16; 2066ca29ff0Smrg 2076ca29ff0Smrg /* Try fine-grained variations */ 2086ca29ff0Smrg offset += prng_rand_n (32); 2096ca29ff0Smrg 2106ca29ff0Smrg /* Test in both directions */ 2116ca29ff0Smrg if (prng_rand_n (2)) 2126ca29ff0Smrg offset = -offset; 2136ca29ff0Smrg 2146ca29ff0Smrg return offset; 2156ca29ff0Smrg} 2166ca29ff0Smrg 2176ca29ff0Smrgstatic void 2186ca29ff0Smrgcheck_transform (pixman_image_t *dst_img, 2196ca29ff0Smrg pixman_image_t *src_img, 2206ca29ff0Smrg pixman_transform_t *transform, 2216ca29ff0Smrg pixman_bool_t bilinear) 2226ca29ff0Smrg{ 2236ca29ff0Smrg pixman_vector_t v1, v2; 2246ca29ff0Smrg 2256ca29ff0Smrg v1.vector[0] = pixman_fixed_1 / 2; 2266ca29ff0Smrg v1.vector[1] = pixman_fixed_1 / 2; 2276ca29ff0Smrg v1.vector[2] = pixman_fixed_1; 2286ca29ff0Smrg assert (pixman_transform_point (transform, &v1)); 2296ca29ff0Smrg 2306ca29ff0Smrg v2.vector[0] = pixman_int_to_fixed (dst_img->bits.width) - 2316ca29ff0Smrg pixman_fixed_1 / 2; 2326ca29ff0Smrg v2.vector[1] = pixman_int_to_fixed (dst_img->bits.height) - 2336ca29ff0Smrg pixman_fixed_1 / 2; 2346ca29ff0Smrg v2.vector[2] = pixman_fixed_1; 2356ca29ff0Smrg assert (pixman_transform_point (transform, &v2)); 2366ca29ff0Smrg 2376ca29ff0Smrg if (bilinear) 2386ca29ff0Smrg { 2396ca29ff0Smrg assert (v1.vector[0] >= pixman_fixed_1 / 2); 2406ca29ff0Smrg assert (v1.vector[1] >= pixman_fixed_1 / 2); 2416ca29ff0Smrg assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width) - 2426ca29ff0Smrg pixman_fixed_1 / 2); 2436ca29ff0Smrg assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height) - 2446ca29ff0Smrg pixman_fixed_1 / 2); 2456ca29ff0Smrg } 2466ca29ff0Smrg else 2476ca29ff0Smrg { 2486ca29ff0Smrg assert (v1.vector[0] >= pixman_fixed_e); 2496ca29ff0Smrg assert (v1.vector[1] >= pixman_fixed_e); 2506ca29ff0Smrg assert (v2.vector[0] <= pixman_int_to_fixed (src_img->bits.width)); 2516ca29ff0Smrg assert (v2.vector[1] <= pixman_int_to_fixed (src_img->bits.height)); 2526ca29ff0Smrg } 2536ca29ff0Smrg} 2546ca29ff0Smrg 2556ca29ff0Smrgstatic uint32_t 2566ca29ff0Smrgtest_cover (int testnum, int verbose) 2576ca29ff0Smrg{ 2586ca29ff0Smrg pixman_fixed_t x_scale, y_scale; 2596ca29ff0Smrg pixman_bool_t left_align, top_align; 2606ca29ff0Smrg pixman_bool_t bilinear; 2616ca29ff0Smrg pixman_filter_t filter; 2626ca29ff0Smrg pixman_op_t op; 2636ca29ff0Smrg size_t src_fmt_index; 2646ca29ff0Smrg pixman_format_code_t src_fmt, dst_fmt, mask_fmt; 2656ca29ff0Smrg pixman_image_t *src_img, *dst_img, *mask_img; 2666ca29ff0Smrg pixman_transform_t src_transform, mask_transform; 2676ca29ff0Smrg pixman_fixed_t fuzz[4]; 2686ca29ff0Smrg uint32_t crc32; 2696ca29ff0Smrg 2706ca29ff0Smrg /* We allocate one fenced image for each pixel format up-front. This is to 2716ca29ff0Smrg * avoid spending a lot of time on memory management rather than on testing 2726ca29ff0Smrg * Pixman optimisations. We need one per thread because the transformation 2736ca29ff0Smrg * matrices and filtering are properties of the source and mask images. 2746ca29ff0Smrg */ 2756ca29ff0Smrg static pixman_image_t *src_imgs[ARRAY_LENGTH (img_fmt_list)]; 2766ca29ff0Smrg static pixman_image_t *mask_bits_img; 2776ca29ff0Smrg static pixman_bool_t fence_images_created; 2786ca29ff0Smrg#ifdef USE_OPENMP 2796ca29ff0Smrg#pragma omp threadprivate (src_imgs) 2806ca29ff0Smrg#pragma omp threadprivate (mask_bits_img) 2816ca29ff0Smrg#pragma omp threadprivate (fence_images_created) 2826ca29ff0Smrg#endif 2836ca29ff0Smrg 2846ca29ff0Smrg if (!fence_images_created) 2856ca29ff0Smrg { 2866ca29ff0Smrg int i; 2876ca29ff0Smrg 2886ca29ff0Smrg prng_srand (0); 2896ca29ff0Smrg 2906ca29ff0Smrg for (i = 0; i < ARRAY_LENGTH (img_fmt_list); i++) 2916ca29ff0Smrg src_imgs[i] = create_src_image (img_fmt_list[i]); 2926ca29ff0Smrg 2936ca29ff0Smrg mask_bits_img = create_src_image (PIXMAN_a8); 2946ca29ff0Smrg 2956ca29ff0Smrg fence_images_created = TRUE; 2966ca29ff0Smrg } 2976ca29ff0Smrg 2986ca29ff0Smrg prng_srand (testnum); 2996ca29ff0Smrg 3006ca29ff0Smrg x_scale = random_scale_factor (); 3016ca29ff0Smrg y_scale = random_scale_factor (); 3026ca29ff0Smrg left_align = prng_rand_n (2); 3036ca29ff0Smrg top_align = prng_rand_n (2); 3046ca29ff0Smrg bilinear = prng_rand_n (2); 3056ca29ff0Smrg filter = bilinear ? PIXMAN_FILTER_BILINEAR : PIXMAN_FILTER_NEAREST; 3066ca29ff0Smrg 3076ca29ff0Smrg op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))]; 3086ca29ff0Smrg 3096ca29ff0Smrg dst_fmt = img_fmt_list[prng_rand_n (ARRAY_LENGTH (img_fmt_list))]; 3106ca29ff0Smrg dst_img = pixman_image_create_bits (dst_fmt, DST_WIDTH, DST_HEIGHT, 3116ca29ff0Smrg NULL, 0); 3126ca29ff0Smrg prng_randmemset (dst_img->bits.bits, 3136ca29ff0Smrg dst_img->bits.rowstride * DST_HEIGHT * sizeof (uint32_t), 3146ca29ff0Smrg 0); 3156ca29ff0Smrg image_endian_swap (dst_img); 3166ca29ff0Smrg 3176ca29ff0Smrg src_fmt_index = prng_rand_n (ARRAY_LENGTH (img_fmt_list)); 3186ca29ff0Smrg src_fmt = img_fmt_list[src_fmt_index]; 3196ca29ff0Smrg src_img = src_imgs[src_fmt_index]; 3206ca29ff0Smrg pixman_image_set_filter (src_img, filter, NULL, 0); 3216ca29ff0Smrg pixman_transform_init_scale (&src_transform, x_scale, y_scale); 3226ca29ff0Smrg src_transform.matrix[0][2] = calc_translate (dst_img->bits.width, 3236ca29ff0Smrg src_img->bits.width, 3246ca29ff0Smrg x_scale, left_align, bilinear); 3256ca29ff0Smrg src_transform.matrix[1][2] = calc_translate (dst_img->bits.height, 3266ca29ff0Smrg src_img->bits.height, 3276ca29ff0Smrg y_scale, top_align, bilinear); 3286ca29ff0Smrg 3296ca29ff0Smrg if (prng_rand_n (2)) 3306ca29ff0Smrg { 3316ca29ff0Smrg /* No mask */ 3326ca29ff0Smrg mask_fmt = PIXMAN_null; 3336ca29ff0Smrg mask_img = NULL; 3346ca29ff0Smrg } 3356ca29ff0Smrg else if (prng_rand_n (2)) 3366ca29ff0Smrg { 3376ca29ff0Smrg /* a8 bitmap mask */ 3386ca29ff0Smrg mask_fmt = PIXMAN_a8; 3396ca29ff0Smrg mask_img = mask_bits_img; 3406ca29ff0Smrg pixman_image_set_filter (mask_img, filter, NULL, 0); 3416ca29ff0Smrg pixman_transform_init_scale (&mask_transform, x_scale, y_scale); 3426ca29ff0Smrg mask_transform.matrix[0][2] = calc_translate (dst_img->bits.width, 3436ca29ff0Smrg mask_img->bits.width, 3446ca29ff0Smrg x_scale, left_align, 3456ca29ff0Smrg bilinear); 3466ca29ff0Smrg mask_transform.matrix[1][2] = calc_translate (dst_img->bits.height, 3476ca29ff0Smrg mask_img->bits.height, 3486ca29ff0Smrg y_scale, top_align, 3496ca29ff0Smrg bilinear); 3506ca29ff0Smrg } 3516ca29ff0Smrg else 3526ca29ff0Smrg { 3536ca29ff0Smrg /* Solid mask */ 3546ca29ff0Smrg pixman_color_t color; 3556ca29ff0Smrg memset (&color, 0xAA, sizeof color); 3566ca29ff0Smrg mask_fmt = PIXMAN_solid; 3576ca29ff0Smrg mask_img = pixman_image_create_solid_fill (&color); 3586ca29ff0Smrg } 3596ca29ff0Smrg 3606ca29ff0Smrg if (!exact) 3616ca29ff0Smrg { 3626ca29ff0Smrg int i = 0; 3636ca29ff0Smrg 3646ca29ff0Smrg while (i < 4) 3656ca29ff0Smrg fuzz[i++] = random_offset (); 3666ca29ff0Smrg 3676ca29ff0Smrg src_transform.matrix[0][2] += fuzz[0]; 3686ca29ff0Smrg src_transform.matrix[1][2] += fuzz[1]; 3696ca29ff0Smrg mask_transform.matrix[0][2] += fuzz[2]; 3706ca29ff0Smrg mask_transform.matrix[1][2] += fuzz[3]; 3716ca29ff0Smrg } 3726ca29ff0Smrg 3736ca29ff0Smrg pixman_image_set_transform (src_img, &src_transform); 3746ca29ff0Smrg if (mask_fmt == PIXMAN_a8) 3756ca29ff0Smrg pixman_image_set_transform (mask_img, &mask_transform); 3766ca29ff0Smrg 3776ca29ff0Smrg if (verbose) 3786ca29ff0Smrg { 3796ca29ff0Smrg printf ("op=%s\n", operator_name (op)); 3806ca29ff0Smrg printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n", 3816ca29ff0Smrg format_name (src_fmt), format_name (dst_fmt), 3826ca29ff0Smrg format_name (mask_fmt)); 3836ca29ff0Smrg printf ("x_scale=0x%08X, y_scale=0x%08X, align %s/%s, %s\n", 3846ca29ff0Smrg x_scale, y_scale, 3856ca29ff0Smrg left_align ? "left" : "right", top_align ? "top" : "bottom", 3866ca29ff0Smrg bilinear ? "bilinear" : "nearest"); 3876ca29ff0Smrg 3886ca29ff0Smrg if (!exact) 3896ca29ff0Smrg { 3906ca29ff0Smrg int i = 0; 3916ca29ff0Smrg 3926ca29ff0Smrg printf ("fuzz factors"); 3936ca29ff0Smrg while (i < 4) 3946ca29ff0Smrg printf (" %d", fuzz[i++]); 3956ca29ff0Smrg printf ("\n"); 3966ca29ff0Smrg } 3976ca29ff0Smrg } 3986ca29ff0Smrg 3996ca29ff0Smrg if (exact) 4006ca29ff0Smrg { 4016ca29ff0Smrg check_transform (dst_img, src_img, &src_transform, bilinear); 4026ca29ff0Smrg if (mask_fmt == PIXMAN_a8) 4036ca29ff0Smrg check_transform (dst_img, mask_img, &mask_transform, bilinear); 4046ca29ff0Smrg } 4056ca29ff0Smrg 4066ca29ff0Smrg pixman_image_composite (op, src_img, mask_img, dst_img, 4076ca29ff0Smrg 0, 0, 0, 0, 0, 0, 4086ca29ff0Smrg dst_img->bits.width, dst_img->bits.height); 4096ca29ff0Smrg 4106ca29ff0Smrg if (verbose) 4116ca29ff0Smrg print_image (dst_img); 4126ca29ff0Smrg 4136ca29ff0Smrg crc32 = compute_crc32_for_image (0, dst_img); 4146ca29ff0Smrg 4156ca29ff0Smrg pixman_image_unref (dst_img); 4166ca29ff0Smrg if (mask_fmt == PIXMAN_solid) 4176ca29ff0Smrg pixman_image_unref (mask_img); 4186ca29ff0Smrg 4196ca29ff0Smrg return crc32; 4206ca29ff0Smrg} 4216ca29ff0Smrg 4226ca29ff0Smrg#if BILINEAR_INTERPOLATION_BITS == 7 4236ca29ff0Smrg#define CHECKSUM_FUZZ 0x6B56F607 4246ca29ff0Smrg#define CHECKSUM_EXACT 0xA669F4A3 4256ca29ff0Smrg#elif BILINEAR_INTERPOLATION_BITS == 4 4266ca29ff0Smrg#define CHECKSUM_FUZZ 0x83119ED0 4276ca29ff0Smrg#define CHECKSUM_EXACT 0x0D3382CD 4286ca29ff0Smrg#else 4296ca29ff0Smrg#define CHECKSUM_FUZZ 0x00000000 4306ca29ff0Smrg#define CHECKSUM_EXACT 0x00000000 4316ca29ff0Smrg#endif 4326ca29ff0Smrg 4336ca29ff0Smrgint 4346ca29ff0Smrgmain (int argc, const char *argv[]) 4356ca29ff0Smrg{ 4366ca29ff0Smrg unsigned long page_size; 4376ca29ff0Smrg 4386ca29ff0Smrg page_size = fence_get_page_size (); 4396ca29ff0Smrg if (page_size == 0 || page_size > 16 * 1024) 4406ca29ff0Smrg return 77; /* automake SKIP */ 4416ca29ff0Smrg 4426ca29ff0Smrg exact = getenv ("EXACT") != NULL; 4436ca29ff0Smrg if (exact) 4446ca29ff0Smrg printf ("Doing plots that are exactly aligned to boundaries\n"); 4456ca29ff0Smrg 4466ca29ff0Smrg return fuzzer_test_main ("cover", 2000000, 4476ca29ff0Smrg exact ? CHECKSUM_EXACT : CHECKSUM_FUZZ, 4486ca29ff0Smrg test_cover, argc, argv); 4496ca29ff0Smrg} 450