xf86-video-intel: 6 commits - src/sna/gen2_render.c src/sna/gen3_render.c src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/gen7_render.c src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna_damage.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Nov 14 06:18:25 PST 2011


 src/sna/gen2_render.c |    6 -
 src/sna/gen3_render.c |    6 -
 src/sna/gen4_render.c |    6 -
 src/sna/gen5_render.c |    6 -
 src/sna/gen6_render.c |    7 +
 src/sna/gen7_render.c |    7 +
 src/sna/sna_accel.c   |  192 ++++++++++++++++++++++++++++++++++++++++++--------
 src/sna/sna_damage.c  |    9 +-
 src/sna/sna_damage.h  |    2 
 9 files changed, 187 insertions(+), 54 deletions(-)

New commits:
commit 5647e2981d81fd2b5cdb22d544f83d2d0f9445c9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 14:11:56 2011 +0000

    sna/damage: Always reduce damage for testing PIXMAN_REGION_OUT
    
    Reported-by: Clemens Eisserer <linuxhippy at gmail.com>
    References: https://bugs.freedesktop.org/show_bug.cgi?id=42414
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index 95a92a5..bc5740d 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -1138,10 +1138,11 @@ static int _sna_damage_contains_box(struct sna_damage *damage,
 		__sna_damage_reduce(damage);
 
 	ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
-	if (damage->n == 0)
+	if (ret != PIXMAN_REGION_OUT || damage->n == 0)
 		return ret;
 
-	return ret == PIXMAN_REGION_IN ? PIXMAN_REGION_IN : PIXMAN_REGION_OUT;
+	__sna_damage_reduce(damage);
+	return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
 }
 
 #if DEBUG_DAMAGE
@@ -1246,9 +1247,7 @@ struct sna_damage *_sna_damage_reduce(struct sna_damage *damage)
 {
 	DBG(("%s\n", __FUNCTION__));
 
-	if (damage->n)
-		__sna_damage_reduce(damage);
-
+	__sna_damage_reduce(damage);
 	if (!pixman_region_not_empty(&damage->region)) {
 		__sna_damage_destroy(damage);
 		damage = NULL;
diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 7fc6d02..5c88cf6 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -133,7 +133,7 @@ static inline void sna_damage_reduce(struct sna_damage **damage)
 	if (*damage == NULL)
 		return;
 
-	if ((*damage)->mode != DAMAGE_ALL)
+	if ((*damage)->n)
 		*damage = _sna_damage_reduce(*damage);
 }
 
commit 405b015fe255c75f91b0f3fe93f06bd14faee5a1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 14:05:10 2011 +0000

    sna: Be explicit in all sna_damage_contains_box() tests
    
    Clarify the exact in/out/maybe expected result when testing.
    
    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 3b0f49d..e0990c5 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -604,7 +604,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		goto done;
 
 	if (sna_damage_contains_box(priv->gpu_damage,
-				    REGION_EXTENTS(NULL, region))) {
+				    REGION_EXTENTS(NULL, region)) != PIXMAN_REGION_OUT) {
 		DBG(("%s: region (%dx%d) intersects gpu damage\n",
 		     __FUNCTION__,
 		     region->extents.x2 - region->extents.x1,
commit 5d23149647b1645057dbd89087691e873494f763
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 13:53:37 2011 +0000

    sna: Remove redundant 'can_fill_spans()'
    
    Spans are almost always accelerated now...
    
    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 00001f7..3b0f49d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2660,19 +2660,6 @@ sna_poly_fill_rect_stippled_blt(DrawablePtr drawable,
 				GCPtr gc, int n, xRectangle *rect,
 				const BoxRec *extents, unsigned clipped);
 
-static bool
-can_fill_spans(DrawablePtr drawable, GCPtr gc)
-{
-	DBG(("%s: is-solid-mask? %d\n", __FUNCTION__,
-	     PM_IS_SOLID(drawable, gc->planemask)));
-	if (!PM_IS_SOLID(drawable, gc->planemask))
-		return false;
-
-	DBG(("%s: non-stipple fill? %d\n", __FUNCTION__,
-	     gc->fillStyle != FillStippled));
-	return gc->fillStyle == FillSolid || gc->fillStyle == FillTiled;
-}
-
 static void
 sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 	       DDXPointPtr pt, int *width, int sorted)
@@ -4224,7 +4211,6 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 
 spans_fallback:
 	if (USE_SPANS &&
-	    can_fill_spans(drawable, gc) &&
 	    sna_drawable_use_gpu_bo(drawable, &region.extents, NULL)) {
 		DBG(("%s: converting line into spans\n", __FUNCTION__));
 		switch (gc->lineStyle) {
@@ -5065,7 +5051,6 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	/* XXX Do we really want to base this decision on the amalgam ? */
 spans_fallback:
 	if (USE_SPANS &&
-	    can_fill_spans(drawable, gc) &&
 	    sna_drawable_use_gpu_bo(drawable, &region.extents, NULL)) {
 		void (*line)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
 		int i;
@@ -5743,8 +5728,11 @@ sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
 		goto fallback;
 	}
 
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto fallback;
+
 	/* For "simple" cases use the miPolyArc to spans path */
-	if (USE_SPANS && arc_to_spans(gc, n) && can_fill_spans(drawable, gc) &&
+	if (USE_SPANS && arc_to_spans(gc, n) &&
 	    sna_drawable_use_gpu_bo(drawable, &region.extents, NULL)) {
 		DBG(("%s: converting arcs into spans\n", __FUNCTION__));
 		/* XXX still around 10x slower for x11perf -ellipse */
commit ae9de984adb275e028e7fbcb8b74a3ce11920eed
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 13:39:34 2011 +0000

    sna: Convert non-FillSolid rectilinear lines to boxes
    
    And render using the tiled/stippled rect routines instead.
    
    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 c3c08a5..00001f7 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4063,7 +4063,7 @@ sna_poly_line_extents(DrawablePtr drawable, GCPtr gc,
 		return 0;
 
 	*out = box;
-	return 1 | blt << 1 | clip << 2;
+	return 1 | blt << 2 | clip << 1;
 }
 
 static void
@@ -4101,24 +4101,32 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	     gc->lineStyle, gc->lineStyle == LineSolid,
 	     gc->lineWidth,
 	     gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
-	     flags & 2));
-	if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid &&
-	    (gc->lineWidth == 0 || (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy))) &&
-	    PM_IS_SOLID(drawable, gc->planemask)) {
+	     flags & 4));
+
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto fallback;
+
+	if (gc->lineStyle != LineSolid)
+		goto spans_fallback;
+	if (!(gc->lineWidth == 0 ||
+	      (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy))))
+		goto spans_fallback;
+
+	if (gc->fillStyle == FillSolid) {
 		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying solid fill [%08lx]\n",
 		     __FUNCTION__, gc->fgPixel));
 
