xf86-video-intel: 6 commits - src/sna/gen6_common.h src/sna/gen6_render.c src/sna/gen7_render.c src/sna/sna_driver.c src/sna/sna_trapezoids_boxes.c src/sna/sna_trapezoids_mono.c test/.gitignore test/Makefile.am test/render-composite-solid-mask.c test/render-copyarea-mask.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Nov 14 04:13:48 PST 2013


 src/sna/gen6_common.h              |    9 +
 src/sna/gen6_render.c              |    2 
 src/sna/gen7_render.c              |    2 
 src/sna/sna_driver.c               |   51 ++++-------
 src/sna/sna_trapezoids_boxes.c     |    3 
 src/sna/sna_trapezoids_mono.c      |    3 
 test/.gitignore                    |    2 
 test/Makefile.am                   |    2 
 test/render-composite-solid-mask.c |  122 +++++++++++++++++++++++++++
 test/render-copyarea-mask.c        |  167 +++++++++++++++++++++++++++++++++++++
 10 files changed, 331 insertions(+), 32 deletions(-)

New commits:
commit 23f47c8b4b4825b9219e1f515015635a7c48ec35
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 14 10:17:49 2013 +0000

    tests: Exercise render copies under a mask
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/.gitignore b/test/.gitignore
index 8e74a9a..05bb936 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -11,6 +11,7 @@ render-fill-copy
 render-composite-solid
 render-composite-solid-mask
 render-copyarea
+render-copyarea-mask
 render-copyarea-size
 render-copy-alphaless
 mixed-stress
diff --git a/test/Makefile.am b/test/Makefile.am
index de91cfa..0b5f8a0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -14,6 +14,7 @@ stress_TESTS = \
 	render-composite-solid \
 	render-composite-solid-mask \
 	render-copyarea \
+	render-copyarea-mask \
 	render-copyarea-size \
 	render-copy-alphaless \
 	mixed-stress \
diff --git a/test/render-copyarea-mask.c b/test/render-copyarea-mask.c
new file mode 100644
index 0000000..c8bb715
--- /dev/null
+++ b/test/render-copyarea-mask.c
@@ -0,0 +1,167 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <X11/Xutil.h> /* for XDestroyImage */
+
+#include "test.h"
+
+static void fill_rect(struct test_display *t,
+		      Picture p,
+		      XRenderPictFormat *format,
+		      int use_window, int tx, int ty,
+		      uint8_t op, int x, int y, int w, int h,
+		      int mask_x, int mask_y, int mask_w, int mask_h,
+		      uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
+{
+	Drawable tmp;
+	Pixmap pixmask;
+	XRenderColor c;
+	Picture src, mask;
+
+	if (use_window) {
+		XSetWindowAttributes attr;
+
+		attr.override_redirect = 1;
+		tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy),
+				    tx, ty,
+				    w, h,
+				    0, format->depth,
+				    InputOutput,
+				    DefaultVisual(t->dpy,
+						  DefaultScreen(t->dpy)),
+				    CWOverrideRedirect, &attr);
+		XMapWindow(t->dpy, tmp);
+	} else
+		tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy),
+				    w, h, format->depth);
+
+	pixmask = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, 8);
+	mask = XRenderCreatePicture(t->dpy, pixmask,
+				    XRenderFindStandardFormat(t->dpy, PictStandardA8),
+				    0, NULL);
+	c.red = c.green = c.blue = c.alpha = 0;
+	XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c,
+			     0, 0, w, h);
+	c.red = c.green = c.blue = c.alpha = 0xffff;
+	XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c,
+			     mask_x, mask_y, mask_w, mask_h);
+
+	src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL);
+	c.red = red * alpha;
+	c.green = green * alpha;
+	c.blue = blue * alpha;
+	c.alpha = alpha << 8 | alpha;
+	XRenderFillRectangle(t->dpy, PictOpSrc, src, &c, 0, 0, w, h);
+
+	XRenderComposite(t->dpy, op, src, mask, p, 0, 0, 0, 0, x, y, w, h);
+
+	XRenderFreePicture(t->dpy, src);
+	if (use_window)
+		XDestroyWindow(t->dpy, tmp);
+	else
+		XFreePixmap(t->dpy, tmp);
+
+	XRenderFreePicture(t->dpy, mask);
+	XFreePixmap(t->dpy, pixmask);
+}
+
+static void clear(struct test_display *dpy, struct test_target *tt)
+{
+	XRenderColor render_color = {0};
+	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
+			     0, 0, tt->width, tt->height);
+}
+
+static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window)
+{
+	struct test_target real, 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->ref, target, &ref);
+	clear(&t->ref, &ref);
+
+	for (s = 0; s < sets; s++) {
+		for (r = 0; r < reps; r++) {
+			int x, y, w, h;
+			int mask_x, mask_y, mask_w, mask_h;
+			int tmpx, tmpy;
+			uint8_t red = rand();
+			uint8_t green = rand();
+			uint8_t blue = rand();
+			uint8_t alpha = rand();
+			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);
+			} while (((tmpx+w > x && tmpx < x+w) ||
+				  (tmpy+h > y && tmpy < y+h)) &&
+				 --try);
+
+			mask_x = (rand() % (2*w)) - w;
+			mask_y = (rand() % (2*h)) - h;
+			mask_w = rand() % w;
+			mask_h = rand() % h;
+
+			if (try) {
+				fill_rect(&t->real, real.picture, real.format,
+					  use_window, tmpx, tmpy,
+					  PictOpSrc, x, y, w, h,
+					  mask_x, mask_y, mask_w, mask_h,
+					  red, green, blue, alpha);
+				fill_rect(&t->ref, ref.picture, ref.format,
+					  use_window, tmpx, tmpy,
+					  PictOpSrc, x, y, w, h,
+					  mask_x, mask_y, mask_w, mask_h,
+					  red, green, blue, alpha);
+			}
+		}
+
+		test_compare(t,
+			     real.draw, real.format,
+			     ref.draw, ref.format,
+			     0, 0, real.width, real.height,
+			     "");
+	}
+
+	printf("passed [%d iterations x %d]\n", reps, sets);
+
+	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->ref, &ref);
+}
+
+int main(int argc, char **argv)
+{
+	struct test test;
+	int i;
+
+	test_init(&test, argc, argv);
+
+	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
+		int reps = 1 << i;
+		int sets = 1 << (12 - i);
+		enum target t;
+
+		if (sets < 2)
+			sets = 2;
+
+		for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
+			rect_tests(&test, reps, sets, t, 0);
+			if (t != PIXMAP)
+			    rect_tests(&test, reps, sets, t, 1);
+		}
+	}
+
+	return 0;
+}
commit aa5a5684ebada60a1b103624a9b49aa085a406c1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 13 16:25:54 2013 +0000

    sna/gen6+: Only substitute SRC for CLEAR if using the correct source
    
    If the source has not been verified to be clear, then using the SRC
    operator will paint the wrong color.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 8c57000..a2b4082 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2159,7 +2159,7 @@ gen6_render_composite(struct sna *sna,
 					    width, height,
 					    tmp);
 
