xf86-video-intel: src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jul 18 03:00:41 PDT 2012


 src/sna/sna_trapezoids.c |  158 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 109 insertions(+), 49 deletions(-)

New commits:
commit bb0303677c38076db14dfbceec3636197a971e8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 18 10:40:50 2012 +0100

    sna/trapezoids: Use pixman from within the spans to reduce two-pass operations
    
    Reduce the two pass CompositeTrapezoids if we can perform the operation
    inplace by calling pixman_image_composite from the span. This step
    enables this for xrgb32.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 634423e..7124baf 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -4824,10 +4824,50 @@ unbounded_pass:
 	return true;
 }
 
+static void
+pixmask_span(struct sna *sna,
+	     struct sna_composite_spans_op *op,
+	     pixman_region16_t *clip,
+	     const BoxRec *box,
+	     int coverage)
+{
+	struct pixman_inplace *pi = (struct pixman_inplace *)op;
+	pixman_image_t *mask = NULL;
+	if (coverage != FAST_SAMPLES_XY) {
+		coverage = coverage * 256 / FAST_SAMPLES_XY;
+		coverage -= coverage >> 8;
+		*pi->bits = coverage;
+		mask = pi->mask;
+	}
+	pixman_image_composite(pi->op, pi->source, mask, pi->image,
+			       pi->sx + box->x1, pi->sy + box->y1,
+			       0, 0,
+			       pi->dx + box->x1, pi->dy + box->y1,
+			       box->x2 - box->x1, box->y2 - box->y1);
+}
+static void
+pixmask_span__clipped(struct sna *sna,
+		      struct sna_composite_spans_op *op,
+		      pixman_region16_t *clip,
+		      const BoxRec *box,
+		      int coverage)
+{
+	pixman_region16_t region;
+	int n;
+
+	pixman_region_init_rects(&region, box, 1);
+	RegionIntersect(&region, &region, clip);
+	n = REGION_NUM_RECTS(&region);
+	box = REGION_RECTS(&region);
+	while (n--)
+		pixmask_span(sna, op, NULL, box++, coverage);
+	pixman_region_fini(&region);
+}
+
 static bool
 trapezoid_span_inplace__x8r8g8b8(CARD8 op,
-				 uint32_t color,
 				 PicturePtr dst,
+				 PicturePtr src, int16_t src_x, int16_t src_y,
 				 PictFormatPtr maskFormat,
 				 int ntrap, xTrapezoid *traps)
 {
@@ -4838,34 +4878,14 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
 	int dx, dy;
 	int n;
 
-	if (op == PictOpOver && (color >> 24) == 0xff)
-		op = PictOpSrc;
-	if (op == PictOpOver) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
-		if (priv && priv->clear && priv->clear_color == 0)
-			op = PictOpSrc;
-	}
-
-	switch (op) {
-	case PictOpSrc:
-		break;
-	default:
-		DBG(("%s: fallback -- can not perform op [%d] in place\n",
-		     __FUNCTION__, op));
-		return false;
-	}
-
-	DBG(("%s: format=%x, op=%d, color=%x\n",
-	     __FUNCTION__, dst->format, op, color));
-
 	if (maskFormat == NULL && ntrap > 1) {
 		DBG(("%s: individual rasterisation requested\n",
 		     __FUNCTION__));
 		do {
 			/* XXX unwind errors? */
-			if (!trapezoid_span_inplace__x8r8g8b8(op, color,
-							      dst, NULL,
-							      1, traps++))
+			if (!trapezoid_span_inplace__x8r8g8b8(op, dst,
+							      src, src_x, src_y,
+							      NULL, 1, traps++))
 				return false;
 		} while (--ntrap);
 		return true;
@@ -4915,37 +4935,76 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
 		tor_add_edge(&tor, &t, &t.right, -1);
 	}
 
