diff --git a/gfx/layers/AnimationHelper.cpp b/gfx/layers/AnimationHelper.cpp index 56e9b9529bba..aed733af0fad 100644 --- a/gfx/layers/AnimationHelper.cpp +++ b/gfx/layers/AnimationHelper.cpp @@ -540,21 +540,18 @@ AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage, transformData.appUnitsPerDevPixel(), 0, &transformData.bounds()); gfx::Matrix4x4 frameTransform = transform; - - //TODO how do we support this without layer information - // If our parent layer is a perspective layer, then the offset into reference - // frame coordinates is already on that layer. If not, then we need to ask + // If the parent has perspective transform, then the offset into reference + // frame coordinates is already on this transform. If not, then we need to ask // for it to be added here. - // if (!aLayer->GetParent() || - // !aLayer->GetParent()->GetTransformIsPerspective()) { - // nsLayoutUtils::PostTranslate(transform, origin, - // transformData.appUnitsPerDevPixel(), - // true); - // } + if (!transformData.hasPerspectiveParent()) { + nsLayoutUtils::PostTranslate(transform, origin, + transformData.appUnitsPerDevPixel(), + true); + } - // if (ContainerLayer* c = aLayer->AsContainerLayer()) { - // transform.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1); - // } + transform.PostScale(transformData.inheritedXScale(), + transformData.inheritedYScale(), + 1); aStorage->SetAnimatedValue(iter.Key(), Move(transform), Move(frameTransform), diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index ba12ac9ab5f9..9f33099006b0 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -187,6 +187,11 @@ struct TransformData { Point3D transformOrigin; nsRect bounds; int32_t appUnitsPerDevPixel; + // The resolution scale inherited from the parent + float inheritedXScale; + float inheritedYScale; + // True if the parent has perspective transform + bool hasPerspectiveParent; }; union AnimationData { diff --git a/gfx/layers/wr/WebRenderContainerLayer.cpp b/gfx/layers/wr/WebRenderContainerLayer.cpp index a7b0f6f6e51f..227dd164e46e 100644 --- a/gfx/layers/wr/WebRenderContainerLayer.cpp +++ b/gfx/layers/wr/WebRenderContainerLayer.cpp @@ -27,6 +27,21 @@ WebRenderContainerLayer::ClearAnimations() Layer::ClearAnimations(); } +void +WebRenderContainerLayer::UpdateTransformDataForAnimation() +{ + for (Animation& animation : mAnimations) { + if (animation.property() == eCSSProperty_transform) { + TransformData& transformData = animation.data().get_TransformData(); + transformData.inheritedXScale() = GetInheritedXScale(); + transformData.inheritedYScale() = GetInheritedYScale(); + transformData.hasPerspectiveParent() = + GetParent() && GetParent()->GetTransformIsPerspective(); + } + } + } +} + void WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) { @@ -42,18 +57,19 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) !GetAnimations().IsEmpty()) { MOZ_ASSERT(GetCompositorAnimationsId()); - animationsId = GetCompositorAnimationsId(); - CompositorAnimations anim; - anim.animations() = GetAnimations(); - anim.id() = animationsId; - WrBridge()->AddWebRenderParentCommand(OpAddCompositorAnimations(anim)); - if (!HasOpacityAnimation()) { maybeOpacity = nullptr; } if (!HasTransformAnimation()) { maybeTransform = nullptr; + UpdateTransformDataForAnimation(); } + + animationsId = GetCompositorAnimationsId(); + CompositorAnimations anim; + anim.animations() = GetAnimations(); + anim.id() = animationsId; + WrBridge()->AddWebRenderParentCommand(OpAddCompositorAnimations(anim)); } StackingContextHelper sc(aBuilder, this, animationsId, maybeOpacity, maybeTransform); diff --git a/gfx/layers/wr/WebRenderContainerLayer.h b/gfx/layers/wr/WebRenderContainerLayer.h index a5548016c410..8efedb003f6d 100644 --- a/gfx/layers/wr/WebRenderContainerLayer.h +++ b/gfx/layers/wr/WebRenderContainerLayer.h @@ -38,6 +38,8 @@ protected: MOZ_COUNT_DTOR(WebRenderContainerLayer); } + void UpdateTransformDataForAnimation(); + public: Layer* GetLayer() override { return this; } void RenderLayer(wr::DisplayListBuilder& aBuilder) override; diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index eb63f5926966..d91abd6f921c 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -823,6 +823,9 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer, Point3D offsetToTransformOrigin = nsDisplayTransform::GetDeltaToTransformOrigin(aFrame, scale, &bounds); nsPoint origin; + float scaleX = 1.0f; + float scaleY = 1.0f; + bool hasPerspectiveParent = false; if (aItem) { // This branch is for display items to leverage the cache of // nsDisplayListBuilder. @@ -839,7 +842,8 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer, } data = TransformData(origin, offsetToTransformOrigin, - bounds, devPixelsToAppUnits); + bounds, devPixelsToAppUnits, + scaleX, scaleY, hasPerspectiveParent); } else if (aProperty == eCSSProperty_opacity) { data = null_t(); }