1#include <stdint.h> 2#include <stdio.h> 3#include <stdlib.h> 4 5#include <X11/Xutil.h> /* for XDestroyImage */ 6#include <pixman.h> 7 8#include "test.h" 9 10static void _render_copy(struct test_target *tt, 11 int x, int y, int w, int h, 12 uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 13{ 14 XRenderColor color; 15 Picture src; 16 Pixmap tmp; 17 18 tmp = XCreatePixmap(tt->dpy->dpy, DefaultRootWindow(tt->dpy->dpy), 19 10+w, 20+h, tt->format->depth); 20 src = XRenderCreatePicture(tt->dpy->dpy, tmp, tt->format, 0, NULL); 21 22 /* magenta border */ 23 color.red = 0xffff; 24 color.green = 0; 25 color.blue = 0xffff; 26 color.alpha = 0xffff; 27 XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 0, 0, w+10, h+20); 28 29 color.red = red * alpha; 30 color.green = green * alpha; 31 color.blue = blue * alpha; 32 color.alpha = alpha << 8 | alpha; 33 XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 5, 10, w, h); 34 35 XRenderComposite(tt->dpy->dpy, PictOpSrc, 36 src, 0, tt->picture, 37 5, 10, 38 0, 0, 39 x, y, 40 w, h); 41 42 XRenderFreePicture(tt->dpy->dpy, src); 43 XFreePixmap(tt->dpy->dpy, tmp); 44} 45 46static void render_copy(struct test_target *out, 47 struct test_target *ref) 48{ 49 int x = rand() % (2*out->width) - out->width; 50 int y = rand() % (2*out->height) - out->height; 51 int w = rand() % (2*out->width); 52 int h = rand() % (2*out->height); 53 int red = rand() & 0xff; 54 int green = rand() & 0xff; 55 int blue = rand() & 0xff; 56 int alpha = rand() & 0xff; 57 58 _render_copy(out, x, y, w, h, red, green, blue, alpha); 59 _render_copy(ref, x, y, w, h, red, green, blue, alpha); 60} 61 62static void fill_rect(struct test_target *tt, 63 int alu, int color, 64 int x, int y, int w, int h) 65{ 66 XGCValues val; 67 68 val.function = alu; 69 val.foreground = color; 70 XChangeGC(tt->dpy->dpy, tt->gc, GCFunction | GCForeground, &val); 71 72 XFillRectangle(tt->dpy->dpy, tt->draw, tt->gc, x, y, w, h); 73} 74 75static void clear(struct test_target *tt) 76{ 77 fill_rect(tt, 78 GXcopy, 0, 79 0, 0, tt->width, tt->height); 80} 81 82static void basic_fill(struct test_target *out, 83 struct test_target *ref) 84{ 85 int x = rand() % (2*out->width) - out->width; 86 int y = rand() % (2*out->height) - out->height; 87 int w = rand() % (2*out->width); 88 int h = rand() % (2*out->height); 89 int color = rand(); 90 int alu = rand() % 16; 91 92 fill_rect(out, alu, color, x, y, w, h); 93 fill_rect(ref, alu, color, x, y, w, h); 94} 95 96static void basic_copy(struct test_target *out, 97 struct test_target *ref) 98{ 99 int sx = rand() % (2*out->width) - ref->width; 100 int sy = rand() % (2*out->height) - ref->height; 101 int dx = rand() % (2*out->width) - ref->width; 102 int dy = rand() % (2*out->height) - ref->height; 103 int w = rand() % (2*out->width); 104 int h = rand() % (2*out->height); 105 XGCValues val; 106 107 val.function = rand() % 16; 108 109 XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val); 110 XCopyArea(out->dpy->dpy, 111 out->draw, out->draw, out->gc, 112 sx, sy, w, h, dx, dy); 113 114 XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val); 115 XCopyArea(ref->dpy->dpy, 116 ref->draw, ref->draw, ref->gc, 117 sx, sy, w, h, dx, dy); 118} 119 120static void _put(struct test_target *tt, 121 int x, int y, int w,int h, int color, int alu) 122{ 123 XImage image; 124 XGCValues val; 125 126 val.function = alu; 127 128 test_init_image(&image, &tt->dpy->shm, tt->format, w, h); 129 pixman_fill((uint32_t*)image.data, 130 image.bytes_per_line/sizeof(uint32_t), 131 image.bits_per_pixel, 132 0, 0, w, h, color); 133 134 XChangeGC(tt->dpy->dpy, tt->gc, GCFunction, &val); 135 if (rand() & 1) { 136 XShmPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 137 0, 0, x, y, w, h, 0); 138 XSync(tt->dpy->dpy, 1); 139 } else { 140 XPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 141 0, 0, x, y, w, h); 142 } 143} 144 145static void basic_put(struct test_target *out, 146 struct test_target *ref) 147{ 148 int x = rand() % (2*out->width) - out->width; 149 int y = rand() % (2*out->height) - out->height; 150 int w = rand() % out->width; 151 int h = rand() % out->height; 152 int color = rand(); 153 int alu = rand() % 16; 154 155 _put(out, x, y, w, h, color, alu); 156 _put(ref, x, y, w, h, color, alu); 157} 158 159static void rect_tests(struct test *test, int iterations, enum target target) 160{ 161 struct test_target out, ref; 162 void (* const ops[])(struct test_target *, struct test_target *) = { 163 basic_copy, 164 basic_fill, 165 basic_put, 166 render_copy, 167 }; 168 int n; 169 170 printf("Running mixed ops stress against %s: ", 171 test_target_name(target)); 172 fflush(stdout); 173 174 test_target_create_render(&test->out, target, &out); 175 test_target_create_render(&test->ref, target, &ref); 176 177 clear(&out); 178 clear(&ref); 179 180 for (n = 0; n < iterations; n++) 181 ops[rand() % ARRAY_SIZE(ops)](&out, &ref); 182 183 test_compare(test, 184 out.draw, out.format, 185 ref.draw, ref.format, 186 0, 0, out.width, out.height, 187 ""); 188 189 printf("passed [%d iterations]\n", n); 190 191 test_target_destroy_render(&test->out, &out); 192 test_target_destroy_render(&test->ref, &ref); 193} 194 195int main(int argc, char **argv) 196{ 197 struct test test; 198 int i; 199 200 test_init(&test, argc, argv); 201 202 for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 203 int iterations = REPS(i); 204 rect_tests(&test, iterations, 0); 205 rect_tests(&test, iterations, 1); 206 } 207 208 return 0; 209} 210