1#include <stdint.h> 2#include <stdio.h> 3#include <stdlib.h> 4 5#include "test.h" 6 7enum edge { 8 EDGE_SHARP = PolyEdgeSharp, 9 EDGE_SMOOTH, 10}; 11 12static void set_edge(Display *dpy, Picture p, enum edge edge) 13{ 14 XRenderPictureAttributes a; 15 16 a.poly_edge = edge; 17 XRenderChangePicture(dpy, p, CPPolyEdge, &a); 18} 19 20static XRenderPictFormat *mask_format(Display *dpy, enum mask mask) 21{ 22 switch (mask) { 23 default: 24 case MASK_NONE: return NULL; 25 case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1); 26 case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8); 27 } 28} 29 30static const char *mask_name(enum mask mask) 31{ 32 switch (mask) { 33 default: 34 case MASK_NONE: return "none"; 35 case MASK_A1: return "a1"; 36 case MASK_A8: return "a8"; 37 } 38} 39 40static const char *edge_name(enum edge edge) 41{ 42 switch (edge) { 43 default: 44 case EDGE_SHARP: return "sharp"; 45 case EDGE_SMOOTH: return "smooth"; 46 } 47} 48 49static void clear(struct test_display *dpy, struct test_target *tt) 50{ 51 XRenderColor render_color = {0}; 52 XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 53 0, 0, tt->width, tt->height); 54} 55 56static void step_to_point(int step, int width, int height, XPointFixed *p) 57{ 58 do { 59 p->x = (step - 64) << 16; 60 p->y = -64 << 16; 61 62 step -= width - 128; 63 if (step <= 0) 64 return; 65 66 p->x = (width + 64) << 16; 67 p->y = (step - 64) << 16; 68 step -= height - 128; 69 70 if (step <= 0) 71 return; 72 73 p->x = (width + 64 - step) << 16; 74 p->y = (height + 64) << 16; 75 step -= width - 128; 76 77 if (step <= 0) 78 return; 79 80 p->x = -64 << 16; 81 p->y = (height + 64 - step) << 16; 82 step -= height - 128; 83 } while (step > 0); 84} 85 86static void edge_test(struct test *t, 87 enum mask mask, 88 enum edge edge, 89 enum target target) 90{ 91 struct test_target out, ref; 92 XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; 93 Picture src_ref, src_out; 94 XTriangle tri; 95 unsigned step, max; 96 97 test_target_create_render(&t->out, target, &out); 98 set_edge(t->out.dpy, out.picture, edge); 99 src_out = XRenderCreateSolidFill(t->out.dpy, &white); 100 101 test_target_create_render(&t->ref, target, &ref); 102 set_edge(t->ref.dpy, ref.picture, edge); 103 src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); 104 105 printf("Testing edges (with mask %s and %s edges) (%s): ", 106 mask_name(mask), 107 edge_name(edge), 108 test_target_name(target)); 109 fflush(stdout); 110 111 max = 2*(out.width + 128 + out.height+128); 112 step = 0; 113 for (step = 0; step <= max; step++) { 114 char buf[80]; 115 116 step_to_point(step, out.width, out.height, &tri.p1); 117 step_to_point(step + out.width + 128, 118 out.width, out.height, 119 &tri.p2); 120 step_to_point(step + out.height + 128 + 2*(out.width + 128), 121 out.width, out.height, 122 &tri.p3); 123 124 sprintf(buf, 125 "tri=((%d, %d), (%d, %d), (%d, %d))\n", 126 tri.p1.x >> 16, tri.p1.y >> 16, 127 tri.p2.x >> 16, tri.p2.y >> 16, 128 tri.p3.x >> 16, tri.p3.y >> 16); 129 130 clear(&t->out, &out); 131 XRenderCompositeTriangles(t->out.dpy, 132 PictOpSrc, 133 src_out, 134 out.picture, 135 mask_format(t->out.dpy, mask), 136 0, 0, 137 &tri, 1); 138 139 clear(&t->ref, &ref); 140 XRenderCompositeTriangles(t->ref.dpy, 141 PictOpSrc, 142 src_ref, 143 ref.picture, 144 mask_format(t->ref.dpy, mask), 145 0, 0, 146 &tri, 1); 147 148 test_compare(t, 149 out.draw, out.format, 150 ref.draw, ref.format, 151 0, 0, out.width, out.height, 152 buf); 153 } 154 155 XRenderFreePicture(t->out.dpy, src_out); 156 test_target_destroy_render(&t->out, &out); 157 158 XRenderFreePicture(t->ref.dpy, src_ref); 159 test_target_destroy_render(&t->ref, &ref); 160 161 printf("pass\n"); 162} 163 164int main(int argc, char **argv) 165{ 166 struct test test; 167 enum target target; 168 enum mask mask; 169 enum edge edge; 170 171 test_init(&test, argc, argv); 172 173 for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { 174 for (mask = MASK_NONE; mask <= MASK_A8; mask++) 175 for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++) 176 edge_test(&test, mask, edge, target); 177 } 178 179 return 0; 180} 181