142542f5fSchristos#include <stdint.h>
242542f5fSchristos#include <stdio.h>
342542f5fSchristos#include <stdlib.h>
442542f5fSchristos
542542f5fSchristos#include <X11/Xutil.h> /* for XDestroyImage */
642542f5fSchristos#include <pixman.h> /* for pixman blt functions */
742542f5fSchristos
842542f5fSchristos#include "test.h"
942542f5fSchristos
1042542f5fSchristosstatic const uint8_t ops[] = {
1142542f5fSchristos	PictOpClear,
1242542f5fSchristos	PictOpSrc,
1342542f5fSchristos	PictOpDst,
1442542f5fSchristos};
1542542f5fSchristos
1642542f5fSchristosstatic void fill_rect(struct test_display *dpy, Picture p, uint8_t op,
1742542f5fSchristos		      int x, int y, int w, int h,
1842542f5fSchristos		      uint8_t s_red, uint8_t s_green, uint8_t s_blue, uint8_t s_alpha,
1942542f5fSchristos		      uint8_t m_red, uint8_t m_green, uint8_t m_blue, uint8_t m_alpha)
2042542f5fSchristos{
2142542f5fSchristos	XRenderColor render_color;
2242542f5fSchristos	Picture source, mask;
2342542f5fSchristos
2442542f5fSchristos	render_color.red   = s_red * s_alpha;
2542542f5fSchristos	render_color.green = s_green * s_alpha;
2642542f5fSchristos	render_color.blue  = s_blue * s_alpha;
2742542f5fSchristos	render_color.alpha = s_alpha << 8 | s_alpha;
2842542f5fSchristos	source = XRenderCreateSolidFill(dpy->dpy, &render_color);
2942542f5fSchristos
3042542f5fSchristos	render_color.red   = m_red * m_alpha;
3142542f5fSchristos	render_color.green = m_green * m_alpha;
3242542f5fSchristos	render_color.blue  = m_blue * m_alpha;
3342542f5fSchristos	render_color.alpha = m_alpha << 8 | m_alpha;
3442542f5fSchristos	mask = XRenderCreateSolidFill(dpy->dpy, &render_color);
3542542f5fSchristos
3642542f5fSchristos	XRenderComposite(dpy->dpy, op, source, mask, p, 0, 0, 0, 0, x, y, w,h);
3742542f5fSchristos
3842542f5fSchristos	XRenderFreePicture(dpy->dpy, mask);
3942542f5fSchristos	XRenderFreePicture(dpy->dpy, source);
4042542f5fSchristos}
4142542f5fSchristos
4242542f5fSchristosstatic void clear(struct test_display *dpy, struct test_target *tt)
4342542f5fSchristos{
4442542f5fSchristos	XRenderColor render_color = {0};
4542542f5fSchristos	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
4642542f5fSchristos			     0, 0, tt->width, tt->height);
4742542f5fSchristos}
4842542f5fSchristos
4942542f5fSchristosstatic void ref_tests(struct test *t, int reps, int sets, enum target target)
5042542f5fSchristos{
5142542f5fSchristos	struct test_target out, ref;
5242542f5fSchristos	int r, s;
5342542f5fSchristos
5442542f5fSchristos	printf("Testing area fills (%s): ", test_target_name(target));
5542542f5fSchristos	fflush(stdout);
5642542f5fSchristos
5742542f5fSchristos	test_target_create_render(&t->out, target, &out);
5842542f5fSchristos	clear(&t->out, &out);
5942542f5fSchristos
6042542f5fSchristos	test_target_create_render(&t->ref, target, &ref);
6142542f5fSchristos	clear(&t->ref, &ref);
6242542f5fSchristos
6342542f5fSchristos	for (s = 0; s < sets; s++) {
6442542f5fSchristos		for (r = 0; r < reps; r++) {
6542542f5fSchristos			int x = rand() % (2*out.width) - out.width;
6642542f5fSchristos			int y = rand() % (2*out.height) - out.height;
6742542f5fSchristos			int w = rand() % out.width;
6842542f5fSchristos			int h = rand() % out.height;
6942542f5fSchristos			int op = ops[rand() % sizeof(ops)];
7042542f5fSchristos			int s_red = rand() % 0xff;
7142542f5fSchristos			int s_green = rand() % 0xff;
7242542f5fSchristos			int s_blue = rand() % 0xff;
7342542f5fSchristos			int s_alpha = rand() % 0xff;
7442542f5fSchristos			int m_red = rand() % 0xff;
7542542f5fSchristos			int m_green = rand() % 0xff;
7642542f5fSchristos			int m_blue = rand() % 0xff;
7742542f5fSchristos			int m_alpha = rand() % 0xff;
7842542f5fSchristos
7942542f5fSchristos			fill_rect(&t->out, out.picture,
8042542f5fSchristos				  op, x, y, w, h,
8142542f5fSchristos				  s_red, s_green, s_blue, s_alpha,
8242542f5fSchristos				  m_red, m_green, m_blue, m_alpha);
8342542f5fSchristos			fill_rect(&t->ref, ref.picture,
8442542f5fSchristos				  op, x, y, w, h,
8542542f5fSchristos				  s_red, s_green, s_blue, s_alpha,
8642542f5fSchristos				  m_red, m_green, m_blue, m_alpha);
8742542f5fSchristos		}
8842542f5fSchristos
8942542f5fSchristos		test_compare(t,
9042542f5fSchristos			     out.draw, out.format,
9142542f5fSchristos			     ref.draw, ref.format,
9242542f5fSchristos			     0, 0, out.width, out.height,
9342542f5fSchristos			     "");
9442542f5fSchristos	}
9542542f5fSchristos
9642542f5fSchristos	printf("passed [%d iterations x %d]\n", reps, sets);
9742542f5fSchristos
9842542f5fSchristos	test_target_destroy_render(&t->out, &out);
9942542f5fSchristos	test_target_destroy_render(&t->ref, &ref);
10042542f5fSchristos}
10142542f5fSchristos
10242542f5fSchristosint main(int argc, char **argv)
10342542f5fSchristos{
10442542f5fSchristos	struct test test;
10542542f5fSchristos	int i;
10642542f5fSchristos
10742542f5fSchristos	test_init(&test, argc, argv);
10842542f5fSchristos
10942542f5fSchristos	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
11042542f5fSchristos		int reps = REPS(i), sets = SETS(i);
11142542f5fSchristos		enum target t;
11242542f5fSchristos
11342542f5fSchristos		for (t = TARGET_FIRST; t <= TARGET_LAST; t++)
11442542f5fSchristos			ref_tests(&test, reps, sets, t);
11542542f5fSchristos	}
11642542f5fSchristos
11742542f5fSchristos	return 0;
11842542f5fSchristos}
119