1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include <X11/Xutil.h> /* for XDestroyImage */
6
7#include "test.h"
8
9static void draw_rect(struct test_display *t, Drawable d, uint8_t alu,
10		      int x, int y, int w, int h, uint32_t fg, int lw)
11{
12	XGCValues val;
13	GC gc;
14
15	val.function = alu;
16	val.foreground = fg;
17	val.line_width = lw;
18
19	gc = XCreateGC(t->dpy, d, GCForeground | GCFunction | GCLineWidth, &val);
20	XDrawRectangle(t->dpy, d, gc, x, y, w, h);
21	XFreeGC(t->dpy, gc);
22}
23
24static void clear(struct test_display *dpy, struct test_target *tt)
25{
26	XRenderColor render_color = {0};
27	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
28			     0, 0, tt->width, tt->height);
29}
30
31static void zrect_tests(struct test *t, int reps, int sets, enum target target)
32{
33	struct test_target out, ref;
34	int r, s;
35
36	printf("Testing empty rects (%s): ", test_target_name(target));
37	fflush(stdout);
38
39	test_target_create_render(&t->out, target, &out);
40	clear(&t->out, &out);
41
42	test_target_create_render(&t->ref, target, &ref);
43	clear(&t->ref, &ref);
44
45	for (s = 0; s < sets; s++) {
46		for (r = 0; r < reps; r++) {
47			int x = rand() % (2*out.width) - out.width;
48			int y = rand() % (2*out.height) - out.height;
49			uint8_t alu = rand() % (GXset + 1);
50			uint32_t fg = rand();
51			uint32_t lw = rand() % 4;
52
53			draw_rect(&t->out, out.draw, alu,
54				  x, y, 0, 0, fg, lw);
55			draw_rect(&t->ref, ref.draw, alu,
56				  x, y, 0, 0, fg, lw);
57		}
58
59		test_compare(t,
60			     out.draw, out.format,
61			     ref.draw, ref.format,
62			     0, 0, out.width, out.height,
63			     "");
64	}
65
66	printf("passed [%d iterations x %d]\n", reps, sets);
67
68	test_target_destroy_render(&t->out, &out);
69	test_target_destroy_render(&t->ref, &ref);
70}
71
72static void hrect_tests(struct test *t, int reps, int sets, enum target target)
73{
74	struct test_target out, ref;
75	int r, s;
76
77	printf("Testing horizontal rects (%s): ", test_target_name(target));
78	fflush(stdout);
79
80	test_target_create_render(&t->out, target, &out);
81	clear(&t->out, &out);
82
83	test_target_create_render(&t->ref, target, &ref);
84	clear(&t->ref, &ref);
85
86	for (s = 0; s < sets; s++) {
87		for (r = 0; r < reps; r++) {
88			int x = rand() % (2*out.width) - out.width;
89			int y = rand() % (2*out.height) - out.height;
90			int w = rand() % (2*out.width);
91			uint8_t alu = rand() % (GXset + 1);
92			uint32_t fg = rand();
93			uint32_t lw = rand() % 4;
94
95			draw_rect(&t->out, out.draw, alu,
96				  x, y, w, 0, fg, lw);
97			draw_rect(&t->ref, ref.draw, alu,
98				  x, y, w, 0, fg, lw);
99		}
100
101		test_compare(t,
102			     out.draw, out.format,
103			     ref.draw, ref.format,
104			     0, 0, out.width, out.height,
105			     "");
106	}
107
108	printf("passed [%d iterations x %d]\n", reps, sets);
109
110	test_target_destroy_render(&t->out, &out);
111	test_target_destroy_render(&t->ref, &ref);
112}
113
114static void vrect_tests(struct test *t, int reps, int sets, enum target target)
115{
116	struct test_target out, ref;
117	int r, s;
118
119	printf("Testing vertical rects (%s): ", test_target_name(target));
120	fflush(stdout);
121
122	test_target_create_render(&t->out, target, &out);
123	clear(&t->out, &out);
124
125	test_target_create_render(&t->ref, target, &ref);
126	clear(&t->ref, &ref);
127
128	for (s = 0; s < sets; s++) {
129		for (r = 0; r < reps; r++) {
130			int x = rand() % (2*out.width) - out.width;
131			int y = rand() % (2*out.height) - out.height;
132			int h = rand() % (2*out.width);
133			uint8_t alu = rand() % (GXset + 1);
134			uint32_t fg = rand();
135			uint32_t lw = rand() % 4;
136
137			draw_rect(&t->out, out.draw, alu,
138				  x, y, 0, h, fg, lw);
139			draw_rect(&t->ref, ref.draw, alu,
140				  x, y, 0, h, fg, lw);
141		}
142
143		test_compare(t,
144			     out.draw, out.format,
145			     ref.draw, ref.format,
146			     0, 0, out.width, out.height,
147			     "");
148	}
149
150	printf("passed [%d iterations x %d]\n", reps, sets);
151
152	test_target_destroy_render(&t->out, &out);
153	test_target_destroy_render(&t->ref, &ref);
154}
155
156static void rect_tests(struct test *t, int reps, int sets, enum target target)
157{
158	struct test_target out, ref;
159	int r, s;
160
161	printf("Testing general (%s): ", test_target_name(target));
162	fflush(stdout);
163
164	test_target_create_render(&t->out, target, &out);
165	clear(&t->out, &out);
166
167	test_target_create_render(&t->ref, target, &ref);
168	clear(&t->ref, &ref);
169
170	for (s = 0; s < sets; s++) {
171		for (r = 0; r < reps; r++) {
172			int x = rand() % (2*out.width) - out.width;
173			int y = rand() % (2*out.height) - out.height;
174			int w = rand() % (2*out.width);
175			int h = rand() % (2*out.height);
176			uint8_t alu = rand() % (GXset + 1);
177			uint32_t fg = rand();
178			uint32_t lw = rand() % 4;
179
180			draw_rect(&t->out, out.draw, alu,
181				  x, y, w, h, fg, lw);
182			draw_rect(&t->ref, ref.draw, alu,
183				  x, y, w, h, fg, lw);
184		}
185
186		test_compare(t,
187			     out.draw, out.format,
188			     ref.draw, ref.format,
189			     0, 0, out.width, out.height,
190			     "");
191	}
192
193	printf("passed [%d iterations x %d]\n", reps, sets);
194
195	test_target_destroy_render(&t->out, &out);
196	test_target_destroy_render(&t->ref, &ref);
197}
198
199int main(int argc, char **argv)
200{
201	struct test test;
202	int i;
203
204	test_init(&test, argc, argv);
205
206	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
207		int reps = REPS(i), sets = SETS(i);
208		enum target t;
209
210		for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
211			zrect_tests(&test, reps, sets, t);
212			hrect_tests(&test, reps, sets, t);
213			vrect_tests(&test, reps, sets, t);
214			rect_tests(&test, reps, sets, t);
215		}
216	}
217
218	return 0;
219}
220