summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/Makefile.am4
-rw-r--r--test/composite_bench.c367
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;
+}