1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 2009 Nokia Corporation 3428d7b3dSmrg * Copyright © 2010 Movial Creative Technologies Oy 4428d7b3dSmrg * Copyright © 2013 Intel Corporation 5428d7b3dSmrg * 6428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 7428d7b3dSmrg * copy of this software and associated documentation files (the "Software"), 8428d7b3dSmrg * to deal in the Software without restriction, including without limitation 9428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the 11428d7b3dSmrg * Software is furnished to do so, subject to the following conditions: 12428d7b3dSmrg * 13428d7b3dSmrg * The above copyright notice and this permission notice (including the next 14428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the 15428d7b3dSmrg * Software. 16428d7b3dSmrg * 17428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22428d7b3dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23428d7b3dSmrg * DEALINGS IN THE SOFTWARE. 24428d7b3dSmrg */ 25428d7b3dSmrg 26428d7b3dSmrg#ifdef HAVE_CONFIG_H 27428d7b3dSmrg#include "config.h" 28428d7b3dSmrg#endif 29428d7b3dSmrg 30428d7b3dSmrg#include <stdio.h> 31428d7b3dSmrg#include <stdlib.h> 32428d7b3dSmrg#include <string.h> 33428d7b3dSmrg#include <stdint.h> 34428d7b3dSmrg#include <stdbool.h> 35428d7b3dSmrg 36428d7b3dSmrg#include <X11/X.h> 37428d7b3dSmrg#include <X11/Xutil.h> /* for XDestroyImage */ 38428d7b3dSmrg#include <X11/Xlibint.h> 39428d7b3dSmrg#include <X11/extensions/Xrender.h> 40428d7b3dSmrg#if HAVE_MIT_SHM 41428d7b3dSmrg#include <X11/extensions/XShm.h> 42428d7b3dSmrg#if HAVE_X11_EXTENSIONS_SHMPROTO_H 43428d7b3dSmrg#include <X11/extensions/shmproto.h> 44428d7b3dSmrg#elif HAVE_X11_EXTENSIONS_SHMSTR_H 45428d7b3dSmrg#include <X11/extensions/shmstr.h> 46428d7b3dSmrg#else 47428d7b3dSmrg#error Failed to find the right header for X11 MIT-SHM protocol definitions 48428d7b3dSmrg#endif 49428d7b3dSmrg#include <sys/ipc.h> 50428d7b3dSmrg#include <sys/shm.h> 51428d7b3dSmrg#endif 52428d7b3dSmrg#include <pixman.h> /* for pixman blt functions */ 53428d7b3dSmrg 54428d7b3dSmrg#include "test.h" 55428d7b3dSmrg 56428d7b3dSmrgstatic const struct format { 57428d7b3dSmrg const char *name; 58428d7b3dSmrg pixman_format_code_t pixman_format; 59428d7b3dSmrg} formats[] = { 60428d7b3dSmrg { "a8r8g8b8", PIXMAN_a8r8g8b8 }, 61428d7b3dSmrg { "x8r8g8b8", PIXMAN_x8r8g8b8 }, 62428d7b3dSmrg { "a8", PIXMAN_a8 }, 63428d7b3dSmrg { "a4", PIXMAN_a4 }, 64428d7b3dSmrg { "a1", PIXMAN_a1 }, 65428d7b3dSmrg}; 66428d7b3dSmrg 67428d7b3dSmrgstatic const struct op { 68428d7b3dSmrg int value; 69428d7b3dSmrg const char *name; 70428d7b3dSmrg} ops[] = { 71428d7b3dSmrg { PictOpClear, "Clear" }, 72428d7b3dSmrg { PictOpSrc, "Src" }, 73428d7b3dSmrg { PictOpDst, "Dst" }, 74428d7b3dSmrg { PictOpOver, "Over" }, 75428d7b3dSmrg { PictOpOverReverse, "OverReverse" }, 76428d7b3dSmrg { PictOpIn, "In" }, 77428d7b3dSmrg { PictOpInReverse, "InReverse" }, 78428d7b3dSmrg { PictOpOut, "Out" }, 79428d7b3dSmrg { PictOpOutReverse, "OutReverse" }, 80428d7b3dSmrg { PictOpAtop, "Atop" }, 81428d7b3dSmrg { PictOpAtopReverse, "AtopReverse" }, 82428d7b3dSmrg { PictOpXor, "Xor" }, 83428d7b3dSmrg { PictOpAdd, "Add" }, 84428d7b3dSmrg { PictOpSaturate, "Saturate" }, 85428d7b3dSmrg { PictOpMultiply, "Multiply" }, 86428d7b3dSmrg { PictOpScreen, "Screen" }, 87428d7b3dSmrg { PictOpOverlay, "Overlay" }, 88428d7b3dSmrg { PictOpDarken, "Darken" }, 89428d7b3dSmrg { PictOpLighten, "Lighten" }, 90428d7b3dSmrg { PictOpColorDodge, "Dodge" }, 91428d7b3dSmrg { PictOpColorBurn, "Burn" }, 92428d7b3dSmrg { PictOpHardLight, "HardLight" }, 93428d7b3dSmrg { PictOpSoftLight, "SoftLight" }, 94428d7b3dSmrg}; 95428d7b3dSmrg 96428d7b3dSmrgstatic Picture source_pixmap(struct test_display *t, struct test_target *target, int format) 97428d7b3dSmrg{ 98428d7b3dSmrg XRenderColor render_color[2] = { 99428d7b3dSmrg { 0x8000, 0x8000, 0x8000, 0x8000 }, 100428d7b3dSmrg { 0xffff, 0xffff, 0xffff, 0xffff }, 101428d7b3dSmrg }; 102428d7b3dSmrg Pixmap pixmap; 103428d7b3dSmrg Picture picture; 104428d7b3dSmrg 105428d7b3dSmrg pixmap = XCreatePixmap(t->dpy, t->root, 106428d7b3dSmrg target->width, target->height, 107428d7b3dSmrg PIXMAN_FORMAT_DEPTH(formats[format].pixman_format)); 108428d7b3dSmrg 109428d7b3dSmrg picture = XRenderCreatePicture(t->dpy, pixmap, 110428d7b3dSmrg XRenderFindStandardFormat(t->dpy, format), 111428d7b3dSmrg 0, NULL); 112428d7b3dSmrg XFreePixmap(t->dpy, pixmap); 113428d7b3dSmrg 114428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[0], 115428d7b3dSmrg 0, 0, target->width, target->height/2); 116428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[1], 117428d7b3dSmrg 0, target->height/2, target->width, target->height/2); 118428d7b3dSmrg 119428d7b3dSmrg return picture; 120428d7b3dSmrg} 121428d7b3dSmrg 122428d7b3dSmrgstatic Picture source_a8r8g8b8(struct test_display *t, struct test_target *target) 123428d7b3dSmrg{ 124428d7b3dSmrg return source_pixmap(t, target, 0); 125428d7b3dSmrg} 126428d7b3dSmrg 127428d7b3dSmrgstatic Picture source_x8r8g8b8(struct test_display *t, struct test_target *target) 128428d7b3dSmrg{ 129428d7b3dSmrg return source_pixmap(t, target, 1); 130428d7b3dSmrg} 131428d7b3dSmrg 132428d7b3dSmrgstatic Picture source_a8(struct test_display *t, struct test_target *target) 133428d7b3dSmrg{ 134428d7b3dSmrg return source_pixmap(t, target, 2); 135428d7b3dSmrg} 136428d7b3dSmrg 137428d7b3dSmrgstatic Picture source_a4(struct test_display *t, struct test_target *target) 138428d7b3dSmrg{ 139428d7b3dSmrg return source_pixmap(t, target, 3); 140428d7b3dSmrg} 141428d7b3dSmrg 142428d7b3dSmrgstatic Picture source_a1(struct test_display *t, struct test_target *target) 143428d7b3dSmrg{ 144428d7b3dSmrg return source_pixmap(t, target, 3); 145428d7b3dSmrg} 146428d7b3dSmrg 147428d7b3dSmrgstatic Picture source_1x1r(struct test_display *t, struct test_target *target) 148428d7b3dSmrg{ 149428d7b3dSmrg XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; 150428d7b3dSmrg XRenderPictureAttributes pa; 151428d7b3dSmrg Pixmap pixmap; 152428d7b3dSmrg Picture picture; 153428d7b3dSmrg 154428d7b3dSmrg pa.repeat = RepeatNormal; 155428d7b3dSmrg 156428d7b3dSmrg pixmap = XCreatePixmap(t->dpy, t->root, 1, 1, 32); 157428d7b3dSmrg picture = XRenderCreatePicture(t->dpy, pixmap, 158428d7b3dSmrg XRenderFindStandardFormat(t->dpy, 0), 159428d7b3dSmrg CPRepeat, &pa); 160428d7b3dSmrg XFreePixmap(t->dpy, pixmap); 161428d7b3dSmrg 162428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color, 163428d7b3dSmrg 0, 0, 1, 1); 164428d7b3dSmrg 165428d7b3dSmrg return picture; 166428d7b3dSmrg} 167428d7b3dSmrg 168428d7b3dSmrgstatic Picture source_solid(struct test_display *t, struct test_target *target) 169428d7b3dSmrg{ 170428d7b3dSmrg XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; 171428d7b3dSmrg return XRenderCreateSolidFill(t->dpy, &render_color); 172428d7b3dSmrg} 173428d7b3dSmrg 174428d7b3dSmrgstatic Picture source_linear_horizontal(struct test_display *t, struct test_target *target) 175428d7b3dSmrg{ 176428d7b3dSmrg XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; 177428d7b3dSmrg XFixed stops[2] = {0, 0xffff}; 178428d7b3dSmrg XLinearGradient gradient = { {0, 0}, {target->width << 16, 0}}; 179428d7b3dSmrg 180428d7b3dSmrg return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); 181428d7b3dSmrg} 182428d7b3dSmrg 183428d7b3dSmrgstatic Picture source_linear_vertical(struct test_display *t, struct test_target *target) 184428d7b3dSmrg{ 185428d7b3dSmrg XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; 186428d7b3dSmrg XFixed stops[2] = {0, 0xffff}; 187428d7b3dSmrg XLinearGradient gradient = { {0, 0}, {0, target->height << 16}}; 188428d7b3dSmrg 189428d7b3dSmrg return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); 190428d7b3dSmrg} 191428d7b3dSmrg 192428d7b3dSmrgstatic Picture source_linear_diagonal(struct test_display *t, struct test_target *target) 193428d7b3dSmrg{ 194428d7b3dSmrg XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; 195428d7b3dSmrg XFixed stops[2] = {0, 0xffff}; 196428d7b3dSmrg XLinearGradient gradient = { {0, 0}, {target->width << 16, target->height << 16}}; 197428d7b3dSmrg 198428d7b3dSmrg return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); 199428d7b3dSmrg} 200428d7b3dSmrg 201428d7b3dSmrgstatic Picture source_radial_concentric(struct test_display *t, struct test_target *target) 202428d7b3dSmrg{ 203428d7b3dSmrg XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; 204428d7b3dSmrg XFixed stops[2] = {0, 0xffff}; 205428d7b3dSmrg XRadialGradient gradient = { 206428d7b3dSmrg { 207428d7b3dSmrg ((target->width << 16) + 1) / 2, 208428d7b3dSmrg ((target->height << 16) + 1) / 2, 209428d7b3dSmrg 0, 210428d7b3dSmrg }, 211428d7b3dSmrg { 212428d7b3dSmrg ((target->width << 16) + 1) / 2, 213428d7b3dSmrg ((target->height << 16) + 1) / 2, 214428d7b3dSmrg target->width << 15, 215428d7b3dSmrg } 216428d7b3dSmrg }; 217428d7b3dSmrg 218428d7b3dSmrg return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2); 219428d7b3dSmrg} 220428d7b3dSmrg 221428d7b3dSmrgstatic Picture source_radial_generic(struct test_display *t, struct test_target *target) 222428d7b3dSmrg{ 223428d7b3dSmrg XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; 224428d7b3dSmrg XFixed stops[2] = {0, 0xffff}; 225428d7b3dSmrg XRadialGradient gradient = { 226428d7b3dSmrg { 0, 0, target->width << 14, }, 227428d7b3dSmrg { target->width << 16, target->height << 16, target->width << 14, } 228428d7b3dSmrg }; 229428d7b3dSmrg 230428d7b3dSmrg return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2); 231428d7b3dSmrg} 232428d7b3dSmrg 233428d7b3dSmrg#if HAVE_MIT_SHM 234428d7b3dSmrgstatic XShmSegmentInfo shmref, shmout; 235428d7b3dSmrg 236428d7b3dSmrgstatic void setup_shm(struct test *t) 237428d7b3dSmrg{ 238428d7b3dSmrg XShmSegmentInfo shm; 239428d7b3dSmrg int size; 240428d7b3dSmrg 241428d7b3dSmrg shm.shmid = -1; 242428d7b3dSmrg 243428d7b3dSmrg if (!(t->ref.has_shm_pixmaps && t->out.has_shm_pixmaps)) 244428d7b3dSmrg return; 245428d7b3dSmrg 246428d7b3dSmrg size = t->ref.width * t->ref.height * 4; 247428d7b3dSmrg size = (size + 4095) & -4096; 248428d7b3dSmrg 249428d7b3dSmrg shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0666); 250428d7b3dSmrg if (shm.shmid == -1) 251428d7b3dSmrg return; 252428d7b3dSmrg 253428d7b3dSmrg shm.shmaddr = shmat(shm.shmid, 0, 0); 254428d7b3dSmrg if (shm.shmaddr == (char *) -1) { 255428d7b3dSmrg shmctl(shm.shmid, IPC_RMID, NULL); 256428d7b3dSmrg shm.shmid = -1; 257428d7b3dSmrg return; 258428d7b3dSmrg } 259428d7b3dSmrg 260428d7b3dSmrg shm.readOnly = False; 261428d7b3dSmrg 262428d7b3dSmrg shmref = shm; 263428d7b3dSmrg XShmAttach(t->ref.dpy, &shmref); 264428d7b3dSmrg XSync(t->ref.dpy, True); 265428d7b3dSmrg 266428d7b3dSmrg shmout = shm; 267428d7b3dSmrg XShmAttach(t->out.dpy, &shmout); 268428d7b3dSmrg XSync(t->out.dpy, True); 269428d7b3dSmrg} 270428d7b3dSmrg 271428d7b3dSmrgstatic Picture source_shm(struct test_display *t, struct test_target *target) 272428d7b3dSmrg{ 273428d7b3dSmrg XShmSegmentInfo *shm = t->target == REF ? &shmref : &shmout; 274428d7b3dSmrg Pixmap pixmap; 275428d7b3dSmrg Picture picture; 276428d7b3dSmrg int size; 277428d7b3dSmrg 278428d7b3dSmrg if (shm->shmid == -1) 279428d7b3dSmrg return 0; 280428d7b3dSmrg 281428d7b3dSmrg pixmap = XShmCreatePixmap(t->dpy, t->root, 282428d7b3dSmrg shm->shmaddr, shm, 283428d7b3dSmrg target->width, target->height, 32); 284428d7b3dSmrg 285428d7b3dSmrg picture = XRenderCreatePicture(t->dpy, pixmap, 286428d7b3dSmrg XRenderFindStandardFormat(t->dpy, 0), 287428d7b3dSmrg 0, NULL); 288428d7b3dSmrg XFreePixmap(t->dpy, pixmap); 289428d7b3dSmrg 290428d7b3dSmrg size = target->width * target->height * 4; 291428d7b3dSmrg memset(shm->shmaddr, 0x80, size/2); 292428d7b3dSmrg memset(shm->shmaddr+size/2, 0xff, size/2); 293428d7b3dSmrg 294428d7b3dSmrg return picture; 295428d7b3dSmrg} 296428d7b3dSmrg#else 297428d7b3dSmrgstatic void setup_shm(struct test *t) { } 298428d7b3dSmrgstatic Picture source_shm(struct test_display *t, struct test_target *target) { return 0; } 299428d7b3dSmrg#endif 300428d7b3dSmrg 301428d7b3dSmrgstatic const struct { 302428d7b3dSmrg Picture (*create)(struct test_display *, struct test_target *); 303428d7b3dSmrg const char *name; 304428d7b3dSmrg} source[] = { 305428d7b3dSmrg { source_a8r8g8b8, "a8r8g8b8 pixmap" }, 306428d7b3dSmrg { source_x8r8g8b8, "x8r8g8b8 pixmap" }, 307428d7b3dSmrg { source_a8, "a8 pixmap" }, 308428d7b3dSmrg { source_a4, "a4 pixmap" }, 309428d7b3dSmrg { source_a1, "a1 pixmap" }, 310428d7b3dSmrg { source_1x1r, "a8r8g8b8 1x1R pixmap" }, 311428d7b3dSmrg { source_solid, "solid" }, 312428d7b3dSmrg { source_shm, "a8r8g8b8 shm" }, 313428d7b3dSmrg { source_linear_horizontal, "linear (horizontal gradient)" }, 314428d7b3dSmrg { source_linear_vertical, "linear (vertical gradient)" }, 315428d7b3dSmrg { source_linear_diagonal, "linear (diagonal gradient)" }, 316428d7b3dSmrg { source_radial_concentric, "radial (concentric)" }, 317428d7b3dSmrg { source_radial_generic, "radial (generic)" }, 318428d7b3dSmrg}; 319428d7b3dSmrg 320428d7b3dSmrgstatic double _bench_source(struct test_display *t, enum target target_type, 321428d7b3dSmrg int op, int src, int loops) 322428d7b3dSmrg{ 323428d7b3dSmrg XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; 324428d7b3dSmrg struct test_target target; 325428d7b3dSmrg Picture picture; 326428d7b3dSmrg struct timespec tv; 327428d7b3dSmrg double elapsed; 328428d7b3dSmrg 329428d7b3dSmrg test_target_create_render(t, target_type, &target); 330428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, 331428d7b3dSmrg 0, 0, target.width, target.height); 332428d7b3dSmrg 333428d7b3dSmrg picture = source[src].create(t, &target); 334428d7b3dSmrg if (picture) { 335428d7b3dSmrg test_timer_start(t, &tv); 336428d7b3dSmrg while (loops--) 337428d7b3dSmrg XRenderComposite(t->dpy, op, 338428d7b3dSmrg picture, 0, target.picture, 339428d7b3dSmrg 0, 0, 340428d7b3dSmrg 0, 0, 341428d7b3dSmrg 0, 0, 342428d7b3dSmrg target.width, target.height); 343428d7b3dSmrg elapsed = test_timer_stop(t, &tv); 344428d7b3dSmrg XRenderFreePicture(t->dpy, picture); 345428d7b3dSmrg } else 346428d7b3dSmrg elapsed = -1; 347428d7b3dSmrg 348428d7b3dSmrg test_target_destroy_render(t, &target); 349428d7b3dSmrg 350428d7b3dSmrg return elapsed; 351428d7b3dSmrg} 352428d7b3dSmrg 353428d7b3dSmrgstatic void bench_source(struct test *t, enum target target, int op, int src) 354428d7b3dSmrg{ 355428d7b3dSmrg double out, ref; 356428d7b3dSmrg 357428d7b3dSmrg fprintf(stdout, "%28s with %s: ", source[src].name, ops[op].name); 358428d7b3dSmrg fflush(stdout); 359428d7b3dSmrg 360428d7b3dSmrg op = ops[op].value; 361428d7b3dSmrg 362428d7b3dSmrg ref = _bench_source(&t->ref, target, op, src, 1000); 363428d7b3dSmrg if (ref < 0) { 364428d7b3dSmrg fprintf(stdout, "SKIP\n"); 365428d7b3dSmrg return; 366428d7b3dSmrg } 367428d7b3dSmrg fprintf(stdout, "ref=%f, ", ref); 368428d7b3dSmrg fflush(stdout); 369428d7b3dSmrg 370428d7b3dSmrg out = _bench_source(&t->out, target, op, src, 1000); 371428d7b3dSmrg if (out < 0) { 372428d7b3dSmrg fprintf(stdout, "SKIP\n"); 373428d7b3dSmrg return; 374428d7b3dSmrg } 375428d7b3dSmrg 376428d7b3dSmrg fprintf(stdout, "out=%f\n", out); 377428d7b3dSmrg} 378428d7b3dSmrg 379428d7b3dSmrgstatic double _bench_mask(struct test_display *t, enum target target_type, 380428d7b3dSmrg int op, int src, int mask, int loops) 381428d7b3dSmrg{ 382428d7b3dSmrg XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; 383428d7b3dSmrg struct test_target target; 384428d7b3dSmrg Picture ps, pm; 385428d7b3dSmrg struct timespec tv; 386428d7b3dSmrg double elapsed; 387428d7b3dSmrg 388428d7b3dSmrg test_target_create_render(t, target_type, &target); 389428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, 390428d7b3dSmrg 0, 0, target.width, target.height); 391428d7b3dSmrg 392428d7b3dSmrg ps = source[src].create(t, &target); 393428d7b3dSmrg pm = source[mask].create(t, &target); 394428d7b3dSmrg if (ps && pm) { 395428d7b3dSmrg test_timer_start(t, &tv); 396428d7b3dSmrg while (loops--) 397428d7b3dSmrg XRenderComposite(t->dpy, op, 398428d7b3dSmrg ps, pm, target.picture, 399428d7b3dSmrg 0, 0, 400428d7b3dSmrg 0, 0, 401428d7b3dSmrg 0, 0, 402428d7b3dSmrg target.width, target.height); 403428d7b3dSmrg elapsed = test_timer_stop(t, &tv); 404428d7b3dSmrg } else 405428d7b3dSmrg elapsed = -1; 406428d7b3dSmrg 407428d7b3dSmrg if (ps) 408428d7b3dSmrg XRenderFreePicture(t->dpy, ps); 409428d7b3dSmrg if (pm) 410428d7b3dSmrg XRenderFreePicture(t->dpy, pm); 411428d7b3dSmrg 412428d7b3dSmrg test_target_destroy_render(t, &target); 413428d7b3dSmrg 414428d7b3dSmrg return elapsed; 415428d7b3dSmrg} 416428d7b3dSmrg 417428d7b3dSmrgstatic void bench_mask(struct test *t, enum target target, int op, int src, int mask) 418428d7b3dSmrg{ 419428d7b3dSmrg double out, ref; 420428d7b3dSmrg 421428d7b3dSmrg fprintf(stdout, "%28s In %28s with %s: ", 422428d7b3dSmrg source[src].name, source[mask].name, ops[op].name); 423428d7b3dSmrg fflush(stdout); 424428d7b3dSmrg 425428d7b3dSmrg op = ops[op].value; 426428d7b3dSmrg 427428d7b3dSmrg ref = _bench_mask(&t->ref, target, op, src, mask, 1000); 428428d7b3dSmrg if (ref < 0) { 429428d7b3dSmrg fprintf(stdout, "SKIP\n"); 430428d7b3dSmrg return; 431428d7b3dSmrg } 432428d7b3dSmrg fprintf(stdout, "ref=%f, ", ref); 433428d7b3dSmrg fflush(stdout); 434428d7b3dSmrg 435428d7b3dSmrg out = _bench_mask(&t->out, target, op, src, mask, 1000); 436428d7b3dSmrg if (out < 0) { 437428d7b3dSmrg fprintf(stdout, "SKIP\n"); 438428d7b3dSmrg return; 439428d7b3dSmrg } 440428d7b3dSmrg 441428d7b3dSmrg fprintf(stdout, "out=%f\n", out); 442428d7b3dSmrg} 443428d7b3dSmrg 444428d7b3dSmrgint main(int argc, char **argv) 445428d7b3dSmrg{ 446428d7b3dSmrg struct test test; 447428d7b3dSmrg unsigned op, src, mask; 448428d7b3dSmrg 449428d7b3dSmrg test_init(&test, argc, argv); 450428d7b3dSmrg 451428d7b3dSmrg setup_shm(&test); 452428d7b3dSmrg 453428d7b3dSmrg for (op = 0; op < sizeof(ops)/sizeof(ops[0]); op++) { 454428d7b3dSmrg for (src = 0; src < sizeof(source)/sizeof(source[0]); src++) 455428d7b3dSmrg bench_source(&test, ROOT, op, src); 456428d7b3dSmrg fprintf (stdout, "\n"); 457428d7b3dSmrg 458428d7b3dSmrg for (src = 0; src < sizeof(source)/sizeof(source[0]); src++) 459428d7b3dSmrg for (mask = 0; mask < sizeof(source)/sizeof(source[0]); mask++) 460428d7b3dSmrg bench_mask(&test, ROOT, op, src, mask); 461428d7b3dSmrg fprintf (stdout, "\n"); 462428d7b3dSmrg } 463428d7b3dSmrg 464428d7b3dSmrg return 0; 465428d7b3dSmrg} 466