1fe8aea9eSmrg#include <stdint.h>
2fe8aea9eSmrg#include <stdio.h>
3fe8aea9eSmrg#include <stdlib.h>
4fe8aea9eSmrg
5fe8aea9eSmrg#include <X11/Xutil.h> /* for XDestroyImage */
6fe8aea9eSmrg#include <pixman.h> /* for pixman blt functions */
7fe8aea9eSmrg
8fe8aea9eSmrg#include "test.h"
9fe8aea9eSmrg
10fe8aea9eSmrgstatic uint8_t clock_bits[] = {0x3C, 0x5E, 0xEF, 0xF7, 0x87, 0xFF, 0x7E, 0x3C};
11fe8aea9eSmrg
12fe8aea9eSmrg/* https://bugs.freedesktop.org/show_bug.cgi?id=91499 */
13fe8aea9eSmrgstatic void draw_clock(struct test_display *t, Drawable d,
14fe8aea9eSmrg		       uint8_t alu, int x, int y, uint32_t fg, uint32_t bg)
15fe8aea9eSmrg{
16fe8aea9eSmrg	Pixmap pixmap;
17fe8aea9eSmrg	XGCValues val;
18fe8aea9eSmrg	GC gc;
19fe8aea9eSmrg
20fe8aea9eSmrg	val.graphics_exposures = 0;
21fe8aea9eSmrg	val.function = alu;
22fe8aea9eSmrg	val.foreground = fg;
23fe8aea9eSmrg	val.background = fg;
24fe8aea9eSmrg
25fe8aea9eSmrg	gc = XCreateGC(t->dpy, d,
26fe8aea9eSmrg		       GCGraphicsExposures | GCForeground | GCBackground | GCFunction,
27fe8aea9eSmrg		       &val);
28fe8aea9eSmrg	pixmap = XCreateBitmapFromData(t->dpy, d, (char *)clock_bits, 8, 8);
29fe8aea9eSmrg
30fe8aea9eSmrg	XCopyPlane(t->dpy, pixmap, d, gc, 0, 0, 8, 8, x, y, 1);
31fe8aea9eSmrg
32fe8aea9eSmrg	XFreePixmap(t->dpy, pixmap);
33fe8aea9eSmrg	XFreeGC(t->dpy, gc);
34fe8aea9eSmrg}
35fe8aea9eSmrg
36fe8aea9eSmrgstatic void clear(struct test_display *dpy, struct test_target *tt)
37fe8aea9eSmrg{
38fe8aea9eSmrg	XRenderColor render_color = {0};
39fe8aea9eSmrg	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
40fe8aea9eSmrg			     0, 0, tt->width, tt->height);
41fe8aea9eSmrg}
42fe8aea9eSmrg
43fe8aea9eSmrgstatic void clock_tests(struct test *t, int reps, int sets, enum target target)
44fe8aea9eSmrg{
45fe8aea9eSmrg	struct test_target out, ref;
46fe8aea9eSmrg	int r, s;
47fe8aea9eSmrg
48fe8aea9eSmrg	printf("Testing clock (%s): ", test_target_name(target));
49fe8aea9eSmrg	fflush(stdout);
50fe8aea9eSmrg
51fe8aea9eSmrg	test_target_create_render(&t->out, target, &out);
52fe8aea9eSmrg	clear(&t->out, &out);
53fe8aea9eSmrg
54fe8aea9eSmrg	test_target_create_render(&t->ref, target, &ref);
55fe8aea9eSmrg	clear(&t->ref, &ref);
56fe8aea9eSmrg
57fe8aea9eSmrg	for (s = 0; s < sets; s++) {
58fe8aea9eSmrg		for (r = 0; r < reps; r++) {
59fe8aea9eSmrg			int x = rand() % (out.width - 8);
60fe8aea9eSmrg			int y = rand() % (out.height - 8);
61fe8aea9eSmrg			uint8_t alu = rand() % (GXset + 1);
62fe8aea9eSmrg			uint32_t bg = rand();
63fe8aea9eSmrg			uint32_t fg = rand();
64fe8aea9eSmrg
65fe8aea9eSmrg			draw_clock(&t->out, out.draw, alu, x, y, fg, bg);
66fe8aea9eSmrg			draw_clock(&t->ref, ref.draw, alu, x, y, fg, bg);
67fe8aea9eSmrg		}
68fe8aea9eSmrg
69fe8aea9eSmrg		test_compare(t,
70fe8aea9eSmrg			     out.draw, out.format,
71fe8aea9eSmrg			     ref.draw, ref.format,
72fe8aea9eSmrg			     0, 0, out.width, out.height,
73fe8aea9eSmrg			     "");
74fe8aea9eSmrg	}
75fe8aea9eSmrg
76fe8aea9eSmrg	printf("passed [%d iterations x %d]\n", reps, sets);
77fe8aea9eSmrg
78fe8aea9eSmrg	test_target_destroy_render(&t->out, &out);
79fe8aea9eSmrg	test_target_destroy_render(&t->ref, &ref);
80fe8aea9eSmrg}
81fe8aea9eSmrg
82fe8aea9eSmrgint main(int argc, char **argv)
83fe8aea9eSmrg{
84fe8aea9eSmrg	struct test test;
85fe8aea9eSmrg	int i;
86fe8aea9eSmrg
87fe8aea9eSmrg	test_init(&test, argc, argv);
88fe8aea9eSmrg
89fe8aea9eSmrg	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
90fe8aea9eSmrg		int reps = REPS(i), sets = SETS(i);
91fe8aea9eSmrg		enum target t;
92fe8aea9eSmrg
93fe8aea9eSmrg		for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
94fe8aea9eSmrg			clock_tests(&test, reps, sets, t);
95fe8aea9eSmrg		}
96fe8aea9eSmrg	}
97fe8aea9eSmrg
98fe8aea9eSmrg	return 0;
99fe8aea9eSmrg}
100