103b705cfSriastradh#include <stdint.h>
203b705cfSriastradh#include <stdio.h>
303b705cfSriastradh#include <stdlib.h>
403b705cfSriastradh
503b705cfSriastradh#include <X11/Xutil.h> /* for XDestroyImage */
603b705cfSriastradh#include <pixman.h>
703b705cfSriastradh
803b705cfSriastradh#include "test.h"
903b705cfSriastradh
1003b705cfSriastradhstatic void fill_rect(struct test_target *tt,
1103b705cfSriastradh		      int alu, int color,
1203b705cfSriastradh		      int x, int y, int w, int h)
1303b705cfSriastradh{
1403b705cfSriastradh	XGCValues val;
1503b705cfSriastradh
1603b705cfSriastradh	val.function = alu;
1703b705cfSriastradh	val.foreground = color;
1803b705cfSriastradh	XChangeGC(tt->dpy->dpy, tt->gc, GCFunction | GCForeground, &val);
1903b705cfSriastradh
2003b705cfSriastradh	XFillRectangle(tt->dpy->dpy, tt->draw, tt->gc, x, y, w, h);
2103b705cfSriastradh}
2203b705cfSriastradh
2303b705cfSriastradhstatic void clear(struct test_target *tt)
2403b705cfSriastradh{
2503b705cfSriastradh	fill_rect(tt,
2603b705cfSriastradh		  GXcopy, 0,
2703b705cfSriastradh		  0, 0, tt->width, tt->height);
2803b705cfSriastradh}
2903b705cfSriastradh
3042542f5fSchristosstatic void fill(struct test_target *out,
3103b705cfSriastradh		 struct test_target *ref)
3203b705cfSriastradh{
3342542f5fSchristos	int x = rand() % (2*out->width) - out->width;
3442542f5fSchristos	int y = rand() % (2*out->height) - out->height;
3542542f5fSchristos	int w = rand() % (2*out->width);
3642542f5fSchristos	int h = rand() % (2*out->height);
3703b705cfSriastradh	int color = rand();
3803b705cfSriastradh	int alu = rand() % 16;
3903b705cfSriastradh
4042542f5fSchristos	fill_rect(out, alu, color, x, y, w, h);
4103b705cfSriastradh	fill_rect(ref, alu, color, x, y, w, h);
4203b705cfSriastradh}
4303b705cfSriastradh
4442542f5fSchristosstatic void copy(struct test_target *out,
4503b705cfSriastradh		 struct test_target *ref)
4603b705cfSriastradh{
4742542f5fSchristos	int sx = rand() % (2*out->width) - ref->width;
4842542f5fSchristos	int sy = rand() % (2*out->height) - ref->height;
4942542f5fSchristos	int dx = rand() % (2*out->width) - ref->width;
5042542f5fSchristos	int dy = rand() % (2*out->height) - ref->height;
5142542f5fSchristos	int w = rand() % (2*out->width);
5242542f5fSchristos	int h = rand() % (2*out->height);
5303b705cfSriastradh	XGCValues val;
5403b705cfSriastradh
5503b705cfSriastradh	val.function = rand() % 16;
5603b705cfSriastradh
5742542f5fSchristos	XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val);
5842542f5fSchristos	XCopyArea(out->dpy->dpy,
5942542f5fSchristos		  out->draw, out->draw, out->gc,
6003b705cfSriastradh		  sx, sy, w, h, dx, dy);
6103b705cfSriastradh
6203b705cfSriastradh	XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val);
6303b705cfSriastradh	XCopyArea(ref->dpy->dpy,
6403b705cfSriastradh		  ref->draw, ref->draw, ref->gc,
6503b705cfSriastradh		  sx, sy, w, h, dx, dy);
6603b705cfSriastradh}
6703b705cfSriastradh
6803b705cfSriastradhstatic void _put(struct test_target *tt,
6903b705cfSriastradh		 int x, int y, int w,int h, int color, int alu)
7003b705cfSriastradh{
7103b705cfSriastradh	XImage image;
7203b705cfSriastradh	XGCValues val;
7303b705cfSriastradh
7403b705cfSriastradh	val.function = alu;
7503b705cfSriastradh
7603b705cfSriastradh	test_init_image(&image, &tt->dpy->shm, tt->format, w, h);
7703b705cfSriastradh	pixman_fill((uint32_t*)image.data,
7803b705cfSriastradh		    image.bytes_per_line/sizeof(uint32_t),
7903b705cfSriastradh		    image.bits_per_pixel,
8003b705cfSriastradh		    0, 0, w, h, color);
8103b705cfSriastradh
8203b705cfSriastradh	XChangeGC(tt->dpy->dpy, tt->gc, GCFunction, &val);
8303b705cfSriastradh	if (rand() & 1) {
8403b705cfSriastradh		XShmPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image,
8503b705cfSriastradh			     0, 0, x, y, w, h, 0);
8603b705cfSriastradh		XSync(tt->dpy->dpy, 1);
8703b705cfSriastradh	} else {
8803b705cfSriastradh		XPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image,
8903b705cfSriastradh			  0, 0, x, y, w, h);
9003b705cfSriastradh	}
9103b705cfSriastradh}
9203b705cfSriastradh
9342542f5fSchristosstatic void put(struct test_target *out,
9403b705cfSriastradh		struct test_target *ref)
9503b705cfSriastradh{
9642542f5fSchristos	int x = rand() % (2*out->width) - out->width;
9742542f5fSchristos	int y = rand() % (2*out->height) - out->height;
9842542f5fSchristos	int w = rand() % out->width;
9942542f5fSchristos	int h = rand() % out->height;
10003b705cfSriastradh	int color = rand();
10103b705cfSriastradh	int alu = rand() % 16;
10203b705cfSriastradh
10342542f5fSchristos	_put(out, x, y, w, h, color, alu);
10403b705cfSriastradh	_put(ref, x, y, w, h, color, alu);
10503b705cfSriastradh}
10603b705cfSriastradh
10703b705cfSriastradhstatic void rect_tests(struct test *test, int iterations, enum target target)
10803b705cfSriastradh{
10942542f5fSchristos	struct test_target out, ref;
11003b705cfSriastradh	void (* const ops[])(struct test_target *, struct test_target *) = {
11103b705cfSriastradh		copy,
11203b705cfSriastradh		fill,
11303b705cfSriastradh		put,
11403b705cfSriastradh	};
11503b705cfSriastradh	int n;
11603b705cfSriastradh
11703b705cfSriastradh	printf("Running mixed ops stress against %s: ",
11803b705cfSriastradh	       test_target_name(target));
11903b705cfSriastradh	fflush(stdout);
12003b705cfSriastradh
12142542f5fSchristos	test_target_create_render(&test->out, target, &out);
12203b705cfSriastradh	test_target_create_render(&test->ref, target, &ref);
12303b705cfSriastradh
12442542f5fSchristos	clear(&out);
12503b705cfSriastradh	clear(&ref);
12603b705cfSriastradh
12703b705cfSriastradh	for (n = 0; n < iterations; n++)
12842542f5fSchristos		ops[rand() % ARRAY_SIZE(ops)](&out, &ref);
12903b705cfSriastradh
13003b705cfSriastradh	test_compare(test,
13142542f5fSchristos		     out.draw, out.format,
13203b705cfSriastradh		     ref.draw, ref.format,
13342542f5fSchristos		     0, 0, out.width, out.height,
13403b705cfSriastradh		     "");
13503b705cfSriastradh
13603b705cfSriastradh	printf("passed [%d iterations]\n", n);
13703b705cfSriastradh
13842542f5fSchristos	test_target_destroy_render(&test->out, &out);
13903b705cfSriastradh	test_target_destroy_render(&test->ref, &ref);
14003b705cfSriastradh}
14103b705cfSriastradh
14203b705cfSriastradhint main(int argc, char **argv)
14303b705cfSriastradh{
14403b705cfSriastradh	struct test test;
14503b705cfSriastradh	int i;
14603b705cfSriastradh
14703b705cfSriastradh	test_init(&test, argc, argv);
14803b705cfSriastradh
14903b705cfSriastradh	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
15042542f5fSchristos		int iterations = REPS(i);
15103b705cfSriastradh		rect_tests(&test, iterations, 0);
15203b705cfSriastradh		rect_tests(&test, iterations, 1);
15303b705cfSriastradh	}
15403b705cfSriastradh
15503b705cfSriastradh	return 0;
15603b705cfSriastradh}
157