diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-01-29 05:32:25 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-01-29 05:32:25 +0000 |
commit | 4b73a0ea22b43807c0118f4d7e9dcac3f0626463 (patch) | |
tree | cc6db15e645480396e78ba0141d74491626622e8 | |
parent | 9f3fc9ec49f0caf53344577896ef9b6468cd3d4f (diff) |
sna: Skip undamaged TearFree redisplays
If we have not had cause to flush the wait_for_shadow buffer during the
course of the rendering, then we never wrote to the backbuffer and its
contents are still identical to the current frontbuffer. So if the
wait_for_shadow is still flagged as required on the scanout, we know we
can safely discard the redisplay request.
References: https://bugs.freedesktop.org/show_bug.cgi?id=70905
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_display.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index cf3e5761..00eab32e 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -4492,8 +4492,10 @@ void sna_mode_redisplay(struct sna *sna) if (!sna->mode.shadow_damage) return; - DBG(("%s: posting shadow damage? %d\n", - __FUNCTION__, !RegionNil(DamageRegion(sna->mode.shadow_damage)))); + DBG(("%s: posting shadow damage? %d (flips pending? %D)\n", + __FUNCTION__, + !RegionNil(DamageRegion(sna->mode.shadow_damage)), + sna->mode.shadow_flip)); assert((sna->flags & SNA_IS_HOSTED) == 0); assert(sna->mode.shadow_active); @@ -4554,8 +4556,19 @@ void sna_mode_redisplay(struct sna *sna) priv = sna_pixmap(sna->front); assert(priv != NULL); - if (priv->move_to_gpu) + if (priv->move_to_gpu) { + if (priv->move_to_gpu == wait_for_shadow) { + /* No damage written to new scanout + * (backbuffer), ignore redisplay request + * and continue with the current intact + * scanout (frontbuffer). + */ + RegionEmpty(region); + return; + } + (void)priv->move_to_gpu(sna, priv, 0); + } assert(priv->move_to_gpu == NULL); } @@ -4565,9 +4578,15 @@ void sna_mode_redisplay(struct sna *sna) struct sna_crtc *sna_crtc = to_sna_crtc(crtc); RegionRec damage; - if (sna_crtc == NULL || - !sna_crtc->shadow || - sna_crtc->bo == sna->mode.shadow) + if (sna_crtc == NULL) + continue; + + DBG(("%s: crtc[%d] shadow? %d, transformed? %d\n", + __FUNCTION__, i, + sna_crtc->shadow, + sna_crtc->bo != sna->mode.shadow)); + + if (!sna_crtc->shadow || sna_crtc->bo == sna->mode.shadow) continue; assert(crtc->enabled); @@ -4715,6 +4734,11 @@ disable2: crtc->bo = kgem_bo_reference(new); } + DBG(("%s: flipped %d outputs, shadow active? %d\n", + __FUNCTION__, + sna->mode.shadow_flip, + sna->mode.shadow ? sna->mode.shadow->handle : 0)); + if (sna->mode.shadow) { assert(old == sna->mode.shadow); assert(old->refcnt >= 1); |