diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-14 13:12:46 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-14 15:04:56 +0000 |
commit | e4ad4477815abe31b1a2323673da86a6def2f246 (patch) | |
tree | 5f13962c207c68a422b0711af297c2f278088971 | |
parent | 3cc04a8e24f02248b6382c9bc354ea15c42b17b6 (diff) |
sna: Use userptr to accelerate GetImage
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 8f12708b..636411b6 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -63,6 +63,7 @@ #define USE_ZERO_SPANS 1 /* -1 force CPU, 1 force GPU */ #define USE_CPU_BO 1 #define USE_USERPTR_UPLOADS 1 +#define USE_USERPTR_DOWNLOADS 1 #define MIGRATE_ALL 0 #define DBG_NO_CPU_UPLOAD 0 @@ -13701,6 +13702,62 @@ static int sna_create_gc(GCPtr gc) return true; } +static bool +sna_get_image_blt(DrawablePtr drawable, + RegionPtr region, + char *dst) +{ + PixmapPtr pixmap = get_drawable_pixmap(drawable); + struct sna_pixmap *priv = sna_pixmap(pixmap); + struct sna *sna = to_sna_from_pixmap(pixmap); + struct kgem_bo *dst_bo; + bool ok = false; + int pitch; + + if (!USE_USERPTR_DOWNLOADS) + return false; + + if (priv == NULL) + return false; + + if (!sna->kgem.has_userptr) + return false; + + if (!DAMAGE_IS_ALL(priv->gpu_damage) || + !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) + return false; + + DBG(("%s: download through a temporary map\n", __FUNCTION__)); + + pitch = PixmapBytePad(region->extents.x2 - region->extents.x1, + drawable->depth); + dst_bo = kgem_create_map(&sna->kgem, dst, + pitch * (region->extents.y2 - region->extents.y1), + false); + if (dst_bo) { + int16_t dx, dy; + + dst_bo->flush = true; + dst_bo->pitch = pitch; + dst_bo->reusable = false; + + get_drawable_deltas(drawable, pixmap, &dx, &dy); + + ok = sna->render.copy_boxes(sna, GXcopy, + pixmap, priv->gpu_bo, dx, dy, + pixmap, dst_bo, + -region->extents.x1, + -region->extents.y1, + ®ion->extents, 1, + COPY_LAST); + + kgem_bo_sync__cpu(&sna->kgem, dst_bo); + kgem_bo_destroy(&sna->kgem, dst_bo); + } + + return ok; +} + static void sna_get_image(DrawablePtr drawable, int x, int y, int w, int h, @@ -13709,6 +13766,7 @@ sna_get_image(DrawablePtr drawable, { RegionRec region; unsigned int flags; + bool can_blt; if (!fbDrawableEnabled(drawable)) return; @@ -13721,6 +13779,13 @@ sna_get_image(DrawablePtr drawable, region.extents.y2 = region.extents.y1 + h; region.data = NULL; + can_blt = format == ZPixmap && + drawable->bitsPerPixel >= 8 && + PM_IS_SOLID(drawable, mask); + + if (can_blt && sna_get_image_blt(drawable, ®ion, dst)) + return; + flags = MOVE_READ; if ((w | h) == 1) flags |= MOVE_INPLACE_HINT; @@ -13729,9 +13794,7 @@ sna_get_image(DrawablePtr drawable, if (!sna_drawable_move_region_to_cpu(drawable, ®ion, flags)) return; - if (format == ZPixmap && - drawable->bitsPerPixel >= 8 && - PM_IS_SOLID(drawable, mask)) { + if (can_blt) { PixmapPtr pixmap = get_drawable_pixmap(drawable); int16_t dx, dy; |