summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-03-09 12:19:33 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-03-09 12:19:33 +0000
commit494edfaaacaae13adfa5e727c66a83cb2294d330 (patch)
tree785ef2f46e1337cfd6eeb2d0bd4496ec11ab3450
parentbd62dc73dcdbab34aa5c83382e46c7315d554a1a (diff)
sna: Handle partial reads with a pending clear
Skip the filling of the whole pixmap if we have a small read and we know the GPU bo is clear. Also choose to operate inplace on the GPU bo if we meet the usual criteria. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_accel.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 5aad88b7..3429438d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1257,13 +1257,6 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
return _sna_pixmap_move_to_cpu(pixmap, flags);
}
- if (priv->clear) {
- DBG(("%s: pending clear, moving whole pixmap\n", __FUNCTION__));
- if (dx | dy)
- RegionTranslate(region, -dx, -dy);
- return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
- }
-
if ((flags & MOVE_READ) == 0) {
DBG(("%s: no read, checking to see if we can stream the write into the GPU bo\n",
__FUNCTION__));
@@ -1295,6 +1288,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
sna_damage_add(&priv->gpu_damage,
region);
+ priv->clear = false;
return true;
}
}
@@ -1333,6 +1327,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
} else
sna_damage_add(&priv->gpu_damage, region);
+ priv->clear = false;
return true;
}
}
@@ -1354,12 +1349,20 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
pixmap->devKind = priv->gpu_bo->pitch;
if (!DAMAGE_IS_ALL(priv->gpu_damage))
sna_damage_add(&priv->gpu_damage, region);
+ priv->clear = false;
return true;
}
priv->mapped = false;
}
+ if (priv->clear && flags & MOVE_WRITE) {
+ DBG(("%s: pending clear, moving whole pixmap for partial write\n", __FUNCTION__));
+ if (dx | dy)
+ RegionTranslate(region, -dx, -dy);
+ return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
+ }
+
if (priv->mapped) {
pixmap->devPrivate.ptr = NULL;
priv->mapped = false;
@@ -1372,6 +1375,35 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
if (priv->gpu_bo == NULL)
goto done;
+ if (priv->clear) {
+ int n = REGION_NUM_RECTS(region);
+ BoxPtr box = REGION_RECTS(region);
+
+ DBG(("%s: pending clear, doing partial fill\n", __FUNCTION__));
+ if (priv->cpu_bo) {
+ DBG(("%s: syncing CPU bo\n", __FUNCTION__));
+ kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
+ }
+
+ do {
+ pixman_fill(pixmap->devPrivate.ptr,
+ pixmap->devKind/sizeof(uint32_t),
+ pixmap->drawable.bitsPerPixel,
+ box->x1, box->y1,
+ box->x2 - box->x1,
+ box->y2 - box->y1,
+ priv->clear_color);
+ box++;
+ } while (--n);
+
+ if (region->extents.x2 - region->extents.x1 > 1 ||
+ region->extents.y2 - region->extents.y1 > 1) {
+ sna_damage_subtract(&priv->gpu_damage, region);
+ priv->clear = false;
+ }
+ goto done;
+ }
+
if ((flags & MOVE_READ) == 0) {
assert(flags & MOVE_WRITE);
sna_damage_subtract(&priv->gpu_damage, region);