diff options
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/composite_bench.c | 367 |
2 files changed, 370 insertions, 1 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index 9dc7219..e8aa887 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -39,9 +39,11 @@ scaling_helpers_test_SOURCES = scaling-helpers-test.c utils.c utils.h # Benchmarks BENCHMARKS = \ - lowlevel-blt-bench + lowlevel-blt-bench \ + composite_bench lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h +composite_bench_SOURCES = composite_bench.c utils.c utils.h noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS) diff --git a/test/composite_bench.c b/test/composite_bench.c new file mode 100644 index 0000000..f9f7a62 --- /dev/null +++ b/test/composite_bench.c @@ -0,0 +1,367 @@ +/* + * Copyright © 2011 SCore Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author : Taekyun Kim (tkq.kim@samsung.net) + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "utils.h" + +#define BENCH_REPEAT_COUNT 100 + +typedef struct _bench_op +{ + pixman_op_t op; + const char *name; +} bench_op; + +typedef struct _bench_format +{ + pixman_format_code_t format; + const char *name; +} bench_format; + +typedef struct _bench_image_size +{ + int src_x; + int src_y; + int src_w; + int src_h; + int dst_x; + int dst_y; + int dst_w; + int dst_h; +} bench_image_size; + +bench_image_size image_size[] = +{ + {0, 0, 1, 512, 0, 0, 512, 512}, + {0, 0, 15, 15, 0, 0, 512, 512}, + {0, 0, 63, 63, 0, 0, 512, 512}, +}; + +bench_op ops[] = +{ + { PIXMAN_OP_SRC, "SRC" }, + { PIXMAN_OP_OVER, "OVER" }, + { PIXMAN_OP_ADD, "ADD" }, + { PIXMAN_OP_IN, "IN" }, + { PIXMAN_OP_OUT, "OUT" }, + { PIXMAN_OP_OUT_REVERSE, "OUT_REVERSE" } +}; + +#define FORMAT_NONE ((pixman_format_code_t)0) + +bench_format formats[] = +{ + { FORMAT_NONE, "None" }, + { PIXMAN_a8r8g8b8, "a8r8g8b8" }, + { PIXMAN_r5g6b5, "r5g6b5" }, + { PIXMAN_x8r8g8b8, "x8r8g8b8" }, + { PIXMAN_a8, "a8" }, + { PIXMAN_a1, "a1" } +}; + +double +bench_repeat_mode(pixman_op_t op, + pixman_format_code_t src_format, + int src_x, int src_y, int src_w, int src_h, + pixman_transform_t *src_trans, + pixman_repeat_t src_repeat, + pixman_filter_t src_filter, + pixman_format_code_t mask_format, + pixman_format_code_t dst_format, + int x, int y, int w, int h, + int num_iterations) +{ + int i; + double t0, t1; + void *src_buf; + void *mask_buf; + void *dst_buf; + int src_stride; + int mask_stride; + int dst_stride; + pixman_image_t *src_image = NULL; + pixman_image_t *mask_image = NULL; + pixman_image_t *dst_image = NULL; + + src_stride = (src_w*PIXMAN_FORMAT_BPP(src_format) + 7)/8; + src_stride = (src_stride + 3) & ~3; + + mask_stride = (w*PIXMAN_FORMAT_BPP(mask_format) + 7)/8; + mask_stride = (mask_stride + 3) & ~3; + + dst_stride = (w*PIXMAN_FORMAT_BPP(dst_format) + 7)/8; + dst_stride = (dst_stride + 3) & ~3; + + src_buf = malloc(src_stride*src_h); + dst_buf = malloc(dst_stride*h); + + memset(src_buf, 0xAA, src_stride*src_h); + memset(dst_buf, 0xAA, dst_stride*h); + + src_image = pixman_image_create_bits(src_format, src_w, src_h, src_buf, src_stride); + dst_image = pixman_image_create_bits(dst_format, w, h, dst_buf, dst_stride); + + if( mask_format != FORMAT_NONE ) + { + mask_buf = malloc(mask_stride*h); + memset(mask_buf, 0x00, mask_stride*h); + mask_image = pixman_image_create_bits(mask_format, w, h, mask_buf, mask_stride); + } + + pixman_image_set_transform(src_image, src_trans); + pixman_image_set_repeat(src_image, src_repeat); + pixman_image_set_filter(src_image, src_filter, NULL, 0); + + t0 = gettime(); + for( i=0; i<num_iterations; i++ ) + { + pixman_image_composite(op, src_image, mask_image, dst_image, + src_x, src_y, x, y, x, y, w, h); + } + t1 = gettime(); + + pixman_image_unref(src_image); + pixman_image_unref(dst_image); + + free(src_buf); + free(dst_buf); + + if( mask_image ) + { + pixman_image_unref(mask_image); + free(mask_buf); + } + + // CAUTION : Non-Repeat can be cropped to src_image + return (double)w*(double)h*(double)num_iterations / ((t1 - t0) * 1000000.0); +} + +void +bench_repeat_mode_op_format(int op, int src_format, int mask_format, int dst_format) +{ + int i; + double mpix_per_sec; + pixman_transform_t id_transform; + pixman_transform_t scale_transform; + + pixman_transform_init_identity(&id_transform); + pixman_transform_init_scale(&scale_transform, + pixman_double_to_fixed(1.001), pixman_double_to_fixed(1.001)); + + printf("//////////////////////////////////////////////////////////////////////////////\n"); + printf("// op=%s, src=%s, mask=%s, dst=%s\n", + ops[op].name, formats[src_format].name, formats[mask_format].name, + formats[dst_format].name); + printf("/////////////////////////////////////////////////////////////////////////////\n"); + printf("<<<<< Reference Compositing Performance 2000x2000 to 2000x2000 >>>>>\n"); + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + 0, 0, 2000, 2000, + &id_transform, + PIXMAN_REPEAT_NONE, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + 0, 0, 2000, 2000, + 100); + printf("Non-scaled : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + 0, 0, 2000, 2000, + &scale_transform, + PIXMAN_REPEAT_NONE, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + 0, 0, 2000, 2000, + 100); + printf("Nearest-scaled : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + 0, 0, 2000, 2000, + &scale_transform, + PIXMAN_REPEAT_NONE, PIXMAN_FILTER_BILINEAR, + formats[mask_format].format, + formats[dst_format].format, + 0, 0, 2000, 2000, + 10); + printf("Bilinear-scaled : %.2fMpix/s\n", mpix_per_sec); + + for( i=0; i<sizeof(image_size)/sizeof(image_size[0]); ++i ) + { + printf("<<<<< src = %d x %d dst = %d x %d >>>>>\n", + image_size[i].src_w, image_size[i].src_h, + image_size[i].dst_w, image_size[i].dst_h); + + /* + * Non-scaled Benchmarks + * */ + printf("- Non-Scaled -\n"); + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &id_transform, + PIXMAN_REPEAT_PAD, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_PAD : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &id_transform, + PIXMAN_REPEAT_NORMAL, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_NORMAL : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &id_transform, + PIXMAN_REPEAT_REFLECT, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_REFLECT : %.2fMpix/s\n", mpix_per_sec); + + /* + * Nearest-scaled (close to 1.x) Benchmarks + * */ + printf("- Nearest-Scaled (close to 1.x) -\n"); + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_PAD, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_PAD : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_NORMAL, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_NORMAL : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_REFLECT, PIXMAN_FILTER_NEAREST, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_REFLECT : %.2fMpix/s\n", mpix_per_sec); + + /* + * Bilinear-scaled (close to 1.x) Benchmarks + * */ + printf("- Bilinear-Scaled (close to 1.x)-\n"); + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_PAD, PIXMAN_FILTER_BILINEAR, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_PAD : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_NORMAL, PIXMAN_FILTER_BILINEAR, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_NORMAL : %.2fMpix/s\n", mpix_per_sec); + + mpix_per_sec = bench_repeat_mode(ops[op].op, formats[src_format].format, + image_size[i].src_x, image_size[i].src_y, + image_size[i].src_w, image_size[i].src_h, + &scale_transform, + PIXMAN_REPEAT_REFLECT, PIXMAN_FILTER_BILINEAR, + formats[mask_format].format, + formats[dst_format].format, + image_size[i].dst_x, image_size[i].dst_y, + image_size[i].dst_w, image_size[i].dst_h, + BENCH_REPEAT_COUNT); + printf("REPEAT_REFLECT : %.2fMpix/s\n", mpix_per_sec); + + printf("\n"); + } +} + +int +main(int argc, char **argv) +{ + int op_idx = 0; + int src_idx = 0; + int mask_idx = 0; + int dst_idx = 0; + + printf("Benchmark for various repeat mode image composition\n"); + + for( op_idx=0; op_idx<sizeof(ops)/sizeof(ops[0]); op_idx++ ) + { + for( src_idx=1; src_idx<sizeof(formats)/sizeof(formats[0]); src_idx++ ) + { + for( mask_idx=0; mask_idx<sizeof(formats)/sizeof(formats[0]); mask_idx++ ) + { + for( dst_idx=1; dst_idx<sizeof(formats)/sizeof(formats[0]); dst_idx++ ) + { + bench_repeat_mode_op_format(op_idx, src_idx, + mask_idx, dst_idx); + } + } + } + } + + return 0; +} |