xf86-video-intel: 3 commits - src/sna/gen4_render.c src/sna/gen5_render.c src/sna/gen6_render.c src/sna/sna_display.c src/sna/sna_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Jun 25 12:38:35 PDT 2011


 src/sna/gen4_render.c |    4 -
 src/sna/gen5_render.c |    8 +-
 src/sna/gen6_render.c |    8 +-
 src/sna/sna_display.c |    3 
 src/sna/sna_dri.c     |  157 +++++++++++++++++++++++---------------------------
 5 files changed, 89 insertions(+), 91 deletions(-)

New commits:
commit b460b9645451af84136c5daebbc00c7545de67f4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 25 16:34:15 2011 +0100

    sna/dri: Fix composited copy-swaps
    
    The secret is not to cheat and render directly to the front buffer, but
    remember to mark the Window as damaged.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 3a8a753..510ddd1 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -324,52 +324,24 @@ static void sna_dri_reference_buffer(DRI2Buffer2Ptr buffer)
 static void damage(DrawablePtr drawable, PixmapPtr pixmap, RegionPtr region)
 {
 	struct sna_pixmap *priv;
-	int16_t dx, dy;
-
-	get_drawable_deltas(drawable, pixmap, &dx, &dy);
+	BoxPtr box;
 
 	priv = sna_pixmap(pixmap);
 	if (priv->gpu_only)
 		return;
 
-	if (region) {
-		BoxPtr box;
-
-		RegionTranslate(region, dx, dy);
-		box = RegionExtents(region);
-		if (RegionNumRects(region) == 1 &&
-		    box->x1 <= 0 && box->y1 <= 0 &&
-		    box->x2 >= pixmap->drawable.width &&
-		    box->y2 >= pixmap->drawable.height) {
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
-			sna_damage_destroy(&priv->cpu_damage);
-		} else {
-			sna_damage_add(&priv->gpu_damage, region);
-			sna_damage_subtract(&priv->cpu_damage, region);
-		}
-
-		RegionTranslate(region, -dx, -dy);
+	box = RegionExtents(region);
+	if (RegionNumRects(region) == 1 &&
+	    box->x1 <= 0 && box->y1 <= 0 &&
+	    box->x2 >= pixmap->drawable.width &&
+	    box->y2 >= pixmap->drawable.height) {
+		sna_damage_all(&priv->gpu_damage,
+			       pixmap->drawable.width,
+			       pixmap->drawable.height);
+		sna_damage_destroy(&priv->cpu_damage);
 	} else {
-		BoxRec box;
-
-		box.x1 = drawable->x + dx;
-		box.x2 = box.x1 + drawable->width;
-
-		box.y1 = drawable->y + dy;
-		box.y2 = box.y1 + drawable->height;
-		if (box.x1 == 0 && box.y1 == 0 &&
-		    box.x2 == pixmap->drawable.width &&
-		    box.y2 == pixmap->drawable.height) {
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
-			sna_damage_destroy(&priv->cpu_damage);
-		} else {
-			sna_damage_add_box(&priv->gpu_damage, &box);
-			sna_damage_subtract_box(&priv->gpu_damage, &box);
-		}
+		sna_damage_add(&priv->gpu_damage, region);
+		sna_damage_subtract(&priv->cpu_damage, region);
 	}
 }
 
@@ -386,7 +358,7 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	pixman_region16_t clip;
 	bool flush = false;
 	BoxRec box, *boxes;
-	int16_t dx, dy;
+	int16_t dx, dy, sx, sy;
 	int n;
 
 	DBG(("%s: dst -- attachment=%d, name=%d, handle=%d [screen=%d]\n",
@@ -400,58 +372,71 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	     src_buffer->attachment,
 	     src_buffer->name,
 	     src_priv->bo->handle));
+	if (region) {
+		DBG(("%s: clip (%d, %d), (%d, %d) x %d\n",
+		     __FUNCTION__,
+		     region->extents.x1, region->extents.y1,
+		     region->extents.x2, region->extents.y2,
+		     REGION_NUM_RECTS(region)));
+	}
 
-	if (draw->type == DRAWABLE_PIXMAP) {
-		if (region) {
-			boxes = REGION_RECTS(region);
-			n = REGION_NUM_RECTS(region);
-			if (n == 0)
-				return;
-		} else {
-			box.x1 = box.y1 = 0;
-			box.x2 = draw->width;
-			box.y2 = draw->height;
+	box.x1 = draw->x;
+	box.y1 = draw->y;
+	box.x2 = draw->x + draw->width;
+	box.y2 = draw->y + draw->height;
+
+	get_drawable_deltas(draw, src, &sx, &sy);
+	sx -= draw->x;
+	sy -= draw->y;
+
+	if (region) {
+		pixman_region_translate(region, draw->x, draw->y);
+		pixman_region_init_rects(&clip, &box, 1);
+		pixman_region_intersect(&clip, &clip, region);
+		region = &clip;
 
-			boxes = &box;
-			n = 1;
+		if (!pixman_region_not_empty(region)) {
+			DBG(("%s: all clipped\n", __FUNCTION__));
+			return;
 		}
-		dx = dy = 0;
-	} else {
+	}
+
+	dx = dy = 0;
+	if (draw->type != DRAWABLE_PIXMAP) {
 		WindowPtr win = (WindowPtr)draw;
 
-		DBG(("%s: draw=(%d, %d), delta=(%d, %d)\n",
+		DBG(("%s: draw=(%d, %d), delta=(%d, %d), clip.extents=(%d, %d), (%d, %d)\n",
 		     __FUNCTION__, draw->x, draw->y,
-		     get_drawable_dx(draw), get_drawable_dy(draw)));
-		if (region) {
-			pixman_region_translate(region, draw->x, draw->y);
-
-			pixman_region_init(&clip);
-			pixman_region_intersect(&clip, &win->clipList, region);
-			if (!pixman_region_not_empty(&clip)) {
-				DBG(("%s: all clipped\n", __FUNCTION__));
-				return;
-			}
-			region = &clip;
+		     get_drawable_dx(draw), get_drawable_dy(draw),
+		     win->clipList.extents.x1, win->clipList.extents.y1,
+		     win->clipList.extents.x2, win->clipList.extents.y2));
 
-			boxes = REGION_RECTS(region);
-			n = REGION_NUM_RECTS(region);
-		} else {
-			boxes = REGION_RECTS(&win->clipList);
-			n = REGION_NUM_RECTS(&win->clipList);
-			region = &win->clipList;
+		if (region == NULL) {
+			pixman_region_init_rects(&clip, &box, 1);
+			region = &clip;
 		}
-		if (n == 0)
+
+		pixman_region_intersect(region, &win->clipList, region);
+		if (!pixman_region_not_empty(region)) {
+			DBG(("%s: all clipped\n", __FUNCTION__));
 			return;
+		}
 
-		if (sync)
-			flush = sna_wait_for_scanline(sna, sna->front, NULL,
+		if (dst == sna->front && sync)
+			flush = sna_wait_for_scanline(sna, dst, NULL,
 						      &region->extents);
 
-		dst = sna->front;
-		dst_bo = sna_pixmap_get_bo(sna->front);
 		get_drawable_deltas(draw, dst, &dx, &dy);
 	}
 
+	if (region) {
+		boxes = REGION_RECTS(region);
+		n = REGION_NUM_RECTS(region);
+		assert(n);
+	} else {
+		boxes = &box;
+		n = 1;
+	}
 	/* It's important that this copy gets submitted before the
 	 * direct rendering client submits rendering for the next
 	 * frame, but we don't actually need to submit right now.  The
@@ -463,16 +448,21 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	 * again.
 	 */
 	sna->render.copy_boxes(sna, GXcopy,
-			       src, src_priv->bo, -draw->x, -draw->y,
+			       src, src_priv->bo, sx, sy,
 			       dst, dst_bo, dx, dy,
 			       boxes, n);
 
-	damage(draw, dst, region);
-
 	DBG(("%s: flushing? %d\n", __FUNCTION__, flush));
 	if (flush) /* STAT! */
 		kgem_submit(&sna->kgem);
 
+	if (region) {
+		pixman_region_translate(region, dx, dy);
+		DamageRegionAppend(&dst->drawable, region);
+		DamageRegionProcessPending(&dst->drawable);
+		damage(draw, dst, region);
+	}
+
 	if (region == &clip)
 		pixman_region_fini(&clip);
 }
@@ -1427,8 +1417,7 @@ sna_dri_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
 	if (pipe > 0)
 		vbl.request.type |= DRM_VBLANK_SECONDARY;
 
-	vbl.request.sequence = current_msc - (current_msc % divisor) +
-	    remainder;
+	vbl.request.sequence = current_msc - current_msc % divisor + remainder;
 
 	/*
 	 * If calculated remainder is larger than requested remainder,
@@ -1437,7 +1426,7 @@ sna_dri_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
 	 * that will happen.
 	 */
 	if ((current_msc % divisor) >= remainder)
-	    vbl.request.sequence += divisor;
+		vbl.request.sequence += divisor;
 
 	vbl.request.signal = (unsigned long)info;
 	if (drmWaitVBlank(sna->kgem.fd, &vbl)) {
commit 28fffbd1d07890c8b4d697369159f6a30f267675
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 25 16:33:31 2011 +0100

    sna/display: Protect against drmModeGetCrtc returning NULL
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 285a39b..1586884 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -526,6 +526,9 @@ void sna_copy_fbcon(struct sna *sna)
 
 		mode_crtc = drmModeGetCrtc(sna->kgem.fd,
 					   sna->mode.mode_res->crtcs[crtc->num]);
+		if (mode_crtc == NULL)
+			continue;
+
 		if (mode_crtc->buffer_id)
 			fbcon = drmModeGetFB(sna->kgem.fd,
 					     mode_crtc->buffer_id);
commit 2c73b4651a04390668c3ed2aa10699663e44fd8a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 25 16:32:30 2011 +0100

    sna/gen4+: Use the drawable rectangle offset for copy boxes
    
    Saves a little bit of work whilst emitting the rectangles.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 1037deb..434de07 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -2194,6 +2194,8 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
+	tmp.dst.x = dst_dx;
+	tmp.dst.y = dst_dy;
 
 	tmp.src.bo = src_bo;
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
@@ -2225,7 +2227,7 @@ gen4_render_copy_boxes(struct sna *sna, uint8_t alu,
 		gen4_render_copy_one(sna, &tmp,
 				     box->x1 + src_dx, box->y1 + src_dy,
 				     box->x2 - box->x1, box->y2 - box->y1,
-				     box->x1 + dst_dx, box->y1 + dst_dy);
+				     box->x1, box->y1);
 		box++;
 	} while (--n);
 
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index a029d18..aa8fc18 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -2132,6 +2132,8 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
+	tmp.dst.x = dst_dx;
+	tmp.dst.y = dst_dy;
 
 	tmp.src.bo = src_bo;
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
@@ -2173,15 +2175,15 @@ gen5_render_copy_boxes(struct sna *sna, uint8_t alu,
 			     box->x1 + src_dx, box->y1 + src_dy,
 			     box->x1 + dst_dx, box->y1 + dst_dy,
 			     box->x2 - box->x1, box->y2 - box->y1));
-			OUT_VERTEX(box->x2 + dst_dx, box->y2 + dst_dy);
+			OUT_VERTEX(box->x2, box->y2);
 			OUT_VERTEX_F((box->x2 + src_dx) * tmp.src.scale[0]);
 			OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]);
 
-			OUT_VERTEX(box->x1 + dst_dx, box->y2 + dst_dy);
+			OUT_VERTEX(box->x1, box->y2);
 			OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]);
 			OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]);
 
-			OUT_VERTEX(box->x1 + dst_dx, box->y1 + dst_dy);
+			OUT_VERTEX(box->x1, box->y1);
 			OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]);
 			OUT_VERTEX_F((box->y1 + src_dy) * tmp.src.scale[1]);
 
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 2f0879e..bd0f8c4 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -2332,6 +2332,8 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 	tmp.dst.height = dst->drawable.height;
 	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
 	tmp.dst.bo = dst_bo;
+	tmp.dst.x = dst_dx;
+	tmp.dst.y = dst_dy;
 
 	tmp.src.bo = src_bo;
 	tmp.src.filter = SAMPLER_FILTER_NEAREST;
@@ -2385,9 +2387,9 @@ gen6_render_copy_boxes(struct sna *sna, uint8_t alu,
 			     box->x1 + src_dx, box->y1 + src_dy,
 			     box->x1 + dst_dx, box->y1 + dst_dy,
 			     box->x2 - box->x1, box->y2 - box->y1));
-			v[0] = pack_2s(box->x2 + dst_dx, box->y2 + dst_dy);
-			v[3] = pack_2s(box->x1 + dst_dx, box->y2 + dst_dy);
-			v[6] = pack_2s(box->x1 + dst_dx, box->y1 + dst_dy);
+			v[0] = pack_2s(box->x2, box->y2);
+			v[3] = pack_2s(box->x1, box->y2);
+			v[6] = pack_2s(box->x1, box->y1);
 
 			v[1] = (box->x2 + src_dx) * tmp.src.scale[0];
 			v[7] = v[4] = (box->x1 + src_dx) * tmp.src.scale[0];


More information about the xorg-commit mailing list