xf86-video-intel: 4 commits - src/sna/sna_accel.c src/sna/sna_composite.c src/sna/sna_dri.c src/sna/sna.h src/sna/sna_trapezoids.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Mar 5 14:53:15 PST 2012


 src/sna/sna.h            |    2 ++
 src/sna/sna_accel.c      |   38 ++++++++++++++++++++++++++++++--------
 src/sna/sna_composite.c  |   46 ++++++++++++++++++++++------------------------
 src/sna/sna_dri.c        |    2 ++
 src/sna/sna_trapezoids.c |   23 ++++++++++++-----------
 5 files changed, 68 insertions(+), 43 deletions(-)

New commits:
commit 60dacdb127599606db13ad111af8ce26c1141da5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 5 22:46:20 2012 +0000

    sna: Only install the flush callback for the duration of the foriegn buffer
    
    After we are no longer sharing the bo with foreign clients, we no longer
    need to keep flushing before every X_Reply and so we can remove the
    callbacks to remove the overhead of having to check every time.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 1196cce..119244d 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -221,6 +221,7 @@ struct sna {
 #define SNA_NO_THROTTLE		0x1
 #define SNA_NO_DELAYED_FLUSH	0x2
 
+	unsigned watch_flush;
 	unsigned flush;
 
 	int timer[NUM_TIMERS];
@@ -560,6 +561,7 @@ Bool sna_accel_pre_init(struct sna *sna);
 Bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
 void sna_accel_block_handler(struct sna *sna);
 void sna_accel_wakeup_handler(struct sna *sna, fd_set *ready);
+void sna_accel_watch_flush(struct sna *sna, int enable);
 void sna_accel_close(struct sna *sna);
 void sna_accel_free(struct sna *sna);
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 460fbb3..1dc0b99 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -345,8 +345,10 @@ static void sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv)
 	if (priv->cpu_bo) {
 		DBG(("%s: discarding CPU buffer, handle=%d, size=%d\n",
 		     __FUNCTION__, priv->cpu_bo->handle, kgem_bo_size(priv->cpu_bo)));
-		if (priv->cpu_bo->sync)
+		if (priv->cpu_bo->sync) {
 			kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo);
+			sna_accel_watch_flush(sna, -1);
+		}
 		kgem_bo_destroy(&sna->kgem, priv->cpu_bo);
 		priv->cpu_bo = NULL;
 	} else
@@ -617,6 +619,7 @@ sna_pixmap_create_shm(ScreenPtr screen,
 					      bpp, pitch, addr);
 	}
 	kgem_bo_set_sync(&sna->kgem, priv->cpu_bo);
+	sna_accel_watch_flush(sna, 1);
 	priv->cpu_bo->pitch = pitch;
 
 	priv->header = true;
@@ -11479,6 +11482,7 @@ sna_accel_flush_callback(CallbackListPtr *list,
 	struct sna *sna = user_data;
 	struct list preserve;
 
+	assert(sna->watch_flush);
 	if (!sna->flush)
 		return;
 
@@ -11828,11 +11832,6 @@ Bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 {
 	const char *backend;
 
-	if (!AddCallback(&ReplyCallback, sna_accel_reply_callback, sna))
-		return FALSE;
-	if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna))
-		return FALSE;
-
 	sna_font_key = AllocateFontPrivateIndex();
 	screen->RealizeFont = sna_realize_font;
 	screen->UnrealizeFont = sna_unrealize_font;
@@ -11928,6 +11927,26 @@ Bool sna_accel_create(struct sna *sna)
 	return TRUE;
 }
 
+void sna_accel_watch_flush(struct sna *sna, int enable)
+{
+	if (sna->watch_flush == 0) {
+		assert(enable > 0);
+		if (!AddCallback(&ReplyCallback, sna_accel_reply_callback, sna) ||
+		    AddCallback(&FlushCallback, sna_accel_flush_callback, sna)) {
+			xf86DrvMsg(sna->scrn->scrnIndex, X_Error,
+				   "Failed to attach ourselves to the flush callbacks, expect missing synchronisation with DRI clients (e.g a compositor)\n");
+		}
+	}
+
+	sna->watch_flush += enable;
+
+	if (sna->watch_flush == 0) {
+		assert(enable < 0);
+		DeleteCallback(&ReplyCallback, sna_accel_reply_callback, sna);
+		DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna);
+	}
+}
+
 void sna_accel_close(struct sna *sna)
 {
 	if (sna->freed_pixmap) {
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index fe3d1cf..3909b84 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -178,6 +178,7 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 	 * As we don't track which Client, we flush for all.
 	 */
 	priv->flush = 1;
+	sna_accel_watch_flush(sna, 1);
 
 	/* Don't allow this named buffer to be replaced */
 	priv->pinned = 1;
@@ -324,6 +325,7 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer)
 
 			/* Undo the DRI markings on this pixmap */
 			list_del(&priv->list);
+			sna_accel_watch_flush(sna, -1);
 			priv->pinned = private->pixmap == sna->front;
 			priv->flush = 0;
 
commit b39d9f9166547effe066acfc3327dd88a019d273
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 5 22:29:38 2012 +0000

    sna: Check for flush at the start of every WriteToClient
    
    The goal is to simply avoid the flush before going to sleep when we have
    no pending events. That is we only want to flush when we know there will
    be at least on X_Reply sent to a Client. (Preferably, it would a Damage
    reply!) We can safe assume that every WriteToClient marks the beginning
    of a new reply added to the Client output queue and thus know that upon
    the next flush event we will emitting a Reply and so need to submit our
    batches.
    
    Second attempt to fix a438e4ac.
    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 709f29d..460fbb3 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11460,11 +11460,14 @@ sna_accel_reply_callback(CallbackListPtr *list,
 			 pointer user_data, pointer call_data)
 {
 	struct sna *sna = user_data;
-	ReplyInfoRec *info = call_data;
 
-	if (sna->flush || !info->startOfReply)
+	if (sna->flush)
 		return;
 
+	/* Assume each callback corresponds to a new request. The use
+	 * of continuation WriteToClients in the server is relatively rare,
+	 * and we err on the side of safety.
+	 */
 	sna->flush = (sna->kgem.flush || sna->kgem.sync ||
 		      !list_is_empty(&sna->dirty_pixmaps));
 }
commit f30b0beea4f5657a60eb5b286f41105298fa451a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Mar 4 22:23:39 2012 +0000

    sna/trapezoids: Ellide empty cells
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index 2d8b3b9..33ea3bb 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -1249,18 +1249,19 @@ tor_blt(struct sna *sna,
 		       cell->x, cell->covered_height, cell->uncovered_area,
 		       cover, xmax));
 
-		box.x2 = x;
-		if (box.x2 > box.x1 && (unbounded || cover)) {
-			__DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__,
-			       box.x1, box.y1,
-			       box.x2 - box.x1,
-			       box.y2 - box.y1,
-			       cover));
-			span(sna, op, clip, &box, cover);
+		if (cell->covered_height || cell->uncovered_area) {
+			box.x2 = x;
+			if (box.x2 > box.x1 && (unbounded || cover)) {
+				__DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__,
+				       box.x1, box.y1,
+				       box.x2 - box.x1,
+				       box.y2 - box.y1,
+				       cover));
+				span(sna, op, clip, &box, cover);
+			}
+			box.x1 = box.x2;
+			cover += cell->covered_height*FAST_SAMPLES_X*2;
 		}
-		box.x1 = box.x2;
-
-		cover += cell->covered_height*FAST_SAMPLES_X*2;
 
 		if (cell->uncovered_area) {
 			int area = cover - cell->uncovered_area;
commit b69c9dfae128ed69a397a066b8fbe62012742bf1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Mar 5 21:05:34 2012 +0000

    sna/composite: Skip clipping the rectangle region against the singular clip
    
    As we will already have taken it into account when constructing the
    region from the rectangles.
    
    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 55a496e..7f1d096 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -563,7 +563,7 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
 				       unsigned int num_rects,
 				       xRectangle *rects,
 				       int tx, int ty,
-				       int maxx, int maxy)
+				       BoxPtr extents)
 {
 	pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
 	pixman_bool_t ret;
@@ -576,25 +576,21 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t *region,
 	}
 
 	for (i = j = 0; i < num_rects; i++) {
-		boxes[j].x1 = rects[i].x;
-		if (boxes[j].x1 < 0)
-			boxes[j].x1 = 0;
-		boxes[j].x1 += tx;
-
-		boxes[j].y1 = rects[i].y;
-		if (boxes[j].y1 < 0)
-			boxes[j].y1 = 0;
-		boxes[j].y1 += ty;
-
-		boxes[j].x2 = bound(rects[i].x, rects[i].width);
-		if (boxes[j].x2 > maxx)
-			boxes[j].x2 = maxx;
-		boxes[j].x2 += tx;
-
-		boxes[j].y2 = bound(rects[i].y, rects[i].height);
-		if (boxes[j].y2 > maxy)
-			boxes[j].y2 = maxy;
-		boxes[j].y2 += ty;
+		boxes[j].x1 = rects[i].x + tx;
+		if (boxes[j].x1 < extents->x1)
+			boxes[j].x1 = extents->x1;
+
+		boxes[j].y1 = rects[i].y + ty;
+		if (boxes[j].y1 < extents->y1)
+			boxes[j].y1 = extents->y1;
+
+		boxes[j].x2 = bound(rects[i].x + tx, rects[i].width);
+		if (boxes[j].x2 > extents->x2)
+			boxes[j].x2 = extents->x2;
+
+		boxes[j].y2 = bound(rects[i].y + ty, rects[i].height);
+		if (boxes[j].y2 > extents->y2)
+			boxes[j].y2 = extents->y2;
 
 		if (boxes[j].x2 > boxes[j].x1 && boxes[j].y2 > boxes[j].y1)
 			j++;
@@ -689,8 +685,9 @@ sna_composite_rectangles(CARD8		 op,
 
 	if (!_pixman_region_init_clipped_rectangles(&region,
 						    num_rects, rects,
-						    dst->pDrawable->x, dst->pDrawable->y,
-						    dst->pDrawable->width, dst->pDrawable->height))
+						    dst->pDrawable->x,
+						    dst->pDrawable->y,
+						    &dst->pCompositeClip->extents))
 	{
 		DBG(("%s: allocation failed for region\n", __FUNCTION__));
 		return;
@@ -702,8 +699,9 @@ sna_composite_rectangles(CARD8		 op,
 	     RegionExtents(&region)->x2, RegionExtents(&region)->y2,
 	     RegionNumRects(&region)));
 
-	if (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
-	    region_is_empty(&region)) {
+	if (dst->pCompositeClip->data &&
+	    (!pixman_region_intersect(&region, &region, dst->pCompositeClip) ||
+	     region_is_empty(&region))) {
 		DBG(("%s: zero-intersection between rectangles and clip\n",
 		     __FUNCTION__));
 		pixman_region_fini(&region);


More information about the xorg-commit mailing list