Bug 1168263 - Propagate the scroll-clip of a descendant of a layer with a perspective transform up to the layer itself. r=kats,mstange

This commit is contained in:
Botond Ballo 2015-11-18 14:21:37 -05:00
Родитель 8e6d03a7b3
Коммит 32478eadd5
2 изменённых файлов: 27 добавлений и 10 удалений

Просмотреть файл

@ -787,13 +787,16 @@ IntersectMaybeRects(const Maybe<IntRectTyped<Units>>& a,
bool
AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
bool* aOutFoundRoot)
bool* aOutFoundRoot,
Maybe<ParentLayerIntRect>& aClipDeferredToParent)
{
Maybe<ParentLayerIntRect> clipDeferredFromChildren;
bool appliedTransform = false;
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
appliedTransform |=
ApplyAsyncContentTransformToTree(child, aOutFoundRoot);
ApplyAsyncContentTransformToTree(child, aOutFoundRoot,
clipDeferredFromChildren);
}
Matrix4x4 oldTransform = aLayer->GetTransform();
@ -900,7 +903,16 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
// move with this APZC.
if (metrics.HasClipRect()) {
ParentLayerIntRect clip = metrics.ClipRect();
asyncClip = IntersectMaybeRects(Some(clip), asyncClip);
if (aLayer->GetParent() && aLayer->GetParent()->GetTransformIsPerspective()) {
// If our parent layer has a perspective transform, we want to apply
// our scroll clip to it instead of to this layer (see bug 1168263).
// A layer with a perspective transform shouldn't have multiple
// children with FrameMetrics, nor a child with multiple FrameMetrics.
MOZ_ASSERT(!aClipDeferredToParent);
aClipDeferredToParent = Some(clip);
} else {
asyncClip = IntersectMaybeRects(Some(clip), asyncClip);
}
}
// Do the same for the ancestor mask layers: ancestorMaskLayers contains
@ -936,11 +948,12 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
transformWithoutOverscrollOrOmta, fixedLayerMargins);
}
if (hasAsyncTransform) {
if (asyncClip) {
aLayer->AsLayerComposite()->SetShadowClipRect(asyncClip);
}
if (hasAsyncTransform || clipDeferredFromChildren) {
aLayer->AsLayerComposite()->SetShadowClipRect(
IntersectMaybeRects(asyncClip, clipDeferredFromChildren));
}
if (hasAsyncTransform) {
// 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
@ -1358,7 +1371,8 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
// in Gecko and partially in Java.
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame);
bool foundRoot = false;
if (ApplyAsyncContentTransformToTree(root, &foundRoot)) {
Maybe<ParentLayerIntRect> clipDeferredFromChildren;
if (ApplyAsyncContentTransformToTree(root, &foundRoot, clipDeferredFromChildren)) {
#if defined(MOZ_ANDROID_APZ)
MOZ_ASSERT(foundRoot);
if (foundRoot && mFixedLayerMargins != ScreenMargin()) {

Просмотреть файл

@ -132,8 +132,11 @@ private:
// applied for |aLayer|. |*aOutFoundRoot| is set to true on Android only, if
// one of the metrics on one of the layers was determined to be the "root"
// and its state was synced to the Java front-end. |aOutFoundRoot| must be
// non-null.
bool ApplyAsyncContentTransformToTree(Layer* aLayer, bool* aOutFoundRoot);
// non-null. As the function recurses over the layer tree, a layer may
// populate |aClipDeferredToParent| a clip rect it wants to set on its parent.
bool ApplyAsyncContentTransformToTree(Layer* aLayer,
bool* aOutFoundRoot,
Maybe<ParentLayerIntRect>& aClipDeferredToParent);
/**
* Update the shadow transform for aLayer assuming that is a scrollbar,
* so that it stays in sync with the content that is being scrolled by APZ.