Bug 1358437 - pass layer's transform attributes for transform animation, r?kats
MozReview-Commit-ID: J7JHuwvWuet
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -535,31 +535,28 @@ AnimationHelper::SampleAnimations(Compos
nsDisplayTransform::FrameTransformProperties props(list,
transformOrigin);
gfx::Matrix4x4 transform =
nsDisplayTransform::GetResultingTransformMatrix(props, origin,
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),
transformData);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -182,16 +182,21 @@ struct AnimationSegment {
// functions to a Matrix4x4 that can be applied directly to the layer.
struct TransformData {
// the origin of the frame being transformed in app units
nsPoint origin;
// the transform-origin property for the transform in device pixels
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 {
null_t;
TransformData;
};
struct Animation {
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -23,42 +23,58 @@ WebRenderContainerLayer::ClearAnimations
mManager->AsWebRenderLayerManager()->
AddCompositorAnimationsIdForDiscard(GetCompositorAnimationsId());
}
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();
+ if (GetParent() && GetParent()->GetTransformIsPerspective()) {
+ transformData.hasPerspectiveParent() = true;
+ }
+ }
+ }
+}
+
+void
WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
gfx::Matrix4x4 transform = GetTransform();
gfx::Matrix4x4* maybeTransform = &transform;
float opacity = GetLocalOpacity();
float* maybeOpacity = &opacity;
uint64_t animationsId = 0;
if (gfxPrefs::WebRenderOMTAEnabled() &&
!GetAnimations().IsEmpty()) {
MOZ_ASSERT(GetCompositorAnimationsId());
+ if (!HasOpacityAnimation()) {
+ maybeOpacity = nullptr;
+ }
+ if (!HasTransformAnimation()) {
+ maybeTransform = nullptr;
+ UpdateTransformDataForAnimation();
+ }
+
animationsId = GetCompositorAnimationsId();
CompositorAnimations anim;
anim.animations() = GetAnimations();
anim.id() = animationsId;
WrBridge()->AddWebRenderParentCommand(OpAddCompositorAnimations(anim));
-
- if (!HasOpacityAnimation()) {
- maybeOpacity = nullptr;
- }
- if (!HasTransformAnimation()) {
- maybeTransform = nullptr;
- }
}
StackingContextHelper sc(aBuilder, this, animationsId, maybeOpacity, maybeTransform);
LayerRect rect = Bounds();
DumpLayerInfo("ContainerLayer", rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
--- a/gfx/layers/wr/WebRenderContainerLayer.h
+++ b/gfx/layers/wr/WebRenderContainerLayer.h
@@ -33,16 +33,18 @@ protected:
mManager->AsWebRenderLayerManager()->
AddCompositorAnimationsIdForDiscard(GetCompositorAnimationsId());
}
ContainerLayer::RemoveAllChildren();
MOZ_COUNT_DTOR(WebRenderContainerLayer);
}
+ void UpdateTransformDataForAnimation();
+
public:
Layer* GetLayer() override { return this; }
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
void ClearAnimations() override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -818,33 +818,37 @@ nsDisplayListBuilder::AddAnimationsAndTr
TransformReferenceBox refBox(aFrame);
nsRect bounds(0, 0, refBox.Width(), refBox.Height());
// all data passed directly to the compositor should be in dev pixels
int32_t devPixelsToAppUnits = aFrame->PresContext()->AppUnitsPerDevPixel();
float scale = devPixelsToAppUnits;
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.
origin = aItem->ToReferenceFrame();
} else {
// This branch is running for restyling.
// Animations are animated at the coordination of the reference
// frame outside, not the given frame itself. The given frame
// is also reference frame too, so the parent's reference frame
// are used.
nsIFrame* referenceFrame =
nsLayoutUtils::GetReferenceFrame(nsLayoutUtils::GetCrossDocParentFrame(aFrame));
origin = aFrame->GetOffsetToCrossDoc(referenceFrame);
}
data = TransformData(origin, offsetToTransformOrigin,
- bounds, devPixelsToAppUnits);
+ bounds, devPixelsToAppUnits,
+ scaleX, scaleY, hasPerspectiveParent);
} else if (aProperty == eCSSProperty_opacity) {
data = null_t();
}
AddAnimationsForProperty(aFrame, aProperty, compositorAnimations,
aLayer, data, pending);
}