1428d7b3dSmrg#include <stdint.h> 2428d7b3dSmrg#include <stdio.h> 3428d7b3dSmrg#include <stdlib.h> 4428d7b3dSmrg 5428d7b3dSmrg#include <X11/Xutil.h> /* for XDestroyImage */ 6428d7b3dSmrg#include <pixman.h> 7428d7b3dSmrg 8428d7b3dSmrg#include "test.h" 9428d7b3dSmrg 10428d7b3dSmrgstatic void _render_copy(struct test_target *tt, 11428d7b3dSmrg int x, int y, int w, int h, 12428d7b3dSmrg uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 13428d7b3dSmrg{ 14428d7b3dSmrg XRenderColor color; 15428d7b3dSmrg Picture src; 16428d7b3dSmrg Pixmap tmp; 17428d7b3dSmrg 18428d7b3dSmrg tmp = XCreatePixmap(tt->dpy->dpy, DefaultRootWindow(tt->dpy->dpy), 19428d7b3dSmrg 10+w, 20+h, tt->format->depth); 20428d7b3dSmrg src = XRenderCreatePicture(tt->dpy->dpy, tmp, tt->format, 0, NULL); 21428d7b3dSmrg 22428d7b3dSmrg /* magenta border */ 23428d7b3dSmrg color.red = 0xffff; 24428d7b3dSmrg color.green = 0; 25428d7b3dSmrg color.blue = 0xffff; 26428d7b3dSmrg color.alpha = 0xffff; 27428d7b3dSmrg XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 0, 0, w+10, h+20); 28428d7b3dSmrg 29428d7b3dSmrg color.red = red * alpha; 30428d7b3dSmrg color.green = green * alpha; 31428d7b3dSmrg color.blue = blue * alpha; 32428d7b3dSmrg color.alpha = alpha << 8 | alpha; 33428d7b3dSmrg XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 5, 10, w, h); 34428d7b3dSmrg 35428d7b3dSmrg XRenderComposite(tt->dpy->dpy, PictOpSrc, 36428d7b3dSmrg src, 0, tt->picture, 37428d7b3dSmrg 5, 10, 38428d7b3dSmrg 0, 0, 39428d7b3dSmrg x, y, 40428d7b3dSmrg w, h); 41428d7b3dSmrg 42428d7b3dSmrg XRenderFreePicture(tt->dpy->dpy, src); 43428d7b3dSmrg XFreePixmap(tt->dpy->dpy, tmp); 44428d7b3dSmrg} 45428d7b3dSmrg 46428d7b3dSmrgstatic void render_copy(struct test_target *out, 47428d7b3dSmrg struct test_target *ref) 48428d7b3dSmrg{ 49428d7b3dSmrg int x = rand() % (2*out->width) - out->width; 50428d7b3dSmrg int y = rand() % (2*out->height) - out->height; 51428d7b3dSmrg int w = rand() % (2*out->width); 52428d7b3dSmrg int h = rand() % (2*out->height); 53428d7b3dSmrg int red = rand() & 0xff; 54428d7b3dSmrg int green = rand() & 0xff; 55428d7b3dSmrg int blue = rand() & 0xff; 56428d7b3dSmrg int alpha = rand() & 0xff; 57428d7b3dSmrg 58428d7b3dSmrg _render_copy(out, x, y, w, h, red, green, blue, alpha); 59428d7b3dSmrg _render_copy(ref, x, y, w, h, red, green, blue, alpha); 60428d7b3dSmrg} 61428d7b3dSmrg 62428d7b3dSmrgstatic void fill_rect(struct test_target *tt, 63428d7b3dSmrg int alu, int color, 64428d7b3dSmrg int x, int y, int w, int h) 65428d7b3dSmrg{ 66428d7b3dSmrg XGCValues val; 67428d7b3dSmrg 68428d7b3dSmrg val.function = alu; 69428d7b3dSmrg val.foreground = color; 70428d7b3dSmrg XChangeGC(tt->dpy->dpy, tt->gc, GCFunction | GCForeground, &val); 71428d7b3dSmrg 72428d7b3dSmrg XFillRectangle(tt->dpy->dpy, tt->draw, tt->gc, x, y, w, h); 73428d7b3dSmrg} 74428d7b3dSmrg 75428d7b3dSmrgstatic void clear(struct test_target *tt) 76428d7b3dSmrg{ 77428d7b3dSmrg fill_rect(tt, 78428d7b3dSmrg GXcopy, 0, 79428d7b3dSmrg 0, 0, tt->width, tt->height); 80428d7b3dSmrg} 81428d7b3dSmrg 82428d7b3dSmrgstatic void basic_fill(struct test_target *out, 83428d7b3dSmrg struct test_target *ref) 84428d7b3dSmrg{ 85428d7b3dSmrg int x = rand() % (2*out->width) - out->width; 86428d7b3dSmrg int y = rand() % (2*out->height) - out->height; 87428d7b3dSmrg int w = rand() % (2*out->width); 88428d7b3dSmrg int h = rand() % (2*out->height); 89428d7b3dSmrg int color = rand(); 90428d7b3dSmrg int alu = rand() % 16; 91428d7b3dSmrg 92428d7b3dSmrg fill_rect(out, alu, color, x, y, w, h); 93428d7b3dSmrg fill_rect(ref, alu, color, x, y, w, h); 94428d7b3dSmrg} 95428d7b3dSmrg 96428d7b3dSmrgstatic void basic_copy(struct test_target *out, 97428d7b3dSmrg struct test_target *ref) 98428d7b3dSmrg{ 99428d7b3dSmrg int sx = rand() % (2*out->width) - ref->width; 100428d7b3dSmrg int sy = rand() % (2*out->height) - ref->height; 101428d7b3dSmrg int dx = rand() % (2*out->width) - ref->width; 102428d7b3dSmrg int dy = rand() % (2*out->height) - ref->height; 103428d7b3dSmrg int w = rand() % (2*out->width); 104428d7b3dSmrg int h = rand() % (2*out->height); 105428d7b3dSmrg XGCValues val; 106428d7b3dSmrg 107428d7b3dSmrg val.function = rand() % 16; 108428d7b3dSmrg 109428d7b3dSmrg XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val); 110428d7b3dSmrg XCopyArea(out->dpy->dpy, 111428d7b3dSmrg out->draw, out->draw, out->gc, 112428d7b3dSmrg sx, sy, w, h, dx, dy); 113428d7b3dSmrg 114428d7b3dSmrg XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val); 115428d7b3dSmrg XCopyArea(ref->dpy->dpy, 116428d7b3dSmrg ref->draw, ref->draw, ref->gc, 117428d7b3dSmrg sx, sy, w, h, dx, dy); 118428d7b3dSmrg} 119428d7b3dSmrg 120428d7b3dSmrgstatic void _put(struct test_target *tt, 121428d7b3dSmrg int x, int y, int w,int h, int color, int alu) 122428d7b3dSmrg{ 123428d7b3dSmrg XImage image; 124428d7b3dSmrg XGCValues val; 125428d7b3dSmrg 126428d7b3dSmrg val.function = alu; 127428d7b3dSmrg 128428d7b3dSmrg test_init_image(&image, &tt->dpy->shm, tt->format, w, h); 129428d7b3dSmrg pixman_fill((uint32_t*)image.data, 130428d7b3dSmrg image.bytes_per_line/sizeof(uint32_t), 131428d7b3dSmrg image.bits_per_pixel, 132428d7b3dSmrg 0, 0, w, h, color); 133428d7b3dSmrg 134428d7b3dSmrg XChangeGC(tt->dpy->dpy, tt->gc, GCFunction, &val); 135428d7b3dSmrg if (rand() & 1) { 136428d7b3dSmrg XShmPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 137428d7b3dSmrg 0, 0, x, y, w, h, 0); 138428d7b3dSmrg XSync(tt->dpy->dpy, 1); 139428d7b3dSmrg } else { 140428d7b3dSmrg XPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 141428d7b3dSmrg 0, 0, x, y, w, h); 142428d7b3dSmrg } 143428d7b3dSmrg} 144428d7b3dSmrg 145428d7b3dSmrgstatic void basic_put(struct test_target *out, 146428d7b3dSmrg struct test_target *ref) 147428d7b3dSmrg{ 148428d7b3dSmrg int x = rand() % (2*out->width) - out->width; 149428d7b3dSmrg int y = rand() % (2*out->height) - out->height; 150428d7b3dSmrg int w = rand() % out->width; 151428d7b3dSmrg int h = rand() % out->height; 152428d7b3dSmrg int color = rand(); 153428d7b3dSmrg int alu = rand() % 16; 154428d7b3dSmrg 155428d7b3dSmrg _put(out, x, y, w, h, color, alu); 156428d7b3dSmrg _put(ref, x, y, w, h, color, alu); 157428d7b3dSmrg} 158428d7b3dSmrg 159428d7b3dSmrgstatic void rect_tests(struct test *test, int iterations, enum target target) 160428d7b3dSmrg{ 161428d7b3dSmrg struct test_target out, ref; 162428d7b3dSmrg void (* const ops[])(struct test_target *, struct test_target *) = { 163428d7b3dSmrg basic_copy, 164428d7b3dSmrg basic_fill, 165428d7b3dSmrg basic_put, 166428d7b3dSmrg render_copy, 167428d7b3dSmrg }; 168428d7b3dSmrg int n; 169428d7b3dSmrg 170428d7b3dSmrg printf("Running mixed ops stress against %s: ", 171428d7b3dSmrg test_target_name(target)); 172428d7b3dSmrg fflush(stdout); 173428d7b3dSmrg 174428d7b3dSmrg test_target_create_render(&test->out, target, &out); 175428d7b3dSmrg test_target_create_render(&test->ref, target, &ref); 176428d7b3dSmrg 177428d7b3dSmrg clear(&out); 178428d7b3dSmrg clear(&ref); 179428d7b3dSmrg 180428d7b3dSmrg for (n = 0; n < iterations; n++) 181428d7b3dSmrg ops[rand() % ARRAY_SIZE(ops)](&out, &ref); 182428d7b3dSmrg 183428d7b3dSmrg test_compare(test, 184428d7b3dSmrg out.draw, out.format, 185428d7b3dSmrg ref.draw, ref.format, 186428d7b3dSmrg 0, 0, out.width, out.height, 187428d7b3dSmrg ""); 188428d7b3dSmrg 189428d7b3dSmrg printf("passed [%d iterations]\n", n); 190428d7b3dSmrg 191428d7b3dSmrg test_target_destroy_render(&test->out, &out); 192428d7b3dSmrg test_target_destroy_render(&test->ref, &ref); 193428d7b3dSmrg} 194428d7b3dSmrg 195428d7b3dSmrgint main(int argc, char **argv) 196428d7b3dSmrg{ 197428d7b3dSmrg struct test test; 198428d7b3dSmrg int i; 199428d7b3dSmrg 200428d7b3dSmrg test_init(&test, argc, argv); 201428d7b3dSmrg 202428d7b3dSmrg for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 203428d7b3dSmrg int iterations = REPS(i); 204428d7b3dSmrg rect_tests(&test, iterations, 0); 205428d7b3dSmrg rect_tests(&test, iterations, 1); 206428d7b3dSmrg } 207428d7b3dSmrg 208428d7b3dSmrg return 0; 209428d7b3dSmrg} 210