From 26d5afca0fa9396df05fff323456a010f641f49b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Feb 2015 17:06:27 +0000 Subject: [PATCH] sna: Always restore the scanout on DPMS on As we may exchange the frontbuffer whilst the outputs are hidden (DPMS off), when we turn them back on, unless we force the CRTCs to be updated, we may end up simply showing a stale scanout buffer not the current frontbuffer. If the two are same, it will just be a kernel no-op. Reported-by: Jiri Slaby Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88826 Signed-off-by: Chris Wilson --- src/sna/sna_display.c | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 74de375..8f85f59 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -117,7 +117,6 @@ extern XF86ConfigPtr xf86configptr; struct sna_crtc { xf86CrtcPtr base; struct drm_mode_modeinfo kmode; - int dpms_mode; PixmapPtr slave_pixmap; DamagePtr slave_damage; struct kgem_bo *bo, *shadow_bo, *client_bo; @@ -864,7 +863,6 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc) output->funcs->dpms(output, DPMSModeOn); } - to_sna_crtc(crtc)->dpms_mode = DPMSModeOn; #if XF86_CRTC_VERSION >= 3 crtc->active = TRUE; #endif @@ -895,8 +893,6 @@ sna_crtc_force_outputs_off(xf86CrtcPtr crtc) output->funcs->dpms(output, DPMSModeOff); } - - to_sna_crtc(crtc)->dpms_mode = DPMSModeOff; } static unsigned @@ -1563,7 +1559,7 @@ __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc) } static void -sna_crtc_disable(xf86CrtcPtr crtc) +sna_crtc_disable(xf86CrtcPtr crtc, bool force) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); @@ -1572,11 +1568,13 @@ sna_crtc_disable(xf86CrtcPtr crtc) if (sna_crtc == NULL) return; - DBG(("%s: disabling crtc [%d, pipe=%d]\n", __FUNCTION__, - sna_crtc->id, sna_crtc->pipe)); + if (!force && sna_crtc->bo == NULL) + return; + + DBG(("%s: disabling crtc [%d, pipe=%d], force?=%d\n", __FUNCTION__, + sna_crtc->id, sna_crtc->pipe, force)); sna_crtc_force_outputs_off(crtc); - assert(sna_crtc->dpms_mode == DPMSModeOff); memset(&arg, 0, sizeof(arg)); arg.crtc_id = sna_crtc->id; @@ -1604,7 +1602,7 @@ static void update_flush_interval(struct sna *sna) continue; } - if (to_sna_crtc(crtc)->dpms_mode != DPMSModeOn) { + if (to_sna_crtc(crtc)->bo == NULL) { DBG(("%s: CRTC:%d (pipe %d) turned off\n", __FUNCTION__,i, to_sna_crtc(crtc)->pipe)); continue; @@ -2442,17 +2440,10 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, 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 (priv->dpms_mode == mode) - return; - - assert(priv); - priv->dpms_mode = mode; + __FUNCTION__, to_sna_crtc(crtc)->pipe, mode, mode == DPMSModeOn)); - if (mode == DPMSModeOn && crtc->enabled && priv->bo == NULL) { + if (mode == DPMSModeOn && crtc->enabled) { if (__sna_crtc_set_mode(crtc)) update_flush_interval(to_sna(crtc->scrn)); else @@ -2460,7 +2451,7 @@ sna_crtc_dpms(xf86CrtcPtr crtc, int mode) } if (mode != DPMSModeOn) - sna_crtc_disable(crtc); + sna_crtc_disable(crtc, false); } void sna_mode_adjust_frame(struct sna *sna, int x, int y) @@ -2790,7 +2781,6 @@ sna_crtc_add(ScrnInfoPtr scrn, int id) return false; sna_crtc->id = id; - sna_crtc->dpms_mode = -1; VG_CLEAR(get_pipe); get_pipe.pipe = 0; @@ -4445,7 +4435,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height) continue; if (!__sna_crtc_set_mode(crtc)) - sna_crtc_disable(crtc); + sna_crtc_disable(crtc, false); } sna_mode_wakeup(sna); @@ -5404,7 +5394,7 @@ fixup_flip: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "failed to restore display configuration\n"); for (; i < sna->mode.num_real_crtc; i++) - sna_crtc_disable(config->crtc[i]); + sna_crtc_disable(config->crtc[i], false); } return 0; } @@ -6061,7 +6051,7 @@ sna_mode_disable(struct sna *sna) */ sna_hide_cursors(sna->scrn); for (i = 0; i < sna->mode.num_real_crtc; i++) - sna_crtc_disable(config->crtc[i]); + sna_crtc_disable(config->crtc[i], false); assert(sna->mode.front_active == 0); sna_mode_wakeup(sna); @@ -6592,7 +6582,7 @@ void sna_mode_check(struct sna *sna) xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: invalid state found on pipe %d, disabling CRTC:%d\n", __FUNCTION__, sna_crtc->pipe, sna_crtc->id); - sna_crtc_disable(crtc); + sna_crtc_disable(crtc, true); } } @@ -6660,14 +6650,13 @@ void sna_mode_reset(struct sna *sna) sna_hide_cursors(sna->scrn); for (i = 0; i < sna->mode.num_real_crtc; i++) if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i]))) - sna_crtc_disable(config->crtc[i]); + sna_crtc_disable(config->crtc[i], true); assert(sna->mode.front_active == 0); for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]); assert(sna_crtc != NULL); - sna_crtc->dpms_mode = -1; /* Force the rotation property to be reset on next use */ rotation_reset(&sna_crtc->primary); @@ -7415,7 +7404,7 @@ disable1: xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", __FUNCTION__, sna_crtc->id, sna_crtc->pipe); - sna_crtc_disable(crtc); + sna_crtc_disable(crtc, false); } kgem_bo_destroy(&sna->kgem, bo); @@ -7476,7 +7465,6 @@ disable1: continue; assert(config->crtc[i]->enabled); - assert(crtc->dpms_mode <= DPMSModeOn); assert(crtc->flip_bo == NULL); arg.crtc_id = crtc->id; @@ -7562,7 +7550,7 @@ fixup_flip: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", __FUNCTION__, crtc->id, crtc->pipe); - sna_crtc_disable(crtc->base); + sna_crtc_disable(crtc->base, false); } continue; } -- 2.1.0