1428d7b3dSmrg#include <stdint.h> 2428d7b3dSmrg#include <stdio.h> 3428d7b3dSmrg#include <stdlib.h> 4428d7b3dSmrg 5428d7b3dSmrg#include <X11/Xutil.h> /* for XDestroyImage */ 6428d7b3dSmrg 7428d7b3dSmrg#include "test.h" 8428d7b3dSmrg 9428d7b3dSmrgstatic void fill_rect(struct test_display *t, 10428d7b3dSmrg Picture p, 11428d7b3dSmrg XRenderPictFormat *format, 12428d7b3dSmrg int use_window, int tx, int ty, 13428d7b3dSmrg uint8_t op, int x, int y, int w, int h, 14428d7b3dSmrg int mask_x, int mask_y, int mask_w, int mask_h, 15428d7b3dSmrg uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 16428d7b3dSmrg{ 17428d7b3dSmrg Drawable tmp; 18428d7b3dSmrg Pixmap pixmask; 19428d7b3dSmrg XRenderColor c; 20428d7b3dSmrg Picture src, mask; 21428d7b3dSmrg 22428d7b3dSmrg if (use_window) { 23428d7b3dSmrg XSetWindowAttributes attr; 24428d7b3dSmrg 25428d7b3dSmrg attr.override_redirect = 1; 26428d7b3dSmrg tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), 27428d7b3dSmrg tx, ty, 28428d7b3dSmrg w, h, 29428d7b3dSmrg 0, format->depth, 30428d7b3dSmrg InputOutput, 31428d7b3dSmrg DefaultVisual(t->dpy, 32428d7b3dSmrg DefaultScreen(t->dpy)), 33428d7b3dSmrg CWOverrideRedirect, &attr); 34428d7b3dSmrg XMapWindow(t->dpy, tmp); 35428d7b3dSmrg } else 36428d7b3dSmrg tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), 37428d7b3dSmrg w, h, format->depth); 38428d7b3dSmrg 39428d7b3dSmrg pixmask = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, 8); 40428d7b3dSmrg mask = XRenderCreatePicture(t->dpy, pixmask, 41428d7b3dSmrg XRenderFindStandardFormat(t->dpy, PictStandardA8), 42428d7b3dSmrg 0, NULL); 43428d7b3dSmrg c.red = c.green = c.blue = c.alpha = 0; 44428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c, 45428d7b3dSmrg 0, 0, w, h); 46428d7b3dSmrg c.red = c.green = c.blue = c.alpha = 0xffff; 47428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c, 48428d7b3dSmrg mask_x, mask_y, mask_w, mask_h); 49428d7b3dSmrg 50428d7b3dSmrg src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); 51428d7b3dSmrg c.red = red * alpha; 52428d7b3dSmrg c.green = green * alpha; 53428d7b3dSmrg c.blue = blue * alpha; 54428d7b3dSmrg c.alpha = alpha << 8 | alpha; 55428d7b3dSmrg XRenderFillRectangle(t->dpy, PictOpSrc, src, &c, 0, 0, w, h); 56428d7b3dSmrg 57428d7b3dSmrg XRenderComposite(t->dpy, op, src, mask, p, 0, 0, 0, 0, x, y, w, h); 58428d7b3dSmrg 59428d7b3dSmrg XRenderFreePicture(t->dpy, src); 60428d7b3dSmrg if (use_window) 61428d7b3dSmrg XDestroyWindow(t->dpy, tmp); 62428d7b3dSmrg else 63428d7b3dSmrg XFreePixmap(t->dpy, tmp); 64428d7b3dSmrg 65428d7b3dSmrg XRenderFreePicture(t->dpy, mask); 66428d7b3dSmrg XFreePixmap(t->dpy, pixmask); 67428d7b3dSmrg} 68428d7b3dSmrg 69428d7b3dSmrgstatic void clear(struct test_display *dpy, struct test_target *tt) 70428d7b3dSmrg{ 71428d7b3dSmrg XRenderColor render_color = {0}; 72428d7b3dSmrg XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 73428d7b3dSmrg 0, 0, tt->width, tt->height); 74428d7b3dSmrg} 75428d7b3dSmrg 76428d7b3dSmrgstatic void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window) 77428d7b3dSmrg{ 78428d7b3dSmrg struct test_target out, ref; 79428d7b3dSmrg int r, s; 80428d7b3dSmrg printf("Testing area fills (%s, using %s source): ", 81428d7b3dSmrg test_target_name(target), use_window ? "window" : "pixmap"); 82428d7b3dSmrg fflush(stdout); 83428d7b3dSmrg 84428d7b3dSmrg test_target_create_render(&t->out, target, &out); 85428d7b3dSmrg clear(&t->out, &out); 86428d7b3dSmrg 87428d7b3dSmrg test_target_create_render(&t->ref, target, &ref); 88428d7b3dSmrg clear(&t->ref, &ref); 89428d7b3dSmrg 90428d7b3dSmrg for (s = 0; s < sets; s++) { 91428d7b3dSmrg for (r = 0; r < reps; r++) { 92428d7b3dSmrg int x, y, w, h; 93428d7b3dSmrg int mask_x, mask_y, mask_w, mask_h; 94428d7b3dSmrg int tmpx, tmpy; 95428d7b3dSmrg uint8_t red = rand(); 96428d7b3dSmrg uint8_t green = rand(); 97428d7b3dSmrg uint8_t blue = rand(); 98428d7b3dSmrg uint8_t alpha = rand(); 99428d7b3dSmrg int try = 50; 100428d7b3dSmrg 101428d7b3dSmrg do { 102428d7b3dSmrg x = rand() % (out.width - 1); 103428d7b3dSmrg y = rand() % (out.height - 1); 104428d7b3dSmrg w = 1 + rand() % (out.width - x - 1); 105428d7b3dSmrg h = 1 + rand() % (out.height - y - 1); 106428d7b3dSmrg tmpx = w == out.width ? 0 : rand() % (out.width - w); 107428d7b3dSmrg tmpy = h == out.height ? 0 : rand() % (out.height - h); 108428d7b3dSmrg } while (((tmpx+w > x && tmpx < x+w) || 109428d7b3dSmrg (tmpy+h > y && tmpy < y+h)) && 110428d7b3dSmrg --try); 111428d7b3dSmrg 112428d7b3dSmrg mask_x = (rand() % (2*w)) - w; 113428d7b3dSmrg mask_y = (rand() % (2*h)) - h; 114428d7b3dSmrg mask_w = rand() % w; 115428d7b3dSmrg mask_h = rand() % h; 116428d7b3dSmrg 117428d7b3dSmrg if (try) { 118428d7b3dSmrg fill_rect(&t->out, out.picture, out.format, 119428d7b3dSmrg use_window, tmpx, tmpy, 120428d7b3dSmrg PictOpSrc, x, y, w, h, 121428d7b3dSmrg mask_x, mask_y, mask_w, mask_h, 122428d7b3dSmrg red, green, blue, alpha); 123428d7b3dSmrg fill_rect(&t->ref, ref.picture, ref.format, 124428d7b3dSmrg use_window, tmpx, tmpy, 125428d7b3dSmrg PictOpSrc, x, y, w, h, 126428d7b3dSmrg mask_x, mask_y, mask_w, mask_h, 127428d7b3dSmrg red, green, blue, alpha); 128428d7b3dSmrg } 129428d7b3dSmrg } 130428d7b3dSmrg 131428d7b3dSmrg test_compare(t, 132428d7b3dSmrg out.draw, out.format, 133428d7b3dSmrg ref.draw, ref.format, 134428d7b3dSmrg 0, 0, out.width, out.height, 135428d7b3dSmrg ""); 136428d7b3dSmrg } 137428d7b3dSmrg 138428d7b3dSmrg printf("passed [%d iterations x %d]\n", reps, sets); 139428d7b3dSmrg 140428d7b3dSmrg test_target_destroy_render(&t->out, &out); 141428d7b3dSmrg test_target_destroy_render(&t->ref, &ref); 142428d7b3dSmrg} 143428d7b3dSmrg 144428d7b3dSmrgint main(int argc, char **argv) 145428d7b3dSmrg{ 146428d7b3dSmrg struct test test; 147428d7b3dSmrg int i; 148428d7b3dSmrg 149428d7b3dSmrg test_init(&test, argc, argv); 150428d7b3dSmrg 151428d7b3dSmrg for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 152428d7b3dSmrg int reps = REPS(i), sets = SETS(i); 153428d7b3dSmrg enum target t; 154428d7b3dSmrg 155428d7b3dSmrg for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { 156428d7b3dSmrg rect_tests(&test, reps, sets, t, 0); 157428d7b3dSmrg if (t != PIXMAP) 158428d7b3dSmrg rect_tests(&test, reps, sets, t, 1); 159428d7b3dSmrg } 160428d7b3dSmrg } 161428d7b3dSmrg 162428d7b3dSmrg return 0; 163428d7b3dSmrg} 164