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

Chris Wilson ickle at kemper.freedesktop.org
Tue Nov 20 10:55:23 PST 2012


 src/sna/sna_dri.c |   87 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 59 insertions(+), 28 deletions(-)

New commits:
commit 9ab1d1f94e502e5fde87e7c171f3502f8a55f22b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 20 18:42:58 2012 +0000

    sna/dri: Queue a vblank-continuation after flip-completion
    
    If a vblank request was delayed due to a pending flip, we need to make
    sure that we then queue it after that flip or else progress ceases.
    
    Reported-by: Jiri Slaby <jirislaby at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56423
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57156
    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 ff1f519..eb7c835 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1261,7 +1261,7 @@ sna_dri_exchange_buffers(DrawablePtr draw,
 
 static void chain_swap(struct sna *sna,
 		       DrawablePtr draw,
-		       struct drm_event_vblank *event,
+		       int frame, unsigned int tv_sec, unsigned int tv_usec,
 		       struct sna_dri_frame_event *chain)
 {
 	drmVBlank vbl;
@@ -1300,7 +1300,7 @@ static void chain_swap(struct sna *sna,
 	}
 
 	DRI2SwapComplete(chain->client, draw,
-			 event->sequence, event->tv_sec, event->tv_usec,
+			 frame, tv_sec, tv_usec,
 			 type, chain->client ? chain->event_complete : NULL, chain->event_data);
 
 	VG_CLEAR(vbl);
@@ -1405,7 +1405,9 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 
 	if (info->chain) {
 		sna_dri_remove_frame_event((WindowPtr)draw, info);
-		chain_swap(sna, draw, event, info->chain);
+		chain_swap(sna, draw,
+			   event->sequence, event->tv_sec, event->tv_usec,
+			   info->chain);
 		draw = NULL;
 	}
 
@@ -1521,6 +1523,17 @@ static void sna_dri_flip_event(struct sna *sna,
 			 */
 			DBG(("%s: flip chain complete, off-delay=%d\n",
 			     __FUNCTION__, flip->off_delay));
+			if (flip->chain) {
+				sna_dri_remove_frame_event((WindowPtr)flip->draw,
+							   flip);
+				chain_swap(sna, flip->draw,
+					   flip->fe_frame,
+					   flip->fe_tv_sec,
+					   flip->fe_tv_usec,
+					   flip->chain);
+				flip->draw = NULL;
+			}
+
 			if (flip->off_delay-- && flip->draw &&
 			    can_flip(sna, flip->draw, flip->front, flip->front) &&
 			    (flip->count = sna_page_flip(sna,
@@ -1585,36 +1598,54 @@ static void sna_dri_flip_event(struct sna *sna,
 			flip->count = sna_page_flip(sna,
 						    get_private(flip->front)->bo,
 						    flip, flip->pipe);
-			if (flip->count == 0)
-				goto finish_async_flip;
+			if (flip->count == 0) {
+				if (flip->chain)
+					goto chain_async_flip;
+				else
+					goto finish_async_flip;
+			}
 
 			flip->next_front.bo = get_private(flip->front)->bo;
 			flip->next_front.name = flip->front->name;
 			flip->off_delay = FLIP_OFF_DELAY;
 
 			sna->dri.flip_pending = flip;
-		} else if (flip->draw &&
-			   can_flip(sna, flip->draw, flip->front, flip->back) &&
-			   flip->off_delay--) {
-			assert(flip == sna_dri_window_get_chain((WindowPtr)flip->draw));
-			DBG(("%s: queuing no-flip [delay=%d]\n",
-			     __FUNCTION__, flip->off_delay));
-			/* Just queue a no-op flip to trigger another event */
-			flip->count = sna_page_flip(sna,
-						    get_private(flip->front)->bo,
-						    flip, flip->pipe);
-			if (flip->count == 0)
-				goto finish_async_flip;
+		} else {
+			if (flip->chain) {
+chain_async_flip:
+				sna_dri_remove_frame_event((WindowPtr)flip->draw,
+							   flip);
+				chain_swap(sna, flip->draw,
+					   flip->fe_frame,
+					   flip->fe_tv_sec,
+					   flip->fe_tv_usec,
+					   flip->chain);
+				flip->draw = NULL;
+			}
 
-			assert(flip->next_front.bo == get_private(flip->front)->bo);
-			assert(flip->next_front.name == flip->front->name);
+			if (flip->draw &&
+			    can_flip(sna, flip->draw, flip->front, flip->back) &&
+			    flip->off_delay--) {
+				assert(flip == sna_dri_window_get_chain((WindowPtr)flip->draw));
+				DBG(("%s: queuing no-flip [delay=%d]\n",
+				     __FUNCTION__, flip->off_delay));
+				/* Just queue a no-op flip to trigger another event */
+				flip->count = sna_page_flip(sna,
+							    get_private(flip->front)->bo,
+							    flip, flip->pipe);
+				if (flip->count == 0)
+					goto finish_async_flip;
+
+				assert(flip->next_front.bo == get_private(flip->front)->bo);
+				assert(flip->next_front.name == flip->front->name);
 
-			sna->dri.flip_pending = flip;
-		} else {
+				sna->dri.flip_pending = flip;
+			} else {
 finish_async_flip:
-			DBG(("%s: async flip completed (drawable gone? %d)\n",
-			     __FUNCTION__, flip->draw == NULL));
-			sna_dri_frame_event_info_free(sna, flip->draw, flip);
+				DBG(("%s: async flip completed (drawable gone? %d)\n",
+				     __FUNCTION__, flip->draw == NULL));
+				sna_dri_frame_event_info_free(sna, flip->draw, flip);
+			}
 		}
 		break;
 #endif
@@ -1890,14 +1921,13 @@ sna_dri_immediate_blit(struct sna *sna,
 		       DrawablePtr draw,
 		       struct sna_dri_frame_event *info)
 {
-	drmVBlank vbl;
-
 	DBG(("%s: emitting immediate blit, throttling client\n", __FUNCTION__));
-	VG_CLEAR(vbl);
 
 	if ((sna->flags & SNA_NO_WAIT) == 0) {
 		info->type = DRI2_SWAP_THROTTLE;
 		if (sna_dri_window_get_chain((WindowPtr)draw) == info) {
+			drmVBlank vbl;
+
 			DBG(("%s: no pending blit, starting chain\n",
 			     __FUNCTION__));
 
@@ -1910,6 +1940,7 @@ sna_dri_immediate_blit(struct sna *sna,
 					 info->event_complete,
 					 info->event_data);
 
+			VG_CLEAR(vbl);
 			vbl.request.type =
 				DRM_VBLANK_RELATIVE |
 				DRM_VBLANK_NEXTONMISS |
commit 7a7a76b359f73a4c4bcda0d88004f4dd5e94a186
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 20 16:05:32 2012 +0000

    sna/dri: Avoid a NULL dereference inside a DBG
    
    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 5729950..ff1f519 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -1086,7 +1086,7 @@ can_flip(struct sna * sna,
 	if (sna_pixmap_get_buffer(pixmap) != front) {
 		DBG(("%s: no, DRI2 drawable is no longer attached (old name=%d, new name=%d) to pixmap=%ld\n",
 		     __FUNCTION__, front->name,
-		     ((DRI2BufferPtr)sna_pixmap_get_buffer(pixmap))->name,
+		     sna_pixmap_get_buffer(pixmap) ? ((DRI2BufferPtr)sna_pixmap_get_buffer(pixmap))->name : 0,
 		     pixmap->drawable.serialNumber));
 		return false;
 	}


More information about the xorg-commit mailing list