diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-24 08:58:51 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-24 10:55:02 +0100 |
commit | 1d74b2e07d125ad95b9db6c9c032e90faf2bfa60 (patch) | |
tree | 77d9bdd0aa0f8d8dd98fbb9a6c29d7b8b4410d87 /src/sna/gen8_render.c | |
parent | 6e2cee27c379278b0321fd1db34ed80c439115a7 (diff) |
sna: Decompose self-copy into overlapping/non-overlapping regions
We only need to stage the copy for the overlapping portion of the
self-copy, for the rest we can do in a single pass.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen8_render.c')
-rw-r--r-- | src/sna/gen8_render.c | 48 |
1 files changed, 10 insertions, 38 deletions
diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c index 53bac819..365e8f6e 100644 --- a/src/sna/gen8_render.c +++ b/src/sna/gen8_render.c @@ -2713,40 +2713,6 @@ prefer_blt_copy(struct sna *sna, return prefer_blt_bo(sna, src_bo) || prefer_blt_bo(sna, dst_bo); } -inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents) -{ - *extents = box[0]; - while (--n) { - box++; - - if (box->x1 < extents->x1) - extents->x1 = box->x1; - if (box->x2 > extents->x2) - extents->x2 = box->x2; - - if (box->y1 < extents->y1) - extents->y1 = box->y1; - if (box->y2 > extents->y2) - extents->y2 = box->y2; - } -} - -static inline bool -overlaps(struct sna *sna, - struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, - struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, - const BoxRec *box, int n, BoxRec *extents) -{ - if (src_bo != dst_bo) - return false; - - boxes_extents(box, n, extents); - return (extents->x2 + src_dx > extents->x1 + dst_dx && - extents->x1 + src_dx < extents->x2 + dst_dx && - extents->y2 + src_dy > extents->y1 + dst_dy && - extents->y1 + src_dy < extents->y2 + dst_dy); -} - static bool gen8_render_copy_boxes(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, @@ -2762,7 +2728,7 @@ gen8_render_copy_boxes(struct sna *sna, uint8_t alu, overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, - box, n, &extents))); + box, n, flags, &extents))); if (prefer_blt_copy(sna, src_bo, dst_bo, flags) && sna_blt_compare_depth(&src->drawable, &dst->drawable) && @@ -2790,7 +2756,8 @@ fallback_blt: if (overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, - box, n, &extents)) { + box, n, flags, + &extents)) { bool big = too_large(extents.x2-extents.x1, extents.y2-extents.y1); if ((big || can_switch_to_blt(sna, dst_bo, flags)) && @@ -2804,9 +2771,14 @@ fallback_blt: if (big) goto fallback_blt; + assert(src_bo == dst_bo); + assert(src->drawable.depth == dst->drawable.depth); + assert(src->drawable.width == dst->drawable.width); + assert(src->drawable.height == dst->drawable.height); return sna_render_copy_boxes__overlap(sna, alu, - src, src_bo, src_dx, src_dy, - dst, dst_bo, dst_dx, dst_dy, + src, src_bo, + src_dx, src_dy, + dst_dx, dst_dy, box, n, &extents); } |