xf86-video-intel: 3 commits - configure.ac src/sna/kgem.c src/sna/sna_accel.c test/basic-copyarea.c test/basic-copyarea-size.c test/basic-fillrect.c test/basic-lines.c test/basic-putimage.c test/basic-rectangle.c test/basic-stippledrect.c test/basic-stress.c test/basic-string.c test/basic-tiledrect.c test/lowlevel-blt-bench.c test/mixed-stress.c test/render-composite-solid.c test/render-composite-solid-mask.c test/render-copy-alphaless.c test/render-copyarea.c test/render-copyarea-mask.c test/render-copyarea-size.c test/render-fill.c test/render-fill-copy.c test/render-trapezoid.c test/render-trapezoid-image.c test/test_display.c test/test.h test/test_image.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jun 20 07:12:58 PDT 2014


 configure.ac                       |    2 
 src/sna/kgem.c                     |    6 
 src/sna/sna_accel.c                |   48 +++--
 test/basic-copyarea-size.c         |   18 +-
 test/basic-copyarea.c              |   56 +++---
 test/basic-fillrect.c              |   52 +++---
 test/basic-lines.c                 |   14 -
 test/basic-putimage.c              |   52 +++---
 test/basic-rectangle.c             |   80 ++++-----
 test/basic-stippledrect.c          |   86 +++++-----
 test/basic-stress.c                |   58 +++----
 test/basic-string.c                |   18 +-
 test/basic-tiledrect.c             |  302 +++++++++++++++++++++++++++++--------
 test/lowlevel-blt-bench.c          |    8 
 test/mixed-stress.c                |   70 ++++----
 test/render-composite-solid-mask.c |   22 +-
 test/render-composite-solid.c      |   48 ++---
 test/render-copy-alphaless.c       |   52 +++---
 test/render-copyarea-mask.c        |   26 +--
 test/render-copyarea-size.c        |   16 -
 test/render-copyarea.c             |   56 +++---
 test/render-fill-copy.c            |   48 ++---
 test/render-fill.c                 |   48 ++---
 test/render-trapezoid-image.c      |   92 +++++------
 test/render-trapezoid.c            |   74 ++++-----
 test/test.h                        |    8 
 test/test_display.c                |   18 +-
 test/test_image.c                  |  152 ++++++++++++++----
 28 files changed, 902 insertions(+), 628 deletions(-)

New commits:
commit e5c68b4358ce541929681c8c1e0ad3ef8c1dc9ed
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jun 20 14:31:19 2014 +0100

    sna: Feed more operations into the 8x8 BLT tiler
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index d77f4c9..d607926 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11463,8 +11463,8 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 	BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
 	int16_t dx, dy;
 
-	DBG(("%s x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n",
-	     __FUNCTION__, n,
+	DBG(("%s pixmap=%ld x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n",
+	     __FUNCTION__, pixmap->drawable.serialNumber, n,
 	     rect->x, rect->y, rect->width, rect->height,
 	     drawable->x, drawable->y,
 	     clipped));
@@ -11482,6 +11482,9 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 				r.x1 += dx; r.y1 += dy;
 				r.x2 += dx; r.y2 += dy;
 			}
+			DBG(("%s: using fill_one() fast path: (%d, %d), (%d, %d). alu=%d, pixel=%08x\n",
+			     __FUNCTION__, r.x1, r.y1, r.x2, r.y2, gc->alu, pixel));
+
 			if (sna->render.fill_one(sna, pixmap, bo, pixel,
 						 r.x1, r.y1, r.x2, r.y2,
 						 gc->alu)) {
@@ -11647,7 +11650,7 @@ done:
 static uint32_t
 get_pixel(PixmapPtr pixmap)
 {
-	DBG(("%s\n", __FUNCTION__));
+	DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber));
 	if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ))
 		return 0;
 
@@ -12186,6 +12189,9 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 				box.y1 = r->y + drawable->y;
 				box.x2 = bound(box.x1, r->width);
 				box.y2 = bound(box.y1, r->height);
+				DBG(("%s: rect=(%d, %d), (%d, %d), box=(%d, %d), (%d, %d)\n", __FUNCTION__,
+				     r->x, r->y, r->width, r->height,
+				     box.x1, box.y1, box.x2, box.y2));
 				r++;
 
 				c = find_clip_box_for_y(clip_start,
@@ -12194,12 +12200,15 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 				while (c != clip_end) {
 					BoxRec bb;
 
+					DBG(("%s: clip=(%d, %d), (%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2));
+
 					if (box.y2 <= c->y1)
 						break;
 
 					bb = box;
 					if (box_intersect(&bb, c++)) {
 						if (!kgem_check_batch(&sna->kgem, 3)) {
+							DBG(("%s: emitting split batch\n", __FUNCTION__));
 							_kgem_submit(&sna->kgem);
 							_kgem_set_mode(&sna->kgem, KGEM_BLT);
 
@@ -12252,6 +12261,9 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 						assert(bb.x2 + dx <= pixmap->drawable.width);
 						assert(bb.y2 + dy <= pixmap->drawable.height);
 
+						DBG(("%s: emit box=(%d, %d),(%d, %d) + (%d, %d), tile=(%d, %d) [relative to drawable: (%d, %d)]\n",
+						     __FUNCTION__, bb.x1, bb.y1, bb.x2, bb.y2, dx, dy, tx, ty, bb.x1 - drawable->x, bb.y1 - drawable->y));
+
 						assert(sna->kgem.mode == KGEM_BLT);
 						b = sna->kgem.batch + sna->kgem.nbatch;
 						b[0] = br00;
@@ -12267,7 +12279,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 			sna->kgem.nbatch = unwind_batch;
 			sna->kgem.nreloc = unwind_reloc;
 			if (sna->kgem.nbatch == 0)
-				kgem_bo_undo(&sna->kgem, bo);
+				kgem_bo_pair_undo(&sna->kgem, bo, tile_bo);
 		}
 	}
 done:
@@ -12291,17 +12303,11 @@ static bool tile8(int x)
 
 static int next8(int x, int max)
 {
-	switch(x) {
-	case 1: return MIN(1, max);
-	case 2: return MIN(2, max);
-	case 3:
-	case 4: return MIN(4, max);
-	case 5:
-	case 6:
-	case 7:
-	case 8: return MIN(8, max);
-	default: return x;
-	}
+	if (x > 2 && x <= 4)
+		x = 4;
+	else if (x < 8)
+		x = 8;
+	return MIN(x, max);
 }
 
 static bool
@@ -12434,8 +12440,9 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 	int tile_width, tile_height;
 	int16_t dx, dy;
 
-	DBG(("%s x %d [(%d, %d)x(%d, %d)...], clipped? %d\n",
-	     __FUNCTION__, n, rect->x, rect->y, rect->width, rect->height,
+	DBG(("%s pixmap=%ld, x %d [(%d, %d)x(%d, %d)...], clipped? %d\n",
+	     __FUNCTION__, pixmap->drawable.serialNumber,
+	     n, rect->x, rect->y, rect->width, rect->height,
 	     clipped));
 
 	assert(tile->drawable.depth == drawable->depth);
@@ -12460,6 +12467,8 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 	if ((tile_width | tile_height) == 8) {
 		bool ret;
 
+		DBG(("%s: have 8x8 tile, using BLT fast path\n", __FUNCTION__));
+
 		tile_bo = sna_pixmap_get_source_bo(tile);
 		if (tile_bo == NULL) {
 			DBG(("%s: unable to move tile go GPU, fallback\n",
@@ -12481,10 +12490,11 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 		if (priv == NULL || priv->gpu_damage == NULL) {
 			w = next8(extents->x2 - extents->x1, w);
 			h = next8(extents->y2 - extents->y1, h);
-			DBG(("%s: triming size for unattached tile: %dx%d\n",
-			     __FUNCTION__, w, h));
 		}
 
+		DBG(("%s: not 8x8, triming size for tile: %dx%d from %dx%d (area %dx%d)\n",
+		     __FUNCTION__, w, h, tile_width, tile_height, extents->x2-extents->x1, extents->y2-extents->y1));
+
 		if ((w|h) < 0x10 && is_power_of_two(w) && is_power_of_two(h) &&
 		    sna_poly_fill_rect_tiled_nxm_blt(drawable, bo, damage,
 						     gc, n, rect,
commit d2b90ac969656de35ec86973f66074654b0e9b4b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jun 20 14:29:43 2014 +0100

    sna: Color patterns for BLT are required to be aligned to 256 byte boundaries
    
    This so far appears to be the most restrictive alignment required, so
    simply increase the upload alignment to 256 bytes.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80033
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 2806553..03193c0 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -106,8 +106,12 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
  * is being simultaneously being read by the GPU, or within the sampler
  * prefetch. In general, the chipsets seem to have a requirement that sampler
  * offsets be aligned to a cacheline (64 bytes).
+ *
+ * Actually, it turns out the BLT color pattern (BR15) has the most severe
+ * alignment restrictions, 64 bytes for 8-bpp, 128 bytes for 16-bpp and 256
+ * bytes for 32-bpp.
  */
-#define UPLOAD_ALIGNMENT 128
+#define UPLOAD_ALIGNMENT 256
 
 #define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
 #define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
commit 8d7e7010e33d73a7d99948403b62d859d7a4dfaa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jun 20 08:28:32 2014 +0100

    test: Increase number of tiled sources
    
    Significantly improve the stress impose upon the tiled BLT operations.
    Also start dumping pngs of the failures.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=80033
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/configure.ac b/configure.ac
index 09dd830..632589c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -202,7 +202,7 @@ if test "x$UDEV" != "xno"; then
 	fi
 fi
 
-PKG_CHECK_MODULES(X11, [x11 xrender xrandr xext xfixes pixman-1], [x11="yes"], [x11="no"])
+PKG_CHECK_MODULES(X11, [x11 xrender xrandr xext xfixes pixman-1 libpng], [x11="yes"], [x11="no"])
 AM_CONDITIONAL(HAVE_X11, test "x$x11" = "xyes")
 
 shm=yes
diff --git a/test/basic-copyarea-size.c b/test/basic-copyarea-size.c
index 5e3373d..b8e9ed0 100644
--- a/test/basic-copyarea-size.c
+++ b/test/basic-copyarea-size.c
@@ -45,14 +45,14 @@ static void target_fini(struct test_display *t, struct draw *tt)
 int main(int argc, char **argv)
 {
 	struct test test;
-	struct draw real, ref;
+	struct draw out, ref;
 	int size, i;
 
 	test_init(&test, argc, argv);
 
 	/* Copy back and forth betwenn two pixmaps, gradually getting larger */
 	for (size = 1; size <= SIZE; size = (size * 3 + 1) / 2) {
-		target_init(&test.real, &real, size);
+		target_init(&test.out, &out, size);
 		target_init(&test.ref, &ref, size);
 
 		printf("size=%d\n", size);
@@ -67,10 +67,10 @@ int main(int argc, char **argv)
 
 				int order = rand() & 1;
 
-				XCopyArea(test.real.dpy,
-					  order ? real.a : real.b,
-					  (!order) ? real.a : real.b,
-					  real.gc,
+				XCopyArea(test.out.dpy,
+					  order ? out.a : out.b,
+					  (!order) ? out.a : out.b,
+					  out.gc,
 					  sx, sy,
 					  size, size,
 					  dx, dy);
@@ -86,17 +86,17 @@ int main(int argc, char **argv)
 		}
 
 		test_compare(&test,
-			     real.a, real.format,
+			     out.a, out.format,
 			     ref.a, ref.format,
 			     0, 0, size, size,
 			     "");
 		test_compare(&test,
-			     real.b, real.format,
+			     out.b, out.format,
 			     ref.b, ref.format,
 			     0, 0, size, size,
 			     "");
 
-		target_fini(&test.real, &real);
+		target_fini(&test.out, &out);
 		target_fini(&test.ref, &ref);
 	}
 
diff --git a/test/basic-copyarea.c b/test/basic-copyarea.c
index d4ae0d1..a1ef349 100644
--- a/test/basic-copyarea.c
+++ b/test/basic-copyarea.c
@@ -9,7 +9,7 @@
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -22,7 +22,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -85,13 +85,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -103,7 +103,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int y = rand() % (tt.height - 1);
 			uint32_t fg = rand();
 
-			fill_rect(&t->real, tt.draw, tt.format,
+			fill_rect(&t->out, tt.draw, tt.format,
 				  0, 0, 0,
 				  GXcopy, x, y, 1, 1, fg);
 
@@ -112,14 +112,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = fg;
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 			uint32_t result;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -138,7 +138,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -154,16 +154,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -174,7 +174,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.draw, tt.format,
+			fill_rect(&t->out, tt.draw, tt.format,
 				  0, 0, 0,
 				  GXcopy, x, y, w, h, fg);
 
@@ -195,7 +195,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			pixman_fill(cells, tt.width, 32, x, y, w, h, fg);
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -223,37 +223,37 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s, using %s source): ",
 	       test_target_name(target), use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (real.width - 1);
-			int y = rand() % (real.height - 1);
-			int w = 1 + rand() % (real.width - x - 1);
-			int h = 1 + rand() % (real.height - y - 1);
-			int tmpx = w == real.width ? 0 : rand() % (real.width - w);
-			int tmpy = h == real.height ? 0 : rand() % (real.height - h);
+			int x = rand() % (out.width - 1);
+			int y = rand() % (out.height - 1);
+			int w = 1 + rand() % (out.width - x - 1);
+			int h = 1 + rand() % (out.height - y - 1);
+			int tmpx = w == out.width ? 0 : rand() % (out.width - w);
+			int tmpy = h == out.height ? 0 : rand() % (out.height - h);
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 
-			fill_rect(&t->real, real.draw, real.format,
+			fill_rect(&t->out, out.draw, out.format,
 				  use_window, tmpx, tmpy,
 				  alu, x, y, w, h, fg);
 			fill_rect(&t->ref, ref.draw, ref.format,
@@ -262,15 +262,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/basic-fillrect.c b/test/basic-fillrect.c
index a2aeec8..80c219c 100644
--- a/test/basic-fillrect.c
+++ b/test/basic-fillrect.c
@@ -9,7 +9,7 @@
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -22,7 +22,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -56,13 +56,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -74,7 +74,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int y = rand() % (tt.height - 1);
 			uint32_t fg = rand();
 
-			fill_rect(&t->real, tt.draw, GXcopy,
+			fill_rect(&t->out, tt.draw, GXcopy,
 				  x, y, 1, 1, fg);
 
 			pixels[r].x = x;
@@ -82,14 +82,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = fg;
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 			uint32_t result;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -108,7 +108,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -124,16 +124,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -144,7 +144,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.draw, GXcopy,
+			fill_rect(&t->out, tt.draw, GXcopy,
 				  x, y, w, h, fg);
 
 			if (x < 0)
@@ -164,7 +164,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			pixman_fill(cells, tt.width, 32, x, y, w, h, fg);
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -192,49 +192,49 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 
-			fill_rect(&t->real, real.draw, alu,
+			fill_rect(&t->out, out.draw, alu,
 				  x, y, w, h, fg);
 			fill_rect(&t->ref, ref.draw, alu,
 				  x, y, w, h, fg);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/basic-lines.c b/test/basic-lines.c
index b710b24..1935cb2 100644
--- a/test/basic-lines.c
+++ b/test/basic-lines.c
@@ -85,14 +85,14 @@ static void draw_line(struct test_display *dpy, struct test_target *tt,
 static void line_tests(struct test *t, enum target target)
 {
 	char buf[1024];
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int a, b, alu, lw, style, cap;
 
 	printf("Testing drawing of single line segments (%s): ",
 	       test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
+	test_target_create_render(&t->out, target, &out);
 	test_target_create_render(&t->ref, target, &ref);
 
 	style = LineSolid;
@@ -108,18 +108,18 @@ static void line_tests(struct test *t, enum target target)
 							points[b].x, points[b].y,
 							lw, cap, alu);
 
-						clear(&t->real, &real);
+						clear(&t->out, &out);
 						clear(&t->ref, &ref);
 
-						draw_line(&t->real, &real, alu, lw, style, cap,
+						draw_line(&t->out, &out, alu, lw, style, cap,
 							  &points[a], &points[b], 64, 64);
 						draw_line(&t->ref, &ref, alu, lw, style, cap,
 							  &points[a], &points[b], 64, 64);
 
 						test_compare(t,
-							     real.draw, real.format,
+							     out.draw, out.format,
 							     ref.draw, ref.format,
-							     0, 0, real.width, real.height,
+							     0, 0, out.width, out.height,
 							     buf);
 					}
 				}
@@ -127,7 +127,7 @@ static void line_tests(struct test *t, enum target target)
 		}
 	}
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 
 	printf("\n");
diff --git a/test/basic-putimage.c b/test/basic-putimage.c
index d570417..e252fe3 100644
--- a/test/basic-putimage.c
+++ b/test/basic-putimage.c
@@ -9,7 +9,7 @@
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -22,7 +22,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -69,13 +69,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s %s shm): ",
 	       test_target_name(target), use_shm ? "with" : "without" );
@@ -91,7 +91,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 			int alpha = rand() % 0xff;
 			uint32_t fg = color(red, green, blue, alpha);
 
-			fill_rect(&t->real, tt.draw, tt.format, use_shm,
+			fill_rect(&t->out, tt.draw, tt.format, use_shm,
 				  GXcopy, x, y, 1, 1, fg);
 
 			pixels[r].x = x;
@@ -99,14 +99,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 			cells[y*tt.width+x] = fg;
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -128,7 +128,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -144,17 +144,17 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s %s shm): ",
 	       test_target_name(target), use_shm ? "with" : "without" );
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -170,13 +170,13 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 			w = rand() % (tt.width - x);
 			h = rand() % (tt.height - y);
 
-			fill_rect(&t->real, tt.draw, tt.format, use_shm,
+			fill_rect(&t->out, tt.draw, tt.format, use_shm,
 				  GXcopy, x, y, w, h, fg);
 
 			pixman_fill(cells, tt.width, 32, x, y, w, h, fg);
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -205,30 +205,30 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_shm)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % real.width;
-			int y = rand() % real.height;
-			int w = rand() % (real.width - x);
-			int h = rand() % (real.height - y);
+			int x = rand() % out.width;
+			int y = rand() % out.height;
+			int w = rand() % (out.width - x);
+			int h = rand() % (out.height - y);
 			uint8_t alu = rand() % (GXset + 1);
 			int red = rand() % 0xff;
 			int green = rand() % 0xff;
@@ -236,22 +236,22 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 			int alpha = rand() % 0xff;
 			uint8_t fg = color(red, green, blue, alpha);
 
-			fill_rect(&t->real, real.draw, real.format, use_shm,
+			fill_rect(&t->out, out.draw, out.format, use_shm,
 				  alu, x, y, w, h, fg);
 			fill_rect(&t->ref, ref.draw, ref.format, use_shm,
 				  alu, x, y, w, h, fg);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 int main(int argc, char **argv)
diff --git a/test/basic-rectangle.c b/test/basic-rectangle.c
index 8de200c..5cdbcd1 100644
--- a/test/basic-rectangle.c
+++ b/test/basic-rectangle.c
@@ -30,169 +30,169 @@ static void clear(struct test_display *dpy, struct test_target *tt)
 
 static void zrect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing empty rects (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t lw = rand() % 4;
 
-			draw_rect(&t->real, real.draw, alu,
+			draw_rect(&t->out, out.draw, alu,
 				  x, y, 0, 0, fg, lw);
 			draw_rect(&t->ref, ref.draw, alu,
 				  x, y, 0, 0, fg, lw);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void hrect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing horizontal rects (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t lw = rand() % 4;
 
-			draw_rect(&t->real, real.draw, alu,
+			draw_rect(&t->out, out.draw, alu,
 				  x, y, w, 0, fg, lw);
 			draw_rect(&t->ref, ref.draw, alu,
 				  x, y, w, 0, fg, lw);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void vrect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing vertical rects (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int h = rand() % (2*real.width);
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int h = rand() % (2*out.width);
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t lw = rand() % 4;
 
-			draw_rect(&t->real, real.draw, alu,
+			draw_rect(&t->out, out.draw, alu,
 				  x, y, 0, h, fg, lw);
 			draw_rect(&t->ref, ref.draw, alu,
 				  x, y, 0, h, fg, lw);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing general (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t lw = rand() % 4;
 
-			draw_rect(&t->real, real.draw, alu,
+			draw_rect(&t->out, out.draw, alu,
 				  x, y, w, h, fg, lw);
 			draw_rect(&t->ref, ref.draw, alu,
 				  x, y, w, h, fg, lw);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/basic-stippledrect.c b/test/basic-stippledrect.c
index 8a89efd..03861e2 100644
--- a/test/basic-stippledrect.c
+++ b/test/basic-stippledrect.c
@@ -54,33 +54,33 @@ static void clear(struct test_target *tt)
 
 static void unclipped_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing unclipped stippled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % real.width;
-			int y = rand() % real.height;
-			int w = rand() % (real.width - x);
-			int h = rand() % (real.height - y);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
+			int x = rand() % out.width;
+			int y = rand() % out.height;
+			int w = rand() % (out.width - x);
+			int h = rand() % (out.height - y);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
 			uint8_t stipple = rand() % 4;
 			uint8_t opaque = rand() % 1;
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, NULL, 0,
+			fill_rect(&out, alu, NULL, 0,
 				  stipple, opaque, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -91,47 +91,47 @@ static void unclipped_tests(struct test *t, int reps, int sets, enum target targ
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void simple_clip_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing simple clipped stippled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
 			uint8_t stipple = rand() % 4;
 			uint8_t opaque = rand() % 1;
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, NULL, 0,
+			fill_rect(&out, alu, NULL, 0,
 				  stipple, opaque, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -142,29 +142,29 @@ static void simple_clip_tests(struct test *t, int reps, int sets, enum target ta
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void complex_clip_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	XRectangle *clip;
 	int nclip, r, s;
 
 	printf("Testing complex clipped stippled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
@@ -173,26 +173,26 @@ static void complex_clip_tests(struct test *t, int reps, int sets, enum target t
 		nclip = (rand() % 16) + 2;
 		clip = malloc(sizeof(XRectangle)*nclip);
 		for (r = 0; r < nclip; r++) {
-			clip[r].x = rand() % real.width;
-			clip[r].y = rand() % real.height;
-			clip[r].width = rand() % (real.width - clip[r].x);
-			clip[r].height = rand() % (real.height - clip[r].y);
+			clip[r].x = rand() % out.width;
+			clip[r].y = rand() % out.height;
+			clip[r].width = rand() % (out.width - clip[r].x);
+			clip[r].height = rand() % (out.height - clip[r].y);
 		}
 
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
 			uint8_t stipple = rand() % 4;
 			uint8_t opaque = rand() % 1;
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, clip, nclip,
+			fill_rect(&out, alu, clip, nclip,
 				  stipple, opaque, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -203,9 +203,9 @@ static void complex_clip_tests(struct test *t, int reps, int sets, enum target t
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 
 		free(clip);
@@ -213,7 +213,7 @@ static void complex_clip_tests(struct test *t, int reps, int sets, enum target t
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/basic-stress.c b/test/basic-stress.c
index 4b42865..94fcc3e 100644
--- a/test/basic-stress.c
+++ b/test/basic-stress.c
@@ -27,36 +27,36 @@ static void clear(struct test_target *tt)
 		  0, 0, tt->width, tt->height);
 }
 
-static void fill(struct test_target *real,
+static void fill(struct test_target *out,
 		 struct test_target *ref)
 {
-	int x = rand() % (2*real->width) - real->width;
-	int y = rand() % (2*real->height) - real->height;
-	int w = rand() % (2*real->width);
-	int h = rand() % (2*real->height);
+	int x = rand() % (2*out->width) - out->width;
+	int y = rand() % (2*out->height) - out->height;
+	int w = rand() % (2*out->width);
+	int h = rand() % (2*out->height);
 	int color = rand();
 	int alu = rand() % 16;
 
-	fill_rect(real, alu, color, x, y, w, h);
+	fill_rect(out, alu, color, x, y, w, h);
 	fill_rect(ref, alu, color, x, y, w, h);
 }
 
-static void copy(struct test_target *real,
+static void copy(struct test_target *out,
 		 struct test_target *ref)
 {
-	int sx = rand() % (2*real->width) - ref->width;
-	int sy = rand() % (2*real->height) - ref->height;
-	int dx = rand() % (2*real->width) - ref->width;
-	int dy = rand() % (2*real->height) - ref->height;
-	int w = rand() % (2*real->width);
-	int h = rand() % (2*real->height);
+	int sx = rand() % (2*out->width) - ref->width;
+	int sy = rand() % (2*out->height) - ref->height;
+	int dx = rand() % (2*out->width) - ref->width;
+	int dy = rand() % (2*out->height) - ref->height;
+	int w = rand() % (2*out->width);
+	int h = rand() % (2*out->height);
 	XGCValues val;
 
 	val.function = rand() % 16;
 
-	XChangeGC(real->dpy->dpy, real->gc, GCFunction, &val);
-	XCopyArea(real->dpy->dpy,
-		  real->draw, real->draw, real->gc,
+	XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val);
+	XCopyArea(out->dpy->dpy,
+		  out->draw, out->draw, out->gc,
 		  sx, sy, w, h, dx, dy);
 
 	XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val);
@@ -90,23 +90,23 @@ static void _put(struct test_target *tt,
 	}
 }
 
-static void put(struct test_target *real,
+static void put(struct test_target *out,
 		struct test_target *ref)
 {
-	int x = rand() % (2*real->width) - real->width;
-	int y = rand() % (2*real->height) - real->height;
-	int w = rand() % real->width;
-	int h = rand() % real->height;
+	int x = rand() % (2*out->width) - out->width;
+	int y = rand() % (2*out->height) - out->height;
+	int w = rand() % out->width;
+	int h = rand() % out->height;
 	int color = rand();
 	int alu = rand() % 16;
 
-	_put(real, x, y, w, h, color, alu);
+	_put(out, x, y, w, h, color, alu);
 	_put(ref, x, y, w, h, color, alu);
 }
 
 static void rect_tests(struct test *test, int iterations, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	void (* const ops[])(struct test_target *, struct test_target *) = {
 		copy,
 		fill,
@@ -118,24 +118,24 @@ static void rect_tests(struct test *test, int iterations, enum target target)
 	       test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&test->real, target, &real);
+	test_target_create_render(&test->out, target, &out);
 	test_target_create_render(&test->ref, target, &ref);
 
-	clear(&real);
+	clear(&out);
 	clear(&ref);
 
 	for (n = 0; n < iterations; n++)
-		ops[rand() % ARRAY_SIZE(ops)](&real, &ref);
+		ops[rand() % ARRAY_SIZE(ops)](&out, &ref);
 
 	test_compare(test,
-		     real.draw, real.format,
+		     out.draw, out.format,
 		     ref.draw, ref.format,
-		     0, 0, real.width, real.height,
+		     0, 0, out.width, out.height,
 		     "");
 
 	printf("passed [%d iterations]\n", n);
 
-	test_target_destroy_render(&test->real, &real);
+	test_target_destroy_render(&test->out, &out);
 	test_target_destroy_render(&test->ref, &ref);
 }
 
diff --git a/test/basic-string.c b/test/basic-string.c
index 1e24b29..4e1dbce 100644
--- a/test/basic-string.c
+++ b/test/basic-string.c
@@ -39,42 +39,42 @@ static void clear(struct test_display *dpy, struct test_target *tt)
 
 static void string_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing general (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 			int str = rand();
 			int fill = rand() & 1;
 
-			draw_string(&t->real, real.draw, alu, x, y, fg, bg, str, fill);
+			draw_string(&t->out, out.draw, alu, x, y, fg, bg, str, fill);
 			draw_string(&t->ref, ref.draw, alu, x, y, fg, bg, str, fill);
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/basic-tiledrect.c b/test/basic-tiledrect.c
index 1596c4c..9af86a9 100644
--- a/test/basic-tiledrect.c
+++ b/test/basic-tiledrect.c
@@ -4,16 +4,61 @@
 
 #include "test.h"
 
-static unsigned char bitmap4x4[] = {
-	   0x03, 0x06, 0x0c, 0x09
+static const unsigned char data[] = {
+	0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+	0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+	0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+	0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
 };
 
-static unsigned char bitmap8x8[3][8] = {
-	{ 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 },
-	{ 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe },
-	{ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+static struct bitmap {
+	int width, height;
+	struct cache {
+		Display *dpy;
+		Pixmap pixmap;
+	} cached[2];
+} bitmaps[] = {
+	{ 1, 1, },
+	{ 1, 2, },
+	{ 2, 3, },
+	{ 3, 2, },
+	{ 4, 4, },
+	{ 6, 6, },
+	{ 8, 8, },
+	{ 8, 4, },
+	{ 8, 2, },
+	{ 8, 1, },
+	{ 4, 8, },
+	{ 2, 8, },
+	{ 1, 8, },
+	{ 16, 16, },
+	{ 15, 17, },
+	{ 24, 24, },
+	{ 32, 32, },
+	{ 16, 8, },
+	{ 16, 4, },
+	{ 16, 2, },
+	{ 16, 1, },
+	{ 8, 16, },
+	{ 4, 16, },
+	{ 2, 16, },
+	{ 1, 16, },
 };
 
+static void reset_cache(void)
+{
+	int n, m;
+
+	for (n = 0; n < sizeof(bitmaps)/sizeof(bitmaps[0]); n++) {
+		for (m = 0; m < 2; m++) {
+			if (bitmaps[n].cached[m].dpy) {
+				XFreePixmap(bitmaps[n].cached[m].dpy, bitmaps[n].cached[m].pixmap);
+				bitmaps[n].cached[m].dpy = NULL;
+			}
+		}
+	}
+}
+
 static void fill_rect(struct test_target *t, uint8_t alu,
 		      XRectangle *clip, int nclip,
 		      uint8_t tile, int tx, int ty,
@@ -21,28 +66,48 @@ static void fill_rect(struct test_target *t, uint8_t alu,
 		      uint32_t fg, uint32_t bg)
 {
 	Display *dpy = t->dpy->dpy;
+	struct bitmap *b = &bitmaps[(tile >> 1) % (sizeof(bitmaps)/sizeof(bitmaps[0]))];
 	XGCValues val;
 	GC gc;
+	int n;
 
 	val.function = alu;
+	val.function = GXcopy;
 	val.fill_style = FillTiled;
 	val.ts_x_origin = tx;
 	val.ts_y_origin = ty;
-	if (tile == 0) {
-		val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, (char *)bitmap4x4, 4, 4,
-						       fg, bg, t->depth);
-	} else {
-		char *b = (char *)bitmap8x8[tile-1];
-		val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, b, 8, 8,
+	if (tile & 1) {
+		val.tile = 0;
+		for (n = 0; n < 2; n++) {
+			if (b->cached[n].dpy == dpy) {
+				val.tile = b->cached[n].pixmap;
+				break;
+			}
+		}
+		if (val.tile == 0) {
+			val.tile = XCreatePixmapFromBitmapData(dpy, t->draw,
+							       (char *)data, b->width, b->height,
+							       fg, bg, t->depth);
+			for (n = 0; n < 2; n++) {
+				if (b->cached[n].dpy == NULL) {
+					b->cached[n].dpy = dpy;
+					b->cached[n].pixmap = val.tile;
+					break;
+				}
+			}
+		}
+	} else
+		val.tile = XCreatePixmapFromBitmapData(dpy, t->draw,
+						       (char *)data, b->width, b->height,
 						       fg, bg, t->depth);
-	}
 
 	gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile | GCFunction, &val);
 	if (nclip)
 		XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted);
 	XFillRectangle(dpy, t->draw, gc, x, y, w, h);
 	XFreeGC(dpy, gc);
-	XFreePixmap(dpy, val.tile);
+	if ((tile & 1) == 0)
+		XFreePixmap(dpy, val.tile);
 }
 
 static void clear(struct test_target *tt)
@@ -52,34 +117,107 @@ static void clear(struct test_target *tt)
 			     0, 0, tt->width, tt->height);
 }
 
+static void small_tests(struct test *t, int reps, int sets, enum target target)
+{
+	struct test_target out, ref;
+	int r, s;
+
+	printf("Testing small tiled fills (%s): ", test_target_name(target));
+	fflush(stdout);
+
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
+
+	test_target_create_render(&t->ref, target, &ref);
+	clear(&ref);
+
+	for (s = 0; s < sets; s++) {
+		for (r = 0; r < reps; r++) {
+			int x = rand() % out.width;
+			int y = rand() % out.height;
+			int w = rand() % out.width;
+			int h = rand() % 8;
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
+			uint8_t tile = rand();
+			uint8_t alu = rand() % (GXset + 1);
+			uint32_t fg = rand();
+			uint32_t bg = rand();
+
+			fill_rect(&out, alu, NULL, 0,
+				  tile, tx, ty,
+				  x, y, w, h,
+				  fg, bg);
+			fill_rect(&ref, alu, NULL, 0,
+				  tile, tx, ty,
+				  x, y, w, h,
+				  fg, bg);
+
+			fill_rect(&out, alu, NULL, 0,
+				  tile, tx, ty,
+				  x, y, h, w,
+				  fg, bg);
+			fill_rect(&ref, alu, NULL, 0,
+				  tile, tx, ty,
+				  x, y, h, w,
+				  fg, bg);
+		}
+
+		test_compare(t,
+			     out.draw, out.format,
+			     ref.draw, ref.format,
+			     0, 0, out.width, out.height,
+			     "");
+
+		if (target == CHILD) {
+			int x = rand() % (t->out.width-out.width);
+			int y = rand() % (t->out.height-out.height);
+
+			clear(&out);
+			clear(&ref);
+
+			XMoveWindow(out.dpy->dpy, out.draw, x, y);
+			XMoveWindow(ref.dpy->dpy, ref.draw, x, y);
+
+			clear(&out);
+			clear(&ref);
+		}
+	}
+
+	printf("passed [%d iterations x %d]\n", reps, sets);
+
+	test_target_destroy_render(&t->out, &out);
+	test_target_destroy_render(&t->ref, &ref);
+}
+
 static void unclipped_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing unclipped tiled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % real.width;
-			int y = rand() % real.height;
-			int w = rand() % (real.width - x);
-			int h = rand() % (real.height - y);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
-			uint8_t tile = rand() % 4;
+			int x = rand() % out.width;
+			int y = rand() % out.height;
+			int w = rand() % (out.width - x);
+			int h = rand() % (out.height - y);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
+			uint8_t tile = rand();
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, NULL, 0,
+			fill_rect(&out, alu, NULL, 0,
 				  tile, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -90,46 +228,60 @@ static void unclipped_tests(struct test *t, int reps, int sets, enum target targ
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
+
+		if (target == CHILD) {
+			int x = rand() % (t->out.width-out.width);
+			int y = rand() % (t->out.height-out.height);
+
+			clear(&out);
+			clear(&ref);
+
+			XMoveWindow(out.dpy->dpy, out.draw, x, y);
+			XMoveWindow(ref.dpy->dpy, ref.draw, x, y);
+
+			clear(&out);
+			clear(&ref);
+		}
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void simple_clip_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing simple clipped tiled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
-			uint8_t tile = rand() % 4;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
+			uint8_t tile = rand();
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, NULL, 0,
+			fill_rect(&out, alu, NULL, 0,
 				  tile, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -140,29 +292,43 @@ static void simple_clip_tests(struct test *t, int reps, int sets, enum target ta
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
+
+		if (target == CHILD) {
+			int x = rand() % (t->out.width-out.width);
+			int y = rand() % (t->out.height-out.height);
+
+			clear(&out);
+			clear(&ref);
+
+			XMoveWindow(out.dpy->dpy, out.draw, x, y);
+			XMoveWindow(ref.dpy->dpy, ref.draw, x, y);
+
+			clear(&out);
+			clear(&ref);
+		}
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
 static void complex_clip_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	XRectangle *clip;
 	int nclip, r, s;
 
 	printf("Testing complex clipped tiled fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&ref);
@@ -171,25 +337,25 @@ static void complex_clip_tests(struct test *t, int reps, int sets, enum target t
 		nclip = (rand() % 16) + 2;
 		clip = malloc(sizeof(XRectangle)*nclip);
 		for (r = 0; r < nclip; r++) {
-			clip[r].x = rand() % real.width;
-			clip[r].y = rand() % real.height;
-			clip[r].width = rand() % (real.width - clip[r].x);
-			clip[r].height = rand() % (real.height - clip[r].y);
+			clip[r].x = rand() % out.width;
+			clip[r].y = rand() % out.height;
+			clip[r].width = rand() % (out.width - clip[r].x);
+			clip[r].height = rand() % (out.height - clip[r].y);
 		}
 
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % (2*real.width);
-			int h = rand() % (2*real.height);
-			int tx = rand() % (2*real.width) - real.width;
-			int ty = rand() % (2*real.height) - real.height;
-			uint8_t tile = rand() % 4;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % (2*out.width);
+			int h = rand() % (2*out.height);
+			int tx = rand() % (2*out.width) - out.width;
+			int ty = rand() % (2*out.height) - out.height;
+			uint8_t tile = rand();
 			uint8_t alu = rand() % (GXset + 1);
 			uint32_t fg = rand();
 			uint32_t bg = rand();
 
-			fill_rect(&real, alu, clip, nclip,
+			fill_rect(&out, alu, clip, nclip,
 				  tile, tx, ty,
 				  x, y, w, h,
 				  fg, bg);
@@ -200,17 +366,31 @@ static void complex_clip_tests(struct test *t, int reps, int sets, enum target t
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 
 		free(clip);
+
+		if (target == CHILD) {
+			int x = rand() % (t->out.width-out.width);
+			int y = rand() % (t->out.height-out.height);
+
+			clear(&out);
+			clear(&ref);
+
+			XMoveWindow(out.dpy->dpy, out.draw, x, y);
+			XMoveWindow(ref.dpy->dpy, ref.draw, x, y);
+
+			clear(&out);
+			clear(&ref);
+		}
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
@@ -226,9 +406,11 @@ int main(int argc, char **argv)
 		enum target t;
 
 		for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
+			small_tests(&test, reps, sets, t);
 			unclipped_tests(&test, reps, sets, t);
 			simple_clip_tests(&test, reps, sets, t);
 			complex_clip_tests(&test, reps, sets, t);
+			reset_cache();
 		}
 	}
 
diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
index f2b6863..3593014 100644
--- a/test/lowlevel-blt-bench.c
+++ b/test/lowlevel-blt-bench.c
@@ -109,13 +109,13 @@ static double _bench(struct test_display *t, enum target target_type,
 
 static void bench(struct test *t, enum target target, int op, int sf)
 {
-	double real, ref;
+	double out, ref;
 
 	ref = _bench(&t->ref, target, op, sf, 1000);
-	real = _bench(&t->real, target, op, sf, 1000);
+	out = _bench(&t->out, target, op, sf, 1000);
 
-	fprintf (stdout, "Testing %s with %s: ref=%f, real=%f\n",
-		 formats[sf].name, ops[op].name, ref, real);
+	fprintf (stdout, "Testing %s with %s: ref=%f, out=%f\n",
+		 formats[sf].name, ops[op].name, ref, out);
 }
 
 int main(int argc, char **argv)
diff --git a/test/mixed-stress.c b/test/mixed-stress.c
index a315a9c..94fa846 100644
--- a/test/mixed-stress.c
+++ b/test/mixed-stress.c
@@ -43,19 +43,19 @@ static void _render_copy(struct test_target *tt,
 	XFreePixmap(tt->dpy->dpy, tmp);
 }
 
-static void render_copy(struct test_target *real,
+static void render_copy(struct test_target *out,
 			struct test_target *ref)
 {
-	int x = rand() % (2*real->width) - real->width;
-	int y = rand() % (2*real->height) - real->height;
-	int w = rand() % (2*real->width);
-	int h = rand() % (2*real->height);
+	int x = rand() % (2*out->width) - out->width;
+	int y = rand() % (2*out->height) - out->height;
+	int w = rand() % (2*out->width);
+	int h = rand() % (2*out->height);
 	int red = rand() & 0xff;
 	int green = rand() & 0xff;
 	int blue = rand() & 0xff;
 	int alpha = rand() & 0xff;
 
-	_render_copy(real, x, y, w, h, red, green, blue, alpha);
+	_render_copy(out, x, y, w, h, red, green, blue, alpha);
 	_render_copy(ref, x, y, w, h, red, green, blue, alpha);
 }
 
@@ -79,36 +79,36 @@ static void clear(struct test_target *tt)
 		  0, 0, tt->width, tt->height);
 }
 
-static void basic_fill(struct test_target *real,
+static void basic_fill(struct test_target *out,
 		       struct test_target *ref)
 {
-	int x = rand() % (2*real->width) - real->width;
-	int y = rand() % (2*real->height) - real->height;
-	int w = rand() % (2*real->width);
-	int h = rand() % (2*real->height);
+	int x = rand() % (2*out->width) - out->width;
+	int y = rand() % (2*out->height) - out->height;
+	int w = rand() % (2*out->width);
+	int h = rand() % (2*out->height);
 	int color = rand();
 	int alu = rand() % 16;
 
-	fill_rect(real, alu, color, x, y, w, h);
+	fill_rect(out, alu, color, x, y, w, h);
 	fill_rect(ref, alu, color, x, y, w, h);
 }
 
-static void basic_copy(struct test_target *real,
+static void basic_copy(struct test_target *out,
 		       struct test_target *ref)
 {
-	int sx = rand() % (2*real->width) - ref->width;
-	int sy = rand() % (2*real->height) - ref->height;
-	int dx = rand() % (2*real->width) - ref->width;
-	int dy = rand() % (2*real->height) - ref->height;
-	int w = rand() % (2*real->width);
-	int h = rand() % (2*real->height);
+	int sx = rand() % (2*out->width) - ref->width;
+	int sy = rand() % (2*out->height) - ref->height;
+	int dx = rand() % (2*out->width) - ref->width;
+	int dy = rand() % (2*out->height) - ref->height;
+	int w = rand() % (2*out->width);
+	int h = rand() % (2*out->height);
 	XGCValues val;
 
 	val.function = rand() % 16;
 
-	XChangeGC(real->dpy->dpy, real->gc, GCFunction, &val);
-	XCopyArea(real->dpy->dpy,
-		  real->draw, real->draw, real->gc,
+	XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val);
+	XCopyArea(out->dpy->dpy,
+		  out->draw, out->draw, out->gc,
 		  sx, sy, w, h, dx, dy);
 
 	XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val);
@@ -142,23 +142,23 @@ static void _put(struct test_target *tt,
 	}
 }
 
-static void basic_put(struct test_target *real,
+static void basic_put(struct test_target *out,
 		      struct test_target *ref)
 {
-	int x = rand() % (2*real->width) - real->width;
-	int y = rand() % (2*real->height) - real->height;
-	int w = rand() % real->width;
-	int h = rand() % real->height;
+	int x = rand() % (2*out->width) - out->width;
+	int y = rand() % (2*out->height) - out->height;
+	int w = rand() % out->width;
+	int h = rand() % out->height;
 	int color = rand();
 	int alu = rand() % 16;
 
-	_put(real, x, y, w, h, color, alu);
+	_put(out, x, y, w, h, color, alu);
 	_put(ref, x, y, w, h, color, alu);
 }
 
 static void rect_tests(struct test *test, int iterations, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	void (* const ops[])(struct test_target *, struct test_target *) = {
 		basic_copy,
 		basic_fill,
@@ -171,24 +171,24 @@ static void rect_tests(struct test *test, int iterations, enum target target)
 	       test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&test->real, target, &real);
+	test_target_create_render(&test->out, target, &out);
 	test_target_create_render(&test->ref, target, &ref);
 
-	clear(&real);
+	clear(&out);
 	clear(&ref);
 
 	for (n = 0; n < iterations; n++)
-		ops[rand() % ARRAY_SIZE(ops)](&real, &ref);
+		ops[rand() % ARRAY_SIZE(ops)](&out, &ref);
 
 	test_compare(test,
-		     real.draw, real.format,
+		     out.draw, out.format,
 		     ref.draw, ref.format,
-		     0, 0, real.width, real.height,
+		     0, 0, out.width, out.height,
 		     "");
 
 	printf("passed [%d iterations]\n", n);
 
-	test_target_destroy_render(&test->real, &real);
+	test_target_destroy_render(&test->out, &out);
 	test_target_destroy_render(&test->ref, &ref);
 }
 
diff --git a/test/render-composite-solid-mask.c b/test/render-composite-solid-mask.c
index 925df3c..b035e50 100644
--- a/test/render-composite-solid-mask.c
+++ b/test/render-composite-solid-mask.c
@@ -48,24 +48,24 @@ static void clear(struct test_display *dpy, struct test_target *tt)
 
 static void ref_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % real.width;
-			int h = rand() % real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % out.width;
+			int h = rand() % out.height;
 			int op = ops[rand() % sizeof(ops)];
 			int s_red = rand() % 0xff;
 			int s_green = rand() % 0xff;
@@ -76,7 +76,7 @@ static void ref_tests(struct test *t, int reps, int sets, enum target target)
 			int m_blue = rand() % 0xff;
 			int m_alpha = rand() % 0xff;
 
-			fill_rect(&t->real, real.picture,
+			fill_rect(&t->out, out.picture,
 				  op, x, y, w, h,
 				  s_red, s_green, s_blue, s_alpha,
 				  m_red, m_green, m_blue, m_alpha);
@@ -87,15 +87,15 @@ static void ref_tests(struct test *t, int reps, int sets, enum target target)
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-composite-solid.c b/test/render-composite-solid.c
index b4742af..9d779be 100644
--- a/test/render-composite-solid.c
+++ b/test/render-composite-solid.c
@@ -34,13 +34,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -55,7 +55,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, 1, 1,
 				  red, green, blue, alpha);
 
@@ -64,14 +64,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -93,7 +93,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -109,16 +109,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -132,7 +132,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, w, h, red, green, blue, alpha);
 
 			if (x < 0)
@@ -153,7 +153,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, alpha));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -179,37 +179,37 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % real.width;
-			int h = rand() % real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % out.width;
+			int h = rand() % out.height;
 			int op = ops[rand() % sizeof(ops)];
 			int red = rand() % 0xff;
 			int green = rand() % 0xff;
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, real.picture,
+			fill_rect(&t->out, out.picture,
 				  op, x, y, w, h,
 				  red, green, blue, alpha);
 			fill_rect(&t->ref, ref.picture,
@@ -218,15 +218,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target)
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-copy-alphaless.c b/test/render-copy-alphaless.c
index 5f1487e..01c74a7 100644
--- a/test/render-copy-alphaless.c
+++ b/test/render-copy-alphaless.c
@@ -9,7 +9,7 @@
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -22,7 +22,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -68,13 +68,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -88,7 +88,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			uint8_t green = rand();
 			uint8_t blue = rand();
 
-			fill_rect(&t->real, tt.picture,
+			fill_rect(&t->out, tt.picture,
 				  x, y, 1, 1,
 				  red, green, blue);
 
@@ -97,14 +97,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = color(red, green, blue, 0xff);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 			uint32_t result;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -123,7 +123,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -139,16 +139,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -161,7 +161,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture,
+			fill_rect(&t->out, tt.picture,
 				  x, y, w, h,
 				  red, green, blue);
 
@@ -183,7 +183,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, 0xff));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -211,20 +211,20 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 	printf("Testing area fills (%s, using %s source): ",
 	       test_target_name(target), use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -236,12 +236,12 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 			uint8_t green = rand();
 			uint8_t blue = rand();
 
-			x = rand() % (real.width - 1);
-			y = rand() % (real.height - 1);
-			w = 1 + rand() % (real.width - x - 1);
-			h = 1 + rand() % (real.height - y - 1);
+			x = rand() % (out.width - 1);
+			y = rand() % (out.height - 1);
+			w = 1 + rand() % (out.width - x - 1);
+			h = 1 + rand() % (out.height - y - 1);
 
-			fill_rect(&t->real, real.picture,
+			fill_rect(&t->out, out.picture,
 				  x, y, w, h,
 				  red, green, blue);
 			fill_rect(&t->ref, ref.picture,
@@ -250,15 +250,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-copyarea-mask.c b/test/render-copyarea-mask.c
index 5116c16..937b5f0 100644
--- a/test/render-copyarea-mask.c
+++ b/test/render-copyarea-mask.c
@@ -75,14 +75,14 @@ static void clear(struct test_display *dpy, struct test_target *tt)
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 	printf("Testing area fills (%s, using %s source): ",
 	       test_target_name(target), use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -99,12 +99,12 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 			int try = 50;
 
 			do {
-				x = rand() % (real.width - 1);
-				y = rand() % (real.height - 1);
-				w = 1 + rand() % (real.width - x - 1);
-				h = 1 + rand() % (real.height - y - 1);
-				tmpx = w == real.width ? 0 : rand() % (real.width - w);
-				tmpy = h == real.height ? 0 : rand() % (real.height - h);
+				x = rand() % (out.width - 1);
+				y = rand() % (out.height - 1);
+				w = 1 + rand() % (out.width - x - 1);
+				h = 1 + rand() % (out.height - y - 1);
+				tmpx = w == out.width ? 0 : rand() % (out.width - w);
+				tmpy = h == out.height ? 0 : rand() % (out.height - h);
 			} while (((tmpx+w > x && tmpx < x+w) ||
 				  (tmpy+h > y && tmpy < y+h)) &&
 				 --try);
@@ -115,7 +115,7 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 			mask_h = rand() % h;
 
 			if (try) {
-				fill_rect(&t->real, real.picture, real.format,
+				fill_rect(&t->out, out.picture, out.format,
 					  use_window, tmpx, tmpy,
 					  PictOpSrc, x, y, w, h,
 					  mask_x, mask_y, mask_w, mask_h,
@@ -129,15 +129,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-copyarea-size.c b/test/render-copyarea-size.c
index 55e3b56..3503b32 100644
--- a/test/render-copyarea-size.c
+++ b/test/render-copyarea-size.c
@@ -53,14 +53,14 @@ static void target_fini(struct test_display *t, struct draw *tt)
 int main(int argc, char **argv)
 {
 	struct test test;
-	struct draw real, ref;
+	struct draw out, ref;
 	int size, i;
 
 	test_init(&test, argc, argv);
 
 	/* Copy back and forth betwenn two pixmaps, gradually getting larger */
 	for (size = 1; size <= SIZE; size = (size * 3 + 1) / 2) {
-		target_init(&test.real, &real, size);
+		target_init(&test.out, &out, size);
 		target_init(&test.ref, &ref, size);
 
 		printf("size=%d\n", size);
@@ -78,10 +78,10 @@ int main(int argc, char **argv)
 
 				int order = rand() & 1;
 
-				XRenderComposite(test.real.dpy, PictOpSrc,
-						 order ? real.pa : real.pb,
+				XRenderComposite(test.out.dpy, PictOpSrc,
+						 order ? out.pa : out.pb,
 						 0,
-						 (!order) ? real.pa : real.pb,
+						 (!order) ? out.pa : out.pb,
 						 sx, sy,
 						 0, 0,
 						 dx, dy,
@@ -99,17 +99,17 @@ int main(int argc, char **argv)
 		}
 
 		test_compare(&test,
-			     real.a, real.format,
+			     out.a, out.format,
 			     ref.a, ref.format,
 			     0, 0, size, size,
 			     "");
 		test_compare(&test,
-			     real.b, real.format,
+			     out.b, out.format,
 			     ref.b, ref.format,
 			     0, 0, size, size,
 			     "");
 
-		target_fini(&test.real, &real);
+		target_fini(&test.out, &out);
 		target_fini(&test.ref, &ref);
 	}
 
diff --git a/test/render-copyarea.c b/test/render-copyarea.c
index 8c00b34..a202dde 100644
--- a/test/render-copyarea.c
+++ b/test/render-copyarea.c
@@ -9,7 +9,7 @@
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -22,7 +22,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -85,13 +85,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -106,7 +106,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			uint8_t blue = rand();
 			uint8_t alpha = rand();
 
-			fill_rect(&t->real, tt.picture, tt.format,
+			fill_rect(&t->out, tt.picture, tt.format,
 				  0, 0, 0,
 				  PictOpSrc, x, y, 1, 1,
 				  red, green, blue, alpha);
@@ -116,14 +116,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 			uint32_t result;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -142,7 +142,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -158,16 +158,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -181,7 +181,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture, tt.format,
+			fill_rect(&t->out, tt.picture, tt.format,
 				  0, 0, 0,
 				  PictOpSrc, x, y, w, h,
 				  red, green, blue, alpha);
@@ -204,7 +204,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, alpha));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -232,20 +232,20 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 	printf("Testing area fills (%s, using %s source): ",
 	       test_target_name(target), use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -261,19 +261,19 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 			int try = 50;
 
 			do {
-				x = rand() % (real.width - 1);
-				y = rand() % (real.height - 1);
-				w = 1 + rand() % (real.width - x - 1);
-				h = 1 + rand() % (real.height - y - 1);
-				tmpx = w == real.width ? 0 : rand() % (real.width - w);
-				tmpy = h == real.height ? 0 : rand() % (real.height - h);
+				x = rand() % (out.width - 1);
+				y = rand() % (out.height - 1);
+				w = 1 + rand() % (out.width - x - 1);
+				h = 1 + rand() % (out.height - y - 1);
+				tmpx = w == out.width ? 0 : rand() % (out.width - w);
+				tmpy = h == out.height ? 0 : rand() % (out.height - h);
 			} while (((tmpx+w > x && tmpx < x+w) ||
 				  (tmpy+h > y && tmpy < y+h)) &&
 				 --try);
 
 
 			if (try) {
-				fill_rect(&t->real, real.picture, real.format,
+				fill_rect(&t->out, out.picture, out.format,
 					  use_window, tmpx, tmpy,
 					  PictOpSrc, x, y, w, h,
 					  red, green, blue, alpha);
@@ -285,15 +285,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target, i
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-fill-copy.c b/test/render-fill-copy.c
index 45551b2..b5b475a 100644
--- a/test/render-fill-copy.c
+++ b/test/render-fill-copy.c
@@ -57,13 +57,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -78,7 +78,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, tt.picture, tt.format,
+			fill_rect(&t->out, tt.picture, tt.format,
 				  PictOpSrc, x, y, 1, 1,
 				  red, green, blue, alpha);
 
@@ -87,14 +87,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -115,7 +115,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -131,16 +131,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -154,7 +154,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture, tt.format,
+			fill_rect(&t->out, tt.picture, tt.format,
 				  PictOpSrc, x, y, w, h,
 				  red, green, blue, alpha);
 
@@ -176,7 +176,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, alpha));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -203,37 +203,37 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % real.width;
-			int h = rand() % real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % out.width;
+			int h = rand() % out.height;
 			int op = ops[rand() % sizeof(ops)];
 			int red = rand() % 0xff;
 			int green = rand() % 0xff;
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, real.picture, real.format,
+			fill_rect(&t->out, out.picture, out.format,
 				  op, x, y, w, h,
 				  red, green, blue, alpha);
 			fill_rect(&t->ref, ref.picture, ref.format,
@@ -242,15 +242,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target)
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-fill.c b/test/render-fill.c
index 54be1a3..37c9d85 100644
--- a/test/render-fill.c
+++ b/test/render-fill.c
@@ -31,13 +31,13 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
 	int r, s;
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	printf("Testing setting of single pixels (%s): ",
 	       test_target_name(target));
@@ -52,7 +52,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, 1, 1,
 				  red, green, blue, alpha);
 
@@ -61,14 +61,14 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			cells[y*tt.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -85,7 +85,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(pixels);
 	free(cells);
 }
@@ -101,16 +101,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -124,7 +124,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, w, h, red, green, blue, alpha);
 
 			if (x < 0)
@@ -145,7 +145,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, alpha));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -171,37 +171,37 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
 static void rect_tests(struct test *t, int reps, int sets, enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % real.width;
-			int h = rand() % real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % out.width;
+			int h = rand() % out.height;
 			int op = ops[rand() % sizeof(ops)];
 			int red = rand() % 0xff;
 			int green = rand() % 0xff;
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, real.picture,
+			fill_rect(&t->out, out.picture,
 				  op, x, y, w, h,
 				  red, green, blue, alpha);
 			fill_rect(&t->ref, ref.picture,
@@ -210,15 +210,15 @@ static void rect_tests(struct test *t, int reps, int sets, enum target target)
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
diff --git a/test/render-trapezoid-image.c b/test/render-trapezoid-image.c
index ecca709..452b4ec 100644
--- a/test/render-trapezoid-image.c
+++ b/test/render-trapezoid-image.c
@@ -56,7 +56,7 @@ static const char *trapezoid_name(enum trapezoid trapezoid)
 
 static void
 show_cells(char *buf,
-	   const uint32_t *real, const uint32_t *ref,
+	   const uint32_t *out, const uint32_t *ref,
 	   int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -69,7 +69,7 @@ show_cells(char *buf,
 			if (i < 0 || i >= w)
 				continue;
 
-			len += sprintf(buf+len, "%08x ", real[j*w+i]);
+			len += sprintf(buf+len, "%08x ", out[j*w+i]);
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -143,7 +143,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
@@ -154,7 +154,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 	       use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -172,8 +172,8 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 				ty = rand() % (tt.height - 1);
 			} while (tx == x && ty == y);
 
-			fill_rect(&t->real, tt.picture,
-				  use_window ? t->real.format : tt.format,
+			fill_rect(&t->out, tt.picture,
+				  use_window ? t->out.format : tt.format,
 				  PictOpSrc, x, y, 1, 1,
 				  0, 0, MASK_NONE,
 				  use_window, tx, ty,
@@ -181,17 +181,17 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 
 			pixels[r].x = x;
 			pixels[r].y = y;
-			cells[y*t->real.width+x] = color(red, green, blue, alpha);
+			cells[y*t->out.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -209,7 +209,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target,
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 
 	free(pixels);
 	free(cells);
@@ -265,7 +265,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s using %s source): ",
@@ -273,10 +273,10 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 	       use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -308,8 +308,8 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 				tx = ty = 0;
 			}
 
-			fill_rect(&t->real, tt.picture,
-				  use_window ? t->real.format : tt.format,
+			fill_rect(&t->out, tt.picture,
+				  use_window ? t->out.format : tt.format,
 				  PictOpSrc, x, y, w, h,
 				  0, 0, MASK_NONE,
 				  use_window, tx, ty,
@@ -323,7 +323,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -351,7 +351,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target, i
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
@@ -362,7 +362,7 @@ static void rect_tests(struct test *t,
 		       enum target target,
 		       int use_window)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (offset %dx%d, mask %s) (%s using %s source): ",
@@ -370,9 +370,9 @@ static void rect_tests(struct test *t,
 	       use_window ? "window" : "pixmap");
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
-	set_mask(&t->real, &real, mask);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
+	set_mask(&t->out, &out, mask);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -389,19 +389,19 @@ static void rect_tests(struct test *t,
 			int tx, ty, try = 50;
 
 			do {
-				x = rand() % (real.width - 1);
-				y = rand() % (real.height - 1);
-				w = 1 + rand() % (real.width - x - 1);
-				h = 1 + rand() % (real.height - y - 1);
-				tx = w == real.width ? 0 : rand() % (real.width - w);
-				ty = h == real.height ? 0 : rand() % (real.height - h);
+				x = rand() % (out.width - 1);
+				y = rand() % (out.height - 1);
+				w = 1 + rand() % (out.width - x - 1);
+				h = 1 + rand() % (out.height - y - 1);
+				tx = w == out.width ? 0 : rand() % (out.width - w);
+				ty = h == out.height ? 0 : rand() % (out.height - h);
 			} while (((tx+w > x && tx < x+w) &&
 				  (ty+h > y && ty < y+h)) &&
 				 --try);
 
 			if (try) {
-				fill_rect(&t->real, real.picture,
-					  use_window ? t->real.format : real.format,
+				fill_rect(&t->out, out.picture,
+					  use_window ? t->out.format : out.format,
 					  op, x, y, w, h,
 					  dx, dy, mask,
 					  use_window, tx, ty,
@@ -416,15 +416,15 @@ static void rect_tests(struct test *t,
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
@@ -508,7 +508,7 @@ static void trap_tests(struct test *t,
 		       int reps, int sets,
 		       enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	XTrapezoid *traps;
 	int max_traps = 65536;
 	int r, s, n;
@@ -523,9 +523,9 @@ static void trap_tests(struct test *t,
 	       test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
-	set_mask(&t->real, &real, mask);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
+	set_mask(&t->out, &out, mask);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -539,17 +539,17 @@ static void trap_tests(struct test *t,
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 			int num_traps = rand() % max_traps;
-			int srcx = rand() % 2*real.width - real.width;
-			int srcy = rand() % 2*real.height - real.height;
-			int srcw = rand() % real.width;
-			int srch = rand() % real.height;
+			int srcx = rand() % 2*out.width - out.width;
+			int srcy = rand() % 2*out.height - out.height;
+			int srcw = rand() % out.width;
+			int srch = rand() % out.height;
 
 			for (n = 0; n < num_traps; n++)
 				random_trapezoid(&traps[n], 0,
-						 0, 0, real.width, real.height);
+						 0, 0, out.width, out.height);
 
 
-			fill_traps(&t->real, real.picture, real.format,
+			fill_traps(&t->out, out.picture, out.format,
 				   op, traps, num_traps, mask,
 				   srcx, srcy, srcw, srch,
 				   red, green, blue, alpha);
@@ -561,15 +561,15 @@ static void trap_tests(struct test *t,
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 	free(traps);
 }
diff --git a/test/render-trapezoid.c b/test/render-trapezoid.c
index 811d909..cd99014 100644
--- a/test/render-trapezoid.c
+++ b/test/render-trapezoid.c
@@ -79,7 +79,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = malloc(t->real.width*t->real.height*4);
+	uint32_t *cells = malloc(t->out.width*t->out.height*4);
 	struct {
 		uint16_t x, y;
 	} *pixels = malloc(reps*sizeof(*pixels));
@@ -88,7 +88,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	printf("Testing setting of single pixels (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
+	test_target_create_render(&t->out, target, &tt);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -99,24 +99,24 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, 1, 1,
 				  0, 0, MASK_NONE,
 				  red, green, blue, alpha);
 
 			pixels[r].x = x;
 			pixels[r].y = y;
-			cells[y*t->real.width+x] = color(red, green, blue, alpha);
+			cells[y*t->out.width+x] = color(red, green, blue, alpha);
 		}
 
-		test_init_image(&image, &t->real.shm, tt.format, 1, 1);
+		test_init_image(&image, &t->out.shm, tt.format, 1, 1);
 
 		for (r = 0; r < reps; r++) {
 			uint32_t result;
 			uint32_t x = pixels[r].x;
 			uint32_t y = pixels[r].y;
 
-			XShmGetImage(t->real.dpy, tt.draw, &image,
+			XShmGetImage(t->out.dpy, tt.draw, &image,
 				     x, y, AllPlanes);
 
 			result = *(uint32_t *)image.data;
@@ -134,7 +134,7 @@ static void pixel_tests(struct test *t, int reps, int sets, enum target target)
 	}
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 
 	free(pixels);
 	free(cells);
@@ -151,16 +151,16 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 {
 	struct test_target tt;
 	XImage image;
-	uint32_t *cells = calloc(sizeof(uint32_t), t->real.width*t->real.height);
+	uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height);
 	int r, s, x, y;
 
 	printf("Testing area sets (%s): ", test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &tt);
-	clear(&t->real, &tt);
+	test_target_create_render(&t->out, target, &tt);
+	clear(&t->out, &tt);
 
-	test_init_image(&image, &t->real.shm, tt.format, tt.width, tt.height);
+	test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
@@ -174,7 +174,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 			x = rand() % (2*tt.width) - tt.width;
 			y = rand() % (2*tt.height) - tt.height;
 
-			fill_rect(&t->real, tt.picture, PictOpSrc,
+			fill_rect(&t->out, tt.picture, PictOpSrc,
 				  x, y, w, h,
 				  0, 0, MASK_NONE,
 				  red, green, blue, alpha);
@@ -197,7 +197,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 				    color(red, green, blue, alpha));
 		}
 
-		XShmGetImage(t->real.dpy, tt.draw, &image, 0, 0, AllPlanes);
+		XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes);
 
 		for (y = 0; y < tt.height; y++) {
 			for (x = 0; x < tt.width; x++) {
@@ -221,7 +221,7 @@ static void area_tests(struct test *t, int reps, int sets, enum target target)
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &tt);
+	test_target_destroy_render(&t->out, &tt);
 	free(cells);
 }
 
@@ -231,32 +231,32 @@ static void rect_tests(struct test *t,
 		       int reps, int sets,
 		       enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	int r, s;
 
 	printf("Testing area fills (offset %dx%d, mask %s) (%s): ",
 	       dx, dy, mask_name(mask), test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
 
 	for (s = 0; s < sets; s++) {
 		for (r = 0; r < reps; r++) {
-			int x = rand() % (2*real.width) - real.width;
-			int y = rand() % (2*real.height) - real.height;
-			int w = rand() % real.width;
-			int h = rand() % real.height;
+			int x = rand() % (2*out.width) - out.width;
+			int y = rand() % (2*out.height) - out.height;
+			int w = rand() % out.width;
+			int h = rand() % out.height;
 			int op = ops[rand() % sizeof(ops)];
 			int red = rand() % 0xff;
 			int green = rand() % 0xff;
 			int blue = rand() % 0xff;
 			int alpha = rand() % 0xff;
 
-			fill_rect(&t->real, real.picture, op,
+			fill_rect(&t->out, out.picture, op,
 				  x, y, w, h, dx, dy, mask,
 				  red, green, blue, alpha);
 			fill_rect(&t->ref, ref.picture, op,
@@ -265,15 +265,15 @@ static void rect_tests(struct test *t,
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 }
 
@@ -331,7 +331,7 @@ static void trap_tests(struct test *t,
 		       int reps, int sets,
 		       enum target target)
 {
-	struct test_target real, ref;
+	struct test_target out, ref;
 	XTrapezoid *traps;
 	int max_traps = 65536;
 	int r, s, n;
@@ -346,8 +346,8 @@ static void trap_tests(struct test *t,
 	       test_target_name(target));
 	fflush(stdout);
 
-	test_target_create_render(&t->real, target, &real);
-	clear(&t->real, &real);
+	test_target_create_render(&t->out, target, &out);
+	clear(&t->out, &out);
 
 	test_target_create_render(&t->ref, target, &ref);
 	clear(&t->ref, &ref);
@@ -365,20 +365,20 @@ static void trap_tests(struct test *t,
 
 			for (n = 0; n < num_traps; n++)
 				random_trapezoid(&traps[n], 0,
-						 0, 0, real.width, real.height);
+						 0, 0, out.width, out.height);
 
 			render_color.red   = red * alpha;
 			render_color.green = green * alpha;
 			render_color.blue  = blue * alpha;
 			render_color.alpha = alpha << 8;
 
-			src = XRenderCreateSolidFill(t->real.dpy,
+			src = XRenderCreateSolidFill(t->out.dpy,
 						     &render_color);
-			XRenderCompositeTrapezoids(t->real.dpy,
-						   op, src, real.picture,
-						   mask_format(t->real.dpy, mask),
+			XRenderCompositeTrapezoids(t->out.dpy,
+						   op, src, out.picture,
+						   mask_format(t->out.dpy, mask),
 						   0, 0, traps, num_traps);
-			XRenderFreePicture(t->real.dpy, src);
+			XRenderFreePicture(t->out.dpy, src);
 
 			src = XRenderCreateSolidFill(t->ref.dpy,
 						     &render_color);
@@ -390,15 +390,15 @@ static void trap_tests(struct test *t,
 		}
 
 		test_compare(t,
-			     real.draw, real.format,
+			     out.draw, out.format,
 			     ref.draw, ref.format,
-			     0, 0, real.width, real.height,
+			     0, 0, out.width, out.height,
 			     "");
 	}
 
 	printf("passed [%d iterations x %d]\n", reps, sets);
 
-	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->out, &out);
 	test_target_destroy_render(&t->ref, &ref);
 	free(traps);
 }
diff --git a/test/test.h b/test/test.h
index 3ee9411..383384b 100644
--- a/test/test.h
+++ b/test/test.h
@@ -33,7 +33,7 @@ struct test {
 		int max_shm_size;
 		int width, height, depth;
 		XRenderPictFormat *format;
-	} real, ref;
+	} out, ref;
 };
 
 void die(const char *fmt, ...);
@@ -42,8 +42,8 @@ void die(const char *fmt, ...);
 
 void test_init(struct test *test, int argc, char **argv);
 
-void test_compare(struct test *real,
-		  Drawable real_draw, XRenderPictFormat *real_format,
+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);
 
@@ -116,7 +116,7 @@ double test_timer_stop(struct test_display *t, struct timespec *tv);
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #endif
 
+#define SETS(I) ((I) >= 12 ? 1 : 1 << (12 - (I)))
 #define REPS(I) (1 << (I))
-#define SETS(I) ((I) < 12 ? 1 << (12 - (I)) : 2)
 
 #endif
diff --git a/test/test_display.c b/test/test_display.c
index 36cfe69..892b54e 100644
--- a/test/test_display.c
+++ b/test/test_display.c
@@ -27,7 +27,7 @@ static Window get_root(struct test_display *t)
 	return w;
 }
 
-static Display *real_display(int argc, char **argv)
+static Display *out_display(int argc, char **argv)
 {
 	Display *dpy;
 	const char *name = NULL;
@@ -52,7 +52,7 @@ static Display *real_display(int argc, char **argv)
 
 	dpy = XOpenDisplay(name);
 	if (dpy == NULL)
-		die("unable to open real display %s\n", name);
+		die("unable to open out display %s\n", name);
 
 	printf("Opened connection to %s for testing.\n", name);
 	return dpy;
@@ -129,15 +129,15 @@ static void default_setup(struct test_display *dpy)
 }
 
 static void test_get_displays(int argc, char **argv,
-			      struct test_display *real,
+			      struct test_display *out,
 			      struct test_display *ref)
 {
-	real->dpy = real_display(argc, argv);
-	default_setup(real);
-	shm_setup(real);
-	real->root = get_root(real);
+	out->dpy = out_display(argc, argv);
+	default_setup(out);
+	shm_setup(out);
+	out->root = get_root(out);
 
-	ref->dpy = ref_display(real->width, real->height, real->depth);
+	ref->dpy = ref_display(out->width, out->height, out->depth);
 	default_setup(ref);
 	shm_setup(ref);
 	ref->root = get_root(ref);
@@ -146,7 +146,7 @@ static void test_get_displays(int argc, char **argv,
 void test_init(struct test *test, int argc, char **argv)
 {
 	memset(test, 0, sizeof(*test));
-	test_get_displays(argc, argv, &test->real, &test->ref);
+	test_get_displays(argc, argv, &test->out, &test->ref);
 }
 
 void test_timer_start(struct test_display *t, struct timespec *tv)
diff --git a/test/test_image.c b/test/test_image.c
index f2cf906..d15a8af 100644
--- a/test/test_image.c
+++ b/test/test_image.c
@@ -1,6 +1,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+#include <png.h>
 
 #include "test.h"
 
@@ -29,7 +30,7 @@ int pixel_difference(uint32_t a, uint32_t b)
 
 static void
 show_pixels(char *buf,
-	    const XImage *real, const XImage *ref,
+	    const XImage *out, const XImage *ref,
 	    int x, int y, int w, int h)
 {
 	int i, j, len = 0;
@@ -44,9 +45,9 @@ show_pixels(char *buf,
 
 			len += sprintf(buf+len,
 				       "%08x ",
-				       *(uint32_t*)(real->data +
-						    j*real->bytes_per_line +
-						    i*real->bits_per_pixel/8));
+				       *(uint32_t*)(out->data +
+						    j*out->bytes_per_line +
+						    i*out->bits_per_pixel/8));
 		}
 
 		len += sprintf(buf+len, "\t");
@@ -58,8 +59,8 @@ show_pixels(char *buf,
 			len += sprintf(buf+len,
 				       "%08x ",
 				       *(uint32_t*)(ref->data +
-						    j*real->bytes_per_line +
-						    i*real->bits_per_pixel/8));
+						    j*out->bytes_per_line +
+						    i*out->bits_per_pixel/8));
 		}
 
 		len += sprintf(buf+len, "\n");
@@ -67,92 +68,167 @@ show_pixels(char *buf,
 }
 
 static void test_compare_fallback(struct test *t,
-				  Drawable real_draw, XRenderPictFormat *real_format,
+				  Drawable out_draw, XRenderPictFormat *out_format,
 				  Drawable ref_draw, XRenderPictFormat *ref_format,
 				  int x, int y, int w, int h)
 {
-	XImage *real_image, *ref_image;
-	char *real, *ref;
+	XImage *out_image, *ref_image;
+	char *out, *ref;
 	char buf[600];
 	uint32_t mask;
 	int i, j;
 
-	die_unless(real_format->depth == ref_format->depth);
+	die_unless(out_format->depth == ref_format->depth);
 
-	real_image = XGetImage(t->real.dpy, real_draw,
+	out_image = XGetImage(t->out.dpy, out_draw,
 			       x, y, w, h,
 			       AllPlanes, ZPixmap);
-	real = real_image->data;
+	out = out_image->data;
 
 	ref_image = XGetImage(t->ref.dpy, ref_draw,
 			      x, y, w, h,
 			      AllPlanes, ZPixmap);
 	ref = ref_image->data;
 
-	mask = depth_mask(real_image->depth);
+	mask = depth_mask(out_image->depth);
 
 	/* Start with an exact comparison. However, one quicky desires
 	 * a fuzzy comparator to hide hardware inaccuracies...
 	 */
 	for (j = 0; j < h; j++) {
 		for (i = 0; i < w; i++) {
-			uint32_t a = ((uint32_t *)real)[i] & mask;
+			uint32_t a = ((uint32_t *)out)[i] & mask;
 			uint32_t b = ((uint32_t *)ref)[i] & mask;
 			if (a != b && pixel_difference(a, b) > MAX_DELTA) {
 				show_pixels(buf,
-					    real_image, ref_image,
+					    out_image, ref_image,
 					    i, j, w, h);
 				die("discrepancy found at (%d+%d, %d+%d): found %08x, expected %08x (delta: %d)\n%s",
 				    x,i, y,j, a, b, pixel_difference(a, b), buf);
 			}
 		}
-		real += real_image->bytes_per_line;
+		out += out_image->bytes_per_line;
 		ref += ref_image->bytes_per_line;
 	}
 
-	XDestroyImage(real_image);
+	XDestroyImage(out_image);
 	XDestroyImage(ref_image);
 }
 
+static void
+unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
+{
+	unsigned int i;
+
+	for (i = 0; i < row_info->rowbytes; i += 4) {
+		uint8_t *b = &data[i];
+		uint32_t pixel;
+		uint8_t  alpha;
+
+		memcpy (&pixel, b, sizeof (uint32_t));
+		alpha = (pixel & 0xff000000) >> 24;
+		if (alpha == 0) {
+			b[0] = (pixel & 0xff0000) >> 16;
+			b[1] = (pixel & 0x00ff00) >>  8;
+			b[2] = (pixel & 0x0000ff) >>  0;
+			b[3] = 0xff;
+		} else {
+			b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
+			b[1] = (((pixel & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
+			b[2] = (((pixel & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
+			b[3] = alpha;
+		}
+	}
+}
+
+static void save_image(XImage *image, const char *filename)
+{
+	FILE *file;
+	png_struct *png = NULL;
+	png_info *info = NULL;
+	png_byte **rows = NULL;
+	int i;
+
+	file = fopen(filename, "w");
+	if (file == NULL)
+		return;
+
+	png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if (png == NULL)
+		goto out;
+
+	info = png_create_info_struct(png);
+	if (info == NULL)
+		goto out;
+
+	rows = png_malloc(png, sizeof(png_byte *) * image->height);
+	if (rows == NULL)
+		goto out;
+	for (i = 0; i < image->height; i++)
+		rows[i] = (png_byte *)(image->data + image->bytes_per_line * i);
+
+	if (setjmp(png_jmpbuf(png)))
+		goto out;
+
+	png_set_IHDR(png, info,
+		     image->width, image->height, 8,
+		     PNG_COLOR_TYPE_RGB_ALPHA,
+		     PNG_INTERLACE_NONE,
+		     PNG_COMPRESSION_TYPE_DEFAULT,
+		     PNG_FILTER_TYPE_DEFAULT);
+
+	png_init_io(png, file);
+	png_write_info(png, info);
+	png_set_write_user_transform_fn(png, unpremultiply_data);
+	png_write_image(png, rows);
+	png_write_end(png, info);
+
+out:
+	if (rows)
+		png_free(png, rows);
+	png_destroy_write_struct(&png, &info);
+	fclose(file);
+}
+
 void test_compare(struct test *t,
-		  Drawable real_draw, XRenderPictFormat *real_format,
+		  Drawable out_draw, XRenderPictFormat *out_format,
 		  Drawable ref_draw, XRenderPictFormat *ref_format,
 		  int x, int y, int w, int h,
 		  const char *info)
 {
-	XImage real_image, ref_image;
+	XImage out_image, ref_image;
 	Pixmap tmp;
-	char *real, *ref;
+	char *out, *ref;
 	char buf[600];
 	uint32_t mask;
 	int i, j;
 	XGCValues gcv;
 	GC gc;
 
-	if (w * h * 4 > t->real.max_shm_size)
+	if (w * h * 4 > t->out.max_shm_size)
 		return test_compare_fallback(t,
-					     real_draw, real_format,
+					     out_draw, out_format,
 					     ref_draw, ref_format,
 					     x, y, w, h);
 
-	test_init_image(&real_image, &t->real.shm, real_format, w, h);
+	test_init_image(&out_image, &t->out.shm, out_format, w, h);
 	test_init_image(&ref_image, &t->ref.shm, ref_format, w, h);
 
 	gcv.graphics_exposures = 0;
 
-	die_unless(real_image.depth == ref_image.depth);
-	die_unless(real_image.bits_per_pixel == ref_image.bits_per_pixel);
-	die_unless(real_image.bits_per_pixel == 32);
+	die_unless(out_image.depth == ref_image.depth);
+	die_unless(out_image.bits_per_pixel == ref_image.bits_per_pixel);
+	die_unless(out_image.bits_per_pixel == 32);
 
-	mask = depth_mask(real_image.depth);
+	mask = depth_mask(out_image.depth);
 
-	tmp = XCreatePixmap(t->real.dpy, real_draw, w, h, real_image.depth);
-	gc = XCreateGC(t->real.dpy, tmp, GCGraphicsExposures, &gcv);
-	XCopyArea(t->real.dpy, real_draw, tmp, gc, x, y, w, h, 0, 0);
-	XShmGetImage(t->real.dpy, tmp, &real_image, 0, 0, AllPlanes);
-	XFreeGC(t->real.dpy, gc);
-	XFreePixmap(t->real.dpy, tmp);
-	real = real_image.data;
+	tmp = XCreatePixmap(t->out.dpy, out_draw, w, h, out_image.depth);
+	gc = XCreateGC(t->out.dpy, tmp, GCGraphicsExposures, &gcv);
+	XCopyArea(t->out.dpy, out_draw, tmp, gc, x, y, w, h, 0, 0);
+	XShmGetImage(t->out.dpy, tmp, &out_image, 0, 0, AllPlanes);
+	XFreeGC(t->out.dpy, gc);
+	XFreePixmap(t->out.dpy, tmp);
+	out = out_image.data;
 
 	tmp = XCreatePixmap(t->ref.dpy, ref_draw, w, h, ref_image.depth);
 	gc = XCreateGC(t->ref.dpy, tmp, GCGraphicsExposures, &gcv);
@@ -167,17 +243,19 @@ void test_compare(struct test *t,
 	 */
 	for (j = 0; j < h; j++) {
 		for (i = 0; i < w; i++) {
-			uint32_t a = ((uint32_t *)real)[i] & mask;
+			uint32_t a = ((uint32_t *)out)[i] & mask;
 			uint32_t b = ((uint32_t *)ref)[i] & mask;
 			if (a != b && pixel_difference(a, b) > MAX_DELTA) {
 				show_pixels(buf,
-					    &real_image, &ref_image,
+					    &out_image, &ref_image,
 					    i, j, w, h);
+				save_image(&out_image, "out.png");
+				save_image(&ref_image,  "ref.png");
 				die("discrepancy found at (%d+%d, %d+%d): found %08x, expected %08x (delta: %d)\n%s%s\n",
 				    x,i, y,j, a, b, pixel_difference(a, b), buf, info);
 			}
 		}
-		real += real_image.bytes_per_line;
+		out += out_image.bytes_per_line;
 		ref += ref_image.bytes_per_line;
 	}
 }


More information about the xorg-commit mailing list