diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-05-17 12:11:34 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-05-17 12:12:07 +0100 |
commit | d6c30d1d4df6bcdfa075bd29da7c8aabee20774c (patch) | |
tree | 0402e282f1f87d2c58afea203131f4f387f0b579 | |
parent | 21f17455650d52848467290f609c678e85b8ceab (diff) |
sna: Clear the cow_list when discarding the clone upon pixmap destroy
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index a50f4d47..2c785704 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -1366,6 +1366,10 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap) if (priv->cow) { struct sna_cow *cow = COW(priv->cow); + DBG(("%s: pixmap=%ld discarding cow, refcnt=%d\n", + __FUNCTION__, pixmap->drawable.serialNumber, cow->refcnt)); + assert(cow->refcnt); + list_del(&priv->cow_list); if (!--cow->refcnt) free(cow); priv->cow = NULL; @@ -1556,8 +1560,9 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) list_del(&priv->cow_list); if (!--cow->refcnt) { + assert(list_is_empty(&cow->list)); free(cow); - } else if (IS_COW_OWNER(priv->cow)) { + } else if (IS_COW_OWNER(priv->cow) && priv->pinned) { PixmapPtr pixmap = priv->pixmap; struct kgem_bo *bo; BoxRec box; @@ -1589,7 +1594,6 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) return false; } - cow->bo = bo; assert(!list_is_empty(&cow->list)); while (!list_is_empty(&cow->list)) { struct sna_pixmap *clone; @@ -1598,9 +1602,11 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) struct sna_pixmap, cow_list); list_del(&clone->cow_list); + assert(clone->gpu_bo == cow->bo); kgem_bo_destroy(&sna->kgem, clone->gpu_bo); clone->gpu_bo = kgem_bo_reference(bo); } + cow->bo = bo; kgem_bo_destroy(&sna->kgem, bo); } else { struct kgem_bo *bo = NULL; @@ -1681,6 +1687,9 @@ sna_pixmap_make_cow(struct sna *sna, cow->bo = src_priv->gpu_bo; cow->refcnt = 1; + DBG(("%s: attaching source cow to pixmap=%ld\n", + __FUNCTION__, src_priv->pixmap->drawable.serialNumber)); + src_priv->cow = MAKE_COW_OWNER(cow); list_init(&src_priv->cow_list); @@ -1691,8 +1700,10 @@ sna_pixmap_make_cow(struct sna *sna, } assert(!src_priv->mapped); - if (cow == COW(dst_priv->cow)) + if (cow == COW(dst_priv->cow)) { + assert(dst_priv->gpu_bo == cow->bo); return true; + } if (dst_priv->cow) sna_pixmap_undo_cow(sna, dst_priv, 0); @@ -1704,6 +1715,9 @@ sna_pixmap_make_cow(struct sna *sna, list_add(&dst_priv->cow_list, &cow->list); cow->refcnt++; + DBG(("%s: attaching clone to pixmap=%ld\n", + __FUNCTION__, dst_priv->pixmap->drawable.serialNumber)); + if (dst_priv->mapped) { dst_priv->pixmap->devPrivate.ptr = NULL; dst_priv->mapped = false; |