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 1003b705cfSriastradhenum trapezoid { 1103b705cfSriastradh RECT_ALIGN, 1203b705cfSriastradh RECT_UNALIGN, 1303b705cfSriastradh GENERAL 1403b705cfSriastradh}; 1503b705cfSriastradh 1603b705cfSriastradhstatic const uint8_t ops[] = { 1703b705cfSriastradh PictOpClear, 1803b705cfSriastradh PictOpSrc, 1903b705cfSriastradh PictOpDst, 2003b705cfSriastradh}; 2103b705cfSriastradh 2203b705cfSriastradhstatic XRenderPictFormat *mask_format(Display *dpy, enum mask mask) 2303b705cfSriastradh{ 2403b705cfSriastradh switch (mask) { 2503b705cfSriastradh default: 2603b705cfSriastradh case MASK_NONE: return NULL; 2703b705cfSriastradh case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1); 2803b705cfSriastradh case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8); 2903b705cfSriastradh } 3003b705cfSriastradh} 3103b705cfSriastradh 3203b705cfSriastradhstatic const char *mask_name(enum mask mask) 3303b705cfSriastradh{ 3403b705cfSriastradh switch (mask) { 3503b705cfSriastradh default: 3603b705cfSriastradh case MASK_NONE: return "none"; 3703b705cfSriastradh case MASK_A1: return "a1"; 3803b705cfSriastradh case MASK_A8: return "a8"; 3903b705cfSriastradh } 4003b705cfSriastradh} 4103b705cfSriastradh 4203b705cfSriastradhstatic const char *trapezoid_name(enum trapezoid trapezoid) 4303b705cfSriastradh{ 4403b705cfSriastradh switch (trapezoid) { 4503b705cfSriastradh default: 4603b705cfSriastradh case RECT_ALIGN: return "pixel-aligned"; 4703b705cfSriastradh case RECT_UNALIGN: return "rectilinear"; 4803b705cfSriastradh case GENERAL: return "general"; 4903b705cfSriastradh } 5003b705cfSriastradh} 5103b705cfSriastradh 5203b705cfSriastradhstatic void fill_rect(struct test_display *dpy, Picture p, uint8_t op, 5303b705cfSriastradh int x, int y, int w, int h, 5403b705cfSriastradh int dx, int dy, enum mask mask, 5503b705cfSriastradh uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 5603b705cfSriastradh{ 5703b705cfSriastradh XRenderColor render_color; 5803b705cfSriastradh XTrapezoid trap; 5903b705cfSriastradh Picture src; 6003b705cfSriastradh 6103b705cfSriastradh render_color.red = red * alpha; 6203b705cfSriastradh render_color.green = green * alpha; 6303b705cfSriastradh render_color.blue = blue * alpha; 6403b705cfSriastradh render_color.alpha = alpha << 8; 6503b705cfSriastradh 6603b705cfSriastradh trap.left.p1.x = trap.left.p2.x = (x << 16) + dx; 6703b705cfSriastradh trap.top = trap.left.p1.y = trap.right.p1.y = (y << 16) + dy; 6803b705cfSriastradh trap.right.p1.x = trap.right.p2.x = ((x + w) << 16) + dx; 6903b705cfSriastradh trap.bottom = trap.left.p2.y = trap.right.p2.y = ((y + h) << 16) + dy; 7003b705cfSriastradh 7103b705cfSriastradh src = XRenderCreateSolidFill(dpy->dpy, &render_color); 7203b705cfSriastradh XRenderCompositeTrapezoids(dpy->dpy, 7303b705cfSriastradh op, src, p, mask_format(dpy->dpy, mask), 7403b705cfSriastradh 0, 0, &trap, 1); 7503b705cfSriastradh XRenderFreePicture(dpy->dpy, src); 7603b705cfSriastradh} 7703b705cfSriastradh 7803b705cfSriastradhstatic void pixel_tests(struct test *t, int reps, int sets, enum target target) 7903b705cfSriastradh{ 8003b705cfSriastradh struct test_target tt; 8103b705cfSriastradh XImage image; 8242542f5fSchristos uint32_t *cells = malloc(t->out.width*t->out.height*4); 8303b705cfSriastradh struct { 8403b705cfSriastradh uint16_t x, y; 8503b705cfSriastradh } *pixels = malloc(reps*sizeof(*pixels)); 8603b705cfSriastradh int r, s; 8703b705cfSriastradh 8803b705cfSriastradh printf("Testing setting of single pixels (%s): ", test_target_name(target)); 8903b705cfSriastradh fflush(stdout); 9003b705cfSriastradh 9142542f5fSchristos test_target_create_render(&t->out, target, &tt); 9203b705cfSriastradh 9303b705cfSriastradh for (s = 0; s < sets; s++) { 9403b705cfSriastradh for (r = 0; r < reps; r++) { 9503b705cfSriastradh int x = rand() % (tt.width - 1); 9603b705cfSriastradh int y = rand() % (tt.height - 1); 9703b705cfSriastradh int red = rand() % 0xff; 9803b705cfSriastradh int green = rand() % 0xff; 9903b705cfSriastradh int blue = rand() % 0xff; 10003b705cfSriastradh int alpha = rand() % 0xff; 10103b705cfSriastradh 10242542f5fSchristos fill_rect(&t->out, tt.picture, PictOpSrc, 10303b705cfSriastradh x, y, 1, 1, 10403b705cfSriastradh 0, 0, MASK_NONE, 10503b705cfSriastradh red, green, blue, alpha); 10603b705cfSriastradh 10703b705cfSriastradh pixels[r].x = x; 10803b705cfSriastradh pixels[r].y = y; 10942542f5fSchristos cells[y*t->out.width+x] = color(red, green, blue, alpha); 11003b705cfSriastradh } 11103b705cfSriastradh 11242542f5fSchristos test_init_image(&image, &t->out.shm, tt.format, 1, 1); 11303b705cfSriastradh 11403b705cfSriastradh for (r = 0; r < reps; r++) { 11503b705cfSriastradh uint32_t result; 11603b705cfSriastradh uint32_t x = pixels[r].x; 11703b705cfSriastradh uint32_t y = pixels[r].y; 11803b705cfSriastradh 11942542f5fSchristos XShmGetImage(t->out.dpy, tt.draw, &image, 12003b705cfSriastradh x, y, AllPlanes); 12103b705cfSriastradh 12203b705cfSriastradh result = *(uint32_t *)image.data; 12303b705cfSriastradh if (!pixel_equal(image.depth, result, 12403b705cfSriastradh cells[y*tt.width+x])) { 12503b705cfSriastradh uint32_t mask = depth_mask(image.depth); 12603b705cfSriastradh die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", 12703b705cfSriastradh x, y, 12803b705cfSriastradh cells[y*tt.width+x] & mask, 12903b705cfSriastradh cells[y*tt.width+x], 13003b705cfSriastradh result & mask, 13103b705cfSriastradh result); 13203b705cfSriastradh } 13303b705cfSriastradh } 13403b705cfSriastradh } 13503b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 13603b705cfSriastradh 13742542f5fSchristos test_target_destroy_render(&t->out, &tt); 13803b705cfSriastradh 13903b705cfSriastradh free(pixels); 14003b705cfSriastradh free(cells); 14103b705cfSriastradh} 14203b705cfSriastradh 14303b705cfSriastradhstatic void clear(struct test_display *dpy, struct test_target *tt) 14403b705cfSriastradh{ 14503b705cfSriastradh XRenderColor render_color = {0}; 14603b705cfSriastradh XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 14703b705cfSriastradh 0, 0, tt->width, tt->height); 14803b705cfSriastradh} 14903b705cfSriastradh 15003b705cfSriastradhstatic void area_tests(struct test *t, int reps, int sets, enum target target) 15103b705cfSriastradh{ 15203b705cfSriastradh struct test_target tt; 15303b705cfSriastradh XImage image; 15442542f5fSchristos uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); 15503b705cfSriastradh int r, s, x, y; 15603b705cfSriastradh 15703b705cfSriastradh printf("Testing area sets (%s): ", test_target_name(target)); 15803b705cfSriastradh fflush(stdout); 15903b705cfSriastradh 16042542f5fSchristos test_target_create_render(&t->out, target, &tt); 16142542f5fSchristos clear(&t->out, &tt); 16203b705cfSriastradh 16342542f5fSchristos test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); 16403b705cfSriastradh 16503b705cfSriastradh for (s = 0; s < sets; s++) { 16603b705cfSriastradh for (r = 0; r < reps; r++) { 16703b705cfSriastradh int w = rand() % tt.width; 16803b705cfSriastradh int h = rand() % tt.height; 16903b705cfSriastradh int red = rand() % 0xff; 17003b705cfSriastradh int green = rand() % 0xff; 17103b705cfSriastradh int blue = rand() % 0xff; 17203b705cfSriastradh int alpha = rand() % 0xff; 17303b705cfSriastradh 17403b705cfSriastradh x = rand() % (2*tt.width) - tt.width; 17503b705cfSriastradh y = rand() % (2*tt.height) - tt.height; 17603b705cfSriastradh 17742542f5fSchristos fill_rect(&t->out, tt.picture, PictOpSrc, 17803b705cfSriastradh x, y, w, h, 17903b705cfSriastradh 0, 0, MASK_NONE, 18003b705cfSriastradh red, green, blue, alpha); 18103b705cfSriastradh 18203b705cfSriastradh if (x < 0) 18303b705cfSriastradh w += x, x = 0; 18403b705cfSriastradh if (y < 0) 18503b705cfSriastradh h += y, y = 0; 18603b705cfSriastradh if (x >= tt.width || y >= tt.height) 18703b705cfSriastradh continue; 18803b705cfSriastradh 18903b705cfSriastradh if (x + w > tt.width) 19003b705cfSriastradh w = tt.width - x; 19103b705cfSriastradh if (y + h > tt.height) 19203b705cfSriastradh h = tt.height - y; 19303b705cfSriastradh if (w <= 0 || h <= 0) 19403b705cfSriastradh continue; 19503b705cfSriastradh 19603b705cfSriastradh pixman_fill(cells, tt.width, 32, x, y, w, h, 19703b705cfSriastradh color(red, green, blue, alpha)); 19803b705cfSriastradh } 19903b705cfSriastradh 20042542f5fSchristos XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); 20103b705cfSriastradh 20203b705cfSriastradh for (y = 0; y < tt.height; y++) { 20303b705cfSriastradh for (x = 0; x < tt.width; x++) { 20403b705cfSriastradh uint32_t result = 20503b705cfSriastradh *(uint32_t *)(image.data + 20603b705cfSriastradh y*image.bytes_per_line + 20703b705cfSriastradh image.bits_per_pixel*x/8); 20803b705cfSriastradh if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { 20903b705cfSriastradh uint32_t mask = depth_mask(image.depth); 21003b705cfSriastradh 21103b705cfSriastradh die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", 21203b705cfSriastradh x, y, 21303b705cfSriastradh cells[y*tt.width+x] & mask, 21403b705cfSriastradh cells[y*tt.width+x], 21503b705cfSriastradh result & mask, 21603b705cfSriastradh result); 21703b705cfSriastradh } 21803b705cfSriastradh } 21903b705cfSriastradh } 22003b705cfSriastradh } 22103b705cfSriastradh 22203b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 22303b705cfSriastradh 22442542f5fSchristos test_target_destroy_render(&t->out, &tt); 22503b705cfSriastradh free(cells); 22603b705cfSriastradh} 22703b705cfSriastradh 22803b705cfSriastradhstatic void rect_tests(struct test *t, 22903b705cfSriastradh int dx, int dy, 23003b705cfSriastradh enum mask mask, 23103b705cfSriastradh int reps, int sets, 23203b705cfSriastradh enum target target) 23303b705cfSriastradh{ 23442542f5fSchristos struct test_target out, ref; 23503b705cfSriastradh int r, s; 23603b705cfSriastradh 23703b705cfSriastradh printf("Testing area fills (offset %dx%d, mask %s) (%s): ", 23803b705cfSriastradh dx, dy, mask_name(mask), test_target_name(target)); 23903b705cfSriastradh fflush(stdout); 24003b705cfSriastradh 24142542f5fSchristos test_target_create_render(&t->out, target, &out); 24242542f5fSchristos clear(&t->out, &out); 24303b705cfSriastradh 24403b705cfSriastradh test_target_create_render(&t->ref, target, &ref); 24503b705cfSriastradh clear(&t->ref, &ref); 24603b705cfSriastradh 24703b705cfSriastradh for (s = 0; s < sets; s++) { 24803b705cfSriastradh for (r = 0; r < reps; r++) { 24942542f5fSchristos int x = rand() % (2*out.width) - out.width; 25042542f5fSchristos int y = rand() % (2*out.height) - out.height; 25142542f5fSchristos int w = rand() % out.width; 25242542f5fSchristos int h = rand() % out.height; 25303b705cfSriastradh int op = ops[rand() % sizeof(ops)]; 25403b705cfSriastradh int red = rand() % 0xff; 25503b705cfSriastradh int green = rand() % 0xff; 25603b705cfSriastradh int blue = rand() % 0xff; 25703b705cfSriastradh int alpha = rand() % 0xff; 25803b705cfSriastradh 25942542f5fSchristos fill_rect(&t->out, out.picture, op, 26003b705cfSriastradh x, y, w, h, dx, dy, mask, 26103b705cfSriastradh red, green, blue, alpha); 26203b705cfSriastradh fill_rect(&t->ref, ref.picture, op, 26303b705cfSriastradh x, y, w, h, dx, dy, mask, 26403b705cfSriastradh red, green, blue, alpha); 26503b705cfSriastradh } 26603b705cfSriastradh 26703b705cfSriastradh test_compare(t, 26842542f5fSchristos out.draw, out.format, 26903b705cfSriastradh ref.draw, ref.format, 27042542f5fSchristos 0, 0, out.width, out.height, 27103b705cfSriastradh ""); 27203b705cfSriastradh } 27303b705cfSriastradh 27403b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 27503b705cfSriastradh 27642542f5fSchristos test_target_destroy_render(&t->out, &out); 27703b705cfSriastradh test_target_destroy_render(&t->ref, &ref); 27803b705cfSriastradh} 27903b705cfSriastradh 28003b705cfSriastradhstatic void random_trapezoid(XTrapezoid *trap, enum trapezoid trapezoid, 28103b705cfSriastradh int x1, int y1, int x2, int y2) 28203b705cfSriastradh{ 28303b705cfSriastradh switch (trapezoid) { 28403b705cfSriastradh case RECT_ALIGN: 28503b705cfSriastradh x1 = x1 + rand() % (x2 - x1); 28603b705cfSriastradh x2 = x1 + rand() % (x2 - x1); 28703b705cfSriastradh y1 = y1 + rand() % (y2 - y1); 28803b705cfSriastradh y2 = y1 + rand() % (y2 - y1); 28903b705cfSriastradh 29003b705cfSriastradh trap->left.p1.x = trap->left.p2.x = x1 << 16; 29103b705cfSriastradh trap->top = trap->left.p1.y = trap->right.p1.y = y1 << 16; 29203b705cfSriastradh trap->right.p1.x = trap->right.p2.x = x2 << 16; 29303b705cfSriastradh trap->bottom = trap->left.p2.y = trap->right.p2.y = y2 << 16; 29403b705cfSriastradh break; 29503b705cfSriastradh 29603b705cfSriastradh case RECT_UNALIGN: 29703b705cfSriastradh x1 <<= 16; x2 <<= 16; 29803b705cfSriastradh y1 <<= 16; y2 <<= 16; 29903b705cfSriastradh 30003b705cfSriastradh x1 = x1 + rand() % (x2 - x1); 30103b705cfSriastradh x2 = x1 + rand() % (x2 - x1); 30203b705cfSriastradh y1 = y1 + rand() % (y2 - y1); 30303b705cfSriastradh y2 = y1 + rand() % (y2 - y1); 30403b705cfSriastradh 30503b705cfSriastradh trap->left.p1.x = trap->left.p2.x = x1; 30603b705cfSriastradh trap->top = trap->left.p1.y = trap->right.p1.y = y1; 30703b705cfSriastradh trap->right.p1.x = trap->right.p2.x = x2; 30803b705cfSriastradh trap->bottom = trap->left.p2.y = trap->right.p2.y = y2; 30903b705cfSriastradh break; 31003b705cfSriastradh 31103b705cfSriastradh case GENERAL: 31203b705cfSriastradh x1 <<= 16; x2 <<= 16; 31303b705cfSriastradh y1 <<= 16; y2 <<= 16; 31403b705cfSriastradh 31503b705cfSriastradh trap->top = y1 + rand() % (y2 - y1); 31603b705cfSriastradh trap->bottom = y1 + rand() % (y2 - y1); 31703b705cfSriastradh 31803b705cfSriastradh trap->left.p1.x = x1 + rand() % (x2 - x1); 31903b705cfSriastradh trap->left.p2.x = x1 + rand() % (x2 - x1); 32003b705cfSriastradh 32103b705cfSriastradh trap->right.p1.x = x1 + rand() % (x2 - x1); 32203b705cfSriastradh trap->right.p2.x = x1 + rand() % (x2 - x1); 32303b705cfSriastradh break; 32403b705cfSriastradh 32503b705cfSriastradh } 32603b705cfSriastradh} 32703b705cfSriastradh 32803b705cfSriastradhstatic void trap_tests(struct test *t, 32903b705cfSriastradh enum mask mask, 33003b705cfSriastradh enum trapezoid trapezoid, 33103b705cfSriastradh int reps, int sets, 33203b705cfSriastradh enum target target) 33303b705cfSriastradh{ 33442542f5fSchristos struct test_target out, ref; 33503b705cfSriastradh XTrapezoid *traps; 33603b705cfSriastradh int max_traps = 65536; 33703b705cfSriastradh int r, s, n; 33803b705cfSriastradh 33903b705cfSriastradh traps = malloc(sizeof(*traps) * max_traps); 34003b705cfSriastradh if (traps == NULL) 34103b705cfSriastradh return; 34203b705cfSriastradh 34303b705cfSriastradh printf("Testing trapezoids (%s with mask %s) (%s): ", 34403b705cfSriastradh trapezoid_name(trapezoid), 34503b705cfSriastradh mask_name(mask), 34603b705cfSriastradh test_target_name(target)); 34703b705cfSriastradh fflush(stdout); 34803b705cfSriastradh 34942542f5fSchristos test_target_create_render(&t->out, target, &out); 35042542f5fSchristos clear(&t->out, &out); 35103b705cfSriastradh 35203b705cfSriastradh test_target_create_render(&t->ref, target, &ref); 35303b705cfSriastradh clear(&t->ref, &ref); 35403b705cfSriastradh 35503b705cfSriastradh for (s = 0; s < sets; s++) { 35603b705cfSriastradh for (r = 0; r < reps; r++) { 35703b705cfSriastradh XRenderColor render_color; 35803b705cfSriastradh int op = ops[rand() % sizeof(ops)]; 35903b705cfSriastradh int red = rand() % 0xff; 36003b705cfSriastradh int green = rand() % 0xff; 36103b705cfSriastradh int blue = rand() % 0xff; 36203b705cfSriastradh int alpha = rand() % 0xff; 36303b705cfSriastradh int num_traps = rand() % max_traps; 36403b705cfSriastradh Picture src; 36503b705cfSriastradh 36603b705cfSriastradh for (n = 0; n < num_traps; n++) 36703b705cfSriastradh random_trapezoid(&traps[n], 0, 36842542f5fSchristos 0, 0, out.width, out.height); 36903b705cfSriastradh 37003b705cfSriastradh render_color.red = red * alpha; 37103b705cfSriastradh render_color.green = green * alpha; 37203b705cfSriastradh render_color.blue = blue * alpha; 37303b705cfSriastradh render_color.alpha = alpha << 8; 37403b705cfSriastradh 37542542f5fSchristos src = XRenderCreateSolidFill(t->out.dpy, 37603b705cfSriastradh &render_color); 37742542f5fSchristos XRenderCompositeTrapezoids(t->out.dpy, 37842542f5fSchristos op, src, out.picture, 37942542f5fSchristos mask_format(t->out.dpy, mask), 38003b705cfSriastradh 0, 0, traps, num_traps); 38142542f5fSchristos XRenderFreePicture(t->out.dpy, src); 38203b705cfSriastradh 38303b705cfSriastradh src = XRenderCreateSolidFill(t->ref.dpy, 38403b705cfSriastradh &render_color); 38503b705cfSriastradh XRenderCompositeTrapezoids(t->ref.dpy, 38603b705cfSriastradh op, src, ref.picture, 38703b705cfSriastradh mask_format(t->ref.dpy, mask), 38803b705cfSriastradh 0, 0, traps, num_traps); 38903b705cfSriastradh XRenderFreePicture(t->ref.dpy, src); 39003b705cfSriastradh } 39103b705cfSriastradh 39203b705cfSriastradh test_compare(t, 39342542f5fSchristos out.draw, out.format, 39403b705cfSriastradh ref.draw, ref.format, 39542542f5fSchristos 0, 0, out.width, out.height, 39603b705cfSriastradh ""); 39703b705cfSriastradh } 39803b705cfSriastradh 39903b705cfSriastradh printf("passed [%d iterations x %d]\n", reps, sets); 40003b705cfSriastradh 40142542f5fSchristos test_target_destroy_render(&t->out, &out); 40203b705cfSriastradh test_target_destroy_render(&t->ref, &ref); 40303b705cfSriastradh free(traps); 40403b705cfSriastradh} 40503b705cfSriastradh 406fe8aea9eSmrgenum edge { 407fe8aea9eSmrg EDGE_SHARP = PolyEdgeSharp, 408fe8aea9eSmrg EDGE_SMOOTH, 409fe8aea9eSmrg}; 410fe8aea9eSmrg 411fe8aea9eSmrgstatic const char *edge_name(enum edge edge) 412fe8aea9eSmrg{ 413fe8aea9eSmrg switch (edge) { 414fe8aea9eSmrg default: 415fe8aea9eSmrg case EDGE_SHARP: return "sharp"; 416fe8aea9eSmrg case EDGE_SMOOTH: return "smooth"; 417fe8aea9eSmrg } 418fe8aea9eSmrg} 419fe8aea9eSmrg 420fe8aea9eSmrgstatic void set_edge(Display *dpy, Picture p, enum edge edge) 421fe8aea9eSmrg{ 422fe8aea9eSmrg XRenderPictureAttributes a; 423fe8aea9eSmrg 424fe8aea9eSmrg a.poly_edge = edge; 425fe8aea9eSmrg XRenderChangePicture(dpy, p, CPPolyEdge, &a); 426fe8aea9eSmrg} 427fe8aea9eSmrg 428fe8aea9eSmrgstatic void edge_test(struct test *t, 429fe8aea9eSmrg enum mask mask, 430fe8aea9eSmrg enum edge edge, 431fe8aea9eSmrg enum target target) 432fe8aea9eSmrg{ 433fe8aea9eSmrg struct test_target out, ref; 434fe8aea9eSmrg XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; 435fe8aea9eSmrg Picture src_ref, src_out; 436fe8aea9eSmrg XTrapezoid trap; 437fe8aea9eSmrg int left_or_right, p; 438fe8aea9eSmrg 439fe8aea9eSmrg test_target_create_render(&t->out, target, &out); 440fe8aea9eSmrg set_edge(t->out.dpy, out.picture, edge); 441fe8aea9eSmrg src_out = XRenderCreateSolidFill(t->out.dpy, &white); 442fe8aea9eSmrg 443fe8aea9eSmrg test_target_create_render(&t->ref, target, &ref); 444fe8aea9eSmrg set_edge(t->ref.dpy, ref.picture, edge); 445fe8aea9eSmrg src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); 446fe8aea9eSmrg 447fe8aea9eSmrg printf("Testing edges (with mask %s and %s edges) (%s): ", 448fe8aea9eSmrg mask_name(mask), 449fe8aea9eSmrg edge_name(edge), 450fe8aea9eSmrg test_target_name(target)); 451fe8aea9eSmrg fflush(stdout); 452fe8aea9eSmrg 453fe8aea9eSmrg for (left_or_right = 0; left_or_right <= 1; left_or_right++) { 454fe8aea9eSmrg for (p = -64; p <= out.width + 64; p++) { 455fe8aea9eSmrg char buf[80]; 456fe8aea9eSmrg 457fe8aea9eSmrg if (left_or_right) { 458fe8aea9eSmrg trap.left.p1.x = 0; 459fe8aea9eSmrg trap.left.p1.y = 0; 460fe8aea9eSmrg trap.left.p2.x = 0; 461fe8aea9eSmrg trap.left.p2.y = out.height << 16; 462fe8aea9eSmrg 463fe8aea9eSmrg trap.right.p1.x = p << 16; 464fe8aea9eSmrg trap.right.p1.y = 0; 465fe8aea9eSmrg trap.right.p2.x = out.width << 16; 466fe8aea9eSmrg trap.right.p2.y = out.height << 16; 467fe8aea9eSmrg } else { 468fe8aea9eSmrg trap.right.p1.x = out.width << 16; 469fe8aea9eSmrg trap.right.p1.y = 0; 470fe8aea9eSmrg trap.right.p2.x = out.width << 16; 471fe8aea9eSmrg trap.right.p2.y = out.height << 16; 472fe8aea9eSmrg 473fe8aea9eSmrg trap.left.p1.x = 0; 474fe8aea9eSmrg trap.left.p1.y = 0; 475fe8aea9eSmrg trap.left.p2.x = p << 16; 476fe8aea9eSmrg trap.left.p2.y = out.height << 16; 477fe8aea9eSmrg } 478fe8aea9eSmrg 479fe8aea9eSmrg trap.top = 0; 480fe8aea9eSmrg trap.bottom = out.height << 16; 481fe8aea9eSmrg 482fe8aea9eSmrg sprintf(buf, 483fe8aea9eSmrg "trap=((%d, %d), (%d, %d)), ((%d, %d), (%d, %d))\n", 484fe8aea9eSmrg trap.left.p1.x >> 16, trap.left.p1.y >> 16, 485fe8aea9eSmrg trap.left.p2.x >> 16, trap.left.p2.y >> 16, 486fe8aea9eSmrg trap.right.p1.x >> 16, trap.right.p1.y >> 16, 487fe8aea9eSmrg trap.right.p2.x >> 16, trap.right.p2.y >> 16); 488fe8aea9eSmrg 489fe8aea9eSmrg clear(&t->out, &out); 490fe8aea9eSmrg XRenderCompositeTrapezoids(t->out.dpy, 491fe8aea9eSmrg PictOpSrc, 492fe8aea9eSmrg src_out, 493fe8aea9eSmrg out.picture, 494fe8aea9eSmrg mask_format(t->out.dpy, mask), 495fe8aea9eSmrg 0, 0, 496fe8aea9eSmrg &trap, 1); 497fe8aea9eSmrg 498fe8aea9eSmrg clear(&t->ref, &ref); 499fe8aea9eSmrg XRenderCompositeTrapezoids(t->ref.dpy, 500fe8aea9eSmrg PictOpSrc, 501fe8aea9eSmrg src_ref, 502fe8aea9eSmrg ref.picture, 503fe8aea9eSmrg mask_format(t->ref.dpy, mask), 504fe8aea9eSmrg 0, 0, 505fe8aea9eSmrg &trap, 1); 506fe8aea9eSmrg 507fe8aea9eSmrg test_compare(t, 508fe8aea9eSmrg out.draw, out.format, 509fe8aea9eSmrg ref.draw, ref.format, 510fe8aea9eSmrg 0, 0, out.width, out.height, 511fe8aea9eSmrg buf); 512fe8aea9eSmrg } 513fe8aea9eSmrg } 514fe8aea9eSmrg 515fe8aea9eSmrg XRenderFreePicture(t->out.dpy, src_out); 516fe8aea9eSmrg test_target_destroy_render(&t->out, &out); 517fe8aea9eSmrg 518fe8aea9eSmrg XRenderFreePicture(t->ref.dpy, src_ref); 519fe8aea9eSmrg test_target_destroy_render(&t->ref, &ref); 520fe8aea9eSmrg 521fe8aea9eSmrg printf("pass\n"); 522fe8aea9eSmrg} 523fe8aea9eSmrg 52403b705cfSriastradhint main(int argc, char **argv) 52503b705cfSriastradh{ 52603b705cfSriastradh struct test test; 52703b705cfSriastradh int i, dx, dy; 52803b705cfSriastradh enum target target; 52903b705cfSriastradh enum mask mask; 530fe8aea9eSmrg enum edge edge; 53103b705cfSriastradh enum trapezoid trapezoid; 53203b705cfSriastradh 53303b705cfSriastradh test_init(&test, argc, argv); 53403b705cfSriastradh 535fe8aea9eSmrg for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { 536fe8aea9eSmrg for (mask = MASK_NONE; mask <= MASK_A8; mask++) 537fe8aea9eSmrg for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++) 538fe8aea9eSmrg edge_test(&test, mask, edge, target); 539fe8aea9eSmrg } 540fe8aea9eSmrg 54103b705cfSriastradh for (i = 0; i <= DEFAULT_ITERATIONS; i++) { 54242542f5fSchristos int reps = REPS(i), sets = SETS(i); 54303b705cfSriastradh 54403b705cfSriastradh for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { 54503b705cfSriastradh pixel_tests(&test, reps, sets, target); 54603b705cfSriastradh area_tests(&test, reps, sets, target); 54703b705cfSriastradh for (dy = 0; dy < 1 << 16; dy += 1 << 14) 54803b705cfSriastradh for (dx = 0; dx < 1 << 16; dx += 1 << 14) 54903b705cfSriastradh for (mask = MASK_NONE; mask <= MASK_A8; mask++) 55003b705cfSriastradh rect_tests(&test, dx, dy, mask, reps, sets, target); 55103b705cfSriastradh for (trapezoid = RECT_ALIGN; trapezoid <= GENERAL; trapezoid++) 55203b705cfSriastradh trap_tests(&test, mask, trapezoid, reps, sets, target); 55303b705cfSriastradh } 55403b705cfSriastradh } 55503b705cfSriastradh 55603b705cfSriastradh return 0; 55703b705cfSriastradh} 558