summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-01-17 13:44:12 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-01-17 18:23:43 +0000
commite4efde920bcab980451e79df7d645d1814e5f78d (patch)
tree4fccb95199d616804921a36102f2b478abada8b1
parenta9b705f9a7bbd37a0543ce5fbd4c60c912d1017d (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.h1
-rw-r--r--src/sna/sna_accel.c60
-rw-r--r--src/sna/sna_composite.c5
-rw-r--r--src/sna/sna_dri.c2
-rw-r--r--src/sna/sna_trapezoids.c1
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(&region, 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(&region, 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, &region);
}
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);