summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-12 11:28:03 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-12 11:28:03 +0100
commit9645e71cb2580adb78bea1cfa70dfc3f66630834 (patch)
tree64ab663cad76160ad7eedf101c0cc6c9cd4fba22
parente8dfc5b3f4ffeec93e52a5319b5a3118edf0e94e (diff)
downloadxorg-driver-xf86-video-intel-9645e71cb2580adb78bea1cfa70dfc3f66630834.tar.gz
sna: Reorder composite fallback migration to handle src==dst || mask==dst
Order is important when moving and marking damaged regions. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_composite.c143
1 files changed, 72 insertions, 71 deletions
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 000e27ef..79fee4f0 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -481,17 +481,6 @@ sna_composite_fb(CARD8 op,
region->extents.x1, region->extents.y1,
region->extents.x2, region->extents.y2));
- DBG(("%s: fallback -- move dst to cpu\n", __FUNCTION__));
- if (op <= PictOpSrc && !dst->alphaMap)
- flags = MOVE_WRITE | MOVE_INPLACE_HINT;
- else
- flags = MOVE_WRITE | MOVE_READ;
- if (!sna_drawable_move_region_to_cpu(dst->pDrawable, region, flags))
- return;
- if (dst->alphaMap &&
- !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, flags))
- return;
-
if (src->pDrawable) {
DBG(("%s: fallback -- move src to cpu\n", __FUNCTION__));
if (!sna_drawable_move_to_cpu(src->pDrawable,
@@ -520,67 +509,79 @@ sna_composite_fb(CARD8 op,
}
validate_source(mask);
- } else {
- if (src->pDrawable &&
- dst->pDrawable->bitsPerPixel >= 8 &&
- src->filter != PictFilterConvolution &&
- (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) &&
- (dst->format == src->format || dst->format == alphaless(src->format)) &&
- sna_transform_is_integer_translation(src->transform, &tx, &ty)) {
- PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable);
- PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable);
- int16_t sx = src_x + tx - (dst->pDrawable->x + dst_x);
- int16_t sy = src_y + ty - (dst->pDrawable->y + dst_y);
-
- assert(src->pDrawable->bitsPerPixel == dst->pDrawable->bitsPerPixel);
- assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel);
-
- if (region->extents.x1 + sx >= 0 &&
- region->extents.y1 + sy >= 0 &&
- region->extents.x2 + sx <= src->pDrawable->width &&
- region->extents.y2 + sy <= src->pDrawable->height) {
- BoxPtr box = RegionRects(region);
- int nbox = RegionNumRects(region);
-
- sx += src->pDrawable->x;
- sy += src->pDrawable->y;
- if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty))
- sx += tx, sy += ty;
-
- assert(region->extents.x1 + sx >= 0);
- assert(region->extents.x2 + sx <= src_pixmap->drawable.width);
- assert(region->extents.y1 + sy >= 0);
- assert(region->extents.y2 + sy <= src_pixmap->drawable.height);
-
- get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
-
- assert(nbox);
- do {
- assert(box->x1 + sx >= 0);
- assert(box->x2 + sx <= src_pixmap->drawable.width);
- assert(box->y1 + sy >= 0);
- assert(box->y2 + sy <= src_pixmap->drawable.height);
-
- assert(box->x1 + dst_x >= 0);
- assert(box->x2 + dst_x <= dst_pixmap->drawable.width);
- assert(box->y1 + dst_y >= 0);
- assert(box->y2 + dst_y <= dst_pixmap->drawable.height);
-
- assert(box->x2 > box->x1 && box->y2 > box->y1);
-
- memcpy_blt(src_pixmap->devPrivate.ptr,
- dst_pixmap->devPrivate.ptr,
- dst_pixmap->drawable.bitsPerPixel,
- src_pixmap->devKind,
- dst_pixmap->devKind,
- box->x1 + sx, box->y1 + sy,
- box->x1 + tx, box->y1 + ty,
- box->x2 - box->x1, box->y2 - box->y1);
- box++;
- } while (--nbox);
+ }
- return;
- }
+ DBG(("%s: fallback -- move dst to cpu\n", __FUNCTION__));
+ if (op <= PictOpSrc && !dst->alphaMap)
+ flags = MOVE_WRITE | MOVE_INPLACE_HINT;
+ else
+ flags = MOVE_WRITE | MOVE_READ;
+ if (!sna_drawable_move_region_to_cpu(dst->pDrawable, region, flags))
+ return;
+ if (dst->alphaMap &&
+ !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, flags))
+ return;
+
+ if (mask == NULL &&
+ src->pDrawable &&
+ dst->pDrawable->bitsPerPixel >= 8 &&
+ src->filter != PictFilterConvolution &&
+ (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) &&
+ (dst->format == src->format || dst->format == alphaless(src->format)) &&
+ sna_transform_is_integer_translation(src->transform, &tx, &ty)) {
+ PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+ PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable);
+ int16_t sx = src_x + tx - (dst->pDrawable->x + dst_x);
+ int16_t sy = src_y + ty - (dst->pDrawable->y + dst_y);
+
+ assert(src->pDrawable->bitsPerPixel == dst->pDrawable->bitsPerPixel);
+ assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel);
+
+ if (region->extents.x1 + sx >= 0 &&
+ region->extents.y1 + sy >= 0 &&
+ region->extents.x2 + sx <= src->pDrawable->width &&
+ region->extents.y2 + sy <= src->pDrawable->height) {
+ BoxPtr box = RegionRects(region);
+ int nbox = RegionNumRects(region);
+
+ sx += src->pDrawable->x;
+ sy += src->pDrawable->y;
+ if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty))
+ sx += tx, sy += ty;
+
+ assert(region->extents.x1 + sx >= 0);
+ assert(region->extents.x2 + sx <= src_pixmap->drawable.width);
+ assert(region->extents.y1 + sy >= 0);
+ assert(region->extents.y2 + sy <= src_pixmap->drawable.height);
+
+ get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
+
+ assert(nbox);
+ do {
+ assert(box->x1 + sx >= 0);
+ assert(box->x2 + sx <= src_pixmap->drawable.width);
+ assert(box->y1 + sy >= 0);
+ assert(box->y2 + sy <= src_pixmap->drawable.height);
+
+ assert(box->x1 + dst_x >= 0);
+ assert(box->x2 + dst_x <= dst_pixmap->drawable.width);
+ assert(box->y1 + dst_y >= 0);
+ assert(box->y2 + dst_y <= dst_pixmap->drawable.height);
+
+ assert(box->x2 > box->x1 && box->y2 > box->y1);
+
+ memcpy_blt(src_pixmap->devPrivate.ptr,
+ dst_pixmap->devPrivate.ptr,
+ dst_pixmap->drawable.bitsPerPixel,
+ src_pixmap->devKind,
+ dst_pixmap->devKind,
+ box->x1 + sx, box->y1 + sy,
+ box->x1 + tx, box->y1 + ty,
+ box->x2 - box->x1, box->y2 - box->y1);
+ box++;
+ } while (--nbox);
+
+ return;
}
}