-		if (flags & 2) {
+		if (flags & 4) {
 			if (sna_drawable_use_gpu_bo(drawable,
 						    &region.extents,
 						    &damage) &&
 			    sna_poly_line_blt(drawable,
 					      priv->gpu_bo, damage,
 					      gc, mode, n, pt,
-					      &region.extents, flags & 4))
+					      &region.extents, flags & 2))
 				return;
 
 			if (sna_drawable_use_cpu_bo(drawable,
@@ -4127,7 +4135,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 			    sna_poly_line_blt(drawable,
 					      priv->cpu_bo, damage,
 					      gc, mode, n, pt,
-					      &region.extents, flags & 4))
+					      &region.extents, flags & 2))
 				return;
 		} else { /* !rectilinear */
 			if (USE_ZERO_SPANS &&
@@ -4137,12 +4145,84 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 			    sna_poly_zero_line_blt(drawable,
 						   priv->gpu_bo, damage,
 						   gc, mode, n, pt,
-						   &region.extents, flags & 4))
+						   &region.extents, flags & 2))
 				return;
 
 		}
+	} else if (flags & 4) {
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
+		struct sna_damage **damage;
+
+		/* Try converting these to a set of rectangles instead */
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents, &damage)) {
+			DDXPointRec p1, p2;
+			xRectangle *rect;
+			int i;
+
+			DBG(("%s: converting to rectagnles\n", __FUNCTION__));
+
+			rect = malloc (n * sizeof (xRectangle));
+			if (rect == NULL)
+				return;
+
+			p1 = pt[0];
+			for (i = 1; i < n; i++) {
+				if (mode == CoordModePrevious) {
+					p2.x = p1.x + pt[i].x;
+					p2.y = p1.y + pt[i].y;
+				} else {
+					p2 = pt[i];
+				}
+				if (p1.x < p2.x) {
+					rect[i].x = p1.x;
+					rect[i].width = p2.x - p1.x;
+				} else if (p1.x > p2.x) {
+					rect[i].x = p2.x;
+					rect[i].width = p1.x - p2.x;
+				} else {
+					rect[i].x = p1.x;
+					rect[i].width = 1;
+				}
+				if (p1.y < p2.y) {
+					rect[i].y = p1.y;
+					rect[i].height = p2.y - p1.y;
+				} else if (p1.y > p2.y) {
+					rect[i].y = p2.y;
+					rect[i].height = p1.y - p2.y;
+				} else {
+					rect[i].y = p1.y;
+					rect[i].height = 1;
+				}
+
+				/* don't paint last pixel */
+				if (gc->capStyle == CapNotLast) {
+					if (p1.x == p2.x)
+						rect[i].height--;
+					else
+						rect[i].width--;
+				}
+				p1 = p2;
+			}
+
+			if (gc->fillStyle == FillTiled) {
+				i = sna_poly_fill_rect_tiled_blt(drawable,
+								 priv->gpu_bo, damage,
+								 gc, n - 1, rect + 1,
+								 &region.extents, flags & 2);
+			} else {
+				i = sna_poly_fill_rect_stippled_blt(drawable,
+								    priv->gpu_bo, damage,
+								    gc, n - 1, rect + 1,
+								    &region.extents, flags & 2);
+			}
+			free (rect);
+
+			if (i)
+				return;
+		}
 	}
 
