103b705cfSriastradh#include <stdint.h> 203b705cfSriastradh#include <stdio.h> 303b705cfSriastradh#include <stdlib.h> 403b705cfSriastradh 503b705cfSriastradh#include <X11/Xutil.h> /* for XDestroyImage */ 603b705cfSriastradh#include <pixman.h> /* for pixman blt functions */ 703b705cfSriastradh 803b705cfSriastradh#include "test.h" 903b705cfSriastradh 1003b705cfSriastradhstatic const uint8_t ops[] = { 1103b705cfSriastradh PictOpClear, 1203b705cfSriastradh PictOpSrc, 1303b705cfSriastradh PictOpDst, 1403b705cfSriastradh}; 1503b705cfSriastradh 1603b705cfSriastradhstatic void fill_rect(struct test_display *dpy, Picture p, uint8_t op, 1703b705cfSriastradh int x, int y, int w, int h, 1803b705cfSriastradh uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 1903b705cfSriastradh{ 2003b705cfSriastradh XRenderColor render_color; 2103b705cfSriastradh 2203b705cfSriastradh render_color.red = red * alpha; 2303b705cfSriastradh render_color.green = green * alpha; 2403b705cfSriastradh render_color.blue = blue * alpha; 2503b705cfSriastradh render_color.alpha = alpha << 8; 2603b705cfSriastradh 2703b705cfSriastradh XRenderFillRectangle(dpy->dpy, op, p, &render_color, x, y, w,h); 2803b705cfSriastradh} 2903b705cfSriastradh 3003b705cfSriastradhstatic void pixel_tests(struct test *t, int reps, int sets, enum target target) 3103b705cfSriastradh{ 3203b705cfSriastradh struct test_target tt; 3303b705cfSriastradh XImage image; 3442542f5fSchristos uint32_t *cells = malloc(t->out.width*t->out.height*4); 3503b705cfSriastradh struct { 3603b705cfSriastradh uint16_t x, y; 3703b705cfSriastradh } *pixels = malloc(reps*sizeof(*pixels)); 3803b705cfSriastradh int r, s; 3903b705cfSriastradh 4042542f5fSchristos test_target_create_render(&t->out, target, &tt); 4103b705cfSriastradh 4203b705cfSriastradh printf("Testing setting of single pixels (%s): ", 4303b705cfSriastradh test_target_name(target)); 4403b705cfSriastradh fflush(stdout); 4503b705cfSriastradh 4603b705cfSriastradh for (s = 0; s < sets; s++) { 4703b705cfSriastradh for (r = 0; r < reps; r++) { 4803b705cfSriastradh int x = rand() % (tt.width - 1); 4903b705cfSriastradh int y = rand() % (tt.height - 1); 5003b705cfSriastradh int red = rand() % 0xff; 5103b705cfSriastradh int green = rand() % 0xff; 5203b705cfSriastradh int blue = rand() % 0xff; 5303b705cfSriastradh int alpha = rand() % 0xff; 5403b705cfSriastradh 5542542f5fSchristos fill_rect(&t->out, tt.picture, PictOpSrc, 5603b705cfSriastradh x, y, 1, 1, 5703b705cfSriastradh red, green, blue, alpha); 5803b705cfSriastradh 5903b705cfSriastradh pixels[r].x = x; 6003b705cfSriastradh pixels[r].y = y; 6103b705cfSriastradh cells[y*tt.width+x] = color(red, green, blue, alpha); 6203b705cfSriastradh } 6303b705cfSriastradh 6442542f5fSchristos test_init_image(&image, &t->out.shm, tt.format, 1, 1); 6503b705cfSriastradh 6603b705cfSriastradh for (r = 0; r < reps; r++) { 6703b705cfSriastradh uint32_t result; 6803b705cfSriastradh uint32_t x = pixels[r].x; 6903b705cfSriastradh uint32_t y = pixels[r].y; 7003b705cfSriastradh 7142542f5fSchristos XShmGetImage(t->out.dpy, tt.draw, &image, 7203b705cfSriastradh x, y, AllPlanes); 7303b705cfSriastradh 7403b705cfSriastradh result = *(uint32_t *)image.data; 7503b705cfSriastradh if (!pixel_equal(image.depth, result, 7603b705cfSriastradh cells[y*tt.width+x])) { 7703b705cfSriastradh uint32_t mask = depth_mask(image.depth); 7803b705cfSriastradh die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", 7903b705cfSriastradh x, y, 8003b705cfSriastradh cells[y*tt.width+x] & mask, 8103b705cfSriastradh cells[y*tt.width+x], 8203b705cfSriastradh result & mask); 8303b705cfSriastradh } 8403b705cfSriastradh } 8503b705cfSriastradh } 8603b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 8703b705cfSriastradh 8842542f5fSchristos test_target_destroy_render(&t->out, &tt); 8903b705cfSriastradh free(pixels); 9003b705cfSriastradh free(cells); 9103b705cfSriastradh} 9203b705cfSriastradh 9303b705cfSriastradhstatic void clear(struct test_display *dpy, struct test_target *tt) 9403b705cfSriastradh{ 9503b705cfSriastradh XRenderColor render_color = {0}; 9603b705cfSriastradh XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 9703b705cfSriastradh 0, 0, tt->width, tt->height); 9803b705cfSriastradh} 9903b705cfSriastradh 10003b705cfSriastradhstatic void area_tests(struct test *t, int reps, int sets, enum target target) 10103b705cfSriastradh{ 10203b705cfSriastradh struct test_target tt; 10303b705cfSriastradh XImage image; 10442542f5fSchristos uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); 10503b705cfSriastradh int r, s, x, y; 10603b705cfSriastradh 10703b705cfSriastradh printf("Testing area sets (%s): ", test_target_name(target)); 10803b705cfSriastradh fflush(stdout); 10903b705cfSriastradh 11042542f5fSchristos test_target_create_render(&t->out, target, &tt); 11142542f5fSchristos clear(&t->out, &tt); 11203b705cfSriastradh 11342542f5fSchristos test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); 11403b705cfSriastradh 11503b705cfSriastradh for (s = 0; s < sets; s++) { 11603b705cfSriastradh for (r = 0; r < reps; r++) { 11703b705cfSriastradh int w = rand() % tt.width; 11803b705cfSriastradh int h = rand() % tt.height; 11903b705cfSriastradh int red = rand() % 0xff; 12003b705cfSriastradh int green = rand() % 0xff; 12103b705cfSriastradh int blue = rand() % 0xff; 12203b705cfSriastradh int alpha = rand() % 0xff; 12303b705cfSriastradh 12403b705cfSriastradh x = rand() % (2*tt.width) - tt.width; 12503b705cfSriastradh y = rand() % (2*tt.height) - tt.height; 12603b705cfSriastradh 12742542f5fSchristos fill_rect(&t->out, tt.picture, PictOpSrc, 12803b705cfSriastradh x, y, w, h, red, green, blue, alpha); 12903b705cfSriastradh 13003b705cfSriastradh if (x < 0) 13103b705cfSriastradh w += x, x = 0; 13203b705cfSriastradh if (y < 0) 13303b705cfSriastradh h += y, y = 0; 13403b705cfSriastradh if (x >= tt.width || y >= tt.height) 13503b705cfSriastradh continue; 13603b705cfSriastradh 13703b705cfSriastradh if (x + w > tt.width) 13803b705cfSriastradh w = tt.width - x; 13903b705cfSriastradh if (y + h > tt.height) 14003b705cfSriastradh h = tt.height - y; 14103b705cfSriastradh if (w <= 0 || h <= 0) 14203b705cfSriastradh continue; 14303b705cfSriastradh 14403b705cfSriastradh pixman_fill(cells, tt.width, 32, x, y, w, h, 14503b705cfSriastradh color(red, green, blue, alpha)); 14603b705cfSriastradh } 14703b705cfSriastradh 14842542f5fSchristos XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); 14903b705cfSriastradh 15003b705cfSriastradh for (y = 0; y < tt.height; y++) { 15103b705cfSriastradh for (x = 0; x < tt.width; x++) { 15203b705cfSriastradh uint32_t result = 15303b705cfSriastradh *(uint32_t *)(image.data + 15403b705cfSriastradh y*image.bytes_per_line + 15503b705cfSriastradh image.bits_per_pixel*x/8); 15603b705cfSriastradh if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { 15703b705cfSriastradh uint32_t mask; 15803b705cfSriastradh if (image.depth == 32) 15903b705cfSriastradh mask = 0xffffffff; 16003b705cfSriastradh else 16103b705cfSriastradh mask = (1 << image.depth) - 1; 16203b705cfSriastradh die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", 16303b705cfSriastradh x, y, 16403b705cfSriastradh cells[y*tt.width+x] & mask, 16503b705cfSriastradh cells[y*tt.width+x], 16603b705cfSriastradh result & mask); 16703b705cfSriastradh } 16803b705cfSriastradh } 16903b705cfSriastradh } 17003b705cfSriastradh } 17103b705cfSriastradh 17203b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 17303b705cfSriastradh 17442542f5fSchristos test_target_destroy_render(&t->out, &tt); 17503b705cfSriastradh free(cells); 17603b705cfSriastradh} 17703b705cfSriastradh 17803b705cfSriastradhstatic void rect_tests(struct test *t, int reps, int sets, enum target target) 17903b705cfSriastradh{ 18042542f5fSchristos struct test_target out, ref; 18103b705cfSriastradh int r, s; 18203b705cfSriastradh 18303b705cfSriastradh printf("Testing area fills (%s): ", test_target_name(target)); 18403b705cfSriastradh fflush(stdout); 18503b705cfSriastradh 18642542f5fSchristos test_target_create_render(&t->out, target, &out); 18742542f5fSchristos clear(&t->out, &out); 18803b705cfSriastradh 18903b705cfSriastradh test_target_create_render(&t->ref, target, &ref); 19003b705cfSriastradh clear(&t->ref, &ref); 19103b705cfSriastradh 19203b705cfSriastradh for (s = 0; s < sets; s++) { 19303b705cfSriastradh for (r = 0; r < reps; r++) { 19442542f5fSchristos int x = rand() % (2*out.width) - out.width; 19542542f5fSchristos int y = rand() % (2*out.height) - out.height; 19642542f5fSchristos int w = rand() % out.width; 19742542f5fSchristos int h = rand() % out.height; 19803b705cfSriastradh int op = ops[rand() % sizeof(ops)]; 19903b705cfSriastradh int red = rand() % 0xff; 20003b705cfSriastradh int green = rand() % 0xff; 20103b705cfSriastradh int blue = rand() % 0xff; 20203b705cfSriastradh int alpha = rand() % 0xff; 20303b705cfSriastradh 20442542f5fSchristos fill_rect(&t->out, out.picture, 20503b705cfSriastradh op, x, y, w, h, 20603b705cfSriastradh red, green, blue, alpha); 20703b705cfSriastradh fill_rect(&t->ref, ref.picture, 20803b705cfSriastradh op, x, y, w, h, 20903b705cfSriastradh red, green, blue, alpha); 21003b705cfSriastradh } 21103b705cfSriastradh 21203b705cfSriastradh test_compare(t, 21342542f5fSchristos out.draw, out.format, 21403b705cfSriastradh ref.draw, ref.format, 21542542f5fSchristos 0, 0, out.width, out.height, 21603b705cfSriastradh ""); 21703b705cfSriastradh } 21803b705cfSriastradh 21903b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 22003b705cfSriastradh 22142542f5fSchristos test_target_destroy_render(&t->out, &out); 22203b705cfSriastradh test_target_destroy_render(&t->ref, &ref); 22303b705cfSriastradh} 22403b705cfSriastradh 22503b705cfSriastradhint main(int argc, char **argv) 22603b705cfSriastradh{ 22703b705cfSriastradh struct test test; 22803b705cfSriastradh int i; 22903b705cfSriastradh 23003b705cfSriastradh test_init(&test, argc, argv); 23103b705cfSriastradh 23203b705cfSriastradh for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 23342542f5fSchristos int reps = REPS(i), sets = SETS(i); 23403b705cfSriastradh enum target t; 23503b705cfSriastradh 23603b705cfSriastradh for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { 23703b705cfSriastradh pixel_tests(&test, reps, sets, t); 23803b705cfSriastradh area_tests(&test, reps, sets, t); 23903b705cfSriastradh rect_tests(&test, reps, sets, t); 24003b705cfSriastradh } 24103b705cfSriastradh } 24203b705cfSriastradh 24303b705cfSriastradh return 0; 24403b705cfSriastradh} 245