-	if (op == PictOpClear)
+	if (op == PictOpClear && src == sna->clear)
 		op = PictOpSrc;
 	tmp->op = op;
 	if (!gen6_composite_set_target(sna, tmp, dst,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 82c785f..f940803 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2437,7 +2437,7 @@ gen7_render_composite(struct sna *sna,
 					    width, height,
 					    tmp);
 
-	if (op == PictOpClear)
+	if (op == PictOpClear && src == sna->clear)
 		op = PictOpSrc;
 	tmp->op = op;
 	if (!gen7_composite_set_target(sna, tmp, dst,
diff --git a/src/sna/sna_trapezoids_boxes.c b/src/sna/sna_trapezoids_boxes.c
index 4b0346b..23a3b45 100644
--- a/src/sna/sna_trapezoids_boxes.c
+++ b/src/sna/sna_trapezoids_boxes.c
@@ -197,6 +197,9 @@ composite_aligned_boxes(struct sna *sna,
 		goto done;
 	}
 
+	if (op == PictOpClear && sna->clear)
+		src = sna->clear;
+
 	if (force_fallback ||
 	    !sna->render.composite(sna, op, src, NULL, dst,
 				   src_x,  src_y,
diff --git a/src/sna/sna_trapezoids_mono.c b/src/sna/sna_trapezoids_mono.c
index f7b9a1c..40d0381 100644
--- a/src/sna/sna_trapezoids_mono.c
+++ b/src/sna/sna_trapezoids_mono.c
@@ -803,6 +803,9 @@ mono_trapezoids_span_converter(struct sna *sna,
 	unbounded = (!sna_drawable_is_clear(dst->pDrawable) &&
 		     !operator_is_bounded(op));
 
+	if (op == PictOpClear && mono.sna->clear)
+		src = mono.sna->clear;
+
 	mono.sna = sna;
 	if (!mono.sna->render.composite(mono.sna, op, src, NULL, dst,
 				       src_x + mono.clip.extents.x1 - dst_x - dx,
commit 97e684ab3c887c1992733d0031f0256e9692d452
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 13 15:28:37 2013 +0000

    sna/gen6+: Improve debug PREFER_RENDER to cover all decision points
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_common.h b/src/sna/gen6_common.h
index 4957a33..39e6150 100644
--- a/src/sna/gen6_common.h
+++ b/src/sna/gen6_common.h
@@ -89,6 +89,9 @@ static inline bool untiled_tlb_miss(struct kgem_bo *bo)
 
 static int prefer_blt_bo(struct sna *sna, struct kgem_bo *bo)
 {
+	if (PREFER_RENDER)
+		return PREFER_RENDER < 0;
+
 	if (bo->rq)
 		return RQ_IS_BLT(bo->rq);
 
@@ -116,6 +119,9 @@ inline static bool prefer_blt_ring(struct sna *sna,
 				   struct kgem_bo *bo,
 				   unsigned flags)
 {
+	if (PREFER_RENDER)
+		return PREFER_RENDER < 0;
+
 	assert(!force_blt_ring(sna));
 	assert(!kgem_bo_is_render(bo));
 
@@ -137,6 +143,9 @@ inline static bool prefer_render_ring(struct sna *sna,
 inline static bool
 prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp)
 {
+	if (PREFER_RENDER)
+		return PREFER_RENDER < 0;
+
 	if (untiled_tlb_miss(tmp->dst.bo) ||
 	    untiled_tlb_miss(tmp->src.bo))
 		return true;
commit 7358ba83a3d4ab37459b4e510704bd0be4438dcd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 13 15:27:05 2013 +0000

    tests: Add render-composite-solid-mask
    
    Another reference test to exercise simple composite pathways clearly.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/.gitignore b/test/.gitignore
index 7088578..8e74a9a 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -9,6 +9,7 @@ render-trapezoid
 render-trapezoid-image
 render-fill-copy
 render-composite-solid
+render-composite-solid-mask
 render-copyarea
 render-copyarea-size
 render-copy-alphaless
diff --git a/test/Makefile.am b/test/Makefile.am
index 7ffb7df..de91cfa 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -12,6 +12,7 @@ stress_TESTS = \
 	render-trapezoid-image \
 	render-fill-copy \
 	render-composite-solid \
+	render-composite-solid-mask \
 	render-copyarea \
 	render-copyarea-size \
 	render-copy-alphaless \
diff --git a/test/render-composite-solid-mask.c b/test/render-composite-solid-mask.c
new file mode 100644
index 0000000..b86512c
--- /dev/null
+++ b/test/render-composite-solid-mask.c
@@ -0,0 +1,122 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <X11/Xutil.h> /* for XDestroyImage */
+#include <pixman.h> /* for pixman blt functions */
+
+#include "test.h"
+
+static const uint8_t ops[] = {
+	PictOpClear,
+	PictOpSrc,
+	PictOpDst,
+};
+
+static void fill_rect(struct test_display *dpy, Picture p, uint8_t op,
+		      int x, int y, int w, int h,
+		      uint8_t s_red, uint8_t s_green, uint8_t s_blue, uint8_t s_alpha,
+		      uint8_t m_red, uint8_t m_green, uint8_t m_blue, uint8_t m_alpha)
+{
+	XRenderColor render_color;
+	Picture source, mask;
+
+	render_color.red   = s_red * s_alpha;
+	render_color.green = s_green * s_alpha;
+	render_color.blue  = s_blue * s_alpha;
+	render_color.alpha = s_alpha << 8 | s_alpha;
+	source = XRenderCreateSolidFill(dpy->dpy, &render_color);
+
+	render_color.red   = m_red * m_alpha;
+	render_color.green = m_green * m_alpha;
+	render_color.blue  = m_blue * m_alpha;
+	render_color.alpha = m_alpha << 8 | m_alpha;
+	mask = XRenderCreateSolidFill(dpy->dpy, &render_color);
+
+	XRenderComposite(dpy->dpy, op, source, mask, p, 0, 0, 0, 0, x, y, w,h);
+
+	XRenderFreePicture(dpy->dpy, mask);
+	XRenderFreePicture(dpy->dpy, source);
+}
+
+static void clear(struct test_display *dpy, struct test_target *tt)
+{
+	XRenderColor render_color = {0};
+	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
+			     0, 0, tt->width, tt->height);
+}
+
+static void ref_tests(struct test *t, int reps, int sets, enum target target)
+{
+	struct test_target real, 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->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 op = ops[rand() % sizeof(ops)];
+			int s_red = rand() % 0xff;
+			int s_green = rand() % 0xff;
+			int s_blue = rand() % 0xff;
+			int s_alpha = rand() % 0xff;
+			int m_red = rand() % 0xff;
+			int m_green = rand() % 0xff;
+			int m_blue = rand() % 0xff;
+			int m_alpha = rand() % 0xff;
+
+			fill_rect(&t->real, real.picture,
+				  op, x, y, w, h,
+				  s_red, s_green, s_blue, s_alpha,
+				  m_red, m_green, m_blue, m_alpha);
+			fill_rect(&t->ref, ref.picture,
+				  op, x, y, w, h,
+				  s_red, s_green, s_blue, s_alpha,
+				  m_red, m_green, m_blue, m_alpha);
+		}
+
+		test_compare(t,
+			     real.draw, real.format,
+			     ref.draw, ref.format,
+			     0, 0, real.width, real.height,
+			     "");
+	}
+
+	printf("passed [%d iterations x %d]\n", reps, sets);
+
+	test_target_destroy_render(&t->real, &real);
+	test_target_destroy_render(&t->ref, &ref);
+}
+
+int main(int argc, char **argv)
+{
+	struct test test;
+	int i;
+
+	test_init(&test, argc, argv);
+
+	for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
+		int reps = 1 << i;
+		int sets = 1 << (12 - i);
+		enum target t;
+
+		if (sets < 2)
+			sets = 2;
+
+		for (t = TARGET_FIRST; t <= TARGET_LAST; t++)
+			ref_tests(&test, reps, sets, t);
+	}
+
+	return 0;
+}
commit f08f9cb28efa1b82f196695c66c3ec3a2b63361c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 13 14:17:51 2013 +0000

    sna: Eliminate a compiler warning for a shadowed variable
    
    sna_driver.c: In function 'sna_load_palette':
    sna_driver.c:86:12: warning: declaration of 'index' shadows a global declaration [-Wshadow]
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 645746d..805ae05 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -83,8 +83,7 @@ sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices,
 		 LOCO * colors, VisualPtr pVisual)
 {
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	int i, j, index;
-	int p;
+	int p, n, i, j;
 	uint16_t lut_r[256], lut_g[256], lut_b[256];
 
 	DBG(("%s\n", __FUNCTION__));
@@ -92,48 +91,43 @@ sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices,
 	for (p = 0; p < xf86_config->num_crtc; p++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[p];
 
+#define C(I,RGB) (colors[I].RGB << 8 | colors[I].RGB)
 		switch (scrn->depth) {
 		case 15:
-			for (i = 0; i < numColors; i++) {
-				index = indices[i];
+			for (n = 0; n < numColors; n++) {
+				i = indices[n];
 				for (j = 0; j < 8; j++) {
-					lut_r[index * 8 + j] =
-					    colors[index].red << 8;
-					lut_g[index * 8 + j] =
-					    colors[index].green << 8;
-					lut_b[index * 8 + j] =
-					    colors[index].blue << 8;
+					lut_r[8*i + j] = C(i, red);
+					lut_g[8*i + j] = C(i, green);
+					lut_b[8*i + j] = C(i, blue);
 				}
 			}
 			break;
 		case 16:
-			for (i = 0; i < numColors; i++) {
-				index = indices[i];
+			for (n = 0; n < numColors; n++) {
+				i = indices[n];
 
-				if (index <= 31) {
+				if (i <= 31) {
 					for (j = 0; j < 8; j++) {
-						lut_r[index * 8 + j] =
-						    colors[index].red << 8;
-						lut_b[index * 8 + j] =
-						    colors[index].blue << 8;
+						lut_r[8*i + j] = C(i, red);
+						lut_b[8*i + j] = C(i, blue);
 					}
 				}
 
-				for (j = 0; j < 4; j++) {
-					lut_g[index * 4 + j] =
-					    colors[index].green << 8;
-				}
+				for (j = 0; j < 4; j++)
+					lut_g[4*i + j] = C(i, green);
 			}
 			break;
 		default:
-			for (i = 0; i < numColors; i++) {
-				index = indices[i];
-				lut_r[index] = colors[index].red << 8;
-				lut_g[index] = colors[index].green << 8;
-				lut_b[index] = colors[index].blue << 8;
+			for (n = 0; n < numColors; n++) {
+				i = indices[n];
+				lut_r[i] = C(i, red);
+				lut_g[i] = C(i, green);
+				lut_b[i] = C(i, blue);
 			}
 			break;
 		}
+#undef C
 
 		/* Make the change through RandR */
 #ifdef RANDR_12_INTERFACE
commit 501dbf45cd85b0008e599637ad3ca76c044d39d5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 13 14:17:51 2013 +0000

    sna: Eliminate a compiler warning for a shadowed variable
    
    We don't strictly need that local structure, so do without and keep the
    compiler quiet.
    
    sna_driver.c: In function 'fb_supports_depth':
    sna_driver.c:414:23: warning: declaration of 'close' shadows a global declaration [-Wshadow]
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 00d90bf..645746d 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -411,7 +411,6 @@ static Bool fb_supports_depth(int fd, int depth)
 {
 	struct drm_i915_gem_create create;
 	struct drm_mode_fb_cmd fb;
-	struct drm_gem_close close;
 	Bool ret;
 
 	VG_CLEAR(create);
@@ -431,9 +430,7 @@ static Bool fb_supports_depth(int fd, int depth)
 	ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &fb) == 0;
 	drmModeRmFB(fd, fb.fb_id);
 
-	VG_CLEAR(close);
-	close.handle = create.handle;
-	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
+	(void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle);
 
 	return ret;
 }


More information about the xorg-commit mailing list