diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-31 12:10:52 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-31 12:31:23 +0000 |
commit | 59535d0e1c587cfe9249ab1baf9acf8470b49b8b (patch) | |
tree | 6c0d6064fdf5a0441cfe125f07c938ff40d13c6a /src/sna | |
parent | 9a2e59bfba6748325918f895b3e58351c7eb4baa (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.h | 2 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 4 | ||||
-rw-r--r-- | src/sna/sna_display.c | 28 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 3 |
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; |