xf86-video-intel: 8 commits - src/sna/blt.c src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_composite.c src/sna/sna_damage.c src/sna/sna_damage.h src/sna/sna_glyphs.c src/sna/sna_render.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jun 11 07:43:16 PDT 2014


 src/sna/blt.c           |   15 +++++++++----
 src/sna/kgem.c          |   27 ++++++++++++++----------
 src/sna/sna_accel.c     |   52 +++++++++++++++++++++++++-----------------------
 src/sna/sna_blt.c       |   10 +++++++--
 src/sna/sna_composite.c |   20 ++++++++++++++++++
 src/sna/sna_damage.c    |   29 ++++++++++++++++++++------
 src/sna/sna_damage.h    |   14 ++++++++----
 src/sna/sna_glyphs.c    |    8 +++----
 src/sna/sna_render.c    |    6 ++---
 9 files changed, 120 insertions(+), 61 deletions(-)

New commits:
commit a90160dcecf0a3df21a04b4f467e660f69ddae54
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 15:40:25 2014 +0100

    sna: Update damage pointer after the implicit reduction
    
    sna_damage_contains_box() routine implicitly reduces the damage before
    performing its check. This may alter and even destroy the damage entry,
    so pass in the handle so that it can be updated correctly.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=77436
    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 65a07e3..21f2dff 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2720,8 +2720,8 @@ move_to_cpu:
 
 		DBG(("%s: try to operate inplace (CPU), read? %d, write? %d\n",
 		     __FUNCTION__, !!(flags & MOVE_READ), !!(flags & MOVE_WRITE)));
-		assert(sna_damage_contains_box(priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
-		assert(sna_damage_contains_box(priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
+		assert(sna_damage_contains_box(&priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
+		assert(sna_damage_contains_box(&priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
 
 		ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
 		if (ptr != NULL) {
@@ -2854,8 +2854,8 @@ move_to_cpu:
 		} else {
 			if (sna_damage_contains_box__no_reduce(priv->cpu_damage,
 							       &region->extents)) {
-				assert(sna_damage_contains_box(priv->gpu_damage, &region->extents) == PIXMAN_REGION_OUT);
-				assert(sna_damage_contains_box(priv->cpu_damage, &region->extents) == PIXMAN_REGION_IN);
+				assert(sna_damage_contains_box(&priv->gpu_damage, &region->extents) == PIXMAN_REGION_OUT);
+				assert(sna_damage_contains_box(&priv->cpu_damage, &region->extents) == PIXMAN_REGION_IN);
 
 				DBG(("%s: region already in CPU damage\n",
 				     __FUNCTION__));
@@ -2863,7 +2863,7 @@ move_to_cpu:
 			}
 		}
 
-		if (sna_damage_contains_box(priv->gpu_damage,
+		if (sna_damage_contains_box(&priv->gpu_damage,
 					    &region->extents) != PIXMAN_REGION_OUT) {
 			RegionRec want, *r = region;
 
@@ -2936,8 +2936,8 @@ move_to_cpu:
 				DBG(("%s: region wholly inside damage\n",
 				     __FUNCTION__));
 
-				assert(sna_damage_contains_box(priv->gpu_damage, &r->extents) == PIXMAN_REGION_IN);
-				assert(sna_damage_contains_box(priv->cpu_damage, &r->extents) == PIXMAN_REGION_OUT);
+				assert(sna_damage_contains_box(&priv->gpu_damage, &r->extents) == PIXMAN_REGION_IN);
+				assert(sna_damage_contains_box(&priv->cpu_damage, &r->extents) == PIXMAN_REGION_OUT);
 
 				download_boxes(sna, priv,
 					       region_num_rects(r),
@@ -3322,8 +3322,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 		   sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) {
 		bool ok = false;
 
-		assert(sna_damage_contains_box(priv->gpu_damage, box) == PIXMAN_REGION_OUT);
-		assert(sna_damage_contains_box(priv->cpu_damage, box) == PIXMAN_REGION_IN);
+		assert(sna_damage_contains_box(&priv->gpu_damage, box) == PIXMAN_REGION_OUT);
+		assert(sna_damage_contains_box(&priv->cpu_damage, box) == PIXMAN_REGION_IN);
 
 		if (use_cpu_bo_for_upload(sna, priv, 0)) {
 			DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__));
@@ -3619,8 +3619,8 @@ create_gpu_bo:
 							       &region.extents)) {
 				DBG(("%s: region wholly contained within GPU damage\n",
 				     __FUNCTION__));
-				assert(sna_damage_contains_box(priv->gpu_damage, &region.extents) == PIXMAN_REGION_IN);
-				assert(sna_damage_contains_box(priv->cpu_damage, &region.extents) == PIXMAN_REGION_OUT);
+				assert(sna_damage_contains_box(&priv->gpu_damage, &region.extents) == PIXMAN_REGION_IN);
+				assert(sna_damage_contains_box(&priv->cpu_damage, &region.extents) == PIXMAN_REGION_OUT);
 				goto use_gpu_bo;
 			} else {
 				DBG(("%s: partial GPU damage with no CPU damage, continuing to use GPU\n",
@@ -3629,7 +3629,7 @@ create_gpu_bo:
 			}
 		}
 
-		ret = sna_damage_contains_box(priv->gpu_damage, &region.extents);
+		ret = sna_damage_contains_box(&priv->gpu_damage, &region.extents);
 		if (ret == PIXMAN_REGION_IN) {
 			DBG(("%s: region wholly contained within GPU damage\n",
 			     __FUNCTION__));
@@ -3644,7 +3644,7 @@ create_gpu_bo:
 	}
 
 	if ((flags & IGNORE_CPU) == 0 && priv->cpu_damage) {
-		ret = sna_damage_contains_box(priv->cpu_damage, &region.extents);
+		ret = sna_damage_contains_box(&priv->cpu_damage, &region.extents);
 		if (ret == PIXMAN_REGION_IN) {
 			DBG(("%s: region wholly contained within CPU damage\n",
 			     __FUNCTION__));
@@ -3824,8 +3824,8 @@ cpu_fail:
 		if (priv->cpu_damage &&
 		    sna_damage_contains_box__no_reduce(priv->cpu_damage,
 						       &region.extents)) {
-			assert(sna_damage_contains_box(priv->gpu_damage, &region.extents) == PIXMAN_REGION_OUT);
-			assert(sna_damage_contains_box(priv->cpu_damage, &region.extents) == PIXMAN_REGION_IN);
+			assert(sna_damage_contains_box(&priv->gpu_damage, &region.extents) == PIXMAN_REGION_OUT);
+			assert(sna_damage_contains_box(&priv->cpu_damage, &region.extents) == PIXMAN_REGION_IN);
 			*damage = NULL;
 		} else
 			*damage = &priv->cpu_damage;
@@ -5448,6 +5448,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		goto fallback;
 	}
 
+		goto fallback;
 	if (priv->gpu_damage || (priv->cpu_damage == NULL && priv->gpu_bo)) {
 		assert(priv->gpu_bo);
 
@@ -5709,8 +5710,8 @@ sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu,
 		return false;
 	}
 
-	assert(sna_damage_contains_box__offset(src_priv->gpu_damage, &region->extents, dx, dy) == PIXMAN_REGION_IN);
-	assert(sna_damage_contains_box__offset(src_priv->cpu_damage, &region->extents, dx, dy) == PIXMAN_REGION_OUT);
+	assert(sna_damage_contains_box__offset(&src_priv->gpu_damage, &region->extents, dx, dy) == PIXMAN_REGION_IN);
+	assert(sna_damage_contains_box__offset(&src_priv->cpu_damage, &region->extents, dx, dy) == PIXMAN_REGION_OUT);
 
 	ptr = kgem_bo_map__cpu(&sna->kgem, src_priv->gpu_bo);
 	if (ptr == NULL) {
@@ -16195,8 +16196,8 @@ sna_get_image__inplace(PixmapPtr pixmap,
 	if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ))
 		return false;
 
-	assert(sna_damage_contains_box(priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
-	assert(sna_damage_contains_box(priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
+	assert(sna_damage_contains_box(&priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
+	assert(sna_damage_contains_box(&priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
 
 	src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
 	if (src == NULL)
@@ -16286,8 +16287,8 @@ sna_get_image__blt(PixmapPtr pixmap,
 
 	DBG(("%s: download through a temporary map\n", __FUNCTION__));
 
-	assert(sna_damage_contains_box(priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
-	assert(sna_damage_contains_box(priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
+	assert(sna_damage_contains_box(&priv->gpu_damage, &region->extents) == PIXMAN_REGION_IN);
+	assert(sna_damage_contains_box(&priv->cpu_damage, &region->extents) == PIXMAN_REGION_OUT);
 
 	pitch = PixmapBytePad(region->extents.x2 - region->extents.x1,
 			      pixmap->drawable.depth);
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index ffbd74d..ec95fff 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -1342,15 +1342,13 @@ fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage
 }
 #endif
 
-static int __sna_damage_contains_box(struct sna_damage *damage,
+static int __sna_damage_contains_box(struct sna_damage **_damage,
 				     const BoxRec *box)
 {
+	struct sna_damage *damage = *_damage;
 	const BoxRec *b;
 	int n, count, ret;
 
-	if (!damage)
-		return PIXMAN_REGION_OUT;
-
 	if (damage->mode == DAMAGE_ALL)
 		return PIXMAN_REGION_IN;
 
@@ -1390,18 +1388,24 @@ static int __sna_damage_contains_box(struct sna_damage *damage,
 	}
 
 	__sna_damage_reduce(damage);
+	if (!pixman_region_not_empty(&damage->region)) {
+		__sna_damage_destroy(damage);
+		*_damage = NULL;
+		return PIXMAN_REGION_OUT;
+	}
+
 	return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
 }
 
 #if HAS_DEBUG_FULL
-int _sna_damage_contains_box(struct sna_damage *damage,
+int _sna_damage_contains_box(struct sna_damage **damage,
 			     const BoxRec *box)
 {
 	char damage_buf[1000];
 	int ret;
 
 	DBG(("%s(%s, [(%d, %d), (%d, %d)])\n", __FUNCTION__,
-	     _debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
+	     _debug_describe_damage(damage_buf, sizeof(damage_buf), *damage),
 	     box->x1, box->y1, box->x2, box->y2));
 
 	ret = __sna_damage_contains_box(damage, box);
@@ -1414,7 +1418,7 @@ int _sna_damage_contains_box(struct sna_damage *damage,
 	return ret;
 }
 #else
-int _sna_damage_contains_box(struct sna_damage *damage,
+int _sna_damage_contains_box(struct sna_damage **damage,
 			     const BoxRec *box)
 {
 	return __sna_damage_contains_box(damage, box);
diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 9b6f213..4e4ef2b 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -207,23 +207,27 @@ sna_damage_overlaps_box(const struct sna_damage *damage,
 	return true;
 }
 
-int _sna_damage_contains_box(struct sna_damage *damage,
+int _sna_damage_contains_box(struct sna_damage **damage,
 			     const BoxRec *box);
-static inline int sna_damage_contains_box(struct sna_damage *damage,
+static inline int sna_damage_contains_box(struct sna_damage **damage,
 					  const BoxRec *box)
 {
-	if (DAMAGE_IS_ALL(damage))
+	if (DAMAGE_IS_ALL(*damage))
 		return PIXMAN_REGION_IN;
+	if (*damage == NULL)
+		return PIXMAN_REGION_OUT;
 
 	return _sna_damage_contains_box(damage, box);
 }
-static inline int sna_damage_contains_box__offset(struct sna_damage *damage,
+static inline int sna_damage_contains_box__offset(struct sna_damage **damage,
 						  const BoxRec *box, int dx, int dy)
 {
 	BoxRec b;
 
-	if (DAMAGE_IS_ALL(damage))
+	if (DAMAGE_IS_ALL(*damage))
 		return PIXMAN_REGION_IN;
+	if (*damage == NULL)
+		return PIXMAN_REGION_OUT;
 
 	b = *box;
 	b.x1 += dx; b.x2 += dx;
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index e58b6e1..26289e7 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -346,7 +346,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
 	}
 
 	if (priv->gpu_bo) {
-		switch (sna_damage_contains_box(priv->cpu_damage, box)) {
+		switch (sna_damage_contains_box(&priv->cpu_damage, box)) {
 		case PIXMAN_REGION_OUT:
 			DBG(("%s: has GPU bo and no damage to upload\n",
 			     __FUNCTION__));
@@ -362,7 +362,7 @@ use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt)
 				     __FUNCTION__));
 				return NULL;
 			}
-			if (sna_damage_contains_box(priv->gpu_damage,
+			if (sna_damage_contains_box(&priv->gpu_damage,
 						    box) != PIXMAN_REGION_OUT) {
 				DBG(("%s: box is damaged on the GPU\n",
 				     __FUNCTION__));
@@ -440,7 +440,7 @@ move_to_gpu(PixmapPtr pixmap, const BoxRec *box, bool blt)
 
 	if (priv->gpu_bo) {
 		if (priv->cpu_damage &&
-		    sna_damage_contains_box(priv->cpu_damage,
+		    sna_damage_contains_box(&priv->cpu_damage,
 					    box) != PIXMAN_REGION_OUT)
 			goto upload;
 
commit c9003c6d9602dba682e577ea7ce39990ea378db3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 15:29:59 2014 +0100

    sna: Fix scanout creation routine for old kernels <= 3.11
    
    With an old kernel, we would fail to actually mark the display as part
    of the scanout domain, but proceed to assign it a fb id. This caused our
    asserts to report our bookkeeping error.
    
    Reported-by: Pavel Ondračka <pavel.ondracka at email.cz>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79909
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f29f8fd..7582e07 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4373,18 +4373,23 @@ static void __kgem_bo_make_scanout(struct kgem *kgem,
 	arg.depth = scrn->depth;
 	arg.handle = bo->handle;
 
-	if (gem_set_caching(kgem->fd, bo->handle, DISPLAY)) {
-		bo->scanout = true;
+	/* First move the scanout out of cached memory */
+	if (kgem->has_llc) {
+		if (!gem_set_caching(kgem->fd, bo->handle, DISPLAY) &&
+		    !gem_set_caching(kgem->fd, bo->handle, UNCACHED))
+			return;
+	}
 
-		/* Pre-emptively move the object into the mappable
-		 * portion to avoid rebinding later when busy.
-		 */
-		if (bo->map__gtt == NULL)
-			bo->map__gtt = __kgem_bo_map__gtt(kgem, bo);
-		if (bo->map__gtt) {
-			*(uint32_t *)bo->map__gtt = 0;
-			bo->domain = DOMAIN_GTT;
-		}
+	bo->scanout = true;
+
+	/* Then pre-emptively move the object into the mappable
+	 * portion to avoid rebinding later when busy.
+	 */
+	if (bo->map__gtt == NULL)
+		bo->map__gtt = __kgem_bo_map__gtt(kgem, bo);
+	if (bo->map__gtt) {
+		*(uint32_t *)bo->map__gtt = 0;
+		bo->domain = DOMAIN_GTT;
 	}
 
 	if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0) {
commit 5705e66a329273c478f6ecd8f41b8f5633095581
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 14:34:33 2014 +0100

    sna: Add some DBG to the memmove path
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/blt.c b/src/sna/blt.c
index f861f65..b61f88b 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -796,6 +796,7 @@ memmove_box(const void *src, void *dst,
 	    const BoxRec *box,
 	    int dx, int dy)
 {
+#define FORCE_MEMMOVE 0
 	union {
 		uint8_t u8;
 		uint16_t u16;
@@ -808,6 +809,7 @@ memmove_box(const void *src, void *dst,
 
 	assert(src);
 	assert(dst);
+	assert(src != dst);
 	assert(bpp >= 8);
 	assert(box->x2 > box->x1);
 	assert(box->y2 > box->y1);
@@ -821,10 +823,11 @@ memmove_box(const void *src, void *dst,
 	width = box->y1 * stride + box->x1 * bpp;
 	src_bytes = (const uint8_t *)src + width;
 	dst_bytes = (uint8_t *)dst + width;
+	assert(dst_bytes != src_bytes);
 
 	width = (box->x2 - box->x1) * bpp;
 	height = (box->y2 - box->y1);
-	assert(width <= 8*stride);
+	assert(width <= stride);
 	if (width == stride) {
 		width *= height;
 		height = 1;
@@ -865,8 +868,9 @@ memmove_box(const void *src, void *dst,
 			break;
 
 		default:
-			if (dst_bytes < src_bytes + width &&
-			    src_bytes < dst_bytes + width) {
+			if (FORCE_MEMMOVE ||
+			    (dst_bytes < src_bytes + width &&
+			     src_bytes < dst_bytes + width)) {
 				do {
 					memmove(dst_bytes, src_bytes, width);
 					src_bytes += stride;
@@ -919,8 +923,9 @@ memmove_box(const void *src, void *dst,
 			break;
 
 		default:
-			if (dst_bytes < src_bytes + width &&
-			    src_bytes < dst_bytes + width) {
+			if (FORCE_MEMMOVE ||
+			    (dst_bytes < src_bytes + width &&
+			     src_bytes < dst_bytes + width)) {
 				do {
 					memmove(dst_bytes, src_bytes, width);
 					src_bytes -= stride;
commit b41a51e0f54c983ef72bc31125419382d666d48c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 14:22:26 2014 +0100

    sna: Tweak self-copy boxes to hit the GPU more often
    
    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 ed53fcc..65a07e3 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5443,8 +5443,10 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	if (dst != src)
 		get_drawable_deltas(dst, pixmap, &tx, &ty);
 
-	if (priv == NULL || DAMAGE_IS_ALL(priv->cpu_damage) || priv->shm)
+	if (priv == NULL || DAMAGE_IS_ALL(priv->cpu_damage)) {
+		DBG(("%s: unattached, or all damaged on CPU\n", __FUNCTION__));
 		goto fallback;
+	}
 
 	if (priv->gpu_damage || (priv->cpu_damage == NULL && priv->gpu_bo)) {
 		assert(priv->gpu_bo);
@@ -5458,6 +5460,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 			     __FUNCTION__));
 			goto fallback;
 		}
+		assert(priv->cpu_damage == NULL);
 
 		if (!sna->render.copy_boxes(sna, alu,
 					    pixmap, priv->gpu_bo, dx, dy,
@@ -5470,7 +5473,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 
 		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 			assert(!priv->clear);
-			if (priv->cpu_bo == NULL) {
+			if (sna_pixmap_free_cpu(sna, priv, false)) {
 				sna_damage_all(&priv->gpu_damage, pixmap);
 			} else {
 				RegionTranslate(region, tx, ty);
@@ -5480,7 +5483,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		assert_pixmap_damage(pixmap);
 	} else {
 fallback:
-		DBG(("%s: fallback", __FUNCTION__));
+		DBG(("%s: fallback\n", __FUNCTION__));
 		if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE))
 			goto free_boxes;
 
commit b879de6246d3f2e66e9c7e326db93e5ff390159f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 14:08:31 2014 +0100

    sna: Recheck source bo after migrating dst (in case of src == dst)
    
    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 958d4f9..f3a9cc2 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -2789,8 +2789,13 @@ fill:
 	tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint,
 					  &dst_box, &tmp->damage);
 
-	if (tmp->dst.bo && hint & REPLACES)
-		kgem_bo_undo(&sna->kgem, tmp->dst.bo);
+	if (tmp->dst.bo && hint & REPLACES) {
+		struct sna_pixmap *priv = sna_pixmap(tmp->dst.pixmap);
+		kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
+	}
+
+	if (tmp->dst.pixmap == src_pixmap)
+		bo = __sna_render_pixmap_bo(sna, src_pixmap, &src_box, true);
 
 	ret = false;
 	if (bo) {
commit 21c150a873a77f983fad29b4517844a0b92e0609
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 14:00:04 2014 +0100

    sna: Skip redundant clears
    
    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 1b236f4..c28cbb6 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -946,6 +946,26 @@ sna_composite_rectangles(CARD8		 op,
 	 */
 	hint = can_render(sna) ? PREFER_GPU : 0;
 	if (op <= PictOpSrc) {
+		if (priv->clear) {
+			uint32_t pixel;
+			bool ok;
+
+			if (op == PictOpClear) {
+				ok = sna_get_pixel_from_rgba(&pixel,
+							     0, 0, 0, 0,
+							     dst->format);
+			} else {
+				ok = sna_get_pixel_from_rgba(&pixel,
+							     color->red,
+							     color->green,
+							     color->blue,
+							     color->alpha,
+							     dst->format);
+			}
+			if (ok && priv->clear_color == pixel)
+				goto done;
+		}
+
 		if (region.data == NULL) {
 			hint |= IGNORE_CPU;
 			if (region_subsumes_drawable(&region, &pixmap->drawable))
commit e1a4438f074f9cd5eba946cc1172c419c31b03c9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 13:59:46 2014 +0100

    sna/glyphs: Always print some DBG when performing fallback
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 93aac34..5d8dd78 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1602,14 +1602,14 @@ glyphs_fallback(CARD8 op,
 	int x, y, n;
 
 	glyph_extents(nlist, list, glyphs, &region.extents);
-	if (region.extents.x2 <= region.extents.x1 ||
-	    region.extents.y2 <= region.extents.y1)
-		return;
-
 	DBG(("%s: (%d, %d), (%d, %d)\n", __FUNCTION__,
 	     region.extents.x1, region.extents.y1,
 	     region.extents.x2, region.extents.y2));
 
+	if (region.extents.x2 <= region.extents.x1 ||
+	    region.extents.y2 <= region.extents.y1)
+		return;
+
 	region.data = NULL;
 	RegionTranslate(&region, dst->pDrawable->x, dst->pDrawable->y);
 	RegionIntersect(&region, &region, dst->pCompositeClip);
commit 040eccb9b10d0941c7d81fc9c66c259563370f2a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jun 11 13:18:33 2014 +0100

    sna: Add some asserts to track redundant damage operations
    
    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 75a65f4..958d4f9 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -3631,6 +3631,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, nbox,
 	    src_bo->tiling, dst_bo->tiling,
 	    src_bo->pitch, dst_bo->pitch));
+	assert(nbox);
 
 	if (wedged(sna) || !kgem_bo_can_blt(kgem, src_bo) || !kgem_bo_can_blt(kgem, dst_bo)) {
 		DBG(("%s: cannot blt to src? %d or dst? %d\n",
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index 8c041de..ffbd74d 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -370,6 +370,7 @@ _sna_damage_create_elt(struct sna_damage *damage,
 
 	DBG(("    %s: prev=(remain %d), count=%d\n",
 	     __FUNCTION__, damage->remain, count));
+	assert(count);
 
 restart:
 	n = count;
@@ -421,6 +422,7 @@ _sna_damage_create_elt_from_boxes(struct sna_damage *damage,
 	int i, n;
 
 	DBG(("    %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
+	assert(count);
 
 restart:
 	n = count;
@@ -483,6 +485,7 @@ _sna_damage_create_elt_from_rectangles(struct sna_damage *damage,
 
 	DBG(("    %s: prev=(remain %d), count=%d\n",
 	     __FUNCTION__, damage->remain, count));
+	assert(count);
 
 restart:
 	n = count;
@@ -545,6 +548,7 @@ _sna_damage_create_elt_from_points(struct sna_damage *damage,
 
 	DBG(("    %s: prev=(remain %d), count=%d\n",
 	     __FUNCTION__, damage->remain, count));
+	assert(count);
 
 restart:
 	n = count;
@@ -1532,6 +1536,9 @@ static int __sna_damage_get_boxes(struct sna_damage *damage, BoxPtr *boxes)
 	if (damage->dirty)
 		__sna_damage_reduce(damage);
 
+	assert(!damage->dirty);
+	assert(damage->mode == DAMAGE_ADD);
+
 	*boxes = region_rects(&damage->region);
 	return region_num_rects(&damage->region);
 }
@@ -1541,6 +1548,10 @@ struct sna_damage *_sna_damage_reduce(struct sna_damage *damage)
 	DBG(("%s\n", __FUNCTION__));
 
 	__sna_damage_reduce(damage);
+
+	assert(!damage->dirty);
+	assert(damage->mode == DAMAGE_ADD);
+
 	if (!pixman_region_not_empty(&damage->region)) {
 		__sna_damage_destroy(damage);
 		damage = NULL;


More information about the xorg-commit mailing list