diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-09 12:19:33 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-09 12:19:33 +0000 |
commit | 494edfaaacaae13adfa5e727c66a83cb2294d330 (patch) | |
tree | 785ef2f46e1337cfd6eeb2d0bd4496ec11ab3450 | |
parent | bd62dc73dcdbab34aa5c83382e46c7315d554a1a (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.c | 46 |
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); |