diff options
-rw-r--r-- | test/.gitignore | 1 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/lowlevel-blt-bench.c | 135 | ||||
-rw-r--r-- | test/test.h | 5 | ||||
-rw-r--r-- | test/test_display.c | 17 |
5 files changed, 160 insertions, 0 deletions
diff --git a/test/.gitignore b/test/.gitignore index e24e3fd0..d3e59c5d 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -13,3 +13,4 @@ render-copyarea render-copyarea-size render-copy-alphaless mixed-stress +lowlevel-blt-bench diff --git a/test/Makefile.am b/test/Makefile.am index c1dd0e9b..0f9bd7d0 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,6 +21,8 @@ stress_TESTS = \ check_PROGRAMS = $(stress_TESTS) +noinst_PROGRAMS = lowlevel-blt-bench + AM_CFLAGS = @CWARNFLAGS@ @X11_CFLAGS@ @DRM_CFLAGS@ LDADD = libtest.la @X11_LIBS@ -lXfixes @DRM_LIBS@ -lrt diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c new file mode 100644 index 00000000..0cea0a81 --- /dev/null +++ b/test/lowlevel-blt-bench.c @@ -0,0 +1,135 @@ +/* + * Copyright © 2009 Nokia Corporation + * Copyright © 2010 Movial Creative Technologies Oy + * Copyright © 2013 Intel 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <stdbool.h> + +#include <X11/X.h> +#include <X11/Xutil.h> /* for XDestroyImage */ +#include <pixman.h> /* for pixman blt functions */ + +#include "test.h" + +static const struct format { + const char *name; + pixman_format_code_t pixman_format; +} formats[] = { + { "a8r8g8b8", PIXMAN_a8r8g8b8 }, + { "x8r8g8b8", PIXMAN_x8r8g8b8 }, + { "a8", PIXMAN_a8 }, + { "a4", PIXMAN_a4 }, + { "a1", PIXMAN_a1 }, +}; + +static const struct op { + const char *name; +} ops[] = { + [PictOpClear] = { "Clear" }, + [PictOpSrc] = { "Src" }, + [PictOpDst] = { "Dst" }, + [PictOpOver] = { "Over" }, + [PictOpOverReverse] = { "OverReverse" }, + [PictOpIn] = { "In" }, + [PictOpInReverse] = { "InReverse" }, + [PictOpOut] = { "Out" }, + [PictOpOutReverse] = { "OutReverse" }, + [PictOpAtop] = { "Atop" }, + [PictOpAtopReverse] = { "AtopReverse" }, + [PictOpXor] = { "Xor" }, + [PictOpAdd] = { "Add" }, + [PictOpSaturate] = { "Saturate" }, +}; + +static double _bench(struct test_display *t, enum target target_type, + int op, int src_format, + int loops) +{ + XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; + struct test_target target; + Pixmap pixmap; + Picture picture; + struct timespec tv; + double elapsed; + + test_target_create_render(t, target_type, &target); + XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, + 0, 0, target.width, target.height); + + pixmap = XCreatePixmap(t->dpy, t->root, + target.width, target.height, + PIXMAN_FORMAT_DEPTH(formats[src_format].pixman_format)); + + picture = XRenderCreatePicture(t->dpy, pixmap, + XRenderFindStandardFormat(t->dpy, src_format), + 0, NULL); + XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color, + 0, 0, target.width, target.height); + + test_timer_start(t, &tv); + while (loops--) + XRenderComposite(t->dpy, op, + picture, 0, target.picture, + 0, 0, + 0, 0, + 0, 0, + target.width, target.height); + elapsed = test_timer_stop(t, &tv); + + XRenderFreePicture(t->dpy, picture); + XFreePixmap(t->dpy, pixmap); + test_target_destroy_render(t, &target); + + return elapsed; +} + +static void bench(struct test *t, enum target target, int op, int sf) +{ + double real, ref; + + ref = _bench(&t->ref, target, op, sf, 1000); + real = _bench(&t->real, target, op, sf, 1000); + + fprintf (stdout, "Testing %s with %s: ref=%f, real=%f\n", + formats[sf].name, ops[op].name, ref, real); +} + +int main(int argc, char **argv) +{ + struct test test; + int op, sf; + + test_init(&test, argc, argv); + + for (op = 0; op < sizeof(ops)/sizeof(ops[0]); op++) { + for (sf = 0; sf < sizeof(formats)/sizeof(formats[0]); sf++) + bench(&test, ROOT, op, sf); + fprintf (stdout, "\n"); + } + + return 0; +} diff --git a/test/test.h b/test/test.h index 1e3995bb..7ef4dca4 100644 --- a/test/test.h +++ b/test/test.h @@ -2,6 +2,8 @@ #define TEST_H #include <stdint.h> +#include <time.h> + #include <X11/Xlib.h> #include <X11/extensions/XShm.h> #include <X11/extensions/Xrender.h> @@ -107,6 +109,9 @@ static inline uint32_t color(uint8_t red, uint8_t green, uint8_t blue, uint8_t a return alpha << 24 | ra >> 8 << 16 | ga >> 8 << 8 | ba >> 8; } +void test_timer_start(struct test_display *t, struct timespec *tv); +double test_timer_stop(struct test_display *t, struct timespec *tv); + #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif diff --git a/test/test_display.c b/test/test_display.c index ad3e40bc..b5e7e06e 100644 --- a/test/test_display.c +++ b/test/test_display.c @@ -148,3 +148,20 @@ void test_init(struct test *test, int argc, char **argv) memset(test, 0, sizeof(*test)); test_get_displays(argc, argv, &test->real, &test->ref); } + +void test_timer_start(struct test_display *t, struct timespec *tv) +{ + clock_gettime(CLOCK_MONOTONIC, tv); +} + +double test_timer_stop(struct test_display *t, struct timespec *tv) +{ + XImage *image; + struct timespec now; + + image = XGetImage(t->dpy, t->root, 0, 0, 1, 1, AllPlanes, ZPixmap); + clock_gettime(CLOCK_MONOTONIC, &now); + XDestroyImage(image); + + return (now.tv_sec - tv->tv_sec) + 1e-9*(now.tv_nsec - tv->tv_nsec); +} |