render-fill.c revision 03b705cf
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; 3403b705cfSriastradh uint32_t *cells = malloc(t->real.width*t->real.height*4); 3503b705cfSriastradh struct { 3603b705cfSriastradh uint16_t x, y; 3703b705cfSriastradh } *pixels = malloc(reps*sizeof(*pixels)); 3803b705cfSriastradh int r, s; 3903b705cfSriastradh 4003b705cfSriastradh test_target_create_render(&t->real, 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 5503b705cfSriastradh fill_rect(&t->real, 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 6403b705cfSriastradh test_init_image(&image, &t->real.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 7103b705cfSriastradh XShmGetImage(t->real.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 8803b705cfSriastradh test_target_destroy_render(&t->real, &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; 10403b705cfSriastradh uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height); 10503b705cfSriastradh int r, s, x, y; 10603b705cfSriastradh 10703b705cfSriastradh printf("Testing area sets (%s): ", test_target_name(target)); 10803b705cfSriastradh fflush(stdout); 10903b705cfSriastradh 11003b705cfSriastradh test_target_create_render(&t->real, target, &tt); 11103b705cfSriastradh clear(&t->real, &tt); 11203b705cfSriastradh 11303b705cfSriastradh test_init_image(&image, &t->real.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 12703b705cfSriastradh fill_rect(&t->real, 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 14803b705cfSriastradh XShmGetImage(t->real.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 17403b705cfSriastradh test_target_destroy_render(&t->real, &tt); 17503b705cfSriastradh free(cells); 17603b705cfSriastradh} 17703b705cfSriastradh 17803b705cfSriastradhstatic void rect_tests(struct test *t, int reps, int sets, enum target target) 17903b705cfSriastradh{ 18003b705cfSriastradh struct test_target real, ref; 18103b705cfSriastradh int r, s; 18203b705cfSriastradh 18303b705cfSriastradh printf("Testing area fills (%s): ", test_target_name(target)); 18403b705cfSriastradh fflush(stdout); 18503b705cfSriastradh 18603b705cfSriastradh test_target_create_render(&t->real, target, &real); 18703b705cfSriastradh clear(&t->real, &real); 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++) { 19403b705cfSriastradh int x = rand() % (2*real.width) - real.width; 19503b705cfSriastradh int y = rand() % (2*real.height) - real.height; 19603b705cfSriastradh int w = rand() % real.width; 19703b705cfSriastradh int h = rand() % real.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 20403b705cfSriastradh fill_rect(&t->real, real.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, 21303b705cfSriastradh real.draw, real.format, 21403b705cfSriastradh ref.draw, ref.format, 21503b705cfSriastradh 0, 0, real.width, real.height, 21603b705cfSriastradh ""); 21703b705cfSriastradh } 21803b705cfSriastradh 21903b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 22003b705cfSriastradh 22103b705cfSriastradh test_target_destroy_render(&t->real, &real); 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++) { 23303b705cfSriastradh int reps = 1 << i; 23403b705cfSriastradh int sets = 1 << (12 - i); 23503b705cfSriastradh enum target t; 23603b705cfSriastradh 23703b705cfSriastradh if (sets < 2) 23803b705cfSriastradh sets = 2; 23903b705cfSriastradh 24003b705cfSriastradh for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { 24103b705cfSriastradh pixel_tests(&test, reps, sets, t); 24203b705cfSriastradh area_tests(&test, reps, sets, t); 24303b705cfSriastradh rect_tests(&test, reps, sets, t); 24403b705cfSriastradh } 24503b705cfSriastradh } 24603b705cfSriastradh 24703b705cfSriastradh return 0; 24803b705cfSriastradh} 249