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

Chris Wilson ickle at kemper.freedesktop.org
Thu Sep 27 13:29:11 PDT 2012


 src/sna/sna_display.c |   34 ++++++++++++++------
 src/sna/sna_dri.c     |   84 +++++++++++++++++++++++---------------------------
 2 files changed, 65 insertions(+), 53 deletions(-)

New commits:
commit 8bfd31e9bb13bcb7f12e4147bec0da87b8e87dde
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 27 18:12:11 2012 +0100

    sna/dri: Improve handling of flipping with no outputs
    
    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 88dec3a..676636a 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -87,7 +87,7 @@ struct sna_dri_frame_event {
 	unsigned int fe_tv_sec;
 	unsigned int fe_tv_usec;
 
-	struct {
+	struct dri_bo {
 		struct kgem_bo *bo;
 		uint32_t name;
 	} old_front, next_front, cache;
@@ -956,7 +956,7 @@ sna_dri_frame_event_info_free(struct sna *sna,
 	free(info);
 }
 
-static bool
+static void
 sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
 {
 	struct kgem_bo *bo = get_private(info->back)->bo;
@@ -964,10 +964,9 @@ sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
 	DBG(("%s()\n", __FUNCTION__));
 
 	assert(sna_pixmap_get_buffer(sna->front) == info->front);
+	assert(get_drawable_pixmap(info->draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
 
 	info->count = sna_page_flip(sna, bo, info, info->pipe);
-	if (info->count == 0)
-		return false;
 
 	info->old_front.name = info->front->name;
 	info->old_front.bo = get_private(info->front)->bo;
@@ -976,7 +975,6 @@ sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
 
 	info->front->name = info->back->name;
 	get_private(info->front)->bo = bo;
-	return true;
 }
 
 static bool
@@ -1261,8 +1259,8 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
 	switch (info->type) {
 	case DRI2_FLIP:
 		/* If we can still flip... */
-		if (can_flip(sna, draw, info->front, info->back) &&
-		    sna_dri_page_flip(sna, info)) {
+		if (can_flip(sna, draw, info->front, info->back)) {
+			sna_dri_page_flip(sna, info);
 			info->back->name = info->old_front.name;
 			get_private(info->back)->bo = info->old_front.bo;
 			info->old_front.bo = NULL;
@@ -1321,40 +1319,23 @@ done:
 	sna_dri_frame_event_info_free(sna, draw, info);
 }
 
-static int
+static void
 sna_dri_flip_continue(struct sna *sna, struct sna_dri_frame_event *info)
 {
-	struct kgem_bo *bo;
-	int name;
+	struct dri_bo tmp;
 
 	DBG(("%s()\n", __FUNCTION__));
 
 	assert(sna_pixmap_get_buffer(get_drawable_pixmap(info->draw)) == info->front);
 
-	name = info->back->name;
-	bo = get_private(info->back)->bo;
-	assert(get_drawable_pixmap(info->draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
+	tmp = info->old_front;
 
-	info->count = sna_page_flip(sna, bo, info, info->pipe);
-	if (info->count == 0)
-		return false;
+	sna_dri_page_flip(sna, info);
 
-	set_bo(sna->front, bo);
-
-	get_private(info->back)->bo = info->old_front.bo;
-	info->back->name = info->old_front.name;
-
-	info->old_front.name = info->front->name;
-	info->old_front.bo = get_private(info->front)->bo;
-
-	info->front->name = name;
-	get_private(info->front)->bo = bo;
+	get_private(info->back)->bo = tmp.bo;
+	info->back->name = tmp.name;
 
 	info->next_front.name = 0;
-
-	sna->dri.flip_pending = info;
-
-	return true;
 }
 
 static void sna_dri_flip_event(struct sna *sna,
@@ -1392,13 +1373,17 @@ static void sna_dri_flip_event(struct sna *sna,
 			DBG(("%s: flip chain complete\n", __FUNCTION__));
 			sna_dri_frame_event_info_free(sna, flip->draw, flip);
 		} else if (flip->draw &&
-			   can_flip(sna, flip->draw, flip->front, flip->back) &&
-			   sna_dri_flip_continue(sna, flip)) {
+			   can_flip(sna, flip->draw, flip->front, flip->back)) {
+			sna_dri_flip_continue(sna, flip);
 			DRI2SwapComplete(flip->client, flip->draw,
 					 0, 0, 0,
 					 DRI2_FLIP_COMPLETE,
 					 flip->client ? flip->event_complete : NULL,
 					 flip->event_data);
+			if (flip->count)
+				sna->dri.flip_pending = flip;
+			else
+				sna_dri_frame_event_info_free(sna, flip->draw, flip);
 		} else {
 			DBG(("%s: no longer able to flip\n", __FUNCTION__));
 
@@ -1513,8 +1498,16 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	VG_CLEAR(vbl);
 
 	pipe = sna_dri_get_pipe(draw);
-	if (pipe == -1)
-		return false;
+	if (pipe == -1) {
+		/* XXX WARN_ON(sna->dri.flip_pending) ? */
+		if (sna->dri.flip_pending == NULL) {
+			sna_dri_exchange_buffers(draw, front, back);
+			DRI2SwapComplete(client, draw, 0, 0, 0,
+					DRI2_EXCHANGE_COMPLETE, func, data);
+			return true;
+		} else
+			return false;
+	}
 
 	/* Truncate to match kernel interfaces; means occasional overflow
 	 * misses, but that's generally not a big deal */
@@ -1560,13 +1553,19 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 		sna_dri_reference_buffer(front);
 		sna_dri_reference_buffer(back);
 
-		if (!sna_dri_page_flip(sna, info)) {
-			DBG(("%s: failed to queue page flip\n", __FUNCTION__));
-			sna_dri_frame_event_info_free(sna, draw, info);
-			return false;
-		}
+		sna_dri_page_flip(sna, info);
+
+		if (info->count == 0) {
+			info->back->name = info->old_front.name;
+			get_private(info->back)->bo = info->old_front.bo;
+			info->old_front.bo = NULL;
 
-		if (type != DRI2_FLIP) {
+			DRI2SwapComplete(info->client, draw, 0, 0, 0,
+					 DRI2_EXCHANGE_COMPLETE,
+					 info->event_complete,
+					 info->event_data);
+			sna_dri_frame_event_info_free(sna, draw, info);
+		} else if (type != DRI2_FLIP) {
 			get_private(info->back)->bo =
 				kgem_create_2d(&sna->kgem,
 					       draw->width,
@@ -2011,10 +2010,7 @@ blit:
 		sna_dri_reference_buffer(front);
 		sna_dri_reference_buffer(back);
 
-		if (!sna_dri_page_flip(sna, info)) {
-			sna_dri_frame_event_info_free(sna, draw, info);
-			goto blit;
-		}
+		sna_dri_page_flip(sna, info);
 
 		info->next_front.name = info->front->name;
 		info->next_front.bo = get_private(info->front)->bo;
commit dddb6e4e63d5cc8b2a1f2ae3ff287922d30460b9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Sep 27 17:17:30 2012 +0100

    sna: Attempt to restore the current mode if pipe is disabled on DPMS on
    
    If we attempt to power up the pipe through a DPMS request, but it was
    previously disabled due to an error, first try re-enabling.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 3c41a2a..61d1a9f 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -787,6 +787,8 @@ sna_crtc_disable(xf86CrtcPtr crtc)
 		kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
 		sna_crtc->bo = NULL;
 	}
+
+	sna_crtc->dpms_mode = DPMSModeOff;
 }
 
 static void update_flush_interval(struct sna *sna)
@@ -824,15 +826,6 @@ static void update_flush_interval(struct sna *sna)
 	       max_vrefresh, sna->vblank_interval));
 }
 
-static void
-sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
-	DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
-	     __FUNCTION__, to_sna_crtc(crtc)->pipe, mode, mode == DPMSModeOn));
-	to_sna_crtc(crtc)->dpms_mode = mode;
-	update_flush_interval(to_sna(crtc->scrn));
-}
-
 void sna_mode_disable_unused(struct sna *sna)
 {
 	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
@@ -1289,6 +1282,28 @@ retry: /* Attach per-crtc pixmap or direct */
 	return TRUE;
 }
 
+static void
+sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+	struct sna_crtc *priv = to_sna_crtc(crtc);
+
+	DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
+	     __FUNCTION__, priv->pipe, mode, mode == DPMSModeOn));
+	if (mode == DPMSModeOn) {
+		if (priv->bo == NULL &&
+		    !sna_crtc_set_mode_major(crtc,
+					     &crtc->mode, crtc->rotation,
+					     crtc->x, crtc->y))
+			sna_crtc_disable(crtc);
+	} else
+		sna_crtc_disable(crtc);
+
+	if (priv->bo != NULL) {
+		priv->dpms_mode = mode;
+		update_flush_interval(to_sna(crtc->scrn));
+	}
+}
+
 void sna_mode_adjust_frame(struct sna *sna, int x, int y)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
@@ -1497,6 +1512,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		return;
 
 	sna_crtc->id = mode->kmode->crtcs[num];
+	sna_crtc->dpms_mode = DPMSModeOff;
 
 	VG_CLEAR(get_pipe);
 	get_pipe.pipe = 0;


More information about the xorg-commit mailing list