From dd1ffeacc28c087d6a924085d671ab3578fd50a1 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Fri, 20 Feb 2015 16:01:41 -0500 Subject: [PATCH] Bug 1130982 - Ensure the clip rect is appropriately adjusted for multi-framemetrics layers. r=botond --- .../composite/AsyncCompositionManager.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index bd3a7a114a9..42e489574a8 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -140,7 +140,7 @@ static void TransformClipRect(Layer* aLayer, const Matrix4x4& aTransform) { - const nsIntRect* clipRect = aLayer->GetClipRect(); + const nsIntRect* clipRect = aLayer->AsLayerComposite()->GetShadowClipRect(); if (clipRect) { LayerIntRect transformed = TransformTo( aTransform, LayerIntRect::FromUntyped(*clipRect)); @@ -582,6 +582,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) Matrix4x4 combinedAsyncTransform; bool hasAsyncTransform = false; LayerMargin fixedLayerMargins(0, 0, 0, 0); + Maybe clipRect = ToMaybe(aLayer->AsLayerComposite()->GetShadowClipRect()); for (uint32_t i = 0; i < aLayer->GetFrameMetricsCount(); i++) { AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController(i); @@ -620,9 +621,32 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) combinedAsyncTransformWithoutOverscroll *= asyncTransformWithoutOverscroll; combinedAsyncTransform *= (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform); + if (i > 0 && clipRect) { + // The clip rect Layout calculates is the intersection of the composition + // bounds of all the scroll frames at the time of the paint (when there + // are no async transforms). + // An async transform on a scroll frame does not affect the composition + // bounds of *that* scroll frame, but it does affect the composition + // bounds of the scroll frames *below* it. + // Therefore, if we have multiple scroll frames associated with this + // layer, the clip rect needs to be adjusted for the async transforms of + // the scroll frames other than the bottom-most one. + // To make this adjustment, we start with the Layout-provided clip rect, + // and at each level other than the bottom, transform it by the async + // transform at that level, and then re-intersect it with the composition + // bounds at that level. + ParentLayerRect transformed = TransformTo( + (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform), + ParentLayerRect(ViewAs(*clipRect))); + clipRect = Some(ParentLayerIntRect::ToUntyped( + RoundedOut(transformed.Intersect(metrics.mCompositionBounds)))); + } } if (hasAsyncTransform) { + if (clipRect) { + aLayer->AsLayerComposite()->SetShadowClipRect(clipRect.ptr()); + } // Apply the APZ transform on top of GetLocalTransform() here (rather than // GetTransform()) in case the OMTA code in SampleAnimations already set a // shadow transform; in that case we want to apply ours on top of that one