xf86-video-intel: 10 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_display.c src/sna/sna.h src/sna/sna_render.c src/sna/sna_render.h src/sna/sna_render_inline.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 19 07:10:07 PDT 2013


 src/sna/kgem.c              |    1 
 src/sna/sna.h               |    5 -
 src/sna/sna_accel.c         |  169 ++++++++++++++++++++++----------------------
 src/sna/sna_blt.c           |   38 +++++----
 src/sna/sna_composite.c     |  122 ++++++++++++++++---------------
 src/sna/sna_display.c       |    4 -
 src/sna/sna_render.c        |    6 +
 src/sna/sna_render.h        |    7 +
 src/sna/sna_render_inline.h |    2 
 src/sna/sna_trapezoids.c    |   16 ++--
 10 files changed, 202 insertions(+), 168 deletions(-)

New commits:
commit 4aa0288f16f03723a7aaa30967809d10fdb15a27
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 19 14:10:02 2013 +0100

    sna: Return true from get_drawable_deltas() if the pixmap is offset
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 249d57c..d0d2de4 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -408,17 +408,18 @@ CARD32 sna_render_format_for_depth(int depth);
 
 void sna_debug_flush(struct sna *sna);
 
-static inline void
+static inline bool
 get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y)
 {
 #ifdef COMPOSITE
 	if (drawable->type == DRAWABLE_WINDOW) {
 		*x = -pixmap->screen_x;
 		*y = -pixmap->screen_y;
-		return;
+		return pixmap->screen_x | pixmap->screen_y;
 	}
 #endif
 	*x = *y = 0;
+	return false;
 }
 
 static inline int
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f070486..5f6d7df 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2288,10 +2288,10 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	    flags & MOVE_WRITE)
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
-	DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
-	if (dx | dy)
+	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
 		RegionTranslate(region, dx, dy);
+	}
 
 	if (region_subsumes_drawable(region, &pixmap->drawable)) {
 		DBG(("%s: region (%d, %d), (%d, %d) subsumes pixmap (%dx%d)\n",
@@ -3107,13 +3107,13 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
 
 		if (flags & IGNORE_CPU) {
 			if (priv->gpu_damage) {
-				get_drawable_deltas(drawable, pixmap, &dx, &dy);
-
 				region.extents = *box;
-				region.extents.x1 += dx;
-				region.extents.x2 += dx;
-				region.extents.y1 += dy;
-				region.extents.y2 += dy;
+				if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+					region.extents.x1 += dx;
+					region.extents.x2 += dx;
+					region.extents.y1 += dy;
+					region.extents.y2 += dy;
+				}
 				region.data = NULL;
 				if (region_subsumes_damage(&region,
 							   priv->gpu_damage))
@@ -3223,13 +3223,13 @@ sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
 				}
 			}
 		} else if (priv->cpu_damage) {
-			get_drawable_deltas(drawable, pixmap, &dx, &dy);
-
 			region.extents = *box;
-			region.extents.x1 += dx;
-			region.extents.x2 += dx;
-			region.extents.y1 += dy;
-			region.extents.y2 += dy;
+			if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+				region.extents.x1 += dx;
+				region.extents.x2 += dx;
+				region.extents.y1 += dy;
+				region.extents.y2 += dy;
+			}
 			region.data = NULL;
 
 			sna_damage_subtract(&priv->cpu_damage, &region);
@@ -3250,13 +3250,15 @@ create_gpu_bo:
 		goto done;
 	}
 
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 
 	region.extents = *box;
-	region.extents.x1 += dx;
-	region.extents.x2 += dx;
-	region.extents.y1 += dy;
-	region.extents.y2 += dy;
+	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+		region.extents.x1 += dx;
+		region.extents.x2 += dx;
+		region.extents.y1 += dy;
+		region.extents.y2 += dy;
+	}
+	region.data = NULL;
 
 	DBG(("%s extents (%d, %d), (%d, %d)\n", __FUNCTION__,
 	     region.extents.x1, region.extents.y1,
@@ -3357,13 +3359,13 @@ use_cpu_bo:
 	if (!USE_CPU_BO || priv->cpu_bo == NULL) {
 cpu_fail:
 		if ((flags & FORCE_GPU) && priv->gpu_bo) {
-			get_drawable_deltas(drawable, pixmap, &dx, &dy);
-
 			region.extents = *box;
-			region.extents.x1 += dx;
-			region.extents.x2 += dx;
-			region.extents.y1 += dy;
-			region.extents.y2 += dy;
+			if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+				region.extents.x1 += dx;
+				region.extents.x2 += dx;
+				region.extents.y1 += dy;
+				region.extents.y2 += dy;
+			}
 			region.data = NULL;
 
 			goto move_to_gpu;
@@ -3382,13 +3384,14 @@ cpu_fail:
 		return NULL;
 	}
 
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 
 	region.extents = *box;
-	region.extents.x1 += dx;
-	region.extents.x2 += dx;
-	region.extents.y1 += dy;
-	region.extents.y2 += dy;
+	if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+		region.extents.x1 += dx;
+		region.extents.x2 += dx;
+		region.extents.y1 += dy;
+		region.extents.y2 += dy;
+	}
 	region.data = NULL;
 
 	/* Both CPU and GPU are busy, prefer to use the GPU */
@@ -4738,9 +4741,8 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	     dx, dy, alu,
 	     pixmap->drawable.width, pixmap->drawable.height));
 
