From e41f4e8c1afa92b5f0dc87ddc6b3b7e8c42e6aa1 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Fri, 11 Mar 2016 16:09:16 -0500 Subject: [PATCH] Bug 1255068 - Do not allow empty transaction transform changes if the scroll position has changed since the last paint. r=kats, r=mattwoodrow MozReview-Commit-ID: 7exuhuf3HTJ --HG-- extra : rebase_source : b131cdc68e07ab8dfdc6ae56caa24cc0ced5102e --- layout/generic/nsFrame.cpp | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 5b7ca31d42ae..b85ded0fbc49 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -5272,6 +5272,37 @@ nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey) /*static*/ uint8_t nsIFrame::sLayerIsPrerenderedDataKey; +static bool +DoesLayerHaveOutOfDateFrameMetrics(Layer* aLayer) +{ + for (uint32_t i = 0; i < aLayer->GetFrameMetricsCount(); i++) { + const FrameMetrics& metrics = aLayer->GetFrameMetrics(i); + nsIScrollableFrame* scrollableFrame = + nsLayoutUtils::FindScrollableFrameFor(metrics.GetScrollId()); + if (!scrollableFrame) { + // This shouldn't happen, so let's do the safe thing and trigger a full + // paint if it does. + return true; + } + nsPoint scrollPosition = scrollableFrame->GetScrollPosition(); + if (metrics.GetScrollOffset() != CSSPoint::FromAppUnits(scrollPosition)) { + return true; + } + } + return false; +} + +static bool +DoesLayerOrAncestorsHaveOutOfDateFrameMetrics(Layer* aLayer) +{ + for (Layer* layer = aLayer; layer; layer = layer->GetParent()) { + if (DoesLayerHaveOutOfDateFrameMetrics(layer)) { + return true; + } + } + return false; +} + bool nsIFrame::TryUpdateTransformOnly(Layer** aLayerResult) { @@ -5284,6 +5315,14 @@ nsIFrame::TryUpdateTransformOnly(Layer** aLayerResult) return false; } + if (DoesLayerOrAncestorsHaveOutOfDateFrameMetrics(layer)) { + // At least one scroll frame that can affect the position of this layer + // has changed its scroll offset since the last paint. Schedule a full + // paint to make sure that this layer's transform and all the frame + // metrics that affect it are in sync. + return false; + } + gfx::Matrix4x4 transform3d; if (!nsLayoutUtils::GetLayerTransformForFrame(this, &transform3d)) { // We're not able to compute a layer transform that we know would