1428d7b3dSmrg#include <stdint.h> 2428d7b3dSmrg#include <stdio.h> 3428d7b3dSmrg#include <stdlib.h> 4428d7b3dSmrg 5428d7b3dSmrg#include "test.h" 6428d7b3dSmrg 7428d7b3dSmrgstatic const unsigned char data[] = { 8428d7b3dSmrg 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 9428d7b3dSmrg 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 10428d7b3dSmrg 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 11428d7b3dSmrg 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 12428d7b3dSmrg}; 13428d7b3dSmrg 14428d7b3dSmrgstatic struct bitmap { 15428d7b3dSmrg int width, height; 16428d7b3dSmrg struct cache { 17428d7b3dSmrg Display *dpy; 18428d7b3dSmrg Pixmap pixmap; 19428d7b3dSmrg } cached[2]; 20428d7b3dSmrg} bitmaps[] = { 21428d7b3dSmrg { 1, 1, }, 22428d7b3dSmrg { 1, 2, }, 23428d7b3dSmrg { 2, 3, }, 24428d7b3dSmrg { 3, 2, }, 25428d7b3dSmrg { 4, 4, }, 26428d7b3dSmrg { 6, 6, }, 27428d7b3dSmrg { 8, 8, }, 28428d7b3dSmrg { 8, 4, }, 29428d7b3dSmrg { 8, 2, }, 30428d7b3dSmrg { 8, 1, }, 31428d7b3dSmrg { 4, 8, }, 32428d7b3dSmrg { 2, 8, }, 33428d7b3dSmrg { 1, 8, }, 34428d7b3dSmrg { 16, 16, }, 35428d7b3dSmrg { 15, 17, }, 36428d7b3dSmrg { 24, 24, }, 37428d7b3dSmrg { 32, 32, }, 38428d7b3dSmrg { 16, 8, }, 39428d7b3dSmrg { 16, 4, }, 40428d7b3dSmrg { 16, 2, }, 41428d7b3dSmrg { 16, 1, }, 42428d7b3dSmrg { 8, 16, }, 43428d7b3dSmrg { 4, 16, }, 44428d7b3dSmrg { 2, 16, }, 45428d7b3dSmrg { 1, 16, }, 46428d7b3dSmrg}; 47428d7b3dSmrg 48428d7b3dSmrgstatic void reset_cache(void) 49428d7b3dSmrg{ 50428d7b3dSmrg int n, m; 51428d7b3dSmrg 52428d7b3dSmrg for (n = 0; n < sizeof(bitmaps)/sizeof(bitmaps[0]); n++) { 53428d7b3dSmrg for (m = 0; m < 2; m++) { 54428d7b3dSmrg if (bitmaps[n].cached[m].dpy) { 55428d7b3dSmrg XFreePixmap(bitmaps[n].cached[m].dpy, bitmaps[n].cached[m].pixmap); 56428d7b3dSmrg bitmaps[n].cached[m].dpy = NULL; 57428d7b3dSmrg } 58428d7b3dSmrg } 59428d7b3dSmrg } 60428d7b3dSmrg} 61428d7b3dSmrg 62428d7b3dSmrgstatic void fill_rect(struct test_target *t, uint8_t alu, 63428d7b3dSmrg XRectangle *clip, int nclip, 64428d7b3dSmrg uint8_t tile, int tx, int ty, 65428d7b3dSmrg int x, int y, int w, int h, 66428d7b3dSmrg uint32_t fg, uint32_t bg) 67428d7b3dSmrg{ 68428d7b3dSmrg Display *dpy = t->dpy->dpy; 69428d7b3dSmrg struct bitmap *b = &bitmaps[(tile >> 1) % (sizeof(bitmaps)/sizeof(bitmaps[0]))]; 70428d7b3dSmrg XGCValues val; 71428d7b3dSmrg GC gc; 72428d7b3dSmrg int n; 73428d7b3dSmrg 74428d7b3dSmrg val.function = alu; 75428d7b3dSmrg val.function = GXcopy; 76428d7b3dSmrg val.fill_style = FillTiled; 77428d7b3dSmrg val.ts_x_origin = tx; 78428d7b3dSmrg val.ts_y_origin = ty; 79428d7b3dSmrg if (tile & 1) { 80428d7b3dSmrg val.tile = 0; 81428d7b3dSmrg for (n = 0; n < 2; n++) { 82428d7b3dSmrg if (b->cached[n].dpy == dpy) { 83428d7b3dSmrg val.tile = b->cached[n].pixmap; 84428d7b3dSmrg break; 85428d7b3dSmrg } 86428d7b3dSmrg } 87428d7b3dSmrg if (val.tile == 0) { 88428d7b3dSmrg val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, 89428d7b3dSmrg (char *)data, b->width, b->height, 90428d7b3dSmrg fg, bg, t->depth); 91428d7b3dSmrg for (n = 0; n < 2; n++) { 92428d7b3dSmrg if (b->cached[n].dpy == NULL) { 93428d7b3dSmrg b->cached[n].dpy = dpy; 94428d7b3dSmrg b->cached[n].pixmap = val.tile; 95428d7b3dSmrg break; 96428d7b3dSmrg } 97428d7b3dSmrg } 98428d7b3dSmrg } 99428d7b3dSmrg } else 100428d7b3dSmrg val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, 101428d7b3dSmrg (char *)data, b->width, b->height, 102428d7b3dSmrg fg, bg, t->depth); 103428d7b3dSmrg 104428d7b3dSmrg gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile | GCFunction, &val); 105428d7b3dSmrg if (nclip) 106428d7b3dSmrg XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted); 107428d7b3dSmrg XFillRectangle(dpy, t->draw, gc, x, y, w, h); 108428d7b3dSmrg XFreeGC(dpy, gc); 109428d7b3dSmrg if ((tile & 1) == 0) 110428d7b3dSmrg XFreePixmap(dpy, val.tile); 111428d7b3dSmrg} 112428d7b3dSmrg 113428d7b3dSmrgstatic void clear(struct test_target *tt) 114428d7b3dSmrg{ 115428d7b3dSmrg XRenderColor render_color = {0}; 116428d7b3dSmrg XRenderFillRectangle(tt->dpy->dpy, PictOpClear, tt->picture, &render_color, 117428d7b3dSmrg 0, 0, tt->width, tt->height); 118428d7b3dSmrg} 119428d7b3dSmrg 120428d7b3dSmrgstatic void small_tests(struct test *t, int reps, int sets, enum target target) 121428d7b3dSmrg{ 122428d7b3dSmrg struct test_target out, ref; 123428d7b3dSmrg int r, s; 124428d7b3dSmrg 125428d7b3dSmrg printf("Testing small tiled fills (%s): ", test_target_name(target)); 126428d7b3dSmrg fflush(stdout); 127428d7b3dSmrg 128428d7b3dSmrg test_target_create_render(&t->out, target, &out); 129428d7b3dSmrg clear(&out); 130428d7b3dSmrg 131428d7b3dSmrg test_target_create_render(&t->ref, target, &ref); 132428d7b3dSmrg clear(&ref); 133428d7b3dSmrg 134428d7b3dSmrg for (s = 0; s < sets; s++) { 135428d7b3dSmrg for (r = 0; r < reps; r++) { 136428d7b3dSmrg int x = rand() % out.width; 137428d7b3dSmrg int y = rand() % out.height; 138428d7b3dSmrg int w = rand() % out.width; 139428d7b3dSmrg int h = rand() % 8; 140428d7b3dSmrg int tx = rand() % (2*out.width) - out.width; 141428d7b3dSmrg int ty = rand() % (2*out.height) - out.height; 142428d7b3dSmrg uint8_t tile = rand(); 143428d7b3dSmrg uint8_t alu = rand() % (GXset + 1); 144428d7b3dSmrg uint32_t fg = rand(); 145428d7b3dSmrg uint32_t bg = rand(); 146428d7b3dSmrg 147428d7b3dSmrg fill_rect(&out, alu, NULL, 0, 148428d7b3dSmrg tile, tx, ty, 149428d7b3dSmrg x, y, w, h, 150428d7b3dSmrg fg, bg); 151428d7b3dSmrg fill_rect(&ref, alu, NULL, 0, 152428d7b3dSmrg tile, tx, ty, 153428d7b3dSmrg x, y, w, h, 154428d7b3dSmrg fg, bg); 155428d7b3dSmrg 156428d7b3dSmrg fill_rect(&out, alu, NULL, 0, 157428d7b3dSmrg tile, tx, ty, 158428d7b3dSmrg x, y, h, w, 159428d7b3dSmrg fg, bg); 160428d7b3dSmrg fill_rect(&ref, alu, NULL, 0, 161428d7b3dSmrg tile, tx, ty, 162428d7b3dSmrg x, y, h, w, 163428d7b3dSmrg fg, bg); 164428d7b3dSmrg } 165428d7b3dSmrg 166428d7b3dSmrg test_compare(t, 167428d7b3dSmrg out.draw, out.format, 168428d7b3dSmrg ref.draw, ref.format, 169428d7b3dSmrg 0, 0, out.width, out.height, 170428d7b3dSmrg ""); 171428d7b3dSmrg 172428d7b3dSmrg if (target == CHILD) { 173428d7b3dSmrg int x = rand() % (t->out.width-out.width); 174428d7b3dSmrg int y = rand() % (t->out.height-out.height); 175428d7b3dSmrg 176428d7b3dSmrg clear(&out); 177428d7b3dSmrg clear(&ref); 178428d7b3dSmrg 179428d7b3dSmrg XMoveWindow(out.dpy->dpy, out.draw, x, y); 180428d7b3dSmrg XMoveWindow(ref.dpy->dpy, ref.draw, x, y); 181428d7b3dSmrg 182428d7b3dSmrg clear(&out); 183428d7b3dSmrg clear(&ref); 184428d7b3dSmrg } 185428d7b3dSmrg } 186428d7b3dSmrg 187428d7b3dSmrg printf("passed [%d iterations x %d]\n", reps, sets); 188428d7b3dSmrg 189428d7b3dSmrg test_target_destroy_render(&t->out, &out); 190428d7b3dSmrg test_target_destroy_render(&t->ref, &ref); 191428d7b3dSmrg} 192428d7b3dSmrg 193428d7b3dSmrgstatic void unclipped_tests(struct test *t, int reps, int sets, enum target target) 194428d7b3dSmrg{ 195428d7b3dSmrg struct test_target out, ref; 196428d7b3dSmrg int r, s; 197428d7b3dSmrg 198428d7b3dSmrg printf("Testing unclipped tiled fills (%s): ", test_target_name(target)); 199428d7b3dSmrg fflush(stdout); 200428d7b3dSmrg 201428d7b3dSmrg test_target_create_render(&t->out, target, &out); 202428d7b3dSmrg clear(&out); 203428d7b3dSmrg 204428d7b3dSmrg test_target_create_render(&t->ref, target, &ref); 205428d7b3dSmrg clear(&ref); 206428d7b3dSmrg 207428d7b3dSmrg for (s = 0; s < sets; s++) { 208428d7b3dSmrg for (r = 0; r < reps; r++) { 209428d7b3dSmrg int x = rand() % out.width; 210428d7b3dSmrg int y = rand() % out.height; 211428d7b3dSmrg int w = rand() % (out.width - x); 212428d7b3dSmrg int h = rand() % (out.height - y); 213428d7b3dSmrg int tx = rand() % (2*out.width) - out.width; 214428d7b3dSmrg int ty = rand() % (2*out.height) - out.height; 215428d7b3dSmrg uint8_t tile = rand(); 216428d7b3dSmrg uint8_t alu = rand() % (GXset + 1); 217428d7b3dSmrg uint32_t fg = rand(); 218428d7b3dSmrg uint32_t bg = rand(); 219428d7b3dSmrg 220428d7b3dSmrg fill_rect(&out, alu, NULL, 0, 221428d7b3dSmrg tile, tx, ty, 222428d7b3dSmrg x, y, w, h, 223428d7b3dSmrg fg, bg); 224428d7b3dSmrg fill_rect(&ref, alu, NULL, 0, 225428d7b3dSmrg tile, tx, ty, 226428d7b3dSmrg x, y, w, h, 227428d7b3dSmrg fg, bg); 228428d7b3dSmrg } 229428d7b3dSmrg 230428d7b3dSmrg test_compare(t, 231428d7b3dSmrg out.draw, out.format, 232428d7b3dSmrg ref.draw, ref.format, 233428d7b3dSmrg 0, 0, out.width, out.height, 234428d7b3dSmrg ""); 235428d7b3dSmrg 236428d7b3dSmrg if (target == CHILD) { 237428d7b3dSmrg int x = rand() % (t->out.width-out.width); 238428d7b3dSmrg int y = rand() % (t->out.height-out.height); 239428d7b3dSmrg 240428d7b3dSmrg clear(&out); 241428d7b3dSmrg clear(&ref); 242428d7b3dSmrg 243428d7b3dSmrg XMoveWindow(out.dpy->dpy, out.draw, x, y); 244428d7b3dSmrg XMoveWindow(ref.dpy->dpy, ref.draw, x, y); 245428d7b3dSmrg 246428d7b3dSmrg clear(&out); 247428d7b3dSmrg clear(&ref); 248428d7b3dSmrg } 249428d7b3dSmrg } 250428d7b3dSmrg 251428d7b3dSmrg printf("passed [%d iterations x %d]\n", reps, sets); 252428d7b3dSmrg 253428d7b3dSmrg test_target_destroy_render(&t->out, &out); 254428d7b3dSmrg test_target_destroy_render(&t->ref, &ref); 255428d7b3dSmrg} 256428d7b3dSmrg 257428d7b3dSmrgstatic void simple_clip_tests(struct test *t, int reps, int sets, enum target target) 258428d7b3dSmrg{ 259428d7b3dSmrg struct test_target out, ref; 260428d7b3dSmrg int r, s; 261428d7b3dSmrg 262428d7b3dSmrg printf("Testing simple clipped tiled fills (%s): ", test_target_name(target)); 263428d7b3dSmrg fflush(stdout); 264428d7b3dSmrg 265428d7b3dSmrg test_target_create_render(&t->out, target, &out); 266428d7b3dSmrg clear(&out); 267428d7b3dSmrg 268428d7b3dSmrg test_target_create_render(&t->ref, target, &ref); 269428d7b3dSmrg clear(&ref); 270428d7b3dSmrg 271428d7b3dSmrg for (s = 0; s < sets; s++) { 272428d7b3dSmrg for (r = 0; r < reps; r++) { 273428d7b3dSmrg int x = rand() % (2*out.width) - out.width; 274428d7b3dSmrg int y = rand() % (2*out.height) - out.height; 275428d7b3dSmrg int w = rand() % (2*out.width); 276428d7b3dSmrg int h = rand() % (2*out.height); 277428d7b3dSmrg int tx = rand() % (2*out.width) - out.width; 278428d7b3dSmrg int ty = rand() % (2*out.height) - out.height; 279428d7b3dSmrg uint8_t tile = rand(); 280428d7b3dSmrg uint8_t alu = rand() % (GXset + 1); 281428d7b3dSmrg uint32_t fg = rand(); 282428d7b3dSmrg uint32_t bg = rand(); 283428d7b3dSmrg 284428d7b3dSmrg fill_rect(&out, alu, NULL, 0, 285428d7b3dSmrg tile, tx, ty, 286428d7b3dSmrg x, y, w, h, 287428d7b3dSmrg fg, bg); 288428d7b3dSmrg fill_rect(&ref, alu, NULL, 0, 289428d7b3dSmrg tile, tx, ty, 290428d7b3dSmrg x, y, w, h, 291428d7b3dSmrg fg, bg); 292428d7b3dSmrg } 293428d7b3dSmrg 294428d7b3dSmrg test_compare(t, 295428d7b3dSmrg out.draw, out.format, 296428d7b3dSmrg ref.draw, ref.format, 297428d7b3dSmrg 0, 0, out.width, out.height, 298428d7b3dSmrg ""); 299428d7b3dSmrg 300428d7b3dSmrg if (target == CHILD) { 301428d7b3dSmrg int x = rand() % (t->out.width-out.width); 302428d7b3dSmrg int y = rand() % (t->out.height-out.height); 303428d7b3dSmrg 304428d7b3dSmrg clear(&out); 305428d7b3dSmrg clear(&ref); 306428d7b3dSmrg 307428d7b3dSmrg XMoveWindow(out.dpy->dpy, out.draw, x, y); 308428d7b3dSmrg XMoveWindow(ref.dpy->dpy, ref.draw, x, y); 309428d7b3dSmrg 310428d7b3dSmrg clear(&out); 311428d7b3dSmrg clear(&ref); 312428d7b3dSmrg } 313428d7b3dSmrg } 314428d7b3dSmrg 315428d7b3dSmrg printf("passed [%d iterations x %d]\n", reps, sets); 316428d7b3dSmrg 317428d7b3dSmrg test_target_destroy_render(&t->out, &out); 318428d7b3dSmrg test_target_destroy_render(&t->ref, &ref); 319428d7b3dSmrg} 320428d7b3dSmrg 321428d7b3dSmrgstatic void complex_clip_tests(struct test *t, int reps, int sets, enum target target) 322428d7b3dSmrg{ 323428d7b3dSmrg struct test_target out, ref; 324428d7b3dSmrg XRectangle *clip; 325428d7b3dSmrg int nclip, r, s; 326428d7b3dSmrg 327428d7b3dSmrg printf("Testing complex clipped tiled fills (%s): ", test_target_name(target)); 328428d7b3dSmrg fflush(stdout); 329428d7b3dSmrg 330428d7b3dSmrg test_target_create_render(&t->out, target, &out); 331428d7b3dSmrg clear(&out); 332428d7b3dSmrg 333428d7b3dSmrg test_target_create_render(&t->ref, target, &ref); 334428d7b3dSmrg clear(&ref); 335428d7b3dSmrg 336428d7b3dSmrg for (s = 0; s < sets; s++) { 337428d7b3dSmrg nclip = (rand() % 16) + 2; 338428d7b3dSmrg clip = malloc(sizeof(XRectangle)*nclip); 339428d7b3dSmrg for (r = 0; r < nclip; r++) { 340428d7b3dSmrg clip[r].x = rand() % out.width; 341428d7b3dSmrg clip[r].y = rand() % out.height; 342428d7b3dSmrg clip[r].width = rand() % (out.width - clip[r].x); 343428d7b3dSmrg clip[r].height = rand() % (out.height - clip[r].y); 344428d7b3dSmrg } 345428d7b3dSmrg 346428d7b3dSmrg for (r = 0; r < reps; r++) { 347428d7b3dSmrg int x = rand() % (2*out.width) - out.width; 348428d7b3dSmrg int y = rand() % (2*out.height) - out.height; 349428d7b3dSmrg int w = rand() % (2*out.width); 350428d7b3dSmrg int h = rand() % (2*out.height); 351428d7b3dSmrg int tx = rand() % (2*out.width) - out.width; 352428d7b3dSmrg int ty = rand() % (2*out.height) - out.height; 353428d7b3dSmrg uint8_t tile = rand(); 354428d7b3dSmrg uint8_t alu = rand() % (GXset + 1); 355428d7b3dSmrg uint32_t fg = rand(); 356428d7b3dSmrg uint32_t bg = rand(); 357428d7b3dSmrg 358428d7b3dSmrg fill_rect(&out, alu, clip, nclip, 359428d7b3dSmrg tile, tx, ty, 360428d7b3dSmrg x, y, w, h, 361428d7b3dSmrg fg, bg); 362428d7b3dSmrg fill_rect(&ref, alu, clip, nclip, 363428d7b3dSmrg tile, tx, ty, 364428d7b3dSmrg x, y, w, h, 365428d7b3dSmrg fg, bg); 366428d7b3dSmrg } 367428d7b3dSmrg 368428d7b3dSmrg test_compare(t, 369428d7b3dSmrg out.draw, out.format, 370428d7b3dSmrg ref.draw, ref.format, 371428d7b3dSmrg 0, 0, out.width, out.height, 372428d7b3dSmrg ""); 373428d7b3dSmrg 374428d7b3dSmrg free(clip); 375428d7b3dSmrg 376428d7b3dSmrg if (target == CHILD) { 377428d7b3dSmrg int x = rand() % (t->out.width-out.width); 378428d7b3dSmrg int y = rand() % (t->out.height-out.height); 379428d7b3dSmrg 380428d7b3dSmrg clear(&out); 381428d7b3dSmrg clear(&ref); 382428d7b3dSmrg 383428d7b3dSmrg XMoveWindow(out.dpy->dpy, out.draw, x, y); 384428d7b3dSmrg XMoveWindow(ref.dpy->dpy, ref.draw, x, y); 385428d7b3dSmrg 386428d7b3dSmrg clear(&out); 387428d7b3dSmrg clear(&ref); 388428d7b3dSmrg } 389428d7b3dSmrg } 390428d7b3dSmrg 391428d7b3dSmrg printf("passed [%d iterations x %d]\n", reps, sets); 392428d7b3dSmrg 393428d7b3dSmrg test_target_destroy_render(&t->out, &out); 394428d7b3dSmrg test_target_destroy_render(&t->ref, &ref); 395428d7b3dSmrg} 396428d7b3dSmrg 397428d7b3dSmrgint main(int argc, char **argv) 398428d7b3dSmrg{ 399428d7b3dSmrg struct test test; 400428d7b3dSmrg int i; 401428d7b3dSmrg 402428d7b3dSmrg test_init(&test, argc, argv); 403428d7b3dSmrg 404428d7b3dSmrg for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 405428d7b3dSmrg int reps = REPS(i), sets = SETS(i); 406428d7b3dSmrg enum target t; 407428d7b3dSmrg 408428d7b3dSmrg for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { 409428d7b3dSmrg small_tests(&test, reps, sets, t); 410428d7b3dSmrg unclipped_tests(&test, reps, sets, t); 411428d7b3dSmrg simple_clip_tests(&test, reps, sets, t); 412428d7b3dSmrg complex_clip_tests(&test, reps, sets, t); 413428d7b3dSmrg reset_cache(); 414428d7b3dSmrg } 415428d7b3dSmrg } 416428d7b3dSmrg 417428d7b3dSmrg return 0; 418428d7b3dSmrg} 419