xf86-video-intel: 3 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_blt.c src/sna/sna_render.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Oct 11 00:51:24 PDT 2011


 src/sna/gen2_render.c    |   26 +++++++++
 src/sna/gen3_render.c    |   54 ++++++++++++++++++
 src/sna/gen4_render.c    |   17 +++++
 src/sna/gen5_render.c    |   26 +++++++++
 src/sna/gen6_render.c    |  135 +++++++++++++++++++++++++++++++++++++++++++++++
 src/sna/gen7_render.c    |  135 +++++++++++++++++++++++++++++++++++++++++++++++
 src/sna/sna_blt.c        |  102 ++++++++++++++++++++++++++++++++++-
 src/sna/sna_render.h     |    3 +
 src/sna/sna_trapezoids.c |    8 +-
 9 files changed, 498 insertions(+), 8 deletions(-)

New commits:
commit 4a2e833ab17e4facf0f90166b82a5696a1deef91
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 11 08:45:47 2011 +0100

    sna/gen7: Add render support for fill one
    
    To prevent the RENDER to BLT transition and potential stall.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index ec5a016..30de36f 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -2942,6 +2942,114 @@ gen7_render_fill(struct sna *sna, uint8_t alu,
 	return TRUE;
 }
 
+static Bool
+gen7_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
+			     uint32_t color,
+			     int16_t x1, int16_t y1, int16_t x2, int16_t y2,
+			     uint8_t alu)
+{
+	BoxRec box;
+
+	box.x1 = x1;
+	box.y1 = y1;
+	box.x2 = x2;
+	box.y2 = y2;
+
+	return sna_blt_fill_boxes(sna, alu,
+				  bo, dst->drawable.bitsPerPixel,
+				  color, &box, 1);
+}
+
+static Bool
+gen7_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
+		     uint32_t color,
+		     int16_t x1, int16_t y1,
+		     int16_t x2, int16_t y2,
+		     uint8_t alu)
+{
+	struct sna_composite_op tmp;
+
+#if NO_FILL_BOXES
+	return gen7_render_fill_one_try_blt(sna, dst, bo, color,
+					    x1, y1, x2, y2, alu);
+#endif
+
+	/* Prefer to use the BLT if already engaged */
+	if (sna->kgem.mode != KGEM_RENDER &&
+	    gen7_render_fill_one_try_blt(sna, dst, bo, color,
+					 x1, y1, x2, y2, alu))
+		return TRUE;
+
+	/* Must use the BLT if we can't RENDER... */
+	if (!(alu == GXcopy || alu == GXclear) ||
+	    dst->drawable.width > 8192 || dst->drawable.height > 8192)
+		return gen7_render_fill_one_try_blt(sna, dst, bo, color,
+						    x1, y1, x2, y2, alu);
+
+	if (alu == GXclear)
+		color = 0;
+
+	tmp.op = color == 0 ? PictOpClear : PictOpSrc;
+
+	tmp.dst.pixmap = dst;
+	tmp.dst.width  = dst->drawable.width;
+	tmp.dst.height = dst->drawable.height;
+	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+	tmp.dst.bo = bo;
+	tmp.dst.x = tmp.dst.y = 0;
+
+	tmp.src.bo =
+		sna_render_get_solid(sna,
+				     sna_rgba_for_color(color,
+							dst->drawable.depth));
+	tmp.src.filter = SAMPLER_FILTER_NEAREST;
+	tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
+
+	tmp.mask.bo = NULL;
+	tmp.mask.filter = SAMPLER_FILTER_NEAREST;
+	tmp.mask.repeat = SAMPLER_EXTEND_NONE;
+
+	tmp.is_affine = TRUE;
+	tmp.floats_per_vertex = 3;
+	tmp.has_component_alpha = 0;
+	tmp.need_magic_ca_pass = FALSE;
+
+	tmp.u.gen7.wm_kernel = GEN6_WM_KERNEL_NOMASK;
+	tmp.u.gen7.nr_surfaces = 2;
+	tmp.u.gen7.nr_inputs = 1;
+	tmp.u.gen7.ve_id = 1;
+
+	if (!kgem_check_bo(&sna->kgem, bo, NULL))
+		_kgem_submit(&sna->kgem);
+
+	gen7_emit_fill_state(sna, &tmp);
+	gen7_align_vertex(sna, &tmp);
+
+	if (!gen7_get_rectangles(sna, &tmp, 1)) {
+		gen7_emit_fill_state(sna, &tmp);
+		gen7_get_rectangles(sna, &tmp, 1);
+	}
+
+	DBG(("	(%d, %d), (%d, %d)\n", x1, y1, x2, y2));
+	OUT_VERTEX(x2, y2);
+	OUT_VERTEX_F(1);
+	OUT_VERTEX_F(1);
+
+	OUT_VERTEX(x1, y2);
+	OUT_VERTEX_F(0);
+	OUT_VERTEX_F(1);
+
+	OUT_VERTEX(x1, y1);
+	OUT_VERTEX_F(0);
+	OUT_VERTEX_F(0);
+
+	gen7_vertex_flush(sna);
+	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+	_kgem_set_mode(&sna->kgem, KGEM_RENDER);
+
+	return TRUE;
+}
+
 static void gen7_render_flush(struct sna *sna)
 {
 	gen7_vertex_finish(sna, TRUE);
@@ -3041,6 +3149,7 @@ Bool gen7_render_init(struct sna *sna)
 
 	sna->render.fill_boxes = gen7_render_fill_boxes;
 	sna->render.fill = gen7_render_fill;
+	sna->render.fill_one = gen7_render_fill_one;
 
 	sna->render.flush = gen7_render_flush;
 	sna->render.reset = gen7_render_reset;
commit 41f525fab5a82c24adafc7e8c8409417d16a0e9a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 11 00:22:11 2011 +0100

    sna/gen6: Add render support for fill-one-box
    
    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 90f4036..2ba7c39 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2797,6 +2797,114 @@ gen6_render_fill(struct sna *sna, uint8_t alu,
 	return TRUE;
 }
 
+static Bool
+gen6_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
+			     uint32_t color,
+			     int16_t x1, int16_t y1, int16_t x2, int16_t y2,
+			     uint8_t alu)
+{
+	BoxRec box;
+
+	box.x1 = x1;
+	box.y1 = y1;
+	box.x2 = x2;
+	box.y2 = y2;
+
+	return sna_blt_fill_boxes(sna, alu,
+				  bo, dst->drawable.bitsPerPixel,
+				  color, &box, 1);
+}
+
+static Bool
+gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
+		     uint32_t color,
+		     int16_t x1, int16_t y1,
+		     int16_t x2, int16_t y2,
+		     uint8_t alu)
+{
+	struct sna_composite_op tmp;
+
+#if NO_FILL_BOXES
+	return gen6_render_fill_one_try_blt(sna, dst, bo, color,
+					    x1, y1, x2, y2, alu);
+#endif
+
+	/* Prefer to use the BLT if already engaged */
+	if (sna->kgem.mode != KGEM_RENDER &&
+	    gen6_render_fill_one_try_blt(sna, dst, bo, color,
+					 x1, y1, x2, y2, alu))
+		return TRUE;
+
+	/* Must use the BLT if we can't RENDER... */
+	if (!(alu == GXcopy || alu == GXclear) ||
+	    dst->drawable.width > 8192 || dst->drawable.height > 8192)
+		return gen6_render_fill_one_try_blt(sna, dst, bo, color,
+						    x1, y1, x2, y2, alu);
+
+	if (alu == GXclear)
+		color = 0;
+
+	tmp.op = color == 0 ? PictOpClear : PictOpSrc;
+
+	tmp.dst.pixmap = dst;
+	tmp.dst.width  = dst->drawable.width;
+	tmp.dst.height = dst->drawable.height;
+	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
+	tmp.dst.bo = bo;
+	tmp.dst.x = tmp.dst.y = 0;
+
+	tmp.src.bo =
+		sna_render_get_solid(sna,
+				     sna_rgba_for_color(color,
+							dst->drawable.depth));
+	tmp.src.filter = SAMPLER_FILTER_NEAREST;
+	tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
+
+	tmp.mask.bo = NULL;
+	tmp.mask.filter = SAMPLER_FILTER_NEAREST;
+	tmp.mask.repeat = SAMPLER_EXTEND_NONE;
+
+	tmp.is_affine = TRUE;
+	tmp.floats_per_vertex = 3;
+	tmp.has_component_alpha = 0;
+	tmp.need_magic_ca_pass = FALSE;
+
+	tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK;
+	tmp.u.gen6.nr_surfaces = 2;
+	tmp.u.gen6.nr_inputs = 1;
+	tmp.u.gen6.ve_id = 1;
+
+	if (!kgem_check_bo(&sna->kgem, bo, NULL))
+		_kgem_submit(&sna->kgem);
+
+	gen6_emit_fill_state(sna, &tmp);
+	gen6_align_vertex(sna, &tmp);
+
+	if (!gen6_get_rectangles(sna, &tmp, 1)) {
+		gen6_emit_fill_state(sna, &tmp);
+		gen6_get_rectangles(sna, &tmp, 1);
+	}
+
+	DBG(("	(%d, %d), (%d, %d)\n", x1, y1, x2, y2));
+	OUT_VERTEX(x2, y2);
+	OUT_VERTEX_F(1);
+	OUT_VERTEX_F(1);
+
+	OUT_VERTEX(x1, y2);
+	OUT_VERTEX_F(0);
+	OUT_VERTEX_F(1);
+
+	OUT_VERTEX(x1, y1);
+	OUT_VERTEX_F(0);
+	OUT_VERTEX_F(0);
+
+	gen6_vertex_flush(sna);
+	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
+	_kgem_set_mode(&sna->kgem, KGEM_RENDER);
+
+	return TRUE;
+}
+
 static void gen6_render_flush(struct sna *sna)
 {
 	gen6_vertex_finish(sna, TRUE);
@@ -2896,6 +3004,7 @@ Bool gen6_render_init(struct sna *sna)
 
 	sna->render.fill_boxes = gen6_render_fill_boxes;
 	sna->render.fill = gen6_render_fill;
+	sna->render.fill_one = gen6_render_fill_one;
 
 	sna->render.flush = gen6_render_flush;
 	sna->render.reset = gen6_render_reset;
commit 5b6575bdded4b24ec1c9515203f44798225c10b6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 10 16:39:02 2011 +0100

    sna: Support a fast composite hook for solitary boxes
    
    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 935dffe..c0d357d 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -950,6 +950,31 @@ gen2_render_composite_blt(struct sna *sna,
 	op->prim_emit(sna, op, r);
 }
 
+fastcall static void
+gen2_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	if (!gen2_get_rectangles(sna, op, 1)) {
+		gen2_emit_composite_state(sna, op);
+		gen2_get_rectangles(sna, op, 1);
+	}
+
+	DBG(("  %s: (%d, %d) x (%d, %d)\n", __FUNCTION__,
+	     box->x1, box->y1,
+	     box->x2 - box->x1,
+	     box->y2 - box->y1));
+
+	r.dst.x  = box->x1; r.dst.y  = box->y1;
+	r.width = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.src = r.mask = r.dst;
+
+	op->prim_emit(sna, op, &r);
+}
+
 static void
 gen2_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -1344,6 +1369,7 @@ gen2_render_composite(struct sna *sna,
 	}
 
 	tmp->blt   = gen2_render_composite_blt;
+	tmp->box   = gen2_render_composite_box;
 	tmp->boxes = gen2_render_composite_boxes;
 	tmp->done  = gen2_render_composite_done;
 
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 57c57b9..dcaf0ff 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -1568,6 +1568,33 @@ gen3_render_composite_blt(struct sna *sna,
 	op->prim_emit(sna, op, r);
 }
 
+fastcall static void
+gen3_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	DBG(("%s: src=+(%d, %d), mask=+(%d, %d), dst=+(%d, %d)\n",
+	     __FUNCTION__,
+	     op->src.offset[0], op->src.offset[1],
+	     op->mask.offset[0], op->mask.offset[1],
+	     op->dst.x, op->dst.y));
+
+	if (!gen3_get_rectangles(sna, op, 1)) {
+		gen3_emit_composite_state(sna, op);
+		gen3_get_rectangles(sna, op, 1);
+	}
+
+	r.dst.x  = box->x1;
+	r.dst.y  = box->y1;
+	r.width  = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.src = r.mask = r.dst;
+
+	op->prim_emit(sna, op, &r);
+}
+
 static void
 gen3_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -2060,6 +2087,26 @@ gen3_align_vertex(struct sna *sna,
 	}
 }
 
+static void
+reduce_damage(struct sna_composite_op *op,
+	      int dst_x, int dst_y,
+	      int width, int height)
+{
+	BoxRec r;
+
+	if (op->damage == NULL)
+		return;
+
+	r.x1 = dst_x + op->dst.x;
+	r.x2 = r.x1 + width;
+
+	r.y1 = dst_y + op->dst.y;
+	r.y2 = r.y1 + height;
+
+	if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+		op->damage = NULL;
+}
+
 static Bool
 gen3_composite_set_target(struct sna_composite_op *op, PicturePtr dst)
 {
@@ -2166,6 +2213,9 @@ gen3_render_composite(struct sna *sna,
 		return FALSE;
 	}
 
+	if (width && height)
+		reduce_damage(tmp, dst_x, dst_y, width, height);
+
 	tmp->op = op;
 	tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
 	if (tmp->dst.width > 2048 || tmp->dst.height > 2048 ||
@@ -2335,6 +2385,7 @@ gen3_render_composite(struct sna *sna,
 	     tmp->floats_per_vertex));
 
 	tmp->blt   = gen3_render_composite_blt;
+	tmp->box   = gen3_render_composite_box;
 	tmp->boxes = gen3_render_composite_boxes;
 	tmp->done  = gen3_render_composite_done;
 
@@ -2675,6 +2726,9 @@ gen3_render_composite_spans(struct sna *sna,
 		return FALSE;
 	}
 
+	if (width && height)
+		reduce_damage(&tmp->base, dst_x, dst_y, width, height);
+
 	tmp->base.op = op;
 	tmp->base.rb_reversed = gen3_dst_rb_reversed(tmp->base.dst.format);
 	if (tmp->base.dst.width > 2048 || tmp->base.dst.height > 2048 ||
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 3c133be..95d9a9d 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -1472,6 +1472,22 @@ gen4_render_composite_blt(struct sna *sna,
 	FLUSH();
 }
 
+fastcall static void
+gen4_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	r.dst.x = box->x1;
+	r.dst.y = box->y1;
+	r.width  = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.mask = r.src = r.dst;
+
+	gen4_render_composite_blt(sna, op, &r);
+}
+
 static void
 gen4_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -2029,6 +2045,7 @@ gen4_render_composite(struct sna *sna,
 	tmp->u.gen4.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
 
 	tmp->blt   = gen4_render_composite_blt;
+	tmp->box   = gen4_render_composite_box;
 	tmp->boxes = gen4_render_composite_boxes;
 	tmp->done  = gen4_render_composite_done;
 
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index ad27d90..ab30c9c 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -1486,6 +1486,31 @@ gen5_render_composite_blt(struct sna *sna,
 	op->prim_emit(sna, op, r);
 }
 
+fastcall static void
+gen5_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	DBG(("  %s: (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     box->x1, box->y1, box->x2, box->y2));
+
+	if (!gen5_get_rectangles(sna, op, 1)) {
+		gen5_bind_surfaces(sna, op);
+		gen5_get_rectangles(sna, op, 1);
+	}
+
+	r.dst.x = box->x1;
+	r.dst.y = box->y1;
+	r.width  = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.mask = r.src = r.dst;
+
+	op->prim_emit(sna, op, &r);
+}
+
 static void
 gen5_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -2040,6 +2065,7 @@ gen5_render_composite(struct sna *sna,
 	tmp->u.gen5.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
 
 	tmp->blt   = gen5_render_composite_blt;
+	tmp->box   = gen5_render_composite_box;
 	tmp->boxes = gen5_render_composite_boxes;
 	tmp->done  = gen5_render_composite_done;
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 044704d..90f4036 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -1620,6 +1620,31 @@ gen6_render_composite_blt(struct sna *sna,
 	op->prim_emit(sna, op, r);
 }
 
+fastcall static void
+gen6_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	if (!gen6_get_rectangles(sna, op, 1)) {
+		gen6_emit_composite_state(sna, op);
+		gen6_get_rectangles(sna, op, 1);
+	}
+
+	DBG(("  %s: (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     box->x1, box->y1, box->x2, box->y2));
+
+	r.dst.x = box->x1;
+	r.dst.y = box->y1;
+	r.width  = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.src = r.mask = r.dst;
+
+	op->prim_emit(sna, op, &r);
+}
+
 static void
 gen6_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -2217,6 +2242,7 @@ gen6_render_composite(struct sna *sna,
 	tmp->u.gen6.ve_id = gen6_choose_composite_vertex_buffer(tmp);
 
 	tmp->blt   = gen6_render_composite_blt;
+	tmp->box   = gen6_render_composite_box;
 	tmp->boxes = gen6_render_composite_boxes;
 	tmp->done  = gen6_render_composite_done;
 
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 8c21693..ec5a016 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1754,6 +1754,31 @@ gen7_render_composite_blt(struct sna *sna,
 	op->prim_emit(sna, op, r);
 }
 
+fastcall static void
+gen7_render_composite_box(struct sna *sna,
+			  const struct sna_composite_op *op,
+			  const BoxRec *box)
+{
+	struct sna_composite_rectangles r;
+
+	if (!gen7_get_rectangles(sna, op, 1)) {
+		gen7_emit_composite_state(sna, op);
+		gen7_get_rectangles(sna, op, 1);
+	}
+
+	DBG(("  %s: (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     box->x1, box->y1, box->x2, box->y2));
+
+	r.dst.x = box->x1;
+	r.dst.y = box->y1;
+	r.width  = box->x2 - box->x1;
+	r.height = box->y2 - box->y1;
+	r.src = r.mask = r.dst;
+
+	op->prim_emit(sna, op, &r);
+}
+
 static void
 gen7_render_composite_boxes(struct sna *sna,
 			    const struct sna_composite_op *op,
@@ -2351,6 +2376,7 @@ gen7_render_composite(struct sna *sna,
 	tmp->u.gen7.ve_id = gen7_choose_composite_vertex_buffer(tmp);
 
 	tmp->blt   = gen7_render_composite_blt;
+	tmp->box   = gen7_render_composite_box;
 	tmp->boxes = gen7_render_composite_boxes;
 	tmp->done  = gen7_render_composite_done;
 
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index d82f845..a8d39bd 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -610,6 +610,17 @@ static void blt_fill_composite(struct sna *sna,
 	sna_blt_fill_one(sna, &op->u.blt, x1, y1, x2-x1, y2-y1);
 }
 
+fastcall static void blt_fill_composite_box(struct sna *sna,
+					    const struct sna_composite_op *op,
+					    const BoxRec *box)
+{
+	sna_blt_fill_one(sna, &op->u.blt,
+			 box->x1 + op->dst.x,
+			 box->y1 + op->dst.y,
+			 box->x2 - box->x1,
+			 box->y2 - box->y1);
+}
+
 static void blt_fill_composite_boxes(struct sna *sna,
 				     const struct sna_composite_op *op,
 				     const BoxRec *box, int n)
@@ -629,6 +640,7 @@ prepare_blt_clear(struct sna *sna,
 	DBG(("%s\n", __FUNCTION__));
 
 	op->blt   = blt_fill_composite;
+	op->box   = blt_fill_composite_box;
 	op->boxes = blt_fill_composite_boxes;
 	op->done  = blt_done;
 
@@ -645,9 +657,10 @@ prepare_blt_fill(struct sna *sna,
 {
 	DBG(("%s\n", __FUNCTION__));
 
-	op->blt = blt_fill_composite;
+	op->blt   = blt_fill_composite;
+	op->box   = blt_fill_composite_box;
 	op->boxes = blt_fill_composite_boxes;
-	op->done = blt_done;
+	op->done  = blt_done;
 
 	return sna_blt_fill_init(sna, &op->u.blt, op->dst.bo,
 				 op->dst.pixmap->drawable.bitsPerPixel,
@@ -702,6 +715,21 @@ blt_copy_composite(struct sna *sna,
 			 x1, y1);
 }
 
+fastcall static void blt_copy_composite_box(struct sna *sna,
+					    const struct sna_composite_op *op,
+					    const BoxRec *box)
+{
+	DBG(("%s: box (%d, %d), (%d, %d)\n",
+	     __FUNCTION__, box->x1, box->y1, box->x2, box->y2));
+	sna_blt_copy_one(sna, &op->u.blt,
+			 box->x1 + op->u.blt.sx,
+			 box->y1 + op->u.blt.sy,
+			 box->x2 - box->x1,
+			 box->y2 - box->y1,
+			 box->x1 + op->dst.x,
+			 box->y1 + op->dst.y);
+}
+
 static void blt_copy_composite_boxes(struct sna *sna,
 				     const struct sna_composite_op *op,
 				     const BoxRec *box, int nbox)
@@ -734,6 +762,7 @@ prepare_blt_copy(struct sna *sna,
 	DBG(("%s\n", __FUNCTION__));
 
 	op->blt   = blt_copy_composite;
+	op->box   = blt_copy_composite_box;
 	op->boxes = blt_copy_composite_boxes;
 	op->done  = blt_done;
 
@@ -799,6 +828,45 @@ blt_put_composite(struct sna *sna,
 	}
 }
 
+fastcall static void blt_put_composite_box(struct sna *sna,
+					   const struct sna_composite_op *op,
+					   const BoxRec *box)
+{
+	PixmapPtr src = op->u.blt.src_pixmap;
+	struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap);
+
+	DBG(("%s: src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__,
+	     op->u.blt.sx, op->u.blt.sy,
+	     op->dst.x, op->dst.y));
+
+	if (!dst_priv->pinned &&
+	    box->x2 - box->x1 == op->dst.width &&
+	    box->y2 - box->y1 == op->dst.height) {
+		int pitch = src->devKind;
+		int bpp = src->drawable.bitsPerPixel / 8;
+		char *data = src->devPrivate.ptr;
+
+		data += (box->y1 + op->u.blt.sy) * pitch;
+		data += (box->x1 + op->u.blt.sx) * bpp;
+
+		dst_priv->gpu_bo =
+			sna_replace(sna,
+				    op->dst.bo,
+				    op->dst.width,
+				    op->dst.height,
+				    src->drawable.bitsPerPixel,
+				    data, pitch);
+	} else {
+		sna_write_boxes(sna,
+				op->dst.bo, op->dst.x, op->dst.y,
+				src->devPrivate.ptr,
+				src->devKind,
+				src->drawable.bitsPerPixel,
+				op->u.blt.sx, op->u.blt.sy,
+				box, 1);
+	}
+}
+
 static void blt_put_composite_boxes(struct sna *sna,
 				    const struct sna_composite_op *op,
 				    const BoxRec *box, int n)
@@ -868,7 +936,8 @@ prepare_blt_put(struct sna *sna,
 		free_bo = src_bo;
 	}
 	if (src_bo) {
-		op->blt = blt_copy_composite;
+		op->blt   = blt_copy_composite;
+		op->box   = blt_copy_composite_box;
 		op->boxes = blt_copy_composite_boxes;
 
 		op->u.blt.src_pixmap = (void *)free_bo;
@@ -882,6 +951,7 @@ prepare_blt_put(struct sna *sna,
 			return FALSE;
 	} else {
 		op->blt   = blt_put_composite;
+		op->box   = blt_put_composite_box;
 		op->boxes = blt_put_composite_boxes;
 		op->done  = nop_done;
 	}
@@ -935,6 +1005,26 @@ has_cpu_area(PixmapPtr pixmap, int x, int y, int w, int h)
 				       &area) == PIXMAN_REGION_OUT;
 }
 
+static void
+reduce_damage(struct sna_composite_op *op,
+	      int dst_x, int dst_y,
+	      int width, int height)
+{
+	BoxRec r;
+
+	if (op->damage == NULL)
+		return;
+
+	r.x1 = dst_x + op->dst.x;
+	r.x2 = r.x1 + width;
+
+	r.y1 = dst_y + op->dst.y;
+	r.y2 = r.y1 + height;
+
+	if (sna_damage_contains_box(*op->damage, &r) == PIXMAN_REGION_IN)
+		op->damage = NULL;
+}
+
 Bool
 sna_blt_composite(struct sna *sna,
 		  uint32_t op,
@@ -983,8 +1073,12 @@ sna_blt_composite(struct sna *sna,
 	get_drawable_deltas(dst->pDrawable, tmp->dst.pixmap,
 			    &tmp->dst.x, &tmp->dst.y);
 	tmp->dst.bo = priv->gpu_bo;
-	if (!priv->gpu_only)
+	if (!priv->gpu_only &&
+	    !sna_damage_is_all(&priv->gpu_damage,
+			       tmp->dst.width, tmp->dst.height))
 		tmp->damage = &priv->gpu_damage;
+	if (width && height)
+		reduce_damage(tmp, dst_x, dst_y, width, height);
 
 	if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL))
 		_kgem_submit(&sna->kgem);
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index e46f027..2cc39f0 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -20,6 +20,9 @@ struct sna_composite_rectangles {
 struct sna_composite_op {
 	fastcall void (*blt)(struct sna *sna, const struct sna_composite_op *op,
 			     const struct sna_composite_rectangles *r);
+	fastcall void (*box)(struct sna *sna,
+			     const struct sna_composite_op *op,
+			     const BoxRec *box);
 	void (*boxes)(struct sna *sna, const struct sna_composite_op *op,
 		      const BoxRec *box, int nbox);
 	void (*done)(struct sna *sna, const struct sna_composite_op *op);
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index d1602e0..86593a9 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -1539,7 +1539,7 @@ mono_add_line(struct mono *mono,
 		e->dxdy = floored_muldivrem (dx, pixman_fixed_1, dy);
 		e->dy = dy;
 
-		e->x = floored_muldivrem (ytop * pixman_fixed_1 + pixman_fixed_1_minus_e/2 - (p1->y + dst_y*pixman_fixed_1),
+		e->x = floored_muldivrem ((ytop-dst_y) * pixman_fixed_1 + pixman_fixed_1_minus_e/2 - p1->y,
 					  dx, dy);
 		e->x.quo += p1->x;
 		e->x.rem -= dy;
@@ -1602,8 +1602,8 @@ start_with_b:
 
 static struct mono_edge *
 mono_sort_edges(struct mono_edge *list,
-	    unsigned int level,
-	    struct mono_edge **head_out)
+		unsigned int level,
+		struct mono_edge **head_out)
 {
 	struct mono_edge *head_other, *remaining;
 	unsigned int i;
@@ -1715,7 +1715,7 @@ mono_span(struct mono *c, int x1, int x2, BoxPtr box)
 		}
 		pixman_region_fini(&region);
 	} else {
-		c->op.boxes(c->sna, &c->op, box, 1);
+		c->op.box(c->sna, &c->op, box);
 		apply_damage_box(&c->op, box);
 	}
 }


More information about the xorg-commit mailing list