sna/damage: Clear damage->all when subtracting

I missed clearing the all-damaged flag on the subtract fast paths,
causing us to disregard further GPU damage and losing track of render
coherency.

Reported-by: Roman Jarosz <kedgedev@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41769
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-10-17 14:22:58 +01:00
parent 46f97127c2
commit f1bb4ebfd8
3 changed files with 21 additions and 6 deletions

View File

@ -1855,6 +1855,10 @@ gen4_composite_set_target(PicturePtr dst, struct sna_composite_op *op)
if (!priv->gpu_only &&
!sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height))
op->damage = &priv->gpu_damage;
DBG(("%s: gpu_only=%d, all-damaged=%d, damage=%p\n",
__FUNCTION__, priv->gpu_only,
sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height),
op->damage));
get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
&op->dst.x, &op->dst.y);

View File

@ -388,13 +388,17 @@ static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char
static void apply_damage(struct sna_composite_op *op, RegionPtr region)
{
DBG(("%s: damage=%p, region=%d\n",
__FUNCTION__, op->damage, REGION_NUM_RECTS(region)));
DBG(("%s: damage=%p, region=%d [(%d, %d), (%d, %d) + (%d, %d)]\n",
__FUNCTION__, op->damage, REGION_NUM_RECTS(region),
region->extents.x1, region->extents.y1,
region->extents.x2, region->extents.y2,
op->dst.x, op->dst.y));
if (op->damage == NULL)
return;
RegionTranslate(region, op->dst.x, op->dst.y);
if (op->dst.x | op->dst.y)
RegionTranslate(region, op->dst.x, op->dst.y);
assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region));
sna_damage_add(op->damage, region);

View File

@ -247,6 +247,8 @@ static void __sna_damage_reduce(struct sna_damage *damage)
BoxPtr boxes;
pixman_region16_t tmp, *region = &damage->region;
assert(!damage->all);
DBG((" reduce: before damage.n=%d region.n=%d\n",
damage->n, REGION_NUM_RECTS(region)));
@ -461,7 +463,6 @@ 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();
@ -484,7 +485,7 @@ struct sna_damage *_sna_damage_is_all(struct sna_damage *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;
@ -540,6 +541,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
&damage->region,
region);
damage->extents = damage->region.extents;
damage->all = 0;
return damage;
}
}
@ -607,10 +609,12 @@ inline static struct sna_damage *__sna_damage_subtract_box(struct sna_damage *da
&damage->region,
&region);
damage->extents = damage->region.extents;
damage->all = 0;
return damage;
}
}
damage->all = 0;
damage->mode = SUBTRACT;
_sna_damage_create_elt(damage, SUBTRACT, box, 1);
@ -646,7 +650,10 @@ static int _sna_damage_contains_box(struct sna_damage *damage,
const BoxRec *box)
{
if (!damage)
return PIXMAN_REGION_OUT;;
return PIXMAN_REGION_OUT;
if (damage->all)
return PIXMAN_REGION_IN;
if (!sna_damage_maybe_contains_box(damage, box))
return PIXMAN_REGION_OUT;