+spans_fallback:
 	if (USE_SPANS &&
 	    can_fill_spans(drawable, gc) &&
 	    sna_drawable_use_gpu_bo(drawable, &region.extents, NULL)) {
commit e861e816f53989ce3ab3ec89dd1d9a35155f999a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 13:39:34 2011 +0000

    sna: Convert non-FillSolid rectilinear segments to boxes
    
    And render using the tiled/stippled rect routines instead.
    
    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 ac76525..c3c08a5 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4879,10 +4879,11 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	     gc->lineWidth,
 	     gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
 	     flags & 4));
-	if (gc->fillStyle == FillSolid &&
-	    gc->lineStyle == LineSolid &&
-	    gc->lineWidth <= 1 &&
-	    PM_IS_SOLID(drawable, gc->planemask)) {
+	if (!PM_IS_SOLID(drawable, gc->planemask))
+		goto fallback;
+	if (gc->lineStyle != LineSolid || gc->lineWidth > 1)
+		goto spans_fallback;
+	if (gc->fillStyle == FillSolid) {
 		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
@@ -4917,9 +4918,72 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 						      gc, n, seg, &region.extents, flags & 2))
 				return;
 		}
+	} else if (flags &4) {
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
+		struct sna_damage **damage;
+
+		/* Try converting these to a set of rectangles instead */
+		if (sna_drawable_use_gpu_bo(drawable, &region.extents, &damage)) {
+			xRectangle *rect;
+			int i;
+
+			DBG(("%s: converting to rectagnles\n", __FUNCTION__));
+
+			rect = malloc (n * sizeof (xRectangle));
+			if (rect == NULL)
+				return;
+
+			for (i = 0; i < n; i++) {
+				if (seg[i].x1 < seg[i].x2) {
+					rect[i].x = seg[i].x1;
+					rect[i].width = seg[i].x2 - seg[i].x1;
+				} else if (seg[i].x1 > seg[i].x2) {
+					rect[i].x = seg[i].x2;
+					rect[i].width = seg[i].x1 - seg[i].x2;
+				} else {
+					rect[i].x = seg[i].x1;
+					rect[i].width = 1;
+				}
+				if (seg[i].y1 < seg[i].y2) {
+					rect[i].y = seg[i].y1;
+					rect[i].height = seg[i].y2 - seg[i].y1;
+				} else if (seg[i].x1 > seg[i].y2) {
+					rect[i].y = seg[i].y2;
+					rect[i].height = seg[i].y1 - seg[i].y2;
+				} else {
+					rect[i].y = seg[i].y1;
+					rect[i].height = 1;
+				}
+
+				/* don't paint last pixel */
+				if (gc->capStyle == CapNotLast) {
+					if (seg->x1 == seg->x2)
+						rect[i].height--;
+					else
+						rect[i].width--;
+				}
+			}
+
+			if (gc->fillStyle == FillTiled) {
+				i = sna_poly_fill_rect_tiled_blt(drawable,
+								 priv->gpu_bo, damage,
+								 gc, n, rect,
+								 &region.extents, flags & 2);
+			} else {
+				i = sna_poly_fill_rect_stippled_blt(drawable,
+								    priv->gpu_bo, damage,
+								    gc, n, rect,
+								    &region.extents, flags & 2);
+			}
+			free (rect);
+
+			if (i)
+				return;
+		}
 	}
 
 	/* XXX Do we really want to base this decision on the amalgam ? */
