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(®ion);
} 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