xf86-video-intel: src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Oct 31 05:29:08 PDT 2011


 src/sna/sna.h         |    2 ++
 src/sna/sna_accel.c   |    4 ++--
 src/sna/sna_display.c |   28 +++++++++++++++++++++++++---
 src/sna/sna_driver.c  |    3 +++
 4 files changed, 32 insertions(+), 5 deletions(-)

New commits:
commit 59535d0e1c587cfe9249ab1baf9acf8470b49b8b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 31 12:10:52 2011 +0000

    sna: Set the flush interval based on output vrefresh
    
    Rather than a blank 25Hz, use twice the vblank interval to hopefully
    avoid bad values.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index f045fa5..3d2ecaf 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -212,6 +212,8 @@ struct sna {
 	int timer[NUM_TIMERS];
 	int timer_active;
 
+	int flush_interval;
+
 	struct list deferred_free;
 	struct list dirty_pixmaps;
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 9ce142d..feb13e9 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -6005,9 +6005,9 @@ static Bool sna_accel_do_flush(struct sna *sna)
 	to.it_value.tv_sec = 0;
 	to.it_value.tv_nsec = 10 * 1000 * 1000;
 
-	/* Then periodic updates at 25Hz.*/
+	/* Then periodic updates at half-vrefresh (update every other vblank) */
 	to.it_interval.tv_sec = 0;
-	to.it_interval.tv_nsec = 40 * 1000 * 1000;
+	to.it_interval.tv_nsec = sna->flush_interval;
 	timerfd_settime(sna->timer[FLUSH_TIMER], 0, &to, NULL);
 
 	sna->timer_active |= 1 << FLUSH_TIMER;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index cc7ac9b..98743bc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -585,6 +585,27 @@ cleanup_fbcon:
 	drmModeFreeFB(fbcon);
 }
 
+static void update_flush_interval(struct sna *sna)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int i, max_vrefresh = 0;
+
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		if (!xf86_config->crtc[i]->enabled)
+			continue;
+
+		max_vrefresh = max(max_vrefresh,
+				   xf86ModeVRefresh(&xf86_config->crtc[i]->mode));
+	}
+
+	if (max_vrefresh == 0)
+		max_vrefresh = 40;
+
+	sna->flush_interval = 2000 * 1000 * 1000 / max_vrefresh;
+	DBG(("max_vrefresh=%d, flush_interval=%d ns\n",
+	       max_vrefresh, sna->flush_inteval));
+}
+
 static Bool
 sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			Rotation rotation, int x, int y)
@@ -652,15 +673,16 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	kgem_submit(&sna->kgem);
 
 	mode_to_kmode(&sna_crtc->kmode, mode);
-	ret = sna_crtc_apply(crtc);
-	if (!ret) {
+	if (!sna_crtc_apply(crtc)) {
 		crtc->x = saved_x;
 		crtc->y = saved_y;
 		crtc->rotation = saved_rotation;
 		crtc->mode = saved_mode;
+		return FALSE;
 	}
 
-	return ret;
+	update_flush_interval(sna);
+	return TRUE;
 }
 
 static void
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 46ca5ce..0df7ca0 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -504,6 +504,9 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 	if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
 		sna->tiling &= ~SNA_TILING_FB;
 
+	/* Default fail-safe value of 25 Hz */
+	sna->flush_interval = 40 * 1000 * 1000;
+
 	sna->flags = 0;
 	if (!xf86ReturnOptValBool(sna->Options, OPTION_THROTTLE, TRUE))
 		sna->flags |= SNA_NO_THROTTLE;


More information about the xorg-commit mailing list