summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-13 10:26:44 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-13 17:43:13 +0100
commit0190964906ad878d469d6021c10cde4e7f5799c3 (patch)
tree38202743689b62f9bbe9dc79d5546e9b6d654920
parentb929717c89352d4b47dc2b9ce58e26fbbf327201 (diff)
sna/damage: Avoid testing against a completey damaged region
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen3_render.c20
-rw-r--r--src/sna/gen4_render.c3
-rw-r--r--src/sna/gen5_render.c3
-rw-r--r--src/sna/gen6_render.c3
-rw-r--r--src/sna/sna_damage.c23
-rw-r--r--src/sna/sna_damage.h17
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,