-	get_drawable_deltas(src, pixmap, &tx, &ty);
-	dx += tx;
-	dy += ty;
+	if (get_drawable_deltas(src, pixmap, &tx, &ty))
+		dx += tx, dy += ty;
 	if (dst != src)
 		get_drawable_deltas(dst, pixmap, &tx, &ty);
 
@@ -4943,8 +4945,8 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 	bpp = dst_pixmap->drawable.bitsPerPixel;
 
-	get_drawable_deltas(dst, dst_pixmap, &dst_dx, &dst_dy);
-	RegionTranslate(region, dst_dx, dst_dy);
+	if (get_drawable_deltas(dst, dst_pixmap, &dst_dx, &dst_dy))
+		RegionTranslate(region, dst_dx, dst_dy);
 	get_drawable_deltas(src, src_pixmap, &src_dx, &src_dy);
 	src_dx += dx - dst_dx;
 	src_dy += dy - dst_dy;
@@ -6902,9 +6904,8 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 	if (n == 0)
 		return;
 
-	get_drawable_deltas(source, src_pixmap, &dx, &dy);
-	sx += dx;
-	sy += dy;
+	if (get_drawable_deltas(source, src_pixmap, &dx, &dy))
+		sx += dx, sy += dy;
 
 	get_drawable_deltas(drawable, dst_pixmap, &dx, &dy);
 	assert_pixmap_contains_boxes(dst_pixmap, box, n, dx, dy);
@@ -10146,9 +10147,10 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 		r.x2 = bound(r.x1, rect->width);
 		r.y2 = bound(r.y1, rect->height);
 		if (box_intersect(&r, &gc->pCompositeClip->extents)) {
-			get_drawable_deltas(drawable, pixmap, &dx, &dy);
-			r.x1 += dx; r.y1 += dy;
-			r.x2 += dx; r.y2 += dy;
+			if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) {
+				r.x1 += dx; r.y1 += dy;
+				r.x2 += dx; r.y2 += dy;
+			}
 			if (sna->render.fill_one(sna, pixmap, bo, pixel,
 						 r.x1, r.y1, r.x2, r.y2,
 						 gc->alu)) {
@@ -12619,10 +12621,10 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 
 		region.data = NULL;
 
-		get_drawable_deltas(draw, pixmap, &dx, &dy);
-		DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
-		if (dx | dy)
+		if (get_drawable_deltas(draw, pixmap, &dx, &dy)) {
+			DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy));
 			RegionTranslate(&region, dx, dy);
+		}
 
 		if (priv->cpu_damage && (flags & 2) == 0) {
 			if (region_subsumes_damage(&region, priv->cpu_damage)) {
@@ -14024,8 +14026,8 @@ sna_push_pixels_solid_blt(GCPtr gc,
 		}
 	}
 
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
-	RegionTranslate(region, dx, dy);
+	if (get_drawable_deltas(drawable, pixmap, &dx, &dy))
+		RegionTranslate(region, dx, dy);
 
 	assert_pixmap_contains_box(pixmap, RegionExtents(region));
 	if (damage)
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 36e2bde..d2152c7 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -537,11 +537,11 @@ sna_composite_fb(CARD8 op,
 
 		src_x += tx; src_y += ty;
 
-		get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty);
-		src_x += tx; src_y += ty;
+		if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty))
+			src_x += tx, src_y += ty;
 
-		get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
-		dst_x += tx; dst_y += ty;
+		if (get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty))
+			dst_x += tx, dst_y += ty;
 
 		do {
 			memcpy_blt(src_pixmap->devPrivate.ptr,
@@ -666,8 +666,7 @@ sna_composite(CARD8 op,
 	if (op <= PictOpSrc && priv->cpu_damage) {
 		int16_t x, y;
 
-		get_drawable_deltas(dst->pDrawable, pixmap, &x, &y);
-		if (x|y)
+		if (get_drawable_deltas(dst->pDrawable, pixmap, &x, &y))
 			pixman_region_translate(&region, x, y);
 
 		sna_damage_subtract(&priv->cpu_damage, &region);
@@ -888,8 +887,8 @@ sna_composite_rectangles(CARD8		 op,
 	     (long)RegionNumRects(&region)));
 
 	pixmap = get_drawable_pixmap(dst->pDrawable);
-	get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
-	pixman_region_translate(&region, dst_x, dst_y);
+	if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y))
+		pixman_region_translate(&region, dst_x, dst_y);
 
 	DBG(("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
 	     __FUNCTION__, dst_x, dst_y,
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index e07ff2c..cc8375f 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -5402,10 +5402,10 @@ trapezoid_span_mono_inplace(struct sna *sna,
 
 unbounded_pass:
 		pixmap = get_drawable_pixmap(dst->pDrawable);
-		get_drawable_deltas(dst->pDrawable, pixmap, &dx, &dy);
 
 		ptr = pixmap->devPrivate.ptr;
-		ptr += dy * pixmap->devKind + dx * pixmap->drawable.bitsPerPixel / 8;
+		if (get_drawable_deltas(dst->pDrawable, pixmap, &dx, &dy))
+			ptr += dy * pixmap->devKind + dx * pixmap->drawable.bitsPerPixel / 8;
 		inplace.fill.data = (uint32_t *)ptr;
 		inplace.fill.stride = pixmap->devKind / sizeof(uint32_t);
 		inplace.fill.bpp = pixmap->drawable.bitsPerPixel;
@@ -5633,10 +5633,10 @@ static void inplace_x8r8g8b8_thread(void *arg)
 		PixmapPtr pixmap;
 
 		pixmap = get_drawable_pixmap(thread->dst->pDrawable);
-		get_drawable_deltas(thread->dst->pDrawable, pixmap, &dst_x, &dst_y);
 
 		inplace.ptr = pixmap->devPrivate.ptr;
-		inplace.ptr += dst_y * pixmap->devKind + dst_x * 4;
+		if (get_drawable_deltas(thread->dst->pDrawable, pixmap, &dst_x, &dst_y))
+			inplace.ptr += dst_y * pixmap->devKind + dst_x * 4;
 		inplace.stride = pixmap->devKind;
 		inplace.color = thread->color;
 
@@ -5824,10 +5824,10 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
 			int16_t dst_x, dst_y;
 
 			pixmap = get_drawable_pixmap(dst->pDrawable);
-			get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
 
 			inplace.ptr = pixmap->devPrivate.ptr;
-			inplace.ptr += dst_y * pixmap->devKind + dst_x * 4;
+			if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y))
+				inplace.ptr += dst_y * pixmap->devKind + dst_x * 4;
 			inplace.stride = pixmap->devKind;
 			inplace.color = color;
 
@@ -6151,10 +6151,10 @@ trapezoid_span_inplace(struct sna *sna,
 	dx = dst->pDrawable->x * FAST_SAMPLES_X;
 	dy = dst->pDrawable->y * FAST_SAMPLES_Y;
 
-	get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
 
 	inplace.ptr = pixmap->devPrivate.ptr;
-	inplace.ptr += dst_y * pixmap->devKind + dst_x;
+	if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y))
+		inplace.ptr += dst_y * pixmap->devKind + dst_x;
 	inplace.stride = pixmap->devKind;
 	inplace.opacity = color >> 24;
 
commit 6921abd81017c9ed7f3b2413784068fbc609a0ea
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 16:21:27 2013 +0100

    sna: Add a fast path for the most common fallback for CPU-CPU blits
    
    This path will mostly be upload for individual glyph uploads, for which
    the malloc overhead is significant.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index beef9a6..b4ef083 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -1953,13 +1953,6 @@ prepare_blt_put(struct sna *sna,
 	return true;
 }
 
-#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format),		\
-				      PICT_FORMAT_TYPE(format),		\
-				      0,				\
-				      PICT_FORMAT_R(format),		\
-				      PICT_FORMAT_G(format),		\
-				      PICT_FORMAT_B(format))
-
 static bool
 is_clear(PixmapPtr pixmap)
 {
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index ea4a100..36e2bde 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -470,6 +470,7 @@ sna_composite_fb(CARD8 op,
 	int src_xoff, src_yoff;
 	int msk_xoff, msk_yoff;
 	int dst_xoff, dst_yoff;
+	int16_t tx, ty;
 	unsigned flags;
 
 	DBG(("%s -- op=%d, fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n",
@@ -519,6 +520,44 @@ sna_composite_fb(CARD8 op,
 	if (mask)
 		validate_source(mask);
 
+	if (mask == NULL &&
+	    src->pDrawable &&
+	    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) &&
+	    region->extents.x1 + src_x + tx >= 0 &&
+	    region->extents.y1 + src_y + ty >= 0 &&
+	    region->extents.x2 + src_x + tx <= src->pDrawable->width &&
+	    region->extents.x2 + src_y + ty <= src->pDrawable->height) {
+		PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable);
+		PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable);
+		int nbox = RegionNumRects(region);
+		BoxPtr box = RegionRects(region);
+
+		src_x += tx; src_y += ty;
+
+		get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty);
+		src_x += tx; src_y += ty;
+
+		get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty);
+		dst_x += tx; dst_y += ty;
+
+		do {
+			memcpy_blt(src_pixmap->devPrivate.ptr,
+				   dst_pixmap->devPrivate.ptr,
+				   dst_pixmap->drawable.bitsPerPixel,
+				   src_pixmap->devKind,
+				   dst_pixmap->devKind,
+				   box->x1 + src_x, box->y1 + src_y,
+				   box->x1 + dst_x, box->y1 + dst_y,
+				   box->x2 - box->x1, box->y2 - box->y1);
+			box++;
+		} while (--nbox);
+
+		return;
+	}
+
 	src_image = image_from_pict(src, FALSE, &src_xoff, &src_yoff);
 	mask_image = image_from_pict(mask, FALSE, &msk_xoff, &msk_yoff);
 	dest_image = image_from_pict(dst, TRUE, &dst_xoff, &dst_yoff);
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index aace869..2636394 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -775,4 +775,11 @@ static inline bool sna_vertex_wait__locked(struct sna_render *r)
 	return was_active;
 }
 
+#define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format),		\
+				      PICT_FORMAT_TYPE(format),		\
+				      0,				\
+				      PICT_FORMAT_R(format),		\
+				      PICT_FORMAT_G(format),		\
+				      PICT_FORMAT_B(format))
+
 #endif /* SNA_RENDER_H */
commit 4da830864983ffe482388e4e4cfee02d106c895e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 15:05:04 2013 +0100

    sna: Remove the duplicated pimxap migration for the composite fb path
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index ae04c00..ea4a100 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -461,9 +461,9 @@ sna_composite_fb(CARD8 op,
 		 PicturePtr mask,
 		 PicturePtr dst,
 		 RegionPtr region,
-		 INT16 src_x,  INT16 src_y,
-		 INT16 mask_x, INT16 mask_y,
-		 INT16 dst_x,  INT16 dst_y,
+		 INT16 src_x, INT16 src_y,
+		 INT16 msk_x, INT16 msk_y,
+		 INT16 dst_x, INT16 dst_y,
 		 CARD16 width, CARD16 height)
 {
 	pixman_image_t *src_image, *mask_image, *dest_image;
@@ -472,6 +472,14 @@ sna_composite_fb(CARD8 op,
 	int dst_xoff, dst_yoff;
 	unsigned flags;
 
+	DBG(("%s -- op=%d, fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n",
+	     __FUNCTION__, op,
+	     dst_x, dst_y,
+	     dst->pDrawable->x, dst->pDrawable->y,
+	     width, height,
+	     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;
@@ -507,8 +515,6 @@ sna_composite_fb(CARD8 op,
 			return;
 	}
 
-	DBG(("%s: fallback -- fbComposite\n", __FUNCTION__));
-
 	validate_source(src);
 	if (mask)
 		validate_source(mask);
@@ -519,10 +525,10 @@ sna_composite_fb(CARD8 op,
 
 	if (src_image && dest_image && !(mask && !mask_image))
 		sna_image_composite(op, src_image, mask_image, dest_image,
-				       src_x + src_xoff, src_y + src_yoff,
-				       mask_x + msk_xoff, mask_y + msk_yoff,
-				       dst_x + dst_xoff, dst_y + dst_yoff,
-				       width, height);
+				    src_x + src_xoff, src_y + src_yoff,
+				    msk_x + msk_xoff, msk_y + msk_yoff,
+				    dst_x + dst_xoff, dst_y + dst_yoff,
+				    width, height);
 
 	free_pixman_pict(src, src_image);
 	free_pixman_pict(mask, mask_image);
@@ -543,7 +549,6 @@ sna_composite(CARD8 op,
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
 	struct sna_composite_op tmp;
-	unsigned flags;
 	RegionRec region;
 	int dx, dy;
 
@@ -661,46 +666,6 @@ sna_composite(CARD8 op,
 	goto out;
 
 fallback:
-	DBG(("%s -- fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n",
-	     __FUNCTION__,
-	     dst_x, dst_y,
-	     dst->pDrawable->x, dst->pDrawable->y,
-	     width, height,
-	     region.extents.x1, region.extents.y1,
-	     region.extents.x2, region.extents.y2));
-	if (op <= PictOpSrc && !dst->alphaMap)
-		flags = MOVE_WRITE | MOVE_INPLACE_HINT;
-	else
-		flags = MOVE_WRITE | MOVE_READ;
-	DBG(("%s: fallback -- move dst to cpu\n", __FUNCTION__));
-	if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region, flags))
-		goto out;
-	if (dst->alphaMap &&
-	    !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, flags))
-		goto out;
-	if (src->pDrawable) {
-		DBG(("%s: fallback -- move src to cpu\n", __FUNCTION__));
-		if (!sna_drawable_move_to_cpu(src->pDrawable,
-					      MOVE_READ))
-			goto out;
-
-		if (src->alphaMap &&
-		    !sna_drawable_move_to_cpu(src->alphaMap->pDrawable,
-					      MOVE_READ))
-			goto out;
-	}
-	if (mask && mask->pDrawable) {
-		DBG(("%s: fallback -- move mask to cpu\n", __FUNCTION__));
-		if (!sna_drawable_move_to_cpu(mask->pDrawable,
-					      MOVE_READ))
-			goto out;
-
-		if (mask->alphaMap &&
-		    !sna_drawable_move_to_cpu(mask->alphaMap->pDrawable,
-					      MOVE_READ))
-			goto out;
-	}
-
 	DBG(("%s: fallback -- fbComposite\n", __FUNCTION__));
 	sna_composite_fb(op, src, mask, dst, &region,
 			 src_x,  src_y,
commit 0d56f0eb84cc80fa5497c06a7967650aa20ebe51
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 14:49:41 2013 +0100

    sna: DBG controls to turn off unwinding partial bo
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 8a0f5e0..f070486 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -69,6 +69,7 @@
 #define USE_USERPTR_UPLOADS 1
 #define USE_USERPTR_DOWNLOADS 1
 #define USE_COW 1
+#define UNDO 1
 
 #define MIGRATE_ALL 0
 #define DBG_NO_CPU_UPLOAD 0
@@ -1833,7 +1834,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 
 	assert(priv->gpu_damage == NULL || priv->gpu_bo);
 
-	if ((flags & MOVE_READ) == 0) {
+	if ((flags & MOVE_READ) == 0 && UNDO) {
 		if (priv->gpu_bo)
 			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
 		if (priv->cpu_bo)
@@ -1923,6 +1924,7 @@ skip_inplace_map:
 		if (priv->mapped) {
 			assert(has_coherent_map(sna, priv->gpu_bo, flags));
 			pixmap->devKind = priv->gpu_bo->pitch;
+
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
 				sna_damage_all(&priv->gpu_damage,
@@ -2173,7 +2175,9 @@ static inline bool region_inplace(struct sna *sna,
 		return false;
 
 	if (flags & MOVE_READ &&
-	    (priv->cpu || region_overlaps_damage(region, priv->cpu_damage, 0, 0))) {
+	    (priv->cpu ||
+	     priv->gpu_damage == NULL ||
+	     region_overlaps_damage(region, priv->cpu_damage, 0, 0))) {
 		DBG(("%s: no, uncovered CPU damage pending\n", __FUNCTION__));
 		return false;
 	}
@@ -3568,7 +3572,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	assert(priv->gpu_damage == NULL || priv->gpu_bo);
 
-	if ((flags & MOVE_READ) == 0) {
+	if ((flags & MOVE_READ) == 0 && UNDO) {
 		if (priv->gpu_bo)
 			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
 		if (priv->cpu_bo)
@@ -5007,7 +5011,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			DBG(("%s: applying src clear [%08x] to dst\n",
 			     __FUNCTION__, src_priv->clear_color));
 			if (n == 1) {
-				if (replaces)
+				if (replaces && UNDO)
 					kgem_bo_undo(&sna->kgem, bo);
 
 				if (!sna->render.fill_one(sna,
@@ -5060,7 +5064,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		    sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ | MOVE_ASYNC_HINT)) {
 			DBG(("%s: move whole src_pixmap to GPU and copy\n",
 			     __FUNCTION__));
-			if (replaces)
+			if (replaces && UNDO)
 				kgem_bo_undo(&sna->kgem, bo);
 
 			if (replaces &&
@@ -5112,7 +5116,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 							 MOVE_READ | MOVE_ASYNC_HINT))
 				goto fallback;
 
-			if (replaces)
+			if (replaces && UNDO)
 				kgem_bo_undo(&sna->kgem, bo);
 
 			if (!sna->render.copy_boxes(sna, alu,
@@ -5148,7 +5152,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			if (!ret)
 				goto fallback;
 
-			if (replaces)
+			if (replaces && UNDO)
 				kgem_bo_undo(&sna->kgem, bo);
 
 			if (src_priv->shm) {
@@ -12666,7 +12670,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 		DBG(("%s: not using GPU, hint=%x\n", __FUNCTION__, hint));
 		goto fallback;
 	}
-	if (hint & REPLACES && (flags & 2) == 0)
+	if (hint & REPLACES && (flags & 2) == 0 && UNDO)
 		kgem_bo_undo(&sna->kgem, bo);
 
 	if (gc_is_solid(gc, &color)) {
commit 494f4bdcb00dc54f84e503b49fd85c8965f7f9ed
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 14:19:16 2013 +0100

    sna: Allow operation inplace when wedged
    
    There are times, such as rendering into the scanout, where continuing to
    use the GTT is preferrable even when wedged.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index dbbc54e..8a0f5e0 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1471,10 +1471,10 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
 	unsigned create;
 
 	if (wedged(sna))
-		return false;
+		goto done;
 
 	if ((priv->create & KGEM_CAN_CREATE_GTT) == 0)
-		return false;
+		goto done;
 
 	assert_pixmap_damage(pixmap);
 
@@ -1482,7 +1482,7 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
 	    (!kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo) ||
 	     __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) {
 		if (priv->pinned)
-			return false;
+			goto done;
 
 		DBG(("%s: discard busy GPU bo\n", __FUNCTION__));
 		sna_pixmap_free_gpu(sna, priv);
@@ -1508,6 +1508,7 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
 			       sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
 			       create);
 
+done:
 	return priv->gpu_bo && kgem_bo_is_mappable(&sna->kgem, priv->gpu_bo);
 }
 
@@ -1909,7 +1910,7 @@ skip_inplace_map:
 	if (USE_INPLACE &&
 	    operate_inplace(priv, flags) &&
 	    pixmap_inplace(sna, pixmap, priv, flags) &&
-	     sna_pixmap_create_mappable_gpu(pixmap, (flags & MOVE_READ) == 0)) {
+	    sna_pixmap_create_mappable_gpu(pixmap, (flags & MOVE_READ) == 0)) {
 		DBG(("%s: try to operate inplace (GTT)\n", __FUNCTION__));
 		assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0);
 		assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL);
@@ -2305,7 +2306,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 	if (USE_INPLACE &&
 	    operate_inplace(priv, flags) &&
 	    region_inplace(sna, pixmap, region, priv, flags) &&
-	     sna_pixmap_create_mappable_gpu(pixmap, false)) {
+	    sna_pixmap_create_mappable_gpu(pixmap, false)) {
 		DBG(("%s: try to operate inplace\n", __FUNCTION__));
 		assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0);
 		/* XXX only sync for writes? */
commit fb058de4e617d7e5058674859993ec635a8d779e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 13:37:12 2013 +0100

    sna: Treat a source with a CPU bo as being attached.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_render_inline.h b/src/sna/sna_render_inline.h
index 1a3be2c..a1b97be 100644
--- a/src/sna/sna_render_inline.h
+++ b/src/sna/sna_render_inline.h
@@ -105,7 +105,7 @@ static inline bool
 unattached(DrawablePtr drawable)
 {
 	struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
-	return priv == NULL || (priv->gpu_damage == NULL && priv->cpu_damage);
+	return priv == NULL || (priv->gpu_damage == NULL && priv->cpu_damage && !priv->cpu_bo);
 }
 
 static inline bool
commit 4723a730f4dc2d007577f43fe232c49b305c2695
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 13:26:36 2013 +0100

    sna: Discard overwritten operations before doing a BLT composite
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index b071683..beef9a6 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -2031,8 +2031,12 @@ clear:
 		hint = 0;
 		if (can_render(sna)) {
 			hint |= PREFER_GPU;
-			if (dst->pCompositeClip->data == NULL && (width | height))
+			if (dst->pCompositeClip->data == NULL && (width | height)) {
 				hint |= IGNORE_CPU;
+				if (width == tmp->dst.pixmap->drawable.width &&
+				    height == tmp->dst.pixmap->drawable.height)
+					hint |= REPLACES;
+			}
 		}
 		tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
 						  &dst_box, &tmp->damage);
@@ -2051,7 +2055,9 @@ clear:
 			if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
 							     MOVE_INPLACE_HINT | MOVE_WRITE))
 				return false;
-		}
+		} else if (hint & REPLACES)
+			kgem_bo_undo(&sna->kgem, tmp->dst.bo);
+
 		return prepare_blt_clear(sna, tmp);
 	}
 
@@ -2081,6 +2087,9 @@ fill:
 			hint |= PREFER_GPU;
 			if (dst->pCompositeClip->data == NULL && (width | height))
 				hint |= IGNORE_CPU;
+				if (width == tmp->dst.pixmap->drawable.width &&
+				    height == tmp->dst.pixmap->drawable.height)
+					hint |= REPLACES;
 		}
 		tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
 						  &dst_box, &tmp->damage);
@@ -2099,7 +2108,8 @@ fill:
 			if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &region,
 							MOVE_INPLACE_HINT | MOVE_WRITE))
 				return false;
-		}
+		} else if (hint & REPLACES)
+			kgem_bo_undo(&sna->kgem, tmp->dst.bo);
 
 		return prepare_blt_fill(sna, tmp, color);
 	}
@@ -2228,14 +2238,21 @@ fill:
 	hint = 0;
 	if (bo || can_render(sna)) {
 		hint |= PREFER_GPU;
-		if (dst->pCompositeClip->data == NULL && (width | height))
+		if (dst->pCompositeClip->data == NULL && (width | height)) {
 			hint |= IGNORE_CPU;
+			if (width == tmp->dst.pixmap->drawable.width &&
+			    height == tmp->dst.pixmap->drawable.height)
+				hint |= REPLACES;
+		}
 		if (bo)
 			hint |= FORCE_GPU;
 	}
 	tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
 					  &dst_box, &tmp->damage);
 
+	if (hint & REPLACES)
+		kgem_bo_undo(&sna->kgem, tmp->dst.bo);
+
 	ret = false;
 	if (bo) {
 		if (!tmp->dst.bo) {
commit b2f32373815e166fc6dceb477139ff2ef27db0ba
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 12:33:10 2013 +0100

    sna: Tidy a few DBG regarding cached uploads
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 2a8dddc..c309cae 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2631,6 +2631,7 @@ void kgem_reset(struct kgem *kgem)
 			bo->gpu_dirty = false;
 
 			if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) {
+				assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE);
 				list_add(&bo->request, &kgem->flushing);
 				bo->rq = (void *)kgem;
 			} else
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 909420d..dbbc54e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2289,7 +2289,14 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 		RegionTranslate(region, dx, dy);
 
 	if (region_subsumes_drawable(region, &pixmap->drawable)) {
-		DBG(("%s: region subsumes drawable\n", __FUNCTION__));
+		DBG(("%s: region (%d, %d), (%d, %d) subsumes pixmap (%dx%d)\n",
+		       __FUNCTION__,
+		       region->extents.x1,
+		       region->extents.y1,
+		       region->extents.x2,
+		       region->extents.y2,
+		       pixmap->drawable.width,
+		       pixmap->drawable.height));
 		if (dx | dy)
 			RegionTranslate(region, -dx, -dy);
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 566f042..ae04c00 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -216,10 +216,13 @@ sna_compute_composite_region(RegionPtr region,
 			pixman_region_fini (region);
 			return FALSE;
 		}
-		DBG(("%s: clip against src: (%d, %d), (%d, %d)\n",
-		     __FUNCTION__,
-		     region->extents.x1, region->extents.y1,
-		     region->extents.x2, region->extents.y2));
+		DBG(("%s: clip against src (%dx%d clip=%d): (%d, %d), (%d, %d)\n",
+		       __FUNCTION__,
+		       src->pDrawable ? src->pDrawable->width : 0,
+		       src->pDrawable ? src->pDrawable->height : 0,
+		       src->clientClipType,
+		       region->extents.x1, region->extents.y1,
+		       region->extents.x2, region->extents.y2));
 
 		if (src->alphaMap) {
 			if (!clip_to_src(region, src->alphaMap,
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 67b7182..010f5fa 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3570,7 +3570,7 @@ void sna_mode_update(struct sna *sna)
 		DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n",
 		     __FUNCTION__,
 		     mode.crtc_id, mode.mode_valid,
-		     mode.fb_id, fb_id, expected));
+		     mode.fb_id, expected));
 
 		if (mode.fb_id != expected)
 			sna_crtc_disable(crtc);
@@ -3779,7 +3779,7 @@ sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region)
 	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe,
 	     region->extents.x1, region->extents.y1,
 	     region->extents.x2, region->extents.y2,
-	     REGION_NUM_RECTS(region)));
+	     (long)RegionNumRects(region)));
 
 	assert(!wedged(sna));
 
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 139081d..ebb1d30 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -553,8 +553,11 @@ static struct kgem_bo *upload(struct sna *sna,
 		    pixmap->usage_hint == 0 &&
 		    channel->width  == pixmap->drawable.width &&
 		    channel->height == pixmap->drawable.height) {
+			DBG(("%s: adding upload cache to pixmap=%ld\n",
+			     __FUNCTION__, pixmap->drawable.serialNumber));
 			assert(priv->gpu_damage == NULL);
 			assert(priv->gpu_bo == NULL);
+			assert(bo->proxy != NULL);
 			kgem_proxy_bo_attach(bo, &priv->gpu_bo);
 		}
 	}
@@ -1210,8 +1213,11 @@ sna_render_picture_extract(struct sna *sna,
 			if (priv != NULL && bo != NULL &&
 			    box.x2 - box.x1 == pixmap->drawable.width &&
 			    box.y2 - box.y1 == pixmap->drawable.height) {
+				DBG(("%s: adding upload cache to pixmap=%ld\n",
+				     __FUNCTION__, pixmap->drawable.serialNumber));
 				assert(priv->gpu_damage == NULL);
 				assert(priv->gpu_bo == NULL);
+				assert(bo->proxy != NULL);
 				kgem_proxy_bo_attach(bo, &priv->gpu_bo);
 			}
 		}
