summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-04-03 16:27:47 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-04-03 16:49:27 +0100
commitf0565852b668832d4988e875bc12e23abb6e1829 (patch)
tree860b84aaf993b1371117c555930d8aef234dd171 /src
parentbaef2201f752da5d0c6322547d925fcbd86c6de4 (diff)
sna: Short-circuit repeated clearing to the same color
Spotted in amongst a KDE debug log was a series of clear; copy; repeat using Composite(). Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna_blt.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 284f77e2..c6219776 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1113,11 +1113,28 @@ inline static void _sna_blt_fill_boxes(struct sna *sna,
} while (1);
}
+static inline void _sna_blt_maybe_clear(const struct sna_composite_op *op, const BoxRec *box)
+{
+ if (box->x2 - box->x1 >= op->dst.width &&
+ box->y2 - box->y1 >= op->dst.height) {
+ struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap);
+ if (op->dst.bo == priv->gpu_bo) {
+ priv->clear = true;
+ priv->clear_color = op->u.blt.pixel;
+ DBG(("%s: pixmap=%ld marking clear [%08x]\n",
+ __FUNCTION__,
+ op->dst.pixmap->drawable.serialNumber,
+ op->u.blt.pixel));
+ }
+ }
+}
+
fastcall static void blt_composite_fill_box_no_offset(struct sna *sna,
const struct sna_composite_op *op,
const BoxRec *box)
{
_sna_blt_fill_box(sna, &op->u.blt, box);
+ _sna_blt_maybe_clear(op, box);
}
static void blt_composite_fill_boxes_no_offset(struct sna *sna,
@@ -1208,6 +1225,7 @@ fastcall static void blt_composite_fill_box(struct sna *sna,
box->y1 + op->dst.y,
box->x2 - box->x1,
box->y2 - box->y1);
+ _sna_blt_maybe_clear(op, box);
}
static void blt_composite_fill_boxes(struct sna *sna,
@@ -2381,8 +2399,8 @@ sna_blt_composite(struct sna *sna,
return false;
}
- was_clear = sna_drawable_is_clear(dst->pDrawable);
tmp->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
+ was_clear = is_clear(tmp->dst.pixmap);
if (width | height) {
dst_box.x1 = dst_x;
@@ -2400,8 +2418,10 @@ sna_blt_composite(struct sna *sna,
if (op == PictOpClear) {
clear:
- if (was_clear)
+ if (was_clear && sna_pixmap(tmp->dst.pixmap)->clear_color == 0) {
+ sna_pixmap(tmp->dst.pixmap)->clear = true;
return prepare_blt_nop(sna, tmp);
+ }
hint = 0;
if (can_render(sna)) {
@@ -2459,6 +2479,11 @@ fill:
if (color == 0)
goto clear;
+ if (was_clear && sna_pixmap(tmp->dst.pixmap)->clear_color == color) {
+ sna_pixmap(tmp->dst.pixmap)->clear = true;
+ return prepare_blt_nop(sna, tmp);
+ }
+
hint = 0;
if (can_render(sna)) {
hint |= PREFER_GPU;