summaryrefslogtreecommitdiff
path: root/test/test.h
blob: 9eec1cf9b52f45d596a34ad210e4112902d73c93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef TEST_H
#define TEST_H

#include <stdint.h>
#include <time.h>

#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xrender.h>

#define DEFAULT_ITERATIONS 20

enum target {
	ROOT,
	CHILD,
	PIXMAP,
};
#define TARGET_FIRST ROOT
#define TARGET_LAST PIXMAP

enum mask {
	MASK_NONE,
	MASK_NONE_AA,
	MASK_A1,
	MASK_A8,
};

struct test {
	struct test_display {
		Display *dpy;
		Window root;
		XShmSegmentInfo shm;
		int max_shm_size;
		int has_shm_pixmaps;
		int width, height, depth;
		XRenderPictFormat *format;
		enum { REF, OUT } target;
	} out, ref;
};

void die(const char *fmt, ...);

#define die_unless(expr) do{ if (!(expr)) die("verification failed: %s\n", #expr); } while(0)

void test_init(struct test *test, int argc, char **argv);

void test_compare(struct test *out,
		  Drawable out_draw, XRenderPictFormat *out_format,
		  Drawable ref_draw, XRenderPictFormat *ref_format,
		  int x, int y, int w, int h, const char *info);

#define MAX_DELTA 3
int pixel_difference(uint32_t a, uint32_t b);

static inline int pixel_equal(int depth, uint32_t a, uint32_t b)
{
	if (depth != 32) {
		uint32_t mask = (1 << depth) - 1;
		a &= mask;
		b &= mask;
	}

	if (a == b)
		return 1;

	return pixel_difference(a, b) < MAX_DELTA;
}

void
test_init_image(XImage *ximage,
		XShmSegmentInfo *shm,
		XRenderPictFormat *format,
		int width, int height);

const char *test_target_name(enum target target);

struct test_target {
	struct test_display *dpy;
	Drawable draw;
	GC gc;
	XRenderPictFormat *format;
	Picture picture;
	int width, height, depth;
	enum target target;
};

void test_target_create_render(struct test_display *dpy,
			       enum target target,
			       struct test_target *tt);
void test_target_destroy_render(struct test_display *dpy,
				struct test_target *tt);

static inline uint32_t depth_mask(int depth)
{
	if (depth == 32)
		return 0xffffffff;
	else
		return (1 << depth) - 1;
}

static inline uint32_t color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
	uint16_t ra = red * alpha;
	uint16_t ga = green * alpha;
	uint16_t ba = blue * alpha;

	return alpha << 24 | ra >> 8 << 16 | ga >> 8 << 8 | ba >> 8;
}

static inline uint32_t xrender_color(const XRenderColor *c)
{
	uint32_t ra = c->red * c->alpha;
	uint32_t ga = c->green * c->alpha;
	uint32_t ba = c->blue * c->alpha;

	return c->alpha >> 8 << 24 | ra >> 24 << 16 | ga >> 24 << 8 | ba >> 24;
}

void test_timer_start(struct test_display *t, struct timespec *tv);
double test_timer_stop(struct test_display *t, struct timespec *tv);

#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#endif

#define SETS(I) ((I) >= 12 ? 1 : 1 << (12 - (I)))
#define REPS(I) (1 << (I))

#endif