diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-04-03 16:27:47 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-04-03 16:49:27 +0100 |
commit | f0565852b668832d4988e875bc12e23abb6e1829 (patch) | |
tree | 860b84aaf993b1371117c555930d8aef234dd171 /src | |
parent | baef2201f752da5d0c6322547d925fcbd86c6de4 (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.c | 29 |
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; |