diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-13 10:26:44 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-13 17:43:13 +0100 |
commit | 0190964906ad878d469d6021c10cde4e7f5799c3 (patch) | |
tree | 38202743689b62f9bbe9dc79d5546e9b6d654920 /src | |
parent | b929717c89352d4b47dc2b9ce58e26fbbf327201 (diff) |
sna/damage: Avoid testing against a completey damaged region
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/gen3_render.c | 20 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 3 | ||||
-rw-r--r-- | src/sna/sna_damage.c | 23 | ||||
-rw-r--r-- | src/sna/sna_damage.h | 17 |
6 files changed, 52 insertions, 17 deletions
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index e9e1cefc..fa72b91a 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -2060,20 +2060,14 @@ gen3_composite_set_target(struct sna *sna, op->dst.height = op->dst.pixmap->drawable.height; priv = sna_pixmap(op->dst.pixmap); - op->dst.bo = NULL; - if (priv && priv->gpu_bo == NULL) { - op->dst.bo = priv->cpu_bo; - op->damage = &priv->cpu_damage; - } - if (op->dst.bo == NULL) { - priv = sna_pixmap_force_to_gpu(op->dst.pixmap); - if (priv == NULL) - return FALSE; + priv = sna_pixmap_force_to_gpu(op->dst.pixmap); + if (priv == NULL) + return FALSE; - op->dst.bo = priv->gpu_bo; - if (!priv->gpu_only) - op->damage = &priv->gpu_damage; - } + op->dst.bo = priv->gpu_bo; + if (!priv->gpu_only && + !sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height)) + op->damage = &priv->gpu_damage; get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 15343ee8..75555332 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1839,7 +1839,8 @@ gen4_composite_set_target(struct sna *sna, return FALSE; op->dst.bo = priv->gpu_bo; - if (!priv->gpu_only) + if (!priv->gpu_only && + !sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height)) op->damage = &priv->gpu_damage; get_drawable_deltas(dst->pDrawable, op->dst.pixmap, diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index de0d67a0..b282666b 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -1855,7 +1855,8 @@ gen5_composite_set_target(struct sna *sna, op->dst.bo = priv->gpu_bo; - if (!priv->gpu_only) + if (!priv->gpu_only && + !sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height)) op->damage = &priv->gpu_damage; DBG(("%s: bo=%p, damage=%p\n", __FUNCTION__, op->dst.bo, op->damage)); diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 0b6f9954..7b22ea20 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2049,7 +2049,8 @@ gen6_composite_set_target(struct sna *sna, return FALSE; op->dst.bo = priv->gpu_bo; - if (!priv->gpu_only) + if (!priv->gpu_only && + !sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height)) op->damage = &priv->gpu_damage; } diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c index 63e83417..64b0c9e5 100644 --- a/src/sna/sna_damage.c +++ b/src/sna/sna_damage.c @@ -134,6 +134,7 @@ static struct sna_damage *_sna_damage_create(void) struct sna_damage *damage; damage = malloc(sizeof(*damage)); + damage->all = 0; damage->n = 0; damage->size = 16; damage->elts = malloc(sizeof(*damage->elts) * damage->size); @@ -454,16 +455,37 @@ struct sna_damage *_sna_damage_all(struct sna_damage *damage, pixman_region_fini(&damage->region); damage->n = 0; damage->last_box = NULL; + damage->all = 1; } else damage = _sna_damage_create(); pixman_region_init_rect(&damage->region, 0, 0, width, height); damage->extents = damage->region.extents; damage->mode = ADD; + damage->all = 1; return damage; } +struct sna_damage *_sna_damage_is_all(struct sna_damage *damage, + int width, int height) +{ + BoxRec box; + + if (damage->mode == SUBTRACT) + __sna_damage_reduce(damage); + + box.x1 = box.y1 = 0; + box.x2 = width; + box.y2 = height; + + if (pixman_region_contains_rectangle(&damage->region, + &box) != PIXMAN_REGION_IN) + return damage; + + return _sna_damage_all(damage, width, height); +} + static inline Bool sna_damage_maybe_contains_box(struct sna_damage *damage, const BoxRec *box) { @@ -516,6 +538,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage, } } + damage->all = 0; damage->mode = SUBTRACT; _sna_damage_create_elt(damage, SUBTRACT, REGION_RECTS(region), diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h index c5dfa7f3..5fb9aef0 100644 --- a/src/sna/sna_damage.h +++ b/src/sna/sna_damage.h @@ -11,7 +11,7 @@ struct sna_damage_box; struct sna_damage { BoxRec extents; - int n, size, mode; + int n, size, mode, all; pixman_region16_t region; struct sna_damage_elt *elts; struct sna_damage_box *last_box; @@ -34,6 +34,21 @@ static inline void sna_damage_add_box(struct sna_damage **damage, *damage = _sna_damage_add_box(*damage, box); } +struct sna_damage *_sna_damage_is_all(struct sna_damage *damage, + int width, int height); +static inline bool sna_damage_is_all(struct sna_damage **damage, + int width, int height) +{ + if (*damage == NULL) + return false; + + if ((*damage)->all) + return true; + + *damage = _sna_damage_is_all(*damage, width, height); + return (*damage)->all; +} + struct sna_damage *_sna_damage_all(struct sna_damage *damage, int width, int height); static inline void sna_damage_all(struct sna_damage **damage, |