diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-17 13:44:12 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-17 18:23:43 +0000 |
commit | e4efde920bcab980451e79df7d645d1814e5f78d (patch) | |
tree | 4fccb95199d616804921a36102f2b478abada8b1 | |
parent | a9b705f9a7bbd37a0543ce5fbd4c60c912d1017d (diff) |
sna: Track whether damage is a complete representation of the dirt
The previous commit undoes a premature optimisation that assumed that
the current damage captured all pixels written. However, it happens to
be a useful optimisation along that path (tracking upload of partial
images), so add the necessary booking that watches for when the union
of cpu and gpu damage is no longer the complete set of all pixels
written, that is if we either migrate from one pixmap to the other, the
undamaged region goes untracked. We also take advantage of whenever we
damage the whole pixel to restore knowledge that our tracking of all
pixels written is complete.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 60 | ||||
-rw-r--r-- | src/sna/sna_composite.c | 5 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 2 | ||||
-rw-r--r-- | src/sna/sna_trapezoids.c | 1 |
5 files changed, 54 insertions, 15 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index e9c85b7a..2f79ac63 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -144,6 +144,7 @@ struct sna_pixmap { uint8_t pinned :1; uint8_t mapped :1; uint8_t flush :1; + uint8_t undamaged :1; uint8_t gpu :1; uint8_t header :1; }; diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 7aa5578b..4a52983a 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -315,6 +315,7 @@ static inline uint32_t default_tiling(PixmapPtr pixmap) pixmap->drawable.width, pixmap->drawable.height)) { sna_damage_destroy(&priv->gpu_damage); + priv->undamaged = false; return I915_TILING_Y; } @@ -786,6 +787,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags) pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); + priv->undamaged = false; list_del(&priv->list); if (priv->cpu_bo) sna_pixmap_free_cpu(sna, priv); @@ -849,6 +851,7 @@ skip_inplace_map: __sna_damage_destroy(DAMAGE_PTR(priv->gpu_damage)); priv->gpu_damage = NULL; + priv->undamaged = true; } if (flags & MOVE_WRITE) { @@ -857,6 +860,7 @@ skip_inplace_map: pixmap->drawable.width, pixmap->drawable.height); sna_pixmap_free_gpu(sna, priv); + priv->undamaged = false; if (priv->flush) list_move(&priv->list, &sna->dirty_pixmaps); @@ -1059,11 +1063,12 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, pixmap->devKind = priv->gpu_bo->pitch; sna_damage_subtract(&priv->cpu_damage, region); - if (priv->cpu_damage == NULL) + if (priv->cpu_damage == NULL) { sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - else + priv->undamaged = false; + } else sna_damage_add(&priv->gpu_damage, region); @@ -1096,11 +1101,12 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, pixmap->devKind = priv->gpu_bo->pitch; sna_damage_subtract(&priv->cpu_damage, region); - if (priv->cpu_damage == NULL) + if (priv->cpu_damage == NULL) { sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - else + priv->undamaged = false; + } else sna_damage_add(&priv->gpu_damage, region); return true; @@ -1170,6 +1176,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, box, n); } sna_damage_destroy(&priv->gpu_damage); + priv->undamaged = true; } if (sna_damage_contains_box(priv->gpu_damage, @@ -1243,6 +1250,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, box, n); sna_damage_destroy(&priv->gpu_damage); + priv->undamaged = true; } else if (DAMAGE_IS_ALL(priv->gpu_damage) || sna_damage_contains_box__no_reduce(priv->gpu_damage, &r->extents)) { @@ -1263,6 +1271,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, box, n); sna_damage_subtract(&priv->gpu_damage, r); + priv->undamaged = true; } else { RegionRec need; @@ -1285,6 +1294,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable, box, n); sna_damage_subtract(&priv->gpu_damage, r); + priv->undamaged = true; RegionUninit(&need); } } @@ -1304,6 +1314,7 @@ done: pixmap->drawable.height)) { DBG(("%s: replaced entire pixmap\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); + priv->undamaged = false; } if (priv->flush) list_move(&priv->list, &sna->dirty_pixmaps); @@ -1434,6 +1445,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box) sna_damage_destroy(&priv->cpu_damage); list_del(&priv->list); + priv->undamaged = true; } else if (DAMAGE_IS_ALL(priv->cpu_damage) || sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) { Bool ok = FALSE; @@ -1453,6 +1465,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box) sna_damage_subtract(&priv->cpu_damage, &r); if (priv->cpu_damage == NULL) list_del(&priv->list); + priv->undamaged = true; } else if (sna_damage_intersect(priv->cpu_damage, &r, &i)) { int n = REGION_NUM_RECTS(&i); Bool ok; @@ -1473,6 +1486,7 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box) box, n); sna_damage_subtract(&priv->cpu_damage, &r); + priv->undamaged = true; RegionUninit(&i); if (priv->cpu_damage == NULL) @@ -1786,6 +1800,7 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags) sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); + priv->undamaged = false; DBG(("%s: marking as all-damaged for GPU\n", __FUNCTION__)); } @@ -1848,8 +1863,10 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); + priv->undamaged = false; DBG(("%s: marking as all-damaged for GPU\n", __FUNCTION__)); + goto active; } } @@ -1892,12 +1909,15 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) __sna_damage_destroy(DAMAGE_PTR(priv->cpu_damage)); priv->cpu_damage = NULL; + priv->undamaged = true; done: list_del(&priv->list); sna_damage_reduce_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); + if (DAMAGE_IS_ALL(priv->gpu_damage)) + priv->undamaged = false; active: if (!priv->pinned) list_move(&priv->inactive, &sna->active_pixmaps); @@ -2214,11 +2234,12 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, list_del(&priv->list); } else sna_damage_subtract(&priv->cpu_damage, region); - if (priv->cpu_damage == NULL) + if (priv->cpu_damage == NULL) { sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - else + priv->undamaged = false; + } else sna_damage_add(&priv->gpu_damage, region); } @@ -2256,11 +2277,12 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, list_del(&priv->list); } else sna_damage_subtract(&priv->cpu_damage, region); - if (priv->cpu_damage == NULL) + if (priv->cpu_damage == NULL) { sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - else + priv->undamaged = false; + } else sna_damage_add(&priv->gpu_damage, region); } @@ -2277,12 +2299,16 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, return false; } else { sna_damage_destroy(&priv->cpu_damage); + priv->undamaged = false; list_del(&priv->list); } } - sna_damage_all(&priv->gpu_damage, - pixmap->drawable.width, - pixmap->drawable.height); + if (priv->undamaged) { + sna_damage_all(&priv->gpu_damage, + pixmap->drawable.width, + pixmap->drawable.height); + priv->undamaged = false; + } sna_pixmap_free_cpu(sna, priv); } } @@ -2308,6 +2334,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, pixmap->drawable.width, pixmap->drawable.height); sna_pixmap_free_gpu(sna, priv); + priv->undamaged = false; } else { sna_damage_subtract(&priv->gpu_damage, region); sna_damage_add(&priv->cpu_damage, region); @@ -2317,6 +2344,7 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, pixmap->drawable.height)) { DBG(("%s: replaced entire pixmap\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); + priv->undamaged = false; } } if (priv->flush) @@ -3000,6 +3028,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, sna_damage_all(&dst_priv->gpu_damage, dst_pixmap->drawable.width, dst_pixmap->drawable.height); + dst_priv->undamaged = false; } else { RegionTranslate(®ion, dst_dx, dst_dy); assert_pixmap_contains_box(dst_pixmap, @@ -3029,6 +3058,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, sna_damage_all(&dst_priv->gpu_damage, dst_pixmap->drawable.width, dst_pixmap->drawable.height); + dst_priv->undamaged = false; } else { RegionTranslate(®ion, dst_dx, dst_dy); assert_pixmap_contains_box(dst_pixmap, @@ -3125,6 +3155,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, sna_damage_all(&dst_priv->gpu_damage, dst_pixmap->drawable.width, dst_pixmap->drawable.height); + dst_priv->undamaged = false; } } else { DBG(("%s: dst is on the GPU, src is on the CPU, uploading into dst\n", @@ -6909,11 +6940,12 @@ sna_poly_fill_rect_blt(DrawablePtr drawable, if (damage) { assert_pixmap_contains_box(pixmap, &r); if (r.x2 - r.x1 == pixmap->drawable.width && - r.y2 - r.y1 == pixmap->drawable.height) + r.y2 - r.y1 == pixmap->drawable.height) { sna_damage_all(damage, pixmap->drawable.width, pixmap->drawable.height); - else + sna_pixmap(pixmap)->undamaged = false; + } else sna_damage_add_box(damage, &r); } } else @@ -10010,6 +10042,8 @@ static void sna_accel_inactive(struct sna *sna) list_del(&priv->list); sna_pixmap_free_cpu(sna, priv); + priv->undamaged = false; + list_add(&priv->inactive, &preserve); } else { DBG(("%s: discarding inactive GPU bo handle=%d\n", diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c index 15876f52..47eac636 100644 --- a/src/sna/sna_composite.c +++ b/src/sna/sna_composite.c @@ -774,10 +774,11 @@ sna_composite_rectangles(CARD8 op, if (region.data == NULL && region.extents.x2 - region.extents.x1 == pixmap->drawable.width && - region.extents.y2 - region.extents.y1 == pixmap->drawable.height) + region.extents.y2 - region.extents.y1 == pixmap->drawable.height) { sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); - else + priv->undamaged = false; + } else sna_damage_add(&priv->gpu_damage, ®ion); } diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 9de7faae..2245c037 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -342,6 +342,7 @@ damage_all: pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); + priv->undamaged = false; } else { BoxPtr box = RegionExtents(region); if (region->data == NULL && @@ -364,6 +365,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); + priv->undamaged = false; kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = ref(bo); diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c index 4f918421..d0385393 100644 --- a/src/sna/sna_trapezoids.c +++ b/src/sna/sna_trapezoids.c @@ -3947,6 +3947,7 @@ static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv, sna_damage_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); + priv->undamaged = false; } else { sna_damage_add_box(&priv->gpu_damage, box); sna_damage_subtract_box(&priv->cpu_damage, box); |