xf86-video-intel: 2 commits - src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Jun 13 03:47:25 PDT 2011


 src/sna/sna.h         |    2 +
 src/sna/sna_display.c |   14 +++++++++
 src/sna/sna_dri.c     |   74 +++++++++++++++++++++++++++++++++-----------------
 3 files changed, 66 insertions(+), 24 deletions(-)

New commits:
commit 2facaa910798c0e7adb34345e6d6913849b7d8a3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jun 13 11:46:04 2011 +0100

    sna/dri: Complete the pending async flip even after DrawableGone
    
    If the client exits before the async page-flip completes then we still
    need to decrement the pending flip count in order to correctly flip the
    scanout next time.
    
    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 75e2c44..502d05b 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -845,16 +845,6 @@ static void sna_dri_flip_event(struct sna *sna,
 	     flip->fe_tv_usec,
 	     flip->type));
 
-	if (!flip->drawable_id)
-		return;
-
-	status = dixLookupDrawable(&drawable,
-				   flip->drawable_id,
-				   serverClient,
-				   M_ANY, DixWriteAccess);
-	if (status != Success)
-		return;
-
 	/* We assume our flips arrive in order, so we don't check the frame */
 	switch (flip->type) {
 	case DRI2_FLIP:
@@ -863,6 +853,16 @@ static void sna_dri_flip_event(struct sna *sna,
 		 * into account. This usually means some defective kms pageflip completion,
 		 * causing wrong (msc, ust) return values and possible visual corruption.
 		 */
+		if (!flip->drawable_id)
+			return;
+
+		status = dixLookupDrawable(&drawable,
+					   flip->drawable_id,
+					   serverClient,
+					   M_ANY, DixWriteAccess);
+		if (status != Success)
+			return;
+
 		if ((flip->fe_frame < flip->frame) &&
 		    (flip->frame - flip->fe_frame < 5)) {
 			static int limit = 5;
@@ -1067,7 +1067,8 @@ immediate:
 			return TRUE;
 		}
 
-		DBG(("%s: emitting immediate vsync'ed blit, throttling client\n"));
+		DBG(("%s: emitting immediate vsync'ed blit, throttling client\n",
+		     __FUNCTION__));
 
 		 info->type = DRI2_SWAP_THROTTLE;
 
@@ -1215,6 +1216,8 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 		goto exchange;
 	}
 
+	DBG(("%s: flip pending on pipe %d? %d\n",
+	     __FUNCTION__, pipe, sna->dri.flip_pending[pipe]));
 	if (!sna->dri.flip_pending[pipe]) {
 		struct sna_dri_frame_event *info;
 		DRI2BufferPtr t;
@@ -1266,6 +1269,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 					   draw->height,
 					   draw->depth,
 					   SNA_CREATE_FB))) {
+		DBG(("%s: new back buffer\n", __FUNCTION__));
 		screen->DestroyPixmap(front_priv->pixmap);
 		front_priv->pixmap = pixmap;
 		front_priv->bo = sna_pixmap_set_dri(sna, pixmap);
@@ -1275,6 +1279,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 
 exchange:
 	sna_dri_exchange_buffers(draw, front, back);
+	assert(((struct sna_dri_private *)front->driverPrivate)->pixmap != sna->front);
 	DRI2SwapComplete(client, draw, 0, 0, 0, type, func, data);
 }
 #endif
commit 86888723901030c5cb9da16cbb03508d4b13332f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jun 12 22:38:01 2011 +0100

    sna: Just do a pointer exchange when flipping with no scanout
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7456f05..ae8e554 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -274,6 +274,8 @@ extern int sna_do_pageflip(struct sna *sna,
 			    PixmapPtr *old_front,
 			    uint32_t *old_fb);
 
+extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
+
 void sna_mode_delete_fb(struct sna *sna, PixmapPtr pixmap, uint32_t fb);
 
 static inline struct sna *
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index e893a37..c2347ef 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1523,6 +1523,20 @@ static int do_page_flip(struct sna *sna, void *data, int ref_crtc_hw_id)
 	return count;
 }
 
+PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap)
+{
+	PixmapPtr old = sna->front;
+	ScrnInfoPtr scrn = sna->scrn;
+
+	sna->front = pixmap;
+	pixmap->refcnt++;
+
+	sna_redirect_screen_pixmap(scrn, old, sna->front);
+	scrn->displayWidth = sna_pixmap_get_bo(pixmap)->pitch / sna->mode.cpp;
+
+	return old;
+}
+
 int
 sna_do_pageflip(struct sna *sna,
 		PixmapPtr pixmap,
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 14a2f3d..75e2c44 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -670,7 +670,8 @@ can_flip(struct sna * sna,
 
 	ScreenPtr screen = draw->pScreen;
 
-	assert(draw->type == DRAWABLE_WINDOW);
+	if (draw->type == DRAWABLE_PIXMAP)
+		return FALSE;
 
 	if (front->format != back->format) {
 		DBG(("%s: no, format mismatch, front = %d, back = %d\n",
@@ -969,10 +970,30 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	     (long long)divisor,
 	     (long long)remainder));
 
+	flip = 0;
+	if (can_flip(sna, draw, front, back)) {
+		DBG(("%s: can flip\n", __FUNCTION__));
+		swap_type = DRI2_FLIP;
+		flip = 1;
+	}
+
 	/* Drawable not displayed... just complete the swap */
 	pipe = sna_dri_get_pipe(draw);
-	if (pipe == -1)
-		goto blit_fallback;
+	if (pipe == -1) {
+		struct sna_dri_private *back_priv = back->driverPrivate;
+		PixmapPtr pixmap;
+
+		if (!flip)
+			goto blit_fallback;
+
+		pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap);
+		pixmap->refcnt--;
+		assert(pixmap->refcnt > 0);
+		sna_dri_exchange_buffers(draw, front, back);
+		DRI2SwapComplete(client, draw, 0, 0, 0,
+				 DRI2_EXCHANGE_COMPLETE, func, data);
+		return TRUE;
+	}
 
 	/* Truncate to match kernel interfaces; means occasional overflow
 	 * misses, but that's generally not a big deal */
@@ -1002,13 +1023,6 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	sna_dri_reference_buffer(front);
 	sna_dri_reference_buffer(back);
 
-	flip = 0;
-	if (can_flip(sna, draw, front, back)) {
-		DBG(("%s: can flip\n", __FUNCTION__));
-		swap_type = DRI2_FLIP;
-		flip = 1;
-	}
-
 	info->type = swap_type;
 	if (divisor == 0)
 		goto immediate;
@@ -1155,9 +1169,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	/* Drawable not displayed... just complete the swap */
-	pipe = sna_dri_get_pipe(draw);
-	if (pipe == -1 || !can_flip(sna, draw, front, back)) {
+	if (!can_flip(sna, draw, front, back)) {
 		BoxRec box, *boxes;
 		int n;
 
@@ -1194,6 +1206,15 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
 		return;
 	}
 
+	pipe = sna_dri_get_pipe(draw);
+	if (pipe == -1) {
+		/* Drawable not displayed... just complete the swap */
+		pixmap = sna_set_screen_pixmap(sna, back_priv->pixmap);
+		pixmap->refcnt--;
+		assert(pixmap->refcnt > 0);
+		goto exchange;
+	}
+
 	if (!sna->dri.flip_pending[pipe]) {
 		struct sna_dri_frame_event *info;
 		DRI2BufferPtr t;


More information about the xorg-commit mailing list