+spans_fallback:
 	if (USE_SPANS &&
 	    can_fill_spans(drawable, gc) &&
 	    sna_drawable_use_gpu_bo(drawable, &region.extents, NULL)) {
commit 6fc2928f578ae1e278c968d5c778d99d56bd667a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 14 13:05:00 2011 +0000

    sna: tidy assignment of composite damage
    
    Make sure that the damage is always set, even if only to NULL, so that
    we are safe if in future the operation state is not initially cleared.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 1b1c8aa..98a02cb 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -1201,9 +1201,9 @@ gen2_composite_set_target(struct sna_composite_op *op,
 		return FALSE;
 
 	op->dst.bo = priv->gpu_bo;
-	if (!sna_damage_is_all(&priv->gpu_damage,
-			       op->dst.width, op->dst.height))
-		op->damage = &priv->gpu_damage;
+	op->damage = &priv->gpu_damage;
+	if (sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height))
+		op->damage = NULL;
 
 	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
 			    &op->dst.x, &op->dst.y);
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 682fdd7..d23f422 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -2187,9 +2187,9 @@ gen3_composite_set_target(struct sna_composite_op *op, PicturePtr dst)
 		return FALSE;
 
 	op->dst.bo = priv->gpu_bo;
-	if (!sna_damage_is_all(&priv->gpu_damage,
-			       op->dst.width, op->dst.height))
-		op->damage = &priv->gpu_damage;
+	op->damage = &priv->gpu_damage;
+	if (sna_damage_is_all(op->damage, op->dst.width, op->dst.height))
+		op->damage = NULL;
 
 	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
 			    &op->dst.x, &op->dst.y);
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 7224e83..c0a32a4 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1826,9 +1826,9 @@ gen4_composite_set_target(PicturePtr dst, struct sna_composite_op *op)
 		return FALSE;
 
 	op->dst.bo = priv->gpu_bo;
-	if (!sna_damage_is_all(&priv->gpu_damage,
-			       op->dst.width, op->dst.height))
-		op->damage = &priv->gpu_damage;
+	op->damage = &priv->gpu_damage;
+	if (sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height))
+		op->damage = NULL;
 	DBG(("%s: gpu_only=%d, all-damaged=%d, damage=%p\n",
 	     __FUNCTION__, priv->gpu_only,
 	     sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height),
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index de1f976..e9a61f0 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1877,9 +1877,9 @@ gen5_composite_set_target(PicturePtr dst, struct sna_composite_op *op)
 
 
 	op->dst.bo = priv->gpu_bo;
-	if (!sna_damage_is_all(&priv->gpu_damage,
-			       op->dst.width, op->dst.height))
-		op->damage = &priv->gpu_damage;
+	op->damage = &priv->gpu_damage;
+	if (sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height))
+		op->damage = NULL;
 
 	DBG(("%s: bo=%p, damage=%p\n", __FUNCTION__, op->dst.bo, op->damage));
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 66bbb9e..164f69d 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2046,9 +2046,10 @@ gen6_composite_set_target(struct sna_composite_op *op, PicturePtr dst)
 			return FALSE;
 
 		op->dst.bo = priv->gpu_bo;
-		if (!sna_damage_is_all(&priv->gpu_damage,
-				       op->dst.width, op->dst.height))
-			op->damage = &priv->gpu_damage;
+		op->damage = &priv->gpu_damage;
+		if (sna_damage_is_all(&priv->gpu_damage,
+				      op->dst.width, op->dst.height))
+			op->damage = NULL;
 	}
 
 	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index ca32cc3..0296841 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2177,9 +2177,10 @@ gen7_composite_set_target(struct sna_composite_op *op, PicturePtr dst)
 			return FALSE;
 
 		op->dst.bo = priv->gpu_bo;
-		if (!sna_damage_is_all(&priv->gpu_damage,
-				       op->dst.width, op->dst.height))
-			op->damage = &priv->gpu_damage;
+		op->damage = &priv->gpu_damage;
+		if (sna_damage_is_all(&priv->gpu_damage,
+				      op->dst.width, op->dst.height))
+			op->damage = NULL;
 	}
 
 	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,


More information about the xorg-commit mailing list