summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-10-10 16:39:02 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-11 08:48:54 +0100
commit5b6575bdded4b24ec1c9515203f44798225c10b6 (patch)
tree445945fac2bc9878b32335b688c8827ddadc85bf
parentc5414ec992d935e10156a2b513d5ec2dded2f689 (diff)
sna: Support a fast composite hook for solitary boxes
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen2_render.c26
-rw-r--r--src/sna/gen3_render.c54
-rw-r--r--src/sna/gen4_render.c17
-rw-r--r--src/sna/gen5_render.c26
-rw-r--r--src/sna/gen6_render.c26
-rw-r--r--src/sna/gen7_render.c26
-rw-r--r--src/sna/sna_blt.c102
-rw-r--r--src/sna/sna_render.h3
-rw-r--r--src/sna/sna_trapezoids.c8
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(&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);
}
}