commit 1b37a167d9caa7868427cb88b2480f3b64e96cc9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 10:51:42 2013 +0100

    sna: Only IGNORE_CPU for blt composite operations if the size is known
    
    Some operations we do not know the true extents and so check the whole
    drawable when considering placement. In this case, the drawing may only
    partially cover the drawable and so we can not simply ignore existing CPU
    damage.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 1df23de..b071683 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -2031,9 +2031,7 @@ clear:
 		hint = 0;
 		if (can_render(sna)) {
 			hint |= PREFER_GPU;
-			if (sna_pixmap(tmp->dst.pixmap)->gpu_bo)
-				hint |= FORCE_GPU;
-			if (dst->pCompositeClip->data == NULL)
+			if (dst->pCompositeClip->data == NULL && (width | height))
 				hint |= IGNORE_CPU;
 		}
 		tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
@@ -2081,9 +2079,7 @@ fill:
 		hint = 0;
 		if (can_render(sna)) {
 			hint |= PREFER_GPU;
-			if (sna_pixmap(tmp->dst.pixmap)->gpu_bo)
-				hint |= FORCE_GPU;
-			if (dst->pCompositeClip->data == NULL)
+			if (dst->pCompositeClip->data == NULL && (width | height))
 				hint |= IGNORE_CPU;
 		}
 		tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
@@ -2232,7 +2228,7 @@ fill:
 	hint = 0;
 	if (bo || can_render(sna)) {
 		hint |= PREFER_GPU;
-		if (dst->pCompositeClip->data == NULL)
+		if (dst->pCompositeClip->data == NULL && (width | height))
 			hint |= IGNORE_CPU;
 		if (bo)
 			hint |= FORCE_GPU;
commit 2d62f7c483a999c24c744c0d257c8524f6fd5d32
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 18 22:00:24 2013 +0100

    sna: Also do exposure checking after source clipping in sna_do_copy
    
    Hopefully a final regression from:
    
    commit 07926bfe507071a3d46a2ec13bb86a36bc225761
    Author: Chris Wilson <chris at chris-wilson.co.uk>
    Date:   Thu Jul 11 15:28:55 2013 +0100
    
        sna: Remove the temporary region allocation from sna_do_copy
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=67055
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 77233cd..909420d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5464,7 +5464,7 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 {
 	RegionPtr clip;
 	RegionRec region;
-	bool expose;
+	BoxRec src_extents;
 
 	DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%dx%d)\n",
 	     __FUNCTION__, sx, sy, dx, dy, width, height));
@@ -5506,6 +5506,8 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	region.extents.y1 = clamp(region.extents.y1, sy - dy);
 	region.extents.y2 = clamp(region.extents.y2, sy - dy);
 
+	src_extents = region.extents;
+
 	/* Compute source clip region */
 	clip = NULL;
 	if (src == dst && gc->clientClipType == CT_NONE) {
@@ -5540,33 +5542,24 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	}
 	if (clip == NULL) {
 		DBG(("%s: fast source clip against extents\n", __FUNCTION__));
-		expose = true;
-		if (region.extents.x1 < src->x) {
+		if (region.extents.x1 < src->x)
 			region.extents.x1 = src->x;
-			expose = false;
-		}
-		if (region.extents.y1 < src->y) {
+		if (region.extents.y1 < src->y)
 			region.extents.y1 = src->y;
-			expose = false;
-		}
-		if (region.extents.x2 > src->x + (int) src->width) {
+		if (region.extents.x2 > src->x + (int) src->width)
 			region.extents.x2 = src->x + (int) src->width;
-			expose = false;
-		}
-		if (region.extents.y2 > src->y + (int) src->height) {
+		if (region.extents.y2 > src->y + (int) src->height)
 			region.extents.y2 = src->y + (int) src->height;
-			expose = false;
-		}
-		if (box_empty(&region.extents))
-			return NULL;
-	} else {
-		expose = false;
+	} else
 		RegionIntersect(&region, &region, clip);
-	}
 	DBG(("%s: src extents (%d, %d), (%d, %d) x %ld\n", __FUNCTION__,
 	     region.extents.x1, region.extents.y1,
 	     region.extents.x2, region.extents.y2,
 	     (long)RegionNumRects(&region)));
+	if ((clip == NULL || clip->data == NULL) &&
+	    *(uint64_t *)&src_extents == *(uint64_t *)&region.extents)
+		*(uint64_t *)&src_extents = 0;
+
 	RegionTranslate(&region, dx-sx, dy-sy);
 	if (gc->pCompositeClip->data)
 		RegionIntersect(&region, &region, gc->pCompositeClip);
@@ -5581,7 +5574,7 @@ sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 	/* Pixmap sources generate a NoExposed (we return NULL to do this) */
 	clip = NULL;
-	if (!expose && gc->fExpose)
+	if (gc->fExpose && *(uint64_t *)&src_extents != 0)
 		clip = miHandleExposures(src, dst, gc,
 					 sx - src->x, sy - src->y,
 					 width, height,


More information about the xorg-commit mailing list