xf86-video-intel: 2 commits - src/sna/sna_accel.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 13 02:19:41 PST 2012


 src/sna/sna_accel.c |   33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

New commits:
commit 94217a4dd908f1368dfdef90797ce74a081663fb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 13 10:03:28 2012 +0000

    sna: Decouple dirty pixmaps from list if we fail to upload them
    
    Rather than iterate endlessly trying to upload the same pixmap when
    failing to flush dirty CPU damage, try again on the next flush.
    
    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 e0709b6..9f60605 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -9657,6 +9657,7 @@ sna_accel_flush_callback(CallbackListPtr *list,
 			 pointer user_data, pointer call_data)
 {
 	struct sna *sna = user_data;
+	struct list preserve;
 
 	if ((sna->kgem.sync|sna->kgem.flush) == 0 &&
 	    list_is_empty(&sna->dirty_pixmaps))
@@ -9665,12 +9666,20 @@ sna_accel_flush_callback(CallbackListPtr *list,
 	DBG(("%s\n", __FUNCTION__));
 
 	/* flush any pending damage from shadow copies to tfp clients */
+	list_init(&preserve);
 	while (!list_is_empty(&sna->dirty_pixmaps)) {
 		struct sna_pixmap *priv = list_first_entry(&sna->dirty_pixmaps,
 							   struct sna_pixmap,
 							   list);
 		assert(priv->cpu_damage != NULL);
-		sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ);
+		if (!sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ))
+			list_move(&priv->list, &preserve);
+	}
+	if (!list_is_empty(&preserve)) {
+		sna->dirty_pixmaps.next = preserve.next;
+		preserve.next->prev = &sna->dirty_pixmaps;
+		preserve.prev->next = &sna->dirty_pixmaps;
+		sna->dirty_pixmaps.prev = preserve.prev;
 	}
 
 	kgem_submit(&sna->kgem);
commit 65ef369c733ab45945a7d5fe4b76fe5c7167b51b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 13 09:58:40 2012 +0000

    sna: Decouple from CPU dirty list after removing all CPU damage
    
    In the paths where we discard CPU damage, we also need to remove it
    from the dirty list so that we do not iterate over it during flush.
    
    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 3c2ac44..e0709b6 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -764,6 +764,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 
 		sna_damage_destroy(&priv->cpu_damage);
 		sna_damage_destroy(&priv->gpu_damage);
+		list_del(&priv->list);
 
 		if (priv->stride && priv->gpu_bo &&
 		    pixmap_inplace(sna, pixmap, priv)) {
@@ -1788,7 +1789,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	if (DAMAGE_IS_ALL(priv->gpu_damage)) {
 		DBG(("%s: already all-damaged\n", __FUNCTION__));
-		goto done;
+		goto active;
 	}
 
 	if ((flags & MOVE_READ) == 0)
@@ -1864,12 +1865,13 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	__sna_damage_destroy(DAMAGE_PTR(priv->cpu_damage));
 	priv->cpu_damage = NULL;
+done:
 	list_del(&priv->list);
 
-done:
 	sna_damage_reduce_all(&priv->gpu_damage,
 			      pixmap->drawable.width,
 			      pixmap->drawable.height);
+active:
 	if (!priv->pinned)
 		list_move(&priv->inactive, &sna->active_pixmaps);
 	return priv;
@@ -2179,9 +2181,10 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 	    sna_put_image_upload_blt(drawable, gc, region,
 				     x, y, w, h, bits, stride)) {
 		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-			if (region_subsumes_drawable(region, &pixmap->drawable))
+			if (region_subsumes_drawable(region, &pixmap->drawable)) {
 				sna_damage_destroy(&priv->cpu_damage);
-			else
+				list_del(&priv->list);
+			} else
 				sna_damage_subtract(&priv->cpu_damage, region);
 			if (priv->cpu_damage == NULL)
 				sna_damage_all(&priv->gpu_damage,
@@ -2220,9 +2223,10 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 				if (sna_put_image_upload_blt(drawable, gc, region,
 							     x, y, w, h, bits, stride)) {
 					if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-						if (region_subsumes_drawable(region, &pixmap->drawable))
+						if (region_subsumes_drawable(region, &pixmap->drawable)) {
 							sna_damage_destroy(&priv->cpu_damage);
-						else
+							list_del(&priv->list);
+						} else
 							sna_damage_subtract(&priv->cpu_damage, region);
 						if (priv->cpu_damage == NULL)
 							sna_damage_all(&priv->gpu_damage,
@@ -2240,8 +2244,10 @@ sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 					if (!sna_pixmap_move_to_gpu(pixmap,
 								    MOVE_WRITE))
 						return false;
-				} else
+				} else {
 					sna_damage_destroy(&priv->cpu_damage);
+					list_del(&priv->list);
+				}
 
 				sna_pixmap_free_cpu(sna, priv);
 			}
@@ -9957,6 +9963,8 @@ static void sna_accel_inactive(struct sna *sna)
 			DBG(("%s: discarding inactive CPU shadow\n",
 			     __FUNCTION__));
 			sna_damage_destroy(&priv->cpu_damage);
+			list_del(&priv->list);
+
 			sna_pixmap_free_cpu(sna, priv);
 			list_add(&priv->inactive, &preserve);
 		} else {


More information about the xorg-commit mailing list