sna: Update damage pointer after the implicit reduction
sna_damage_contains_box() routine implicitly reduces the damage before performing its check. This may alter and even destroy the damage entry, so pass in the handle so that it can be updated correctly. References: https://bugs.freedesktop.org/show_bug.cgi?id=77436 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
c9003c6d96
commit
a90160dcec
|
|
@ -2720,8 +2720,8 @@ move_to_cpu:
|
|||
|
||||
DBG(("%s: try to operate inplace (CPU), read? %d, write? %d\n",
|
||||
__FUNCTION__, !!(flags & MOVE_READ), !!(flags & MOVE_WRITE)));
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
|
||||
ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
|
||||
if (ptr != NULL) {
|
||||
|
|
@ -2854,8 +2854,8 @@ move_to_cpu:
|
|||
} else {
|
||||
if (sna_damage_contains_box__no_reduce(priv->cpu_damage,
|
||||
®ion->extents)) {
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
|
||||
DBG(("%s: region already in CPU damage\n",
|
||||
__FUNCTION__));
|
||||
|
|
@ -2863,7 +2863,7 @@ move_to_cpu:
|
|||
}
|
||||
}
|
||||
|
||||
if (sna_damage_contains_box(priv->gpu_damage,
|
||||
if (sna_damage_contains_box(&priv->gpu_damage,
|
||||
®ion->extents) != PIXMAN_REGION_OUT) {
|
||||
RegionRec want, *r = region;
|
||||
|
||||
|
|
@ -2936,8 +2936,8 @@ move_to_cpu:
|
|||
DBG(("%s: region wholly inside damage\n",
|
||||
__FUNCTION__));
|
||||
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, &r->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, &r->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, &r->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, &r->extents) == PIXMAN_REGION_OUT);
|
||||
|
||||
download_boxes(sna, priv,
|
||||
region_num_rects(r),
|
||||
|
|
@ -3322,8 +3322,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
|
|||
sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) {
|
||||
bool ok = false;
|
||||
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, box) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, box) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, box) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, box) == PIXMAN_REGION_IN);
|
||||
|
||||
if (use_cpu_bo_for_upload(sna, priv, 0)) {
|
||||
DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
|
||||
|
|
@ -3619,8 +3619,8 @@ create_gpu_bo:
|
|||
®ion.extents)) {
|
||||
DBG(("%s: region wholly contained within GPU damage\n",
|
||||
__FUNCTION__));
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_OUT);
|
||||
goto use_gpu_bo;
|
||||
} else {
|
||||
DBG(("%s: partial GPU damage with no CPU damage, continuing to use GPU\n",
|
||||
|
|
@ -3629,7 +3629,7 @@ create_gpu_bo:
|
|||
}
|
||||
}
|
||||
|
||||
ret = sna_damage_contains_box(priv->gpu_damage, ®ion.extents);
|
||||
ret = sna_damage_contains_box(&priv->gpu_damage, ®ion.extents);
|
||||
if (ret == PIXMAN_REGION_IN) {
|
||||
DBG(("%s: region wholly contained within GPU damage\n",
|
||||
__FUNCTION__));
|
||||
|
|
@ -3644,7 +3644,7 @@ create_gpu_bo:
|
|||
}
|
||||
|
||||
if ((flags & IGNORE_CPU) == 0 && priv->cpu_damage) {
|
||||
ret = sna_damage_contains_box(priv->cpu_damage, ®ion.extents);
|
||||
ret = sna_damage_contains_box(&priv->cpu_damage, ®ion.extents);
|
||||
if (ret == PIXMAN_REGION_IN) {
|
||||
DBG(("%s: region wholly contained within CPU damage\n",
|
||||
__FUNCTION__));
|
||||
|
|
@ -3824,8 +3824,8 @@ cpu_fail:
|
|||
if (priv->cpu_damage &&
|
||||
sna_damage_contains_box__no_reduce(priv->cpu_damage,
|
||||
®ion.extents)) {
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_IN);
|
||||
*damage = NULL;
|
||||
} else
|
||||
*damage = &priv->cpu_damage;
|
||||
|
|
@ -5448,6 +5448,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
|||
goto fallback;
|
||||
}
|
||||
|
||||
goto fallback;
|
||||
if (priv->gpu_damage || (priv->cpu_damage == NULL && priv->gpu_bo)) {
|
||||
assert(priv->gpu_bo);
|
||||
|
||||
|
|
@ -5709,8 +5710,8 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
|
|||
return false;
|
||||
}
|
||||
|
||||
assert(sna_damage_contains_box__offset(src_priv->gpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box__offset(src_priv->cpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box__offset(&src_priv->gpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box__offset(&src_priv->cpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_OUT);
|
||||
|
||||
ptr = kgem_bo_map__cpu(&sna->kgem, src_priv->gpu_bo);
|
||||
if (ptr == NULL) {
|
||||
|
|
@ -16195,8 +16196,8 @@ sna_get_image__inplace(PixmapPtr pixmap,
|
|||
if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ))
|
||||
return false;
|
||||
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
|
||||
src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
|
||||
if (src == NULL)
|
||||
|
|
@ -16286,8 +16287,8 @@ sna_get_image__blt(PixmapPtr pixmap,
|
|||
|
||||
DBG(("%s: download through a temporary map\n", __FUNCTION__));
|
||||
|
||||
assert(sna_damage_contains_box(priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN);
|
||||
assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT);
|
||||
|
||||
pitch = PixmapBytePad(region->extents.x2 - region->extents.x1,
|
||||
pixmap->drawable.depth);
|
||||
|
|
|
|||
|
|
@ -1342,15 +1342,13 @@ fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage
|
|||
}
|
||||
#endif
|
||||
|
||||
static int __sna_damage_contains_box(struct sna_damage *damage,
|
||||
static int __sna_damage_contains_box(struct sna_damage **_damage,
|
||||
const BoxRec *box)
|
||||
{
|
||||
struct sna_damage *damage = *_damage;
|
||||
const BoxRec *b;
|
||||
int n, count, ret;
|
||||
|
||||
if (!damage)
|
||||
return PIXMAN_REGION_OUT;
|
||||
|
||||
if (damage->mode == DAMAGE_ALL)
|
||||
return PIXMAN_REGION_IN;
|
||||
|
||||
|
|
@ -1390,18 +1388,24 @@ static int __sna_damage_contains_box(struct sna_damage *damage,
|
|||
}
|
||||
|
||||
__sna_damage_reduce(damage);
|
||||
if (!pixman_region_not_empty(&damage->region)) {
|
||||
__sna_damage_destroy(damage);
|
||||
*_damage = NULL;
|
||||
return PIXMAN_REGION_OUT;
|
||||
}
|
||||
|
||||
return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
|
||||
}
|
||||
|
||||
#if HAS_DEBUG_FULL
|
||||
int _sna_damage_contains_box(struct sna_damage *damage,
|
||||
int _sna_damage_contains_box(struct sna_damage **damage,
|
||||
const BoxRec *box)
|
||||
{
|
||||
char damage_buf[1000];
|
||||
int ret;
|
||||
|
||||
DBG(("%s(%s, [(%d, %d), (%d, %d)])\n", __FUNCTION__,
|
||||
_debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
|
||||
_debug_describe_damage(damage_buf, sizeof(damage_buf), *damage),
|
||||
box->x1, box->y1, box->x2, box->y2));
|
||||
|
||||
ret = __sna_damage_contains_box(damage, box);
|
||||
|
|
@ -1414,7 +1418,7 @@ int _sna_damage_contains_box(struct sna_damage *damage,
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
int _sna_damage_contains_box(struct sna_damage *damage,
|
||||
int _sna_damage_contains_box(struct sna_damage **damage,
|
||||
const BoxRec *box)
|
||||
{
|
||||
return __sna_damage_contains_box(damage, box);
|
||||
|
|
|
|||
|
|
@ -207,23 +207,27 @@ sna_damage_overlaps_box(const struct sna_damage *damage,
|
|||
return true;
|
||||
}
|
||||
|
||||
int _sna_damage_contains_box(struct sna_damage *damage,
|
||||
int _sna_damage_contains_box(struct sna_damage **damage,
|
||||
const BoxRec *box);
|
||||
static inline int sna_damage_contains_box(struct sna_damage *damage,
|
||||
static inline int sna_damage_contains_box(struct sna_damage **damage,
|
||||
const BoxRec *box)
|
||||
{
|
||||
if (DAMAGE_IS_ALL(damage))
|
||||
if (DAMAGE_IS_ALL(*damage))
|
||||
return PIXMAN_REGION_IN;
|
||||
if (*damage == NULL)
|
||||
return PIXMAN_REGION_OUT;
|
||||
|
||||
return _sna_damage_contains_box(damage, box);
|
||||
}
|
||||
static inline int sna_damage_contains_box__offset(struct sna_damage *damage,
|
||||
static inline int sna_damage_contains_box__offset(struct sna_damage **damage,
|
||||
const BoxRec *box, int dx, int dy)
|
||||
{
|
||||
BoxRec b;
|
||||
|
||||
if (DAMAGE_IS_ALL(damage))
|
||||
if (DAMAGE_IS_ALL(*damage))
|
||||
return PIXMAN_REGION_IN;
|
||||
if (*damage == NULL)
|
||||
return PIXMAN_REGION_OUT;
|
||||
|
||||
b = *box;
|
||||
b.x1 += dx; b.x2 += dx;
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
|
|||
}
|
||||
|
||||
if (priv->gpu_bo) {
|
||||
switch (sna_damage_contains_box(priv->cpu_damage, box)) {
|
||||
switch (sna_damage_contains_box(&priv->cpu_damage, box)) {
|
||||
case PIXMAN_REGION_OUT:
|
||||
DBG(("%s: has GPU bo and no damage to upload\n",
|
||||
__FUNCTION__));
|
||||
|
|
@ -362,7 +362,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
|
|||
__FUNCTION__));
|
||||
return NULL;
|
||||
}
|
||||
if (sna_damage_contains_box(priv->gpu_damage,
|
||||
if (sna_damage_contains_box(&priv->gpu_damage,
|
||||
box) != PIXMAN_REGION_OUT) {
|
||||
DBG(("%s: box is damaged on the GPU\n",
|
||||
__FUNCTION__));
|
||||
|
|
@ -440,7 +440,7 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box, bool blt)
|
|||
|
||||
if (priv->gpu_bo) {
|
||||
if (priv->cpu_damage &&
|
||||
sna_damage_contains_box(priv->cpu_damage,
|
||||
sna_damage_contains_box(&priv->cpu_damage,
|
||||
box) != PIXMAN_REGION_OUT)
|
||||
goto upload;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue