summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-08-27 11:42:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-08-27 11:44:13 +0100
commitac1b83240e5d4dc5d5bacad3ed49446143cc5589 (patch)
tree2ce54bbd6d9acda5433f995818e253ec2bb8667a
parent786a770f528a0daee2971494352672cb89f48384 (diff)
sna/accel: Simplify single pixel read-back
The single pixel case is usually assocated with synchronisation of perf clients and so we do not want to incur extra complication along that path. Also the cost of tracking a single pixel of non-damage outweighs its benefit. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c126
1 files changed, 69 insertions, 57 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 79717115..8a7cec2a 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -464,67 +464,79 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (sna_damage_contains_box(priv->gpu_damage,
REGION_EXTENTS(NULL, region))) {
- RegionRec want, need, *r;
-
- DBG(("%s: region intersects gpu damage\n", __FUNCTION__));
-
- r = region;
- /* expand the region to move 32x32 pixel blocks at a time */
- if (priv->cpu_damage == NULL) {
- int n = REGION_NUM_RECTS(region), i;
- BoxPtr boxes = REGION_RECTS(region);
- BoxPtr blocks = malloc(sizeof(BoxRec) * REGION_NUM_RECTS(region));
- if (blocks) {
- for (i = 0; i < n; i++) {
- blocks[i].x1 = boxes[i].x1 & ~31;
- if (blocks[i].x1 < 0)
- blocks[i].x1 = 0;
-
- blocks[i].x2 = (boxes[i].x2 + 31) & ~31;
- if (blocks[i].x2 > pixmap->drawable.width)
- blocks[i].x2 = pixmap->drawable.width;
-
- blocks[i].y1 = boxes[i].y1 & ~31;
- if (blocks[i].y1 < 0)
- blocks[i].y1 = 0;
-
- blocks[i].y2 = (boxes[i].y2 + 31) & ~31;
- if (blocks[i].y2 > pixmap->drawable.height)
- blocks[i].y2 = pixmap->drawable.height;
+ DBG(("%s: region (%dx%d) intersects gpu damage\n",
+ __FUNCTION__,
+ region->extents.x2 - region->extents.x1,
+ region->extents.y2 - region->extents.y1));
+
+ if (region->extents.x2 - region->extents.x1 == 1 &&
+ region->extents.y2 - region->extents.y1 == 1) {
+ /* Oftenassociated with synchonrisation, KISS */
+ sna_read_boxes(sna,
+ priv->gpu_bo, 0, 0,
+ pixmap, 0, 0,
+ &region->extents, 1);
+ } else {
+ RegionRec want, need, *r;
+
+ r = region;
+ /* expand the region to move 32x32 pixel blocks at a time */
+ if (priv->cpu_damage == NULL) {
+ int n = REGION_NUM_RECTS(region), i;
+ BoxPtr boxes = REGION_RECTS(region);
+ BoxPtr blocks = malloc(sizeof(BoxRec) * REGION_NUM_RECTS(region));
+ if (blocks) {
+ for (i = 0; i < n; i++) {
+ blocks[i].x1 = boxes[i].x1 & ~31;
+ if (blocks[i].x1 < 0)
+ blocks[i].x1 = 0;
+
+ blocks[i].x2 = (boxes[i].x2 + 31) & ~31;
+ if (blocks[i].x2 > pixmap->drawable.width)
+ blocks[i].x2 = pixmap->drawable.width;
+
+ blocks[i].y1 = boxes[i].y1 & ~31;
+ if (blocks[i].y1 < 0)
+ blocks[i].y1 = 0;
+
+ blocks[i].y2 = (boxes[i].y2 + 31) & ~31;
+ if (blocks[i].y2 > pixmap->drawable.height)
+ blocks[i].y2 = pixmap->drawable.height;
+ }
+ if (pixman_region_init_rects(&want, blocks, i))
+ r = &want;
+ free(blocks);
}
- if (pixman_region_init_rects(&want, blocks, i))
- r = &want;
- free(blocks);
}
- }
-
- pixman_region_init(&need);
- if (sna_damage_intersect(priv->gpu_damage, r, &need)) {
- BoxPtr box = REGION_RECTS(&need);
- int n = REGION_NUM_RECTS(&need);
- struct kgem_bo *dst_bo;
- Bool ok = FALSE;
-
- dst_bo = NULL;
- if (sna->kgem.gen >= 30)
- dst_bo = pixmap_vmap(&sna->kgem, pixmap);
- if (dst_bo)
- ok = sna->render.copy_boxes(sna, GXcopy,
- pixmap, priv->gpu_bo, 0, 0,
- pixmap, dst_bo, 0, 0,
- box, n);
- if (!ok)
- sna_read_boxes(sna,
- priv->gpu_bo, 0, 0,
- pixmap, 0, 0,
- box, n);
- sna_damage_subtract(&priv->gpu_damage,
- n <= REGION_NUM_RECTS(r) ? &need : r);
- RegionUninit(&need);
+ pixman_region_init(&need);
+ if (sna_damage_intersect(priv->gpu_damage, r, &need)) {
+ BoxPtr box = REGION_RECTS(&need);
+ int n = REGION_NUM_RECTS(&need);
+ struct kgem_bo *dst_bo;
+ Bool ok = FALSE;
+
+ dst_bo = NULL;
+ if (sna->kgem.gen >= 30)
+ dst_bo = pixmap_vmap(&sna->kgem, pixmap);
+ if (dst_bo)
+ ok = sna->render.copy_boxes(sna, GXcopy,
+ pixmap, priv->gpu_bo, 0, 0,
+ pixmap, dst_bo, 0, 0,
+ box, n);
+ if (!ok)
+ sna_read_boxes(sna,
+ priv->gpu_bo, 0, 0,
+ pixmap, 0, 0,
+ box, n);
+
+ sna_damage_subtract(&priv->gpu_damage,
+ n <= REGION_NUM_RECTS(r) ? &need : r);
+ RegionUninit(&need);
+ }
+ if (r == &want)
+ pixman_region_fini(&want);
}
- if (r == &want)
- pixman_region_fini(&want);
}
done: