xf86-video-intel: src/sna/sna_dri2.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Jun 30 08:43:34 PDT 2014


 src/sna/sna_dri2.c |   70 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 53 insertions(+), 17 deletions(-)

New commits:
commit 6c3399715e316be970c696b8949e3c14e83ea5df
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 30 16:32:45 2014 +0100

    sna/dri2: Apply the paraniod buffer clip in the correct coordinate system
    
    We need to only clip to the extents of the copy in the buffer space -
    which implies that we need to translate the region into that space before
    doing the clip.
    
    Reported-by: Ilia Mirkin <imirkin at alum.mit.edu>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 80429eb..000ebcf 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -867,7 +867,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	struct kgem_bo *dst_bo;
 	const BoxRec *boxes;
 	int16_t dx, dy, sx, sy;
-	int w, h, n;
+	int n;
 
 	/* To hide a stale DRI2Buffer, one may choose to substitute
 	 * pixmap->gpu_bo instead of dst/src->bo, however you then run
@@ -882,23 +882,10 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	assert(is_front(dst->attachment) || is_front(src->attachment));
 	assert(dst->attachment != src->attachment);
 
-	/* Copy the minimum of the Drawable / src / dst extents */
-	w = draw->width;
-	if ((src_priv->size & 0xffff) < w)
-		w = src_priv->size & 0xffff;
-	if ((dst_priv->size & 0xffff) < w)
-		w = dst_priv->size & 0xffff;
-
-	h = draw->height;
-	if ((src_priv->size >> 16) < h)
-		h = src_priv->size >> 16;
-	if ((dst_priv->size >> 16) < h)
-		h = dst_priv->size >> 16;
-
 	clip.extents.x1 = draw->x;
 	clip.extents.y1 = draw->y;
-	clip.extents.x2 = draw->x + w;
-	clip.extents.y2 = draw->y + h;
+	clip.extents.x2 = draw->x + draw->width;
+	clip.extents.y2 = draw->y + draw->height;
 	clip.data = NULL;
 
 	if (region) {
@@ -968,6 +955,30 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		DBG(("%s: updated FrontLeft src_bo from handle=%d to handle=%d\n",
 		     __FUNCTION__, src_priv->bo->handle, src_bo->handle));
 		assert(src_bo->refcnt);
+	} else {
+		bool changed = false;
+
+		DBG(("%s: source size %dx%d, region size %dx%d\n",
+		     __FUNCTION__,
+		     src_priv->size & 0xffff, src_priv->size >> 16,
+		     (region ?: &clip)->extents.x2 - (region ?: &clip)->extents.x1,
+		     (region ?: &clip)->extents.y2 - (region ?: &clip)->extents.y1));
+
+		assert(sx + clip.extents.x1 >= 0);
+		assert(sy + clip.extents.y1 >= 0);
+
+		if (sx + clip.extents.x2 > (src_priv->size & 0xffff)) {
+			clip.extents.x2 = (src_priv->size & 0xffff) - sx;
+			changed = !!region;
+		}
+
+		if (sy + clip.extents.y2 > (src_priv->size >> 16)) {
+			clip.extents.y2 = (src_priv->size >> 16) - sy;
+			changed = !!region;
+		}
+
+		if (changed)
+			pixman_region_intersect(region, &clip, region);
 	}
 
 	dst_bo = dst_priv->bo;
@@ -988,8 +999,33 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		DBG(("%s: updated FrontLeft dst_bo from handle=%d to handle=%d\n",
 		     __FUNCTION__, dst_priv->bo->handle, dst_bo->handle));
 		assert(dst_bo->refcnt);
-	} else
+	} else {
+		bool changed = false;
+
+		DBG(("%s: target size %dx%d, region size %dx%d\n",
+		     __FUNCTION__,
+		     dst_priv->size & 0xffff, dst_priv->size >> 16,
+		     (region ?: &clip)->extents.x2 - (region ?: &clip)->extents.x1,
+		     (region ?: &clip)->extents.y2 - (region ?: &clip)->extents.y1));
+
+		assert(dx + clip.extents.x1 >= 0);
+		assert(dy + clip.extents.y1 >= 0);
+
+		if (dx + clip.extents.x2 > (dst_priv->size & 0xffff)) {
+			clip.extents.x2 = (dst_priv->size & 0xffff) - dx;
+			changed = !!region;
+		}
+
+		if (dy + clip.extents.y2 > (dst_priv->size >> 16)) {
+			clip.extents.y2 = (dst_priv->size >> 16) - dy;
+			changed = !!region;
+		}
+
+		if (changed)
+			pixman_region_intersect(region, &clip, region);
+
 		sync = false;
+	}
 
 	if (!wedged(sna)) {
 		xf86CrtcPtr crtc;


More information about the xorg-commit mailing list