|
Packit |
030a23 |
/*
|
|
Packit |
030a23 |
* Copyright © 2014 RISC OS Open Ltd
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
Packit |
030a23 |
* documentation for any purpose is hereby granted without fee, provided that
|
|
Packit |
030a23 |
* the above copyright notice appear in all copies and that both that
|
|
Packit |
030a23 |
* copyright notice and this permission notice appear in supporting
|
|
Packit |
030a23 |
* documentation, and that the name of the copyright holders not be used in
|
|
Packit |
030a23 |
* advertising or publicity pertaining to distribution of the software without
|
|
Packit |
030a23 |
* specific, written prior permission. The copyright holders make no
|
|
Packit |
030a23 |
* representations about the suitability of this software for any purpose. It
|
|
Packit |
030a23 |
* is provided "as is" without express or implied warranty.
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
Packit |
030a23 |
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
Packit |
030a23 |
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
Packit |
030a23 |
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit |
030a23 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
Packit |
030a23 |
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
Packit |
030a23 |
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
Packit |
030a23 |
* SOFTWARE.
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* Author: Ben Avison (bavison@riscosopen.org)
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#include <stdio.h>
|
|
Packit |
030a23 |
#include <stdlib.h>
|
|
Packit |
030a23 |
#include <string.h>
|
|
Packit |
030a23 |
#include <ctype.h>
|
|
Packit |
030a23 |
#include <stdint.h>
|
|
Packit |
030a23 |
#include "utils.h"
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#ifdef HAVE_GETTIMEOFDAY
|
|
Packit |
030a23 |
#include <sys/time.h>
|
|
Packit |
030a23 |
#else
|
|
Packit |
030a23 |
#include <time.h>
|
|
Packit |
030a23 |
#endif
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#define WIDTH 1920
|
|
Packit |
030a23 |
#define HEIGHT 1080
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* How much data to read to flush all cached data to RAM */
|
|
Packit |
030a23 |
#define MAX_L2CACHE_SIZE (8 * 1024 * 1024)
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#define PAGE_SIZE (4 * 1024)
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
struct bench_info
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_op_t op;
|
|
Packit |
030a23 |
pixman_transform_t transform;
|
|
Packit |
030a23 |
pixman_image_t *src_image;
|
|
Packit |
030a23 |
pixman_image_t *mask_image;
|
|
Packit |
030a23 |
pixman_image_t *dest_image;
|
|
Packit |
030a23 |
int32_t src_x;
|
|
Packit |
030a23 |
int32_t src_y;
|
|
Packit |
030a23 |
};
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
typedef struct bench_info bench_info_t;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
struct box_48_16
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_fixed_48_16_t x1;
|
|
Packit |
030a23 |
pixman_fixed_48_16_t y1;
|
|
Packit |
030a23 |
pixman_fixed_48_16_t x2;
|
|
Packit |
030a23 |
pixman_fixed_48_16_t y2;
|
|
Packit |
030a23 |
};
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
typedef struct box_48_16 box_48_16_t;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* This function is copied verbatim from pixman.c. */
|
|
Packit |
030a23 |
static pixman_bool_t
|
|
Packit |
030a23 |
compute_transformed_extents (pixman_transform_t *transform,
|
|
Packit |
030a23 |
const pixman_box32_t *extents,
|
|
Packit |
030a23 |
box_48_16_t *transformed)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
|
|
Packit |
030a23 |
pixman_fixed_t x1, y1, x2, y2;
|
|
Packit |
030a23 |
int i;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
|
|
Packit |
030a23 |
y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
|
|
Packit |
030a23 |
x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
|
|
Packit |
030a23 |
y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!transform)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
transformed->x1 = x1;
|
|
Packit |
030a23 |
transformed->y1 = y1;
|
|
Packit |
030a23 |
transformed->x2 = x2;
|
|
Packit |
030a23 |
transformed->y2 = y2;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return TRUE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
tx1 = ty1 = INT64_MAX;
|
|
Packit |
030a23 |
tx2 = ty2 = INT64_MIN;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
for (i = 0; i < 4; ++i)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_fixed_48_16_t tx, ty;
|
|
Packit |
030a23 |
pixman_vector_t v;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
v.vector[0] = (i & 0x01)? x1 : x2;
|
|
Packit |
030a23 |
v.vector[1] = (i & 0x02)? y1 : y2;
|
|
Packit |
030a23 |
v.vector[2] = pixman_fixed_1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!pixman_transform_point (transform, &v))
|
|
Packit |
030a23 |
return FALSE;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
tx = (pixman_fixed_48_16_t)v.vector[0];
|
|
Packit |
030a23 |
ty = (pixman_fixed_48_16_t)v.vector[1];
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (tx < tx1)
|
|
Packit |
030a23 |
tx1 = tx;
|
|
Packit |
030a23 |
if (ty < ty1)
|
|
Packit |
030a23 |
ty1 = ty;
|
|
Packit |
030a23 |
if (tx > tx2)
|
|
Packit |
030a23 |
tx2 = tx;
|
|
Packit |
030a23 |
if (ty > ty2)
|
|
Packit |
030a23 |
ty2 = ty;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
transformed->x1 = tx1;
|
|
Packit |
030a23 |
transformed->y1 = ty1;
|
|
Packit |
030a23 |
transformed->x2 = tx2;
|
|
Packit |
030a23 |
transformed->y2 = ty2;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return TRUE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
create_image (uint32_t width,
|
|
Packit |
030a23 |
uint32_t height,
|
|
Packit |
030a23 |
pixman_format_code_t format,
|
|
Packit |
030a23 |
pixman_filter_t filter,
|
|
Packit |
030a23 |
uint32_t **bits,
|
|
Packit |
030a23 |
pixman_image_t **image)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
uint32_t stride = (width * PIXMAN_FORMAT_BPP (format) + 31) / 32 * 4;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*bits = aligned_malloc (PAGE_SIZE, stride * height);
|
|
Packit |
030a23 |
memset (*bits, 0xCC, stride * height);
|
|
Packit |
030a23 |
*image = pixman_image_create_bits (format, width, height, *bits, stride);
|
|
Packit |
030a23 |
pixman_image_set_repeat (*image, PIXMAN_REPEAT_NORMAL);
|
|
Packit |
030a23 |
pixman_image_set_filter (*image, filter, NULL, 0);
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* This needs to match the shortest cacheline length we expect to encounter */
|
|
Packit |
030a23 |
#define CACHE_CLEAN_INCREMENT 32
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
flush_cache (void)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
static const char clean_space[MAX_L2CACHE_SIZE];
|
|
Packit |
030a23 |
volatile const char *x = clean_space;
|
|
Packit |
030a23 |
const char *clean_end = clean_space + sizeof clean_space;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
while (x < clean_end)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
(void) *x;
|
|
Packit |
030a23 |
x += CACHE_CLEAN_INCREMENT;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Obtain current time in microseconds modulo 2^32 */
|
|
Packit |
030a23 |
uint32_t
|
|
Packit |
030a23 |
gettimei (void)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
#ifdef HAVE_GETTIMEOFDAY
|
|
Packit |
030a23 |
struct timeval tv;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
gettimeofday (&tv, NULL);
|
|
Packit |
030a23 |
return tv.tv_sec * 1000000 + tv.tv_usec;
|
|
Packit |
030a23 |
#else
|
|
Packit |
030a23 |
return (uint64_t) clock () * 1000000 / CLOCKS_PER_SEC;
|
|
Packit |
030a23 |
#endif
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
pixman_image_composite_wrapper (const pixman_composite_info_t *info)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_image_composite (info->op,
|
|
Packit |
030a23 |
info->src_image, info->mask_image, info->dest_image,
|
|
Packit |
030a23 |
info->src_x, info->src_y,
|
|
Packit |
030a23 |
info->mask_x, info->mask_y,
|
|
Packit |
030a23 |
info->dest_x, info->dest_y,
|
|
Packit |
030a23 |
info->width, info->height);
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
pixman_image_composite_empty (const pixman_composite_info_t *info)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_image_composite (info->op,
|
|
Packit |
030a23 |
info->src_image, info->mask_image, info->dest_image,
|
|
Packit |
030a23 |
info->src_x, info->src_y,
|
|
Packit |
030a23 |
info->mask_x, info->mask_y,
|
|
Packit |
030a23 |
info->dest_x, info->dest_y,
|
|
Packit |
030a23 |
1, 1);
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
bench (const bench_info_t *bi,
|
|
Packit |
030a23 |
uint32_t max_n,
|
|
Packit |
030a23 |
uint32_t max_time,
|
|
Packit |
030a23 |
uint32_t *ret_n,
|
|
Packit |
030a23 |
uint32_t *ret_time,
|
|
Packit |
030a23 |
void (*func) (const pixman_composite_info_t *info))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
uint32_t n = 0;
|
|
Packit |
030a23 |
uint32_t t0;
|
|
Packit |
030a23 |
uint32_t t1;
|
|
Packit |
030a23 |
uint32_t x = 0;
|
|
Packit |
030a23 |
pixman_transform_t t;
|
|
Packit |
030a23 |
pixman_composite_info_t info;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
t = bi->transform;
|
|
Packit |
030a23 |
info.op = bi->op;
|
|
Packit |
030a23 |
info.src_image = bi->src_image;
|
|
Packit |
030a23 |
info.mask_image = bi->mask_image;
|
|
Packit |
030a23 |
info.dest_image = bi->dest_image;
|
|
Packit |
030a23 |
info.src_x = 0;
|
|
Packit |
030a23 |
info.src_y = 0;
|
|
Packit |
030a23 |
info.mask_x = 0;
|
|
Packit |
030a23 |
info.mask_y = 0;
|
|
Packit |
030a23 |
/* info.dest_x set below */
|
|
Packit |
030a23 |
info.dest_y = 0;
|
|
Packit |
030a23 |
info.width = WIDTH;
|
|
Packit |
030a23 |
info.height = HEIGHT;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
t0 = gettimei ();
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
do
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (++x >= 64)
|
|
Packit |
030a23 |
x = 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
info.dest_x = 63 - x;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
t.matrix[0][2] = pixman_int_to_fixed (bi->src_x + x);
|
|
Packit |
030a23 |
t.matrix[1][2] = pixman_int_to_fixed (bi->src_y);
|
|
Packit |
030a23 |
pixman_image_set_transform (bi->src_image, &t);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (bi->mask_image)
|
|
Packit |
030a23 |
pixman_image_set_transform (bi->mask_image, &t);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
func (&info;;
|
|
Packit |
030a23 |
t1 = gettimei ();
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
while (++n < max_n && (t1 - t0) < max_time);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (ret_n)
|
|
Packit |
030a23 |
*ret_n = n;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*ret_time = t1 - t0;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
int
|
|
Packit |
030a23 |
parse_fixed_argument (char *arg, pixman_fixed_t *value)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
char *tailptr;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*value = pixman_double_to_fixed (strtod (arg, &tailptr));
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return *tailptr == '\0';
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
int
|
|
Packit |
030a23 |
parse_arguments (int argc,
|
|
Packit |
030a23 |
char *argv[],
|
|
Packit |
030a23 |
pixman_transform_t *t,
|
|
Packit |
030a23 |
pixman_op_t *op,
|
|
Packit |
030a23 |
pixman_format_code_t *src_format,
|
|
Packit |
030a23 |
pixman_format_code_t *mask_format,
|
|
Packit |
030a23 |
pixman_format_code_t *dest_format)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if (!parse_fixed_argument (*argv, &t->matrix[0][0]))
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*++argv == NULL)
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!parse_fixed_argument (*argv, &t->matrix[0][1]))
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*++argv == NULL)
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!parse_fixed_argument (*argv, &t->matrix[1][0]))
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*++argv == NULL)
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!parse_fixed_argument (*argv, &t->matrix[1][1]))
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*++argv == NULL)
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*op = operator_from_string (*argv);
|
|
Packit |
030a23 |
if (*op == PIXMAN_OP_NONE)
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*++argv == NULL)
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*src_format = format_from_string (*argv);
|
|
Packit |
030a23 |
if (*src_format == PIXMAN_null)
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
++argv;
|
|
Packit |
030a23 |
if (argv[0] && argv[1])
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
*mask_format = format_from_string (*argv);
|
|
Packit |
030a23 |
if (*mask_format == PIXMAN_null)
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
++argv;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
if (*argv)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
*dest_format = format_from_string (*argv);
|
|
Packit |
030a23 |
if (*dest_format == PIXMAN_null)
|
|
Packit |
030a23 |
return 0;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
return 1;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
run_benchmark (const bench_info_t *bi)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
uint32_t n; /* number of iterations in at least 5 seconds */
|
|
Packit |
030a23 |
uint32_t t1; /* time taken to do n iterations, microseconds */
|
|
Packit |
030a23 |
uint32_t t2; /* calling overhead for n iterations, microseconds */
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
flush_cache ();
|
|
Packit |
030a23 |
bench (bi, UINT32_MAX, 5000000, &n, &t1, pixman_image_composite_wrapper);
|
|
Packit |
030a23 |
bench (bi, n, UINT32_MAX, NULL, &t2, pixman_image_composite_empty);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* The result indicates the output rate in megapixels/second */
|
|
Packit |
030a23 |
printf ("%6.2f\n", (double) n * WIDTH * HEIGHT / (t1 - t2));
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
int
|
|
Packit |
030a23 |
main (int argc, char *argv[])
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
bench_info_t binfo;
|
|
Packit |
030a23 |
pixman_filter_t filter = PIXMAN_FILTER_NEAREST;
|
|
Packit |
030a23 |
pixman_format_code_t src_format = PIXMAN_a8r8g8b8;
|
|
Packit |
030a23 |
pixman_format_code_t mask_format = 0;
|
|
Packit |
030a23 |
pixman_format_code_t dest_format = PIXMAN_a8r8g8b8;
|
|
Packit |
030a23 |
pixman_box32_t dest_box = { 0, 0, WIDTH, HEIGHT };
|
|
Packit |
030a23 |
box_48_16_t transformed = { 0 };
|
|
Packit |
030a23 |
int32_t xmin, ymin, xmax, ymax;
|
|
Packit |
030a23 |
uint32_t *src, *mask, *dest;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
binfo.op = PIXMAN_OP_SRC;
|
|
Packit |
030a23 |
binfo.mask_image = NULL;
|
|
Packit |
030a23 |
pixman_transform_init_identity (&binfo.transform);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
++argv;
|
|
Packit |
030a23 |
if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n')
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
filter = PIXMAN_FILTER_NEAREST;
|
|
Packit |
030a23 |
++argv;
|
|
Packit |
030a23 |
--argc;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b')
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
filter = PIXMAN_FILTER_BILINEAR;
|
|
Packit |
030a23 |
++argv;
|
|
Packit |
030a23 |
--argc;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (argc == 1 ||
|
|
Packit |
030a23 |
!parse_arguments (argc, argv, &binfo.transform, &binfo.op,
|
|
Packit |
030a23 |
&src_format, &mask_format, &dest_format))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n");
|
|
Packit |
030a23 |
printf (" [src format] [mask format] [dest format]\n");
|
|
Packit |
030a23 |
printf (" -n : nearest scaling (default)\n");
|
|
Packit |
030a23 |
printf (" -b : bilinear scaling\n");
|
|
Packit |
030a23 |
printf (" axx : x_out:x_in factor\n");
|
|
Packit |
030a23 |
printf (" axy : x_out:y_in factor (default 0)\n");
|
|
Packit |
030a23 |
printf (" ayx : y_out:x_in factor (default 0)\n");
|
|
Packit |
030a23 |
printf (" ayy : y_out:y_in factor (default 1)\n");
|
|
Packit |
030a23 |
printf (" combine type : src, over, in etc (default src)\n");
|
|
Packit |
030a23 |
printf (" src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n");
|
|
Packit |
030a23 |
printf (" mask format : as for src format, but no mask used if omitted\n");
|
|
Packit |
030a23 |
printf (" dest format : as for src format (default a8r8g8b8)\n");
|
|
Packit |
030a23 |
printf ("The output is a single number in megapixels/second.\n");
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return EXIT_FAILURE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Compute required extents for source and mask image so they qualify
|
|
Packit |
030a23 |
* for COVER fast paths and get the flags in pixman.c:analyze_extent().
|
|
Packit |
030a23 |
* These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR,
|
|
Packit |
030a23 |
* but at the same time they also allow COVER_CLIP_NEAREST.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
compute_transformed_extents (&binfo.transform, &dest_box, &transformed);
|
|
Packit |
030a23 |
xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2);
|
|
Packit |
030a23 |
ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2);
|
|
Packit |
030a23 |
xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2);
|
|
Packit |
030a23 |
ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2);
|
|
Packit |
030a23 |
/* Note:
|
|
Packit |
030a23 |
* The upper limits can be reduced to the following when fetchers
|
|
Packit |
030a23 |
* are guaranteed to not access pixels with zero weight. This concerns
|
|
Packit |
030a23 |
* particularly all bilinear samplers.
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e);
|
|
Packit |
030a23 |
* ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e);
|
|
Packit |
030a23 |
* This is equivalent to subtracting 0.5 and rounding up, rather than
|
|
Packit |
030a23 |
* subtracting 0.5, rounding down and adding 1.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
binfo.src_x = -xmin;
|
|
Packit |
030a23 |
binfo.src_y = -ymin;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Always over-allocate width by 64 pixels for all src, mask and dst,
|
|
Packit |
030a23 |
* so that we can iterate over an x-offset 0..63 in bench ().
|
|
Packit |
030a23 |
* This is similar to lowlevel-blt-bench, which uses the same method
|
|
Packit |
030a23 |
* to hit different cacheline misalignments.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter,
|
|
Packit |
030a23 |
&src, &binfo.src_image);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (mask_format)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter,
|
|
Packit |
030a23 |
&mask, &binfo.mask_image);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if ((PIXMAN_FORMAT_R(mask_format) ||
|
|
Packit |
030a23 |
PIXMAN_FORMAT_G(mask_format) ||
|
|
Packit |
030a23 |
PIXMAN_FORMAT_B(mask_format)))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_image_set_component_alpha (binfo.mask_image, 1);
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
create_image (WIDTH + 64, HEIGHT, dest_format, filter,
|
|
Packit |
030a23 |
&dest, &binfo.dest_image);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
run_benchmark (&binfo);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return EXIT_SUCCESS;
|
|
Packit |
030a23 |
}
|