-	switch (op) {
-	case PictOpSrc:
-		if (dst->pCompositeClip->data)
-			span = tor_blt_lerp32_clipped;
-		else
-			span = tor_blt_lerp32;
-		break;
-	}
-
 	DBG(("%s: move-to-cpu\n", __FUNCTION__));
 	region.data = NULL;
 	if (sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
 					    MOVE_WRITE | MOVE_READ)) {
 		PixmapPtr pixmap;
-		struct inplace inplace;
+		uint32_t color;
 
 		pixmap = get_drawable_pixmap(dst->pDrawable);
-
 		get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
 
-		inplace.ptr = pixmap->devPrivate.ptr;
-		inplace.ptr += dst_y * pixmap->devKind + dst_x;
-		inplace.stride = pixmap->devKind;
-		inplace.color = color;
+		if (!sna_picture_is_solid(src, &color))
+			goto pixman;
+
+		if (op == PictOpOver && (color >> 24) == 0xff)
+			op = PictOpSrc;
+		if (op == PictOpOver) {
+			struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable);
+			if (priv && priv->clear && priv->clear_color == 0)
+				op = PictOpSrc;
+		}
+
+		DBG(("%s: format=%x, op=%d, color=%x\n",
+		     __FUNCTION__, dst->format, op, color));
+
+		if (op == PictOpSrc) {
+			struct inplace inplace;
+
+			inplace.ptr = pixmap->devPrivate.ptr;
+			inplace.ptr += dst_y * pixmap->devKind + dst_x;
+			inplace.stride = pixmap->devKind;
+			inplace.color = color;
+
+			if (dst->pCompositeClip->data)
+				span = tor_blt_lerp32_clipped;
+			else
+				span = tor_blt_lerp32;
+
+			DBG(("%s: render inplace op=%d, color=%08x\n",
+			     __FUNCTION__, op, color));
+
+			tor_render(NULL, &tor, (void*)&inplace,
+				   dst->pCompositeClip, span, false);
+			tor_fini(&tor);
+		} else {
+			struct pixman_inplace pi;
+
+pixman:
+			pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy);
+			pi.source = image_from_pict(src, false, &pi.sx, &pi.sy);
+			pi.sx += src_x;
+			pi.sy += src_y;
+			pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0);
+			pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL);
+			pi.bits = pixman_image_get_data(pi.mask);
+			pi.op = op;
+
+			if (dst->pCompositeClip->data)
+				span = pixmask_span__clipped;
+			else
+				span = pixmask_span;
 
-		DBG(("%s: render inplace op=%d, color=%08x\n",
-		     __FUNCTION__, op, color));
-		tor_render(NULL, &tor, (void*)&inplace,
-			   dst->pCompositeClip, span, false);
+			tor_render(NULL, &tor, (void*)&pi,
+				   dst->pCompositeClip, span,
+				   operator_is_bounded(op));
+			tor_fini(&tor);
 
-		tor_fini(&tor);
+			pixman_image_unref(pi.mask);
+			pixman_image_unref(pi.source);
+			pixman_image_unref(pi.image);
+		}
 	}
 
 	return true;
@@ -4994,17 +5053,18 @@ trapezoid_span_inplace(CARD8 op, PicturePtr src, PicturePtr dst,
 		return trapezoid_span_mono_inplace(op, src, dst,
 						   src_x, src_y, ntrap, traps);
 
+	if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8)
+		return trapezoid_span_inplace__x8r8g8b8(op, dst,
+							src, src_x, src_y,
+							maskFormat,
+							ntrap, traps);
+
 	if (!sna_picture_is_solid(src, &color)) {
 		DBG(("%s: fallback -- can not perform operation in place, requires solid source\n",
 		     __FUNCTION__));
 		return false;
 	}
 
-	if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8)
-		return trapezoid_span_inplace__x8r8g8b8(op, color,
-							dst, maskFormat,
-							ntrap, traps);
-
 	if (dst->format != PICT_a8) {
 		DBG(("%s: fallback -- can not perform operation in place, format=%x\n",
 		     __FUNCTION__, dst->format));


More information about the xorg-commit mailing list