xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_damage.c src/sna/sna_damage.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Dec 23 19:29:48 PST 2011


 src/sna/kgem.c       |   56 ++++++-
 src/sna/sna_accel.c  |    4 
 src/sna/sna_damage.c |  402 +++++++++++++++++++--------------------------------
 src/sna/sna_damage.h |   16 +-
 4 files changed, 215 insertions(+), 263 deletions(-)

New commits:
commit 098592ca5d79af2e4bdcd82ee598c4b2ba08df6b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 02:49:24 2011 +0000

    sna: Remove the independent tracking of elts from boxes
    
    Following the switch to a global mode for damage, the elts array became
    redundant and all that is required is the list of boxes.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c
index b194e93..85d9d69 100644
--- a/src/sna/sna_damage.c
+++ b/src/sna/sna_damage.c
@@ -125,15 +125,17 @@ static const char *_debug_describe_damage(char *buf, int max,
 		snprintf(buf, max, "[[(%d, %d), (%d, %d)]: all]",
 			 damage->extents.x1, damage->extents.y1,
 			 damage->extents.x2, damage->extents.y2);
-		assert(damage->n == 0);
 	} else {
-		sprintf(damage_str, "[%d : ...]", damage->n);
-		snprintf(buf, max, "[[(%d, %d), (%d, %d)]:  %s %c %s]",
+		if (damage->dirty) {
+			sprintf(damage_str, "%c[ ...]",
+				damage->mode == DAMAGE_SUBTRACT ? '-' : '+');
+		} else
+			damage_str = "";
+		snprintf(buf, max, "[[(%d, %d), (%d, %d)]: %s %s]",
 			 damage->extents.x1, damage->extents.y1,
 			 damage->extents.x2, damage->extents.y2,
 			 _debug_describe_region(region_str, str_max,
 						&damage->region),
-			 damage->mode == DAMAGE_SUBTRACT ? '-' : '+',
 			 damage_str);
 	}
 
@@ -142,15 +144,17 @@ static const char *_debug_describe_damage(char *buf, int max,
 
 #endif
 
-struct sna_damage_box {
-	struct list list;
-	uint16_t size, remain;
-};
+static struct sna_damage_box *
+reset_embedded_box(struct sna_damage *damage)
+{
+	damage->dirty = false;
+	damage->box = damage->embedded_box.box;
+	damage->embedded_box.size =
+		damage->remain = ARRAY_SIZE(damage->embedded_box.box);
+	list_init(&damage->embedded_box.list);
 
-struct sna_damage_elt {
-	BoxPtr box;
-	uint16_t n;
-};
+	return (struct sna_damage_box *)&damage->embedded_box;
+}
 
 static struct sna_damage *_sna_damage_create(void)
 {
@@ -164,80 +168,62 @@ static struct sna_damage *_sna_damage_create(void)
 		if (damage == NULL)
 			return NULL;
 	}
-	list_init(&damage->boxes);
-	damage->last_box = NULL;
+	reset_embedded_box(damage);
 	damage->mode = DAMAGE_ADD;
 	pixman_region_init(&damage->region);
 	damage->extents.x1 = damage->extents.y1 = MAXSHORT;
 	damage->extents.x2 = damage->extents.y2 = MINSHORT;
 
-	damage->n = 0;
-	damage->size = 16;
-	damage->elts = malloc(sizeof(*damage->elts) * damage->size);
-	if (damage->elts == NULL) {
-		__freed_damage = damage;
-		return NULL;
-	}
-
 	return damage;
 }
 
-static BoxPtr _sna_damage_create_boxes(struct sna_damage *damage,
-				       int count)
+struct sna_damage_box {
+	struct list list;
+	int size;
+};
+
+static bool _sna_damage_create_boxes(struct sna_damage *damage,
+				     int count)
 {
 	struct sna_damage_box *box;
 	int n;
 
-	if (damage->last_box && damage->last_box->remain >= count) {
-		box = damage->last_box;
-		n = box->size - box->remain;
-		DBG(("    %s(%d): reuse last box, used=%d, remain=%d\n",
-		     __FUNCTION__, count, n, box->remain));
-		box->remain -= count;
-		if (box->remain == 0)
-			damage->last_box = NULL;
-		return (BoxPtr)(box+1) + n;
-	}
-
-	n = ALIGN(count, 64);
+	box = list_entry(damage->embedded_box.list.prev,
+			 struct sna_damage_box,
+			 list);
+	n = 2*box->size;
+	if (n < count)
+		n = ALIGN(count, 64);
 
 	DBG(("    %s(%d->%d): new\n", __FUNCTION__, count, n));
 
 	box = malloc(sizeof(*box) + sizeof(BoxRec)*n);
 	if (box == NULL)
-		return NULL;
+		return false;
 
-	box->size = n;
-	box->remain = n - count;
-	list_add(&box->list, &damage->boxes);
+	list_add(&box->list, &damage->embedded_box.list);
 
-	damage->last_box = box;
-	return (BoxPtr)(box+1);
+	box->size = damage->remain = n;
+	damage->box = (BoxRec *)(box + 1);
+	return true;
 }
 
 static void
 _sna_damage_create_elt(struct sna_damage *damage,
 		       const BoxRec *boxes, int count)
 {
-	struct sna_damage_elt *elt;
-
-	DBG(("    %s: n=%d, prev=(remain %d)\n", __FUNCTION__,
-	     damage->n,
-	     damage->last_box ? damage->last_box->remain : 0));
-
-	if (damage->last_box) {
-		int n;
+	int n;
 
-		n = count;
-		if (n > damage->last_box->remain)
-			n = damage->last_box->remain;
+	DBG(("    %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
 
-		elt = damage->elts + damage->n-1;
-		memcpy(elt->box + elt->n, boxes, n * sizeof(BoxRec));
-		elt->n += n;
-		damage->last_box->remain -= n;
-		if (damage->last_box->remain == 0)
-			damage->last_box = NULL;
+	damage->dirty = true;
+	n = count;
+	if (n > damage->remain)
+		n = damage->remain;
+	if (n) {
+		memcpy(damage->box, boxes, n * sizeof(BoxRec));
+		damage->box += n;
+		damage->remain -= n;
 
 		count -=n;
 		boxes += n;
@@ -245,28 +231,14 @@ _sna_damage_create_elt(struct sna_damage *damage,
 			return;
 	}
 
-	if (damage->n == damage->size) {
-		int newsize = damage->size * 2;
-		struct sna_damage_elt *newelts = realloc(damage->elts,
-							 newsize*sizeof(*elt));
-		if (newelts == NULL)
-			return;
-
-		damage->elts = newelts;
-		damage->size = newsize;
-	}
-
 	DBG(("    %s(): new elt\n", __FUNCTION__));
 
-	elt = damage->elts + damage->n++;
-	elt->n = count;
-	elt->box = _sna_damage_create_boxes(damage, count);
-	if (elt->box == NULL){
-		damage->n--;
+	if (!_sna_damage_create_boxes(damage, count))
 		return;
-	}
 
-	 memcpy(elt->box, boxes, count * sizeof(BoxRec));
+	 memcpy(damage->box, boxes, count * sizeof(BoxRec));
+	 damage->box += count;
+	 damage->remain -= count;
 }
 
 static void
@@ -274,33 +246,22 @@ _sna_damage_create_elt_from_boxes(struct sna_damage *damage,
 				  const BoxRec *boxes, int count,
 				  int16_t dx, int16_t dy)
 {
-	struct sna_damage_elt *elt;
-	int i;
-
-	DBG(("    %s: n=%d, prev=(remain %d)\n", __FUNCTION__,
-	     damage->n,
-	     damage->last_box ? damage->last_box->remain : 0));
-
-	if (damage->last_box) {
-		int n;
-		BoxRec *b;
+	int i, n;
 
-		n = count;
-		if (n > damage->last_box->remain)
-			n = damage->last_box->remain;
+	DBG(("    %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
 
-		elt = damage->elts + damage->n-1;
-		b = elt->box + elt->n;
+	n = count;
+	if (n > damage->remain)
+		n = damage->remain;
+	if (n) {
 		for (i = 0; i < n; i++) {
-			b[i].x1 = boxes[i].x1 + dx;
-			b[i].x2 = boxes[i].x2 + dx;
-			b[i].y1 = boxes[i].y1 + dy;
-			b[i].y2 = boxes[i].y2 + dy;
+			damage->box[i].x1 = boxes[i].x1 + dx;
+			damage->box[i].x2 = boxes[i].x2 + dx;
+			damage->box[i].y1 = boxes[i].y1 + dy;
+			damage->box[i].y2 = boxes[i].y2 + dy;
 		}
-		elt->n += n;
-		damage->last_box->remain -= n;
-		if (damage->last_box->remain == 0)
-			damage->last_box = NULL;
+		damage->box += n;
+		damage->remain -= n;
 
 		count -=n;
 		boxes += n;
@@ -308,33 +269,19 @@ _sna_damage_create_elt_from_boxes(struct sna_damage *damage,
 			return;
 	}
 
-	if (damage->n == damage->size) {
-		int newsize = damage->size * 2;
-		struct sna_damage_elt *newelts = realloc(damage->elts,
-							 newsize*sizeof(*elt));
-		if (newelts == NULL)
-			return;
-
-		damage->elts = newelts;
-		damage->size = newsize;
-	}
-
 	DBG(("    %s(): new elt\n", __FUNCTION__));
 
-	elt = damage->elts + damage->n++;
-	elt->n = count;
-	elt->box = _sna_damage_create_boxes(damage, count);
-	if (elt->box == NULL) {
-		damage->n--;
+	if (!_sna_damage_create_boxes(damage, count))
 		return;
-	}
 
 	for (i = 0; i < count; i++) {
-		elt->box[i].x1 = boxes[i].x1 + dx;
-		elt->box[i].x2 = boxes[i].x2 + dx;
-		elt->box[i].y1 = boxes[i].y1 + dy;
-		elt->box[i].y2 = boxes[i].y2 + dy;
+		damage->box[i].x1 = boxes[i].x1 + dx;
+		damage->box[i].x2 = boxes[i].x2 + dx;
+		damage->box[i].y1 = boxes[i].y1 + dy;
+		damage->box[i].y2 = boxes[i].y2 + dy;
 	}
+	damage->box += i;
+	damage->remain -= i;
 }
 
 static void
@@ -342,33 +289,22 @@ _sna_damage_create_elt_from_rectangles(struct sna_damage *damage,
 				       const xRectangle *r, int count,
 				       int16_t dx, int16_t dy)
 {
-	struct sna_damage_elt *elt;
-	int i;
-
-	DBG(("    %s: n=%d, prev=(remain %d)\n", __FUNCTION__,
-	     damage->n,
-	     damage->last_box ? damage->last_box->remain : 0));
-
-	if (damage->last_box) {
-		int n;
-		BoxRec *b;
+	int i, n;
 
-		n = count;
-		if (n > damage->last_box->remain)
-			n = damage->last_box->remain;
+	DBG(("    %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
 
-		elt = damage->elts + damage->n-1;
-		b = elt->box + elt->n;
+	n = count;
+	if (n > damage->remain)
+		n = damage->remain;
+	if (n) {
 		for (i = 0; i < n; i++) {
-			b[i].x1 = r[i].x + dx;
-			b[i].x2 = b[i].x1 + r[i].width;
-			b[i].y1 = r[i].y + dy;
-			b[i].y2 = b[i].y1 + r[i].height;
+			damage->box[i].x1 = r[i].x + dx;
+			damage->box[i].x2 = damage->box[i].x1 + r[i].width;
+			damage->box[i].y1 = r[i].y + dy;
+			damage->box[i].y2 = damage->box[i].y1 + r[i].height;
 		}
-		elt->n += n;
-		damage->last_box->remain -= n;
-		if (damage->last_box->remain == 0)
-			damage->last_box = NULL;
+		damage->box += n;
+		damage->remain -= n;
 
 		count -=n;
 		r += n;
@@ -376,33 +312,19 @@ _sna_damage_create_elt_from_rectangles(struct sna_damage *damage,
 			return;
 	}
 
-	if (damage->n == damage->size) {
-		int newsize = damage->size * 2;
-		struct sna_damage_elt *newelts = realloc(damage->elts,
-							 newsize*sizeof(*elt));
-		if (newelts == NULL)
-			return;
-
-		damage->elts = newelts;
-		damage->size = newsize;
-	}
-
 	DBG(("    %s(): new elt\n", __FUNCTION__));
 
-	elt = damage->elts + damage->n++;
-	elt->n = count;
-	elt->box = _sna_damage_create_boxes(damage, count);
-	if (elt->box == NULL) {
-		damage->n--;
+	if (!_sna_damage_create_boxes(damage, count))
 		return;
-	}
 
 	for (i = 0; i < count; i++) {
-		elt->box[i].x1 = r[i].x + dx;
-		elt->box[i].x2 = elt->box[i].x1 + r[i].width;
-		elt->box[i].y1 = r[i].y + dy;
-		elt->box[i].y2 = elt->box[i].y1 + r[i].height;
+		damage->box[i].x1 = r[i].x + dx;
+		damage->box[i].x2 = damage->box[i].x1 + r[i].width;
+		damage->box[i].y1 = r[i].y + dy;
+		damage->box[i].y2 = damage->box[i].y1 + r[i].height;
 	}
+	damage->box += n;
+	damage->remain -= n;
 }
 
 static void
@@ -410,33 +332,22 @@ _sna_damage_create_elt_from_points(struct sna_damage *damage,
 				   const DDXPointRec *p, int count,
 				   int16_t dx, int16_t dy)
 {
-	struct sna_damage_elt *elt;
-	int i;
-
-	DBG(("    %s: n=%d, prev=(remain %d)\n", __FUNCTION__,
-	     damage->n,
-	     damage->last_box ? damage->last_box->remain : 0));
+	int i, n;
 
-	if (damage->last_box) {
-		int n;
-		BoxRec *b;
+	DBG(("    %s: prev=(remain %d)\n", __FUNCTION__, damage->remain));
 
-		n = count;
-		if (n > damage->last_box->remain)
-			n = damage->last_box->remain;
-
-		elt = damage->elts + damage->n-1;
-		b = elt->box + elt->n;
+	n = count;
+	if (n > damage->remain)
+		n = damage->remain;
+	if (n) {
 		for (i = 0; i < n; i++) {
-			b[i].x1 = p[i].x + dx;
-			b[i].x2 = b[i].x1 + 1;
-			b[i].y1 = p[i].y + dy;
-			b[i].y2 = b[i].y1 + 1;
+			damage->box[i].x1 = p[i].x + dx;
+			damage->box[i].x2 = damage->box[i].x1 + 1;
+			damage->box[i].y1 = p[i].y + dy;
+			damage->box[i].y2 = damage->box[i].y1 + 1;
 		}
-		elt->n += n;
-		damage->last_box->remain -= n;
-		if (damage->last_box->remain == 0)
-			damage->last_box = NULL;
+		damage->box += n;
+		damage->remain -= n;
 
 		count -=n;
 		p += n;
@@ -444,33 +355,19 @@ _sna_damage_create_elt_from_points(struct sna_damage *damage,
 			return;
 	}
 
-	if (damage->n == damage->size) {
-		int newsize = damage->size * 2;
-		struct sna_damage_elt *newelts = realloc(damage->elts,
-							 newsize*sizeof(*elt));
-		if (newelts == NULL)
-			return;
-
-		damage->elts = newelts;
-		damage->size = newsize;
-	}
-
 	DBG(("    %s(): new elt\n", __FUNCTION__));
 
-	elt = damage->elts + damage->n++;
-	elt->n = count;
-	elt->box = _sna_damage_create_boxes(damage, count);
-	if (elt->box == NULL) {
-		damage->n--;
+	if (! _sna_damage_create_boxes(damage, count))
 		return;
-	}
 
 	for (i = 0; i < count; i++) {
-		elt->box[i].x1 = p[i].x + dx;
-		elt->box[i].x2 = elt->box[i].x1 + 1;
-		elt->box[i].y1 = p[i].y + dy;
-		elt->box[i].y2 = elt->box[i].y1 + 1;
+		damage->box[i].x1 = p[i].x + dx;
+		damage->box[i].x2 = damage->box[i].x1 + 1;
+		damage->box[i].y1 = p[i].y + dy;
+		damage->box[i].y2 = damage->box[i].y1 + 1;
 	}
+	damage->box += count;
+	damage->remain -= count;
 }
 
 static void free_list(struct list *head)
@@ -487,28 +384,35 @@ static void __sna_damage_reduce(struct sna_damage *damage)
 	int n, nboxes;
 	BoxPtr boxes;
 	pixman_region16_t tmp, *region = &damage->region;
+	struct sna_damage_box *iter;
 
 	assert(damage->mode != DAMAGE_ALL);
-	assert(damage->n);
-
-	DBG(("    reduce: before damage.n=%d region.n=%d\n",
-	     damage->n, REGION_NUM_RECTS(region)));
-
-	nboxes = damage->elts[0].n;
-	if (damage->n == 1) {
-		boxes = damage->elts[0].box;
-	} else {
-		for (n = 1; n < damage->n; n++)
-			nboxes += damage->elts[n].n;
-
+	assert(damage->dirty);
+
+	DBG(("    reduce: before region.n=%d\n", REGION_NUM_RECTS(region)));
+
+	nboxes = damage->embedded_box.size;
+	boxes = damage->embedded_box.box;
+	list_for_each_entry(iter, &damage->embedded_box.list, list)
+		nboxes += iter->size;
+	nboxes -= damage->remain;
+	if (nboxes == 0)
+		goto done;
+	if (nboxes > damage->embedded_box.size) {
 		boxes = malloc(sizeof(BoxRec)*nboxes);
-		nboxes = 0;
-		for (n = 0; n < damage->n; n++) {
-			memcpy(boxes+nboxes,
-			       damage->elts[n].box,
-			       damage->elts[n].n*sizeof(BoxRec));
-			nboxes += damage->elts[n].n;
+		if (boxes == NULL)
+			goto done;
+
+		memcpy(boxes, damage->embedded_box.box, sizeof(damage->embedded_box.box));
+		n = damage->embedded_box.size;
+		list_for_each_entry(iter, &damage->embedded_box.list, list) {
+			int len = iter->size;
+			if (n + len > nboxes)
+				len = nboxes - n;
+			memcpy(boxes + n, iter+1, len * sizeof(BoxRec));
+			n += len;
 		}
+		assert(n == nboxes);
 	}
 
 	pixman_region_init_rects(&tmp, boxes, nboxes);
@@ -517,16 +421,15 @@ static void __sna_damage_reduce(struct sna_damage *damage)
 	else
 		pixman_region_subtract(region, region, &tmp);
 	pixman_region_fini(&tmp);
+	if (boxes != damage->embedded_box.box)
+		free(boxes);
 
 	damage->extents = region->extents;
 
-	if (boxes != damage->elts[0].box)
-		free(boxes);
-
-	damage->n = 0;
+done:
 	damage->mode = DAMAGE_ADD;
-	free_list(&damage->boxes);
-	damage->last_box = NULL;
+	free_list(&damage->embedded_box.list);
+	reset_embedded_box(damage);
 
 	DBG(("    reduce: after region.n=%d\n", REGION_NUM_RECTS(region)));
 }
@@ -651,7 +554,7 @@ __sna_damage_add_boxes(struct sna_damage *damage,
 	_sna_damage_create_elt_from_boxes(damage, box, n, dx, dy);
 
 	if (REGION_NUM_RECTS(&damage->region) == 0) {
-		damage->region.extents = *damage->elts[0].box;
+		damage->region.extents = box[0];
 		damage->region.data = NULL;
 		damage->extents = extents;
 	} else {
@@ -754,7 +657,10 @@ __sna_damage_add_rectangles(struct sna_damage *damage,
 	_sna_damage_create_elt_from_rectangles(damage, r, n, dx, dy);
 
 	if (REGION_NUM_RECTS(&damage->region) == 0) {
-		damage->region.extents = *damage->elts[0].box;
+		damage->region.extents.x1 = r[0].x + dx;
+		damage->region.extents.x2 = r[0].x + r[0].width + dx;
+		damage->region.extents.y1 = r[0].y + dy;
+		damage->region.extents.y2 = r[0].y + r[0].height + dy;
 		damage->region.data = NULL;
 		damage->extents = extents;
 	} else {
@@ -848,7 +754,10 @@ __sna_damage_add_points(struct sna_damage *damage,
 	_sna_damage_create_elt_from_points(damage, p, n, dx, dy);
 
 	if (REGION_NUM_RECTS(&damage->region) == 0) {
-		damage->region.extents = *damage->elts[0].box;
+		damage->region.extents.x1 = p[0].x + dx;
+		damage->region.extents.x2 = p[0].x + dx + 1;
+		damage->region.extents.y1 = p[0].y + dy;
+		damage->region.extents.y2 = p[0].y + dy + 1;
 		damage->region.data = NULL;
 		damage->extents = extents;
 	} else {
@@ -973,10 +882,9 @@ struct sna_damage *_sna_damage_all(struct sna_damage *damage,
 	DBG(("%s(%d, %d)\n", __FUNCTION__, width, height));
 
 	if (damage) {
-		free_list(&damage->boxes);
 		pixman_region_fini(&damage->region);
-		damage->n = 0;
-		damage->last_box = NULL;
+		free_list(&damage->embedded_box.list);
+		reset_embedded_box(damage);
 	} else {
 		damage = _sna_damage_create();
 		if (damage == NULL)
@@ -993,7 +901,7 @@ struct sna_damage *_sna_damage_all(struct sna_damage *damage,
 struct sna_damage *_sna_damage_is_all(struct sna_damage *damage,
 				      int width, int height)
 {
-	if (damage->n)
+	if (damage->dirty)
 		__sna_damage_reduce(damage);
 
 	if (damage->region.data)
@@ -1039,7 +947,7 @@ static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage,
 		return damage;
 
 	if (damage->mode != DAMAGE_SUBTRACT) {
-		if (damage->n)
+		if (damage->dirty)
 			__sna_damage_reduce(damage);
 
 		if (pixman_region_equal(region, &damage->region)) {
@@ -1112,7 +1020,7 @@ inline static struct sna_damage *__sna_damage_subtract_box(struct sna_damage *da
 		return damage;
 
 	if (damage->mode != DAMAGE_SUBTRACT) {
-		if (damage->n)
+		if (damage->dirty)
 			__sna_damage_reduce(damage);
 
 		if (!pixman_region_not_empty(&damage->region)) {
@@ -1182,7 +1090,7 @@ static int _sna_damage_contains_box(struct sna_damage *damage,
 		__sna_damage_reduce(damage);
 
 	ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box);
-	if (ret != PIXMAN_REGION_OUT || damage->n == 0)
+	if (ret != PIXMAN_REGION_OUT || !damage->dirty)
 		return ret;
 
 	__sna_damage_reduce(damage);
@@ -1236,7 +1144,7 @@ static Bool _sna_damage_intersect(struct sna_damage *damage,
 	    region->extents.y1 >= damage->extents.y2)
 		return FALSE;
 
-	if (damage->n)
+	if (damage->dirty)
 		__sna_damage_reduce(damage);
 
 	if (!pixman_region_not_empty(&damage->region))
@@ -1280,7 +1188,7 @@ static int _sna_damage_get_boxes(struct sna_damage *damage, BoxPtr *boxes)
 	if (!damage)
 		return 0;
 
-	if (damage->n)
+	if (damage->dirty)
 		__sna_damage_reduce(damage);
 
 	*boxes = REGION_RECTS(&damage->region);
@@ -1323,9 +1231,7 @@ int sna_damage_get_boxes(struct sna_damage *damage, BoxPtr *boxes)
 
 void __sna_damage_destroy(struct sna_damage *damage)
 {
-	free(damage->elts);
-
-	free_list(&damage->boxes);
+	free_list(&damage->embedded_box.list);
 
 	pixman_region_fini(&damage->region);
 	if (__freed_damage == NULL)
diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 0e681b7..d74d5de 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -6,7 +6,6 @@
 
 #include "compiler.h"
 
-struct sna_damage_elt;
 struct sna_damage_box;
 
 struct sna_damage {
@@ -17,10 +16,13 @@ struct sna_damage {
 		DAMAGE_SUBTRACT,
 		DAMAGE_ALL,
 	} mode;
-	int n, size;
-	struct sna_damage_elt *elts;
-	struct sna_damage_box *last_box;
-	struct list boxes;
+	int remain, dirty;
+	BoxPtr box;
+	struct {
+		struct list list;
+		int size;
+		BoxRec box[8];
+	} embedded_box;
 };
 
 fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage,
@@ -133,7 +135,7 @@ static inline void sna_damage_reduce(struct sna_damage **damage)
 	if (*damage == NULL)
 		return;
 
-	if ((*damage)->n)
+	if ((*damage)->dirty)
 		*damage = _sna_damage_reduce(*damage);
 }
 
@@ -145,7 +147,7 @@ static inline void sna_damage_reduce_all(struct sna_damage **damage,
 	if (*damage == NULL)
 		return;
 
-	if ((*damage)->n && (*damage = _sna_damage_reduce(*damage)) == NULL)
+	if ((*damage)->dirty && (*damage = _sna_damage_reduce(*damage)) == NULL)
 		return;
 
 	if ((*damage)->mode == DAMAGE_ADD &&
commit 73df0c7ab7c3a9edf0be2439c7e7ab07c0d75ecf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 02:48:18 2011 +0000

    sna: Tune region upload inplace threshold
    
    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 9cde949..460b29f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -816,8 +816,8 @@ static inline bool region_inplace(struct sna *sna,
 
 	return ((region->extents.x2 - region->extents.x1) *
 		(region->extents.y2 - region->extents.y1) *
-		pixmap->drawable.bitsPerPixel >> 15)
-		>= sna->kgem.half_cpu_cache_pages/2;
+		pixmap->drawable.bitsPerPixel >> 12)
+		>= sna->kgem.half_cpu_cache_pages;
 }
 
 bool
commit ef66c5b5ad221211948ec795ade031591c3f0ac7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Dec 24 00:15:33 2011 +0000

    sna: Search the inactive VMA cache first for a linear mapping
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index c733da5..b8c05fa 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1507,6 +1507,44 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 	bool use_active = (flags & CREATE_INACTIVE) == 0;
 	struct list *cache;
 
+	if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
+		int for_cpu = !!(flags & CREATE_CPU_MAP);
+		assert(use_active == false);
+		list_for_each_entry(bo, &kgem->vma_inactive, vma) {
+			if (IS_CPU_MAP(bo->map) != for_cpu)
+				continue;
+
+			if (size > bo->size || 2*size < bo->size)
+				continue;
+
+			if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
+				kgem->need_purge |= bo->domain == DOMAIN_GPU;
+				kgem_bo_free(kgem, bo);
+				break;
+			}
+
+			if (I915_TILING_NONE != bo->tiling &&
+			    gem_set_tiling(kgem->fd, bo->handle,
+					   I915_TILING_NONE, 0) != I915_TILING_NONE)
+				continue;
+
+			list_del(&bo->list);
+			if (bo->rq == &_kgem_static_request)
+				list_del(&bo->request);
+			list_move_tail(&bo->vma, &kgem->vma_cache);
+
+			bo->tiling = I915_TILING_NONE;
+			bo->pitch = 0;
+			bo->delta = 0;
+			DBG(("  %s: found handle=%d (size=%d) in linear vma cache\n",
+			     __FUNCTION__, bo->handle, bo->size));
+			assert(use_active || bo->domain != DOMAIN_GPU);
+			assert(!bo->needs_flush || use_active);
+			//assert(use_active || !kgem_busy(kgem, bo->handle));
+			return bo;
+		}
+	}
+
 	cache = use_active ? active(kgem, size): inactive(kgem, size);
 	list_for_each_entry_safe(bo, next, cache, list) {
 		assert(bo->refcnt == 0);
@@ -1529,19 +1567,25 @@ search_linear_cache(struct kgem *kgem, unsigned int size, unsigned flags)
 			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
 				int for_cpu = !!(flags & CREATE_CPU_MAP);
 				if (IS_CPU_MAP(bo->map) != for_cpu) {
-					if (first == NULL)
-						first = bo;
+					if (first != NULL)
+						break;
+
+					first = bo;
 					continue;
 				}
 			} else {
-				if (first == NULL)
-					first = bo;
+				if (first != NULL)
+					break;
+
+				first = bo;
 				continue;
 			}
 		} else {
 			if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) {
-				if (first == NULL)
-					first = bo;
+				if (first != NULL)
+					break;
+
+				first = bo;
 				continue;
 			}
 		}


More information about the xorg-commit mailing list