static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_shm) { struct test_target real, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->real, target, &real); clear(&t->real, &real); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % real.width; int y = rand() % real.height; int w = rand() % (real.width - x); int h = rand() % (real.height - y); uint8_t alu = rand() % (GXset + 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; uint8_t fg = color(red, green, blue, alpha); fill_rect(&t->real, real.draw, real.format, use_shm, alu, x, y, w, h, fg); fill_rect(&t->ref, ref.draw, ref.format, use_shm, alu, x, y, w, h, fg); } test_compare(t, real.draw, real.format, ref.draw, ref.format, 0, 0, real.width, real.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &real); test_target_destroy_render(&t->ref, &ref); }
static void glyph_iter_init(struct glyph_iter *gi, struct test *t, enum target target) { memset(gi, 0, sizeof(*gi)); gi->out.dpy = &t->out; test_target_create_render(&t->out, target, &gi->out.tt); gi->ref.dpy = &t->ref; test_target_create_render(&t->ref, target, &gi->ref.tt); gi->stage = GLYPHS; gi->glyph_format = -1; gi->op = -1; gi->dst_color = -1; gi->src_color = -1; gi->mask_format = -1; gi->clip = -1; }
static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target real, ref; int r, s; printf("Testing general (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->real, target, &real); clear(&t->real, &real); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*real.width) - real.width; int y = rand() % (2*real.height) - real.height; int w = rand() % (2*real.width); int h = rand() % (2*real.height); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t lw = rand() % 4; draw_rect(&t->real, real.draw, alu, x, y, w, h, fg, lw); draw_rect(&t->ref, ref.draw, alu, x, y, w, h, fg, lw); } test_compare(t, real.draw, real.format, ref.draw, ref.format, 0, 0, real.width, real.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &real); test_target_destroy_render(&t->ref, &ref); }
static double _bench_mask(struct test_display *t, enum target target_type, int op, int src, int mask, int loops) { XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; struct test_target target; Picture ps, pm; struct timespec tv; double elapsed; test_target_create_render(t, target_type, &target); XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, 0, 0, target.width, target.height); ps = source[src].create(t, &target); pm = source[mask].create(t, &target); if (ps && pm) { test_timer_start(t, &tv); while (loops--) XRenderComposite(t->dpy, op, ps, pm, target.picture, 0, 0, 0, 0, 0, 0, target.width, target.height); elapsed = test_timer_stop(t, &tv); } else elapsed = -1; if (ps) XRenderFreePicture(t->dpy, ps); if (pm) XRenderFreePicture(t->dpy, pm); test_target_destroy_render(t, &target); return elapsed; }
static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->real, target, &tt); clear(&t->real, &tt); test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->real, tt.picture, PictOpSrc, x, y, w, h, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &tt); free(cells); }
static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->real.width*t->real.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->real, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->real, tt.picture, PictOpSrc, x, y, 1, 1, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->real.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->real.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &tt); free(pixels); free(cells); }
static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->real, target, &tt); clear(&t->real, &tt); test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; uint32_t fg = rand(); x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->real, tt.draw, GXcopy, x, y, w, h, fg); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, fg); } XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *) (image.data + y*image.bytes_per_line + x*image.bits_per_pixel/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &tt); free(cells); }
static void edge_test(struct test *t, enum mask mask, enum edge edge, enum target target) { struct test_target out, ref; XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; Picture src_ref, src_out; XTriangle tri; unsigned step, max; test_target_create_render(&t->out, target, &out); set_edge(t->out.dpy, out.picture, edge); src_out = XRenderCreateSolidFill(t->out.dpy, &white); test_target_create_render(&t->ref, target, &ref); set_edge(t->ref.dpy, ref.picture, edge); src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); printf("Testing edges (with mask %s and %s edges) (%s): ", mask_name(mask), edge_name(edge), test_target_name(target)); fflush(stdout); max = 2*(out.width + 128 + out.height+128); step = 0; for (step = 0; step <= max; step++) { char buf[80]; step_to_point(step, out.width, out.height, &tri.p1); step_to_point(step + out.width + 128, out.width, out.height, &tri.p2); step_to_point(step + out.height + 128 + 2*(out.width + 128), out.width, out.height, &tri.p3); sprintf(buf, "tri=((%d, %d), (%d, %d), (%d, %d))\n", tri.p1.x >> 16, tri.p1.y >> 16, tri.p2.x >> 16, tri.p2.y >> 16, tri.p3.x >> 16, tri.p3.y >> 16); clear(&t->out, &out); XRenderCompositeTriangles(t->out.dpy, PictOpSrc, src_out, out.picture, mask_format(t->out.dpy, mask), 0, 0, &tri, 1); clear(&t->ref, &ref); XRenderCompositeTriangles(t->ref.dpy, PictOpSrc, src_ref, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, &tri, 1); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } XRenderFreePicture(t->out.dpy, src_out); test_target_destroy_render(&t->out, &out); XRenderFreePicture(t->ref.dpy, src_ref); test_target_destroy_render(&t->ref, &ref); printf("pass\n"); }
static void area_tests(struct test *t, int reps, int sets, enum target target, int use_shm) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height); int r, s, x, y; printf("Testing area sets (%s %s shm): ", test_target_name(target), use_shm ? "with" : "without" ); fflush(stdout); test_target_create_render(&t->real, target, &tt); clear(&t->real, &tt); test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; uint32_t fg = color(red, green, blue, alpha); int w, h; x = rand() % tt.width; y = rand() % tt.height; w = rand() % (tt.width - x); h = rand() % (tt.height - y); fill_rect(&t->real, tt.draw, tt.format, use_shm, GXcopy, x, y, w, h, fg); pixman_fill(cells, tt.width, 32, x, y, w, h, fg); } XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); char buf[600]; show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x[%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &tt); free(cells); }
static void hv0(struct test *t, enum target target) { char buf[1024]; struct test_target out, ref; int a, alu, cap; XSegment seg[(NUM_POINTS+1)*8]; int n, x, y, nseg; printf("Testing drawing of zero-width line segments (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); test_target_create_render(&t->ref, target, &ref); y = x = n = 0; for (a = 0; a <= NUM_POINTS; a++) { seg[n].x1 = a + 64; seg[n].y1 = y + 64; seg[n].x2 = NUM_POINTS + 64; seg[n].y2 = y + 64; n++; y++; seg[n].x1 = NUM_POINTS - a + 64; seg[n].y1 = y + 64; seg[n].x2 = 0 + 64; seg[n].y2 = y + 64; n++; y++; seg[n].x2 = a + 64; seg[n].y2 = y + 64; seg[n].x1 = NUM_POINTS + 64; seg[n].y1 = y + 64; n++; y++; seg[n].x2 = NUM_POINTS - a + 64; seg[n].y2 = y + 64; seg[n].x1 = 0 + 64; seg[n].y1 = y + 64; n++; y++; seg[n].y1 = a + 64; seg[n].x1 = x + 64; seg[n].y2 = NUM_POINTS + 64; seg[n].x2 = x + 64; n++; x++; seg[n].y1 = NUM_POINTS - a + 64; seg[n].x1 = x + 64; seg[n].y2 = 0 + 64; seg[n].x2 = x + 64; n++; x++; seg[n].y2 = a + 64; seg[n].x2 = x + 64; seg[n].y1 = NUM_POINTS + 64; seg[n].x1 = x + 64; n++; x++; seg[n].y2 = NUM_POINTS - a + 64; seg[n].x2 = x + 64; seg[n].y1 = 0 + 64; seg[n].x1 = x + 64; n++; x++; } for (alu = 0; alu < 16; alu++) { for (cap = CapNotLast; cap <= CapProjecting; cap++) { for (nseg = 0; nseg < n; nseg++) { sprintf(buf, "cap=%d, alu=%d, nseg=%d", cap, alu, nseg); clear(&t->out, &out); clear(&t->ref, &ref); draw(&t->out, &out, alu, 0, LineSolid, cap, seg, nseg); draw(&t->ref, &ref, alu, 0, LineSolid, cap, seg, nseg); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } } test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); printf("\n"); }
static void trap_tests(struct test *t, enum mask mask, enum trapezoid trapezoid, int reps, int sets, enum target target) { struct test_target real, ref; XTrapezoid *traps; int max_traps = 65536; int r, s, n; traps = malloc(sizeof(*traps) * max_traps); if (traps == NULL) return; printf("Testing trapezoids (%s with mask %s) (%s): ", trapezoid_name(trapezoid), mask_name(mask), test_target_name(target)); fflush(stdout); test_target_create_render(&t->real, target, &real); clear(&t->real, &real); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { XRenderColor render_color; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int num_traps = rand() % max_traps; Picture src; for (n = 0; n < num_traps; n++) random_trapezoid(&traps[n], 0, 0, 0, real.width, real.height); render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8; src = XRenderCreateSolidFill(t->real.dpy, &render_color); XRenderCompositeTrapezoids(t->real.dpy, op, src, real.picture, mask_format(t->real.dpy, mask), 0, 0, traps, num_traps); XRenderFreePicture(t->real.dpy, src); src = XRenderCreateSolidFill(t->ref.dpy, &render_color); XRenderCompositeTrapezoids(t->ref.dpy, op, src, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, traps, num_traps); XRenderFreePicture(t->ref.dpy, src); } test_compare(t, real.draw, real.format, ref.draw, ref.format, 0, 0, real.width, real.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->real, &real); test_target_destroy_render(&t->ref, &ref); free(traps); }
static void edge_test(struct test *t, enum mask mask, enum edge edge, enum target target) { struct test_target out, ref; XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; Picture src_ref, src_out; XTrapezoid trap; int left_or_right, p; test_target_create_render(&t->out, target, &out); set_edge(t->out.dpy, out.picture, edge); src_out = XRenderCreateSolidFill(t->out.dpy, &white); test_target_create_render(&t->ref, target, &ref); set_edge(t->ref.dpy, ref.picture, edge); src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); printf("Testing edges (with mask %s and %s edges) (%s): ", mask_name(mask), edge_name(edge), test_target_name(target)); fflush(stdout); for (left_or_right = 0; left_or_right <= 1; left_or_right++) { for (p = -64; p <= out.width + 64; p++) { char buf[80]; if (left_or_right) { trap.left.p1.x = 0; trap.left.p1.y = 0; trap.left.p2.x = 0; trap.left.p2.y = out.height << 16; trap.right.p1.x = p << 16; trap.right.p1.y = 0; trap.right.p2.x = out.width << 16; trap.right.p2.y = out.height << 16; } else { trap.right.p1.x = out.width << 16; trap.right.p1.y = 0; trap.right.p2.x = out.width << 16; trap.right.p2.y = out.height << 16; trap.left.p1.x = 0; trap.left.p1.y = 0; trap.left.p2.x = p << 16; trap.left.p2.y = out.height << 16; } trap.top = 0; trap.bottom = out.height << 16; sprintf(buf, "trap=((%d, %d), (%d, %d)), ((%d, %d), (%d, %d))\n", trap.left.p1.x >> 16, trap.left.p1.y >> 16, trap.left.p2.x >> 16, trap.left.p2.y >> 16, trap.right.p1.x >> 16, trap.right.p1.y >> 16, trap.right.p2.x >> 16, trap.right.p2.y >> 16); clear(&t->out, &out); XRenderCompositeTrapezoids(t->out.dpy, PictOpSrc, src_out, out.picture, mask_format(t->out.dpy, mask), 0, 0, &trap, 1); clear(&t->ref, &ref); XRenderCompositeTrapezoids(t->ref.dpy, PictOpSrc, src_ref, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, &trap, 1); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } XRenderFreePicture(t->out.dpy, src_out); test_target_destroy_render(&t->out, &out); XRenderFreePicture(t->ref.dpy, src_ref); test_target_destroy_render(&t->ref, &ref); printf("pass\n"); }