From 5b6575bdded4b24ec1c9515203f44798225c10b6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 10 Oct 2011 16:39:02 +0100 Subject: sna: Support a fast composite hook for solitary boxes Signed-off-by: Chris Wilson --- 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 | 26 ++++++++++++ src/sna/gen7_render.c | 26 ++++++++++++ src/sna/sna_blt.c | 102 +++++++++++++++++++++++++++++++++++++++++++++-- src/sna/sna_render.h | 3 ++ src/sna/sna_trapezoids.c | 8 ++-- 9 files changed, 280 insertions(+), 8 deletions(-) diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index 935dffe8..c0d357d9 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 57c57b96..dcaf0ff7 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 3c133be2..95d9a9da 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 ad27d908..ab30c9c8 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 044704d3..90f4036f 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 8c216938..ec5a0163 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 d82f8451..a8d39bdc 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 e46f027a..2cc39f0e 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 d1602e02..86593a9b 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); } } -- cgit v1.2.3