summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-10-31 12:10:52 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-31 12:31:23 +0000
commit59535d0e1c587cfe9249ab1baf9acf8470b49b8b (patch)
tree6c0d6064fdf5a0441cfe125f07c938ff40d13c6a /src/sna
parent9a2e59bfba6748325918f895b3e58351c7eb4baa (diff)
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@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r--src/sna/sna.h2
-rw-r--r--src/sna/sna_accel.c4
-rw-r--r--src/sna/sna_display.c28
-rw-r--r--src/sna/sna_driver.c3
4 files changed, 32 insertions, 5 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index f045fa50..3d2ecaf8 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 9ce142d8..feb13e9f 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 cc7ac9be..98743bc6 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 46ca5ce8..0df7ca0c 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;