16ca29ff0Smrg/* 26ca29ff0Smrg * Copyright © 2014 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#include <stdio.h> 276ca29ff0Smrg#include <stdlib.h> 286ca29ff0Smrg#include <string.h> 296ca29ff0Smrg#include <ctype.h> 306ca29ff0Smrg#include <stdint.h> 316ca29ff0Smrg#include "utils.h" 326ca29ff0Smrg 336ca29ff0Smrg#ifdef HAVE_GETTIMEOFDAY 346ca29ff0Smrg#include <sys/time.h> 356ca29ff0Smrg#else 366ca29ff0Smrg#include <time.h> 376ca29ff0Smrg#endif 386ca29ff0Smrg 396ca29ff0Smrg#define WIDTH 1920 406ca29ff0Smrg#define HEIGHT 1080 416ca29ff0Smrg 426ca29ff0Smrg/* How much data to read to flush all cached data to RAM */ 436ca29ff0Smrg#define MAX_L2CACHE_SIZE (8 * 1024 * 1024) 446ca29ff0Smrg 456ca29ff0Smrg#define PAGE_SIZE (4 * 1024) 466ca29ff0Smrg 476ca29ff0Smrgstruct bench_info 486ca29ff0Smrg{ 496ca29ff0Smrg pixman_op_t op; 506ca29ff0Smrg pixman_transform_t transform; 516ca29ff0Smrg pixman_image_t *src_image; 526ca29ff0Smrg pixman_image_t *mask_image; 536ca29ff0Smrg pixman_image_t *dest_image; 546ca29ff0Smrg int32_t src_x; 556ca29ff0Smrg int32_t src_y; 566ca29ff0Smrg}; 576ca29ff0Smrg 586ca29ff0Smrgtypedef struct bench_info bench_info_t; 596ca29ff0Smrg 606ca29ff0Smrgstruct box_48_16 616ca29ff0Smrg{ 626ca29ff0Smrg pixman_fixed_48_16_t x1; 636ca29ff0Smrg pixman_fixed_48_16_t y1; 646ca29ff0Smrg pixman_fixed_48_16_t x2; 656ca29ff0Smrg pixman_fixed_48_16_t y2; 666ca29ff0Smrg}; 676ca29ff0Smrg 686ca29ff0Smrgtypedef struct box_48_16 box_48_16_t; 696ca29ff0Smrg 706ca29ff0Smrg/* This function is copied verbatim from pixman.c. */ 716ca29ff0Smrgstatic pixman_bool_t 726ca29ff0Smrgcompute_transformed_extents (pixman_transform_t *transform, 736ca29ff0Smrg const pixman_box32_t *extents, 746ca29ff0Smrg box_48_16_t *transformed) 756ca29ff0Smrg{ 766ca29ff0Smrg pixman_fixed_48_16_t tx1, ty1, tx2, ty2; 776ca29ff0Smrg pixman_fixed_t x1, y1, x2, y2; 786ca29ff0Smrg int i; 796ca29ff0Smrg 806ca29ff0Smrg x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2; 816ca29ff0Smrg y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2; 826ca29ff0Smrg x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2; 836ca29ff0Smrg y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2; 846ca29ff0Smrg 856ca29ff0Smrg if (!transform) 866ca29ff0Smrg { 876ca29ff0Smrg transformed->x1 = x1; 886ca29ff0Smrg transformed->y1 = y1; 896ca29ff0Smrg transformed->x2 = x2; 906ca29ff0Smrg transformed->y2 = y2; 916ca29ff0Smrg 926ca29ff0Smrg return TRUE; 936ca29ff0Smrg } 946ca29ff0Smrg 956ca29ff0Smrg tx1 = ty1 = INT64_MAX; 966ca29ff0Smrg tx2 = ty2 = INT64_MIN; 976ca29ff0Smrg 986ca29ff0Smrg for (i = 0; i < 4; ++i) 996ca29ff0Smrg { 1006ca29ff0Smrg pixman_fixed_48_16_t tx, ty; 1016ca29ff0Smrg pixman_vector_t v; 1026ca29ff0Smrg 1036ca29ff0Smrg v.vector[0] = (i & 0x01)? x1 : x2; 1046ca29ff0Smrg v.vector[1] = (i & 0x02)? y1 : y2; 1056ca29ff0Smrg v.vector[2] = pixman_fixed_1; 1066ca29ff0Smrg 1076ca29ff0Smrg if (!pixman_transform_point (transform, &v)) 1086ca29ff0Smrg return FALSE; 1096ca29ff0Smrg 1106ca29ff0Smrg tx = (pixman_fixed_48_16_t)v.vector[0]; 1116ca29ff0Smrg ty = (pixman_fixed_48_16_t)v.vector[1]; 1126ca29ff0Smrg 1136ca29ff0Smrg if (tx < tx1) 1146ca29ff0Smrg tx1 = tx; 1156ca29ff0Smrg if (ty < ty1) 1166ca29ff0Smrg ty1 = ty; 1176ca29ff0Smrg if (tx > tx2) 1186ca29ff0Smrg tx2 = tx; 1196ca29ff0Smrg if (ty > ty2) 1206ca29ff0Smrg ty2 = ty; 1216ca29ff0Smrg } 1226ca29ff0Smrg 1236ca29ff0Smrg transformed->x1 = tx1; 1246ca29ff0Smrg transformed->y1 = ty1; 1256ca29ff0Smrg transformed->x2 = tx2; 1266ca29ff0Smrg transformed->y2 = ty2; 1276ca29ff0Smrg 1286ca29ff0Smrg return TRUE; 1296ca29ff0Smrg} 1306ca29ff0Smrg 1316ca29ff0Smrgstatic void 1326ca29ff0Smrgcreate_image (uint32_t width, 1336ca29ff0Smrg uint32_t height, 1346ca29ff0Smrg pixman_format_code_t format, 1356ca29ff0Smrg pixman_filter_t filter, 1366ca29ff0Smrg uint32_t **bits, 1376ca29ff0Smrg pixman_image_t **image) 1386ca29ff0Smrg{ 1396ca29ff0Smrg uint32_t stride = (width * PIXMAN_FORMAT_BPP (format) + 31) / 32 * 4; 1406ca29ff0Smrg 1416ca29ff0Smrg *bits = aligned_malloc (PAGE_SIZE, stride * height); 1426ca29ff0Smrg memset (*bits, 0xCC, stride * height); 1436ca29ff0Smrg *image = pixman_image_create_bits (format, width, height, *bits, stride); 1446ca29ff0Smrg pixman_image_set_repeat (*image, PIXMAN_REPEAT_NORMAL); 1456ca29ff0Smrg pixman_image_set_filter (*image, filter, NULL, 0); 1466ca29ff0Smrg} 1476ca29ff0Smrg 1486ca29ff0Smrg/* This needs to match the shortest cacheline length we expect to encounter */ 1496ca29ff0Smrg#define CACHE_CLEAN_INCREMENT 32 1506ca29ff0Smrg 1516ca29ff0Smrgstatic void 1526ca29ff0Smrgflush_cache (void) 1536ca29ff0Smrg{ 1546ca29ff0Smrg static const char clean_space[MAX_L2CACHE_SIZE]; 1556ca29ff0Smrg volatile const char *x = clean_space; 1566ca29ff0Smrg const char *clean_end = clean_space + sizeof clean_space; 1576ca29ff0Smrg 1586ca29ff0Smrg while (x < clean_end) 1596ca29ff0Smrg { 1606ca29ff0Smrg (void) *x; 1616ca29ff0Smrg x += CACHE_CLEAN_INCREMENT; 1626ca29ff0Smrg } 1636ca29ff0Smrg} 1646ca29ff0Smrg 1656ca29ff0Smrg/* Obtain current time in microseconds modulo 2^32 */ 1666ca29ff0Smrguint32_t 1676ca29ff0Smrggettimei (void) 1686ca29ff0Smrg{ 1696ca29ff0Smrg#ifdef HAVE_GETTIMEOFDAY 1706ca29ff0Smrg struct timeval tv; 1716ca29ff0Smrg 1726ca29ff0Smrg gettimeofday (&tv, NULL); 1736ca29ff0Smrg return tv.tv_sec * 1000000 + tv.tv_usec; 1746ca29ff0Smrg#else 1756ca29ff0Smrg return (uint64_t) clock () * 1000000 / CLOCKS_PER_SEC; 1766ca29ff0Smrg#endif 1776ca29ff0Smrg} 1786ca29ff0Smrg 1796ca29ff0Smrgstatic void 1806ca29ff0Smrgpixman_image_composite_wrapper (const pixman_composite_info_t *info) 1816ca29ff0Smrg{ 1826ca29ff0Smrg pixman_image_composite (info->op, 1836ca29ff0Smrg info->src_image, info->mask_image, info->dest_image, 1846ca29ff0Smrg info->src_x, info->src_y, 1856ca29ff0Smrg info->mask_x, info->mask_y, 1866ca29ff0Smrg info->dest_x, info->dest_y, 1876ca29ff0Smrg info->width, info->height); 1886ca29ff0Smrg} 1896ca29ff0Smrg 1906ca29ff0Smrgstatic void 1916ca29ff0Smrgpixman_image_composite_empty (const pixman_composite_info_t *info) 1926ca29ff0Smrg{ 1936ca29ff0Smrg pixman_image_composite (info->op, 1946ca29ff0Smrg info->src_image, info->mask_image, info->dest_image, 1956ca29ff0Smrg info->src_x, info->src_y, 1966ca29ff0Smrg info->mask_x, info->mask_y, 1976ca29ff0Smrg info->dest_x, info->dest_y, 1986ca29ff0Smrg 1, 1); 1996ca29ff0Smrg} 2006ca29ff0Smrg 2016ca29ff0Smrgstatic void 2026ca29ff0Smrgbench (const bench_info_t *bi, 2036ca29ff0Smrg uint32_t max_n, 2046ca29ff0Smrg uint32_t max_time, 2056ca29ff0Smrg uint32_t *ret_n, 2066ca29ff0Smrg uint32_t *ret_time, 2076ca29ff0Smrg void (*func) (const pixman_composite_info_t *info)) 2086ca29ff0Smrg{ 2096ca29ff0Smrg uint32_t n = 0; 2106ca29ff0Smrg uint32_t t0; 2116ca29ff0Smrg uint32_t t1; 2126ca29ff0Smrg uint32_t x = 0; 2136ca29ff0Smrg pixman_transform_t t; 2146ca29ff0Smrg pixman_composite_info_t info; 2156ca29ff0Smrg 2166ca29ff0Smrg t = bi->transform; 2176ca29ff0Smrg info.op = bi->op; 2186ca29ff0Smrg info.src_image = bi->src_image; 2196ca29ff0Smrg info.mask_image = bi->mask_image; 2206ca29ff0Smrg info.dest_image = bi->dest_image; 2216ca29ff0Smrg info.src_x = 0; 2226ca29ff0Smrg info.src_y = 0; 2236ca29ff0Smrg info.mask_x = 0; 2246ca29ff0Smrg info.mask_y = 0; 2256ca29ff0Smrg /* info.dest_x set below */ 2266ca29ff0Smrg info.dest_y = 0; 2276ca29ff0Smrg info.width = WIDTH; 2286ca29ff0Smrg info.height = HEIGHT; 2296ca29ff0Smrg 2306ca29ff0Smrg t0 = gettimei (); 2316ca29ff0Smrg 2326ca29ff0Smrg do 2336ca29ff0Smrg { 2346ca29ff0Smrg 2356ca29ff0Smrg if (++x >= 64) 2366ca29ff0Smrg x = 0; 2376ca29ff0Smrg 2386ca29ff0Smrg info.dest_x = 63 - x; 2396ca29ff0Smrg 2406ca29ff0Smrg t.matrix[0][2] = pixman_int_to_fixed (bi->src_x + x); 2416ca29ff0Smrg t.matrix[1][2] = pixman_int_to_fixed (bi->src_y); 2426ca29ff0Smrg pixman_image_set_transform (bi->src_image, &t); 2436ca29ff0Smrg 2446ca29ff0Smrg if (bi->mask_image) 2456ca29ff0Smrg pixman_image_set_transform (bi->mask_image, &t); 2466ca29ff0Smrg 2476ca29ff0Smrg func (&info); 2486ca29ff0Smrg t1 = gettimei (); 2496ca29ff0Smrg } 2506ca29ff0Smrg while (++n < max_n && (t1 - t0) < max_time); 2516ca29ff0Smrg 2526ca29ff0Smrg if (ret_n) 2536ca29ff0Smrg *ret_n = n; 2546ca29ff0Smrg 2556ca29ff0Smrg *ret_time = t1 - t0; 2566ca29ff0Smrg} 2576ca29ff0Smrg 2586ca29ff0Smrgint 2596ca29ff0Smrgparse_fixed_argument (char *arg, pixman_fixed_t *value) 2606ca29ff0Smrg{ 2616ca29ff0Smrg char *tailptr; 2626ca29ff0Smrg 2636ca29ff0Smrg *value = pixman_double_to_fixed (strtod (arg, &tailptr)); 2646ca29ff0Smrg 2656ca29ff0Smrg return *tailptr == '\0'; 2666ca29ff0Smrg} 2676ca29ff0Smrg 2686ca29ff0Smrgint 2696ca29ff0Smrgparse_arguments (int argc, 2706ca29ff0Smrg char *argv[], 2716ca29ff0Smrg pixman_transform_t *t, 2726ca29ff0Smrg pixman_op_t *op, 2736ca29ff0Smrg pixman_format_code_t *src_format, 2746ca29ff0Smrg pixman_format_code_t *mask_format, 2756ca29ff0Smrg pixman_format_code_t *dest_format) 2766ca29ff0Smrg{ 2776ca29ff0Smrg if (!parse_fixed_argument (*argv, &t->matrix[0][0])) 2786ca29ff0Smrg return 0; 2796ca29ff0Smrg 2806ca29ff0Smrg if (*++argv == NULL) 2816ca29ff0Smrg return 1; 2826ca29ff0Smrg 2836ca29ff0Smrg if (!parse_fixed_argument (*argv, &t->matrix[0][1])) 2846ca29ff0Smrg return 0; 2856ca29ff0Smrg 2866ca29ff0Smrg if (*++argv == NULL) 2876ca29ff0Smrg return 1; 2886ca29ff0Smrg 2896ca29ff0Smrg if (!parse_fixed_argument (*argv, &t->matrix[1][0])) 2906ca29ff0Smrg return 0; 2916ca29ff0Smrg 2926ca29ff0Smrg if (*++argv == NULL) 2936ca29ff0Smrg return 1; 2946ca29ff0Smrg 2956ca29ff0Smrg if (!parse_fixed_argument (*argv, &t->matrix[1][1])) 2966ca29ff0Smrg return 0; 2976ca29ff0Smrg 2986ca29ff0Smrg if (*++argv == NULL) 2996ca29ff0Smrg return 1; 3006ca29ff0Smrg 3016ca29ff0Smrg *op = operator_from_string (*argv); 3026ca29ff0Smrg if (*op == PIXMAN_OP_NONE) 3036ca29ff0Smrg return 0; 3046ca29ff0Smrg 3056ca29ff0Smrg if (*++argv == NULL) 3066ca29ff0Smrg return 1; 3076ca29ff0Smrg 3086ca29ff0Smrg *src_format = format_from_string (*argv); 3096ca29ff0Smrg if (*src_format == PIXMAN_null) 3106ca29ff0Smrg return 0; 3116ca29ff0Smrg 3126ca29ff0Smrg ++argv; 3136ca29ff0Smrg if (argv[0] && argv[1]) 3146ca29ff0Smrg { 3156ca29ff0Smrg *mask_format = format_from_string (*argv); 3166ca29ff0Smrg if (*mask_format == PIXMAN_null) 3176ca29ff0Smrg return 0; 3186ca29ff0Smrg ++argv; 3196ca29ff0Smrg } 3206ca29ff0Smrg if (*argv) 3216ca29ff0Smrg { 3226ca29ff0Smrg *dest_format = format_from_string (*argv); 3236ca29ff0Smrg if (*dest_format == PIXMAN_null) 3246ca29ff0Smrg return 0; 3256ca29ff0Smrg } 3266ca29ff0Smrg return 1; 3276ca29ff0Smrg} 3286ca29ff0Smrg 3296ca29ff0Smrgstatic void 3306ca29ff0Smrgrun_benchmark (const bench_info_t *bi) 3316ca29ff0Smrg{ 3326ca29ff0Smrg uint32_t n; /* number of iterations in at least 5 seconds */ 3336ca29ff0Smrg uint32_t t1; /* time taken to do n iterations, microseconds */ 3346ca29ff0Smrg uint32_t t2; /* calling overhead for n iterations, microseconds */ 3356ca29ff0Smrg 3366ca29ff0Smrg flush_cache (); 3376ca29ff0Smrg bench (bi, UINT32_MAX, 5000000, &n, &t1, pixman_image_composite_wrapper); 3386ca29ff0Smrg bench (bi, n, UINT32_MAX, NULL, &t2, pixman_image_composite_empty); 3396ca29ff0Smrg 3406ca29ff0Smrg /* The result indicates the output rate in megapixels/second */ 3416ca29ff0Smrg printf ("%6.2f\n", (double) n * WIDTH * HEIGHT / (t1 - t2)); 3426ca29ff0Smrg} 3436ca29ff0Smrg 3446ca29ff0Smrg 3456ca29ff0Smrgint 3466ca29ff0Smrgmain (int argc, char *argv[]) 3476ca29ff0Smrg{ 3486ca29ff0Smrg bench_info_t binfo; 3496ca29ff0Smrg pixman_filter_t filter = PIXMAN_FILTER_NEAREST; 3506ca29ff0Smrg pixman_format_code_t src_format = PIXMAN_a8r8g8b8; 3516ca29ff0Smrg pixman_format_code_t mask_format = 0; 3526ca29ff0Smrg pixman_format_code_t dest_format = PIXMAN_a8r8g8b8; 3536ca29ff0Smrg pixman_box32_t dest_box = { 0, 0, WIDTH, HEIGHT }; 3546ca29ff0Smrg box_48_16_t transformed = { 0 }; 3556ca29ff0Smrg int32_t xmin, ymin, xmax, ymax; 3566ca29ff0Smrg uint32_t *src, *mask, *dest; 3576ca29ff0Smrg 3586ca29ff0Smrg binfo.op = PIXMAN_OP_SRC; 3596ca29ff0Smrg binfo.mask_image = NULL; 3606ca29ff0Smrg pixman_transform_init_identity (&binfo.transform); 3616ca29ff0Smrg 3626ca29ff0Smrg ++argv; 3636ca29ff0Smrg if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n') 3646ca29ff0Smrg { 3656ca29ff0Smrg filter = PIXMAN_FILTER_NEAREST; 3666ca29ff0Smrg ++argv; 3676ca29ff0Smrg --argc; 3686ca29ff0Smrg } 3696ca29ff0Smrg 3706ca29ff0Smrg if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b') 3716ca29ff0Smrg { 3726ca29ff0Smrg filter = PIXMAN_FILTER_BILINEAR; 3736ca29ff0Smrg ++argv; 3746ca29ff0Smrg --argc; 3756ca29ff0Smrg } 3766ca29ff0Smrg 3776ca29ff0Smrg if (argc == 1 || 3786ca29ff0Smrg !parse_arguments (argc, argv, &binfo.transform, &binfo.op, 3796ca29ff0Smrg &src_format, &mask_format, &dest_format)) 3806ca29ff0Smrg { 3816ca29ff0Smrg printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n"); 3826ca29ff0Smrg printf (" [src format] [mask format] [dest format]\n"); 3836ca29ff0Smrg printf (" -n : nearest scaling (default)\n"); 3846ca29ff0Smrg printf (" -b : bilinear scaling\n"); 3856ca29ff0Smrg printf (" axx : x_out:x_in factor\n"); 3866ca29ff0Smrg printf (" axy : x_out:y_in factor (default 0)\n"); 3876ca29ff0Smrg printf (" ayx : y_out:x_in factor (default 0)\n"); 3886ca29ff0Smrg printf (" ayy : y_out:y_in factor (default 1)\n"); 3896ca29ff0Smrg printf (" combine type : src, over, in etc (default src)\n"); 3906ca29ff0Smrg printf (" src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n"); 3916ca29ff0Smrg printf (" mask format : as for src format, but no mask used if omitted\n"); 3926ca29ff0Smrg printf (" dest format : as for src format (default a8r8g8b8)\n"); 3936ca29ff0Smrg printf ("The output is a single number in megapixels/second.\n"); 3946ca29ff0Smrg 3956ca29ff0Smrg return EXIT_FAILURE; 3966ca29ff0Smrg } 3976ca29ff0Smrg 3986ca29ff0Smrg /* Compute required extents for source and mask image so they qualify 3996ca29ff0Smrg * for COVER fast paths and get the flags in pixman.c:analyze_extent(). 4006ca29ff0Smrg * These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, 4016ca29ff0Smrg * but at the same time they also allow COVER_CLIP_NEAREST. 4026ca29ff0Smrg */ 4036ca29ff0Smrg compute_transformed_extents (&binfo.transform, &dest_box, &transformed); 4046ca29ff0Smrg xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2); 4056ca29ff0Smrg ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2); 4066ca29ff0Smrg xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2); 4076ca29ff0Smrg ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2); 4086ca29ff0Smrg /* Note: 4096ca29ff0Smrg * The upper limits can be reduced to the following when fetchers 4106ca29ff0Smrg * are guaranteed to not access pixels with zero weight. This concerns 4116ca29ff0Smrg * particularly all bilinear samplers. 4126ca29ff0Smrg * 4136ca29ff0Smrg * xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e); 4146ca29ff0Smrg * ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e); 4156ca29ff0Smrg * This is equivalent to subtracting 0.5 and rounding up, rather than 4166ca29ff0Smrg * subtracting 0.5, rounding down and adding 1. 4176ca29ff0Smrg */ 4186ca29ff0Smrg binfo.src_x = -xmin; 4196ca29ff0Smrg binfo.src_y = -ymin; 4206ca29ff0Smrg 4216ca29ff0Smrg /* Always over-allocate width by 64 pixels for all src, mask and dst, 4226ca29ff0Smrg * so that we can iterate over an x-offset 0..63 in bench (). 4236ca29ff0Smrg * This is similar to lowlevel-blt-bench, which uses the same method 4246ca29ff0Smrg * to hit different cacheline misalignments. 4256ca29ff0Smrg */ 4266ca29ff0Smrg create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter, 4276ca29ff0Smrg &src, &binfo.src_image); 4286ca29ff0Smrg 4296ca29ff0Smrg if (mask_format) 4306ca29ff0Smrg { 4316ca29ff0Smrg create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter, 4326ca29ff0Smrg &mask, &binfo.mask_image); 4336ca29ff0Smrg 4346ca29ff0Smrg if ((PIXMAN_FORMAT_R(mask_format) || 4356ca29ff0Smrg PIXMAN_FORMAT_G(mask_format) || 4366ca29ff0Smrg PIXMAN_FORMAT_B(mask_format))) 4376ca29ff0Smrg { 4386ca29ff0Smrg pixman_image_set_component_alpha (binfo.mask_image, 1); 4396ca29ff0Smrg } 4406ca29ff0Smrg } 4416ca29ff0Smrg 4426ca29ff0Smrg create_image (WIDTH + 64, HEIGHT, dest_format, filter, 4436ca29ff0Smrg &dest, &binfo.dest_image); 4446ca29ff0Smrg 4456ca29ff0Smrg run_benchmark (&binfo); 4466ca29ff0Smrg 4476ca29ff0Smrg return EXIT_SUCCESS; 4486ca29ff0Smrg} 449