summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-01-29 05:32:25 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-01-29 05:32:25 +0000
commit4b73a0ea22b43807c0118f4d7e9dcac3f0626463 (patch)
treecc6db15e645480396e78ba0141d74491626622e8
parent9f3fc9ec49f0caf53344577896ef9b6468cd3d4f (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.c36
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);