Bug 1394308 - Apply inherited scale for OMTA to support layers-free, r?kats draft
authorpeter chang <pchang@mozilla.com>
Wed, 06 Sep 2017 16:29:52 +0800
changeset 662933 f52999cb06cb1f161990121a1114fdab8da40998
parent 658578 632e42dca494ec3d90b70325d9c359f80cb3f38a
child 662934 34e56a99426ff34a733456d5b100a3a060e29492
push id79243
push userbmo:howareyou322@gmail.com
push dateTue, 12 Sep 2017 09:27:01 +0000
reviewerskats
bugs1394308
milestone57.0a1
Bug 1394308 - Apply inherited scale for OMTA to support layers-free, r?kats Expose the API to get/set inherited scale from stacking context and we can use these APIs to calculate correct scale for OMTA MozReview-Commit-ID: DZEkodHTy8v
gfx/layers/wr/StackingContextHelper.cpp
gfx/layers/wr/StackingContextHelper.h
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -97,27 +97,28 @@ StackingContextHelper::StackingContextHe
     nsRect itemBounds = aDisplayList->GetClippedBoundsWithRespectToASR(aDisplayListBuilder, aItem->GetActiveScrolledRoot());
     nsRect childrenVisible = aItem->GetVisibleRectForChildren();
     visibleRect = itemBounds.Intersect(childrenVisible);
 
     // Apply the inherited scale from parent
     mTransform.PostScale(aParentSC.mXScale, aParentSC.mYScale, 1.0);
     mTransform.NudgeToIntegersFixedEpsilon();
 
+    // Calculate the correct scale for current stacking context
     gfx::Size scale = mTransform.As2D().ScaleFactors(true);
 
     // Restore the scale to default if the scale is too small
     if (FuzzyEqualsAdditive(scale.width, 0.0f) ||
         FuzzyEqualsAdditive(scale.height, 0.0f)) {
       scale = gfx::Size(1.0f, 1.0f);
     }
 
     mTransform.PreScale(1.0f/scale.width, 1.0f/scale.height, 1.0);
 
-    // Store the inherited scale if has
+    // Store the inherited scale for child
     this->mXScale = scale.width;
     this->mYScale = scale.height;
   } else {
     visibleRect = aDisplayList->GetBounds(aDisplayListBuilder);
     // The position of bounds are calculated by transform and perspective matrix in 3d case. reset it to (0, 0)
     visibleRect.MoveTo(0, 0);
   }
   float appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -78,16 +78,28 @@ public:
   // same as the layer space. (TODO: try to make this more explicit somehow).
   wr::LayoutRect ToRelativeLayoutRect(const LayerRect& aRect) const;
   wr::LayoutRect ToRelativeLayoutRect(const LayoutDeviceRect& aRect) const;
   // Same but for points
   wr::LayoutPoint ToRelativeLayoutPoint(const LayerPoint& aPoint) const;
   // Same but rounds the rectangle to ints after transforming.
   wr::LayoutRect ToRelativeLayoutRectRounded(const LayoutDeviceRect& aRect) const;
 
+  // Export the inherited scale
+  gfx::Size GetInheritedScale() const {
+    return gfx::Size(mXScale, mYScale);
+  }
+
+  // Provide interface to setup the inherited scale to support
+  // special cases, like OMTA
+  void SetInheritedScale(const gfx::Size& aScale) {
+    mXScale = aScale.width;
+    mYScale = aScale.height;
+  }
+
   bool IsBackfaceVisible() const { return mTransform.IsBackfaceVisible(); }
 
 private:
   wr::DisplayListBuilder* mBuilder;
   LayerPoint mOrigin;
   gfx::Matrix4x4 mTransform;
 
   float mXScale;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7793,25 +7793,16 @@ nsDisplayTransform::CreateWebRenderComma
 
   if (!animationInfo.GetAnimations().IsEmpty()) {
     animationsId = animationInfo.GetCompositorAnimationsId();
 
     // Update transfrom as nullptr in stacking context if there exists
     // transform animation, the transform value will be resolved
     // after animation sampling on the compositor
     transformForSC = nullptr;
-
-    // Pass default transform to compositor in case gecko fails to
-    // get animated value after animation sampling.
-    OptionalTransform transformForCompositor = newTransformMatrix;
-
-    OpAddCompositorAnimations
-      anim(CompositorAnimations(animationInfo.GetAnimations(), animationsId),
-           transformForCompositor, void_t());
-    aManager->WrBridge()->AddWebRenderParentCommand(anim);
   }
 
   gfx::Matrix4x4Typed<LayerPixel, LayerPixel> boundTransform = ViewAs< gfx::Matrix4x4Typed<LayerPixel, LayerPixel> >(newTransformMatrix);
   boundTransform._41 = 0.0f;
   boundTransform._42 = 0.0f;
   boundTransform._43 = 0.0f;
 
   nsTArray<mozilla::wr::WrFilterOp> filters;
@@ -7822,16 +7813,42 @@ nsDisplayTransform::CreateWebRenderComma
                            mStoredList.GetChildren(),
                            &boundTransform,
                            animationsId,
                            nullptr,
                            transformForSC,
                            nullptr,
                            filters);
 
+  if (animationsId) {
+    // Get the inheritedScale from parent and pass the scale to compositor
+    // to get correct sampling result
+    gfx::Size scale = aSc.GetInheritedScale();
+    for (layers::Animation& animation : animationInfo.GetAnimations()) {
+      if (animation.property() == eCSSProperty_transform) {
+        TransformData& transformData = animation.data().get_TransformData();
+        transformData.inheritedXScale() = scale.width;
+        transformData.inheritedYScale() = scale.height;
+      }
+    }
+
+    // Pass default transform to compositor in case gecko fails to
+    // get animated value after animation sampling.
+    OptionalTransform transformForCompositor = newTransformMatrix;
+    OpAddCompositorAnimations
+      anim(CompositorAnimations(animationInfo.GetAnimations(), animationsId),
+           transformForCompositor, void_t());
+    aManager->WrBridge()->AddWebRenderParentCommand(anim);
+
+    // Since we passed a nullptr transformForSC to the StackingContextHelper,
+    // we now set up the correct inherited scale for the stacking context.
+    newTransformMatrix.PostScale(scale.width, scale.height, 1.0f);
+    sc.SetInheritedScale(newTransformMatrix.As2D().ScaleFactors(true));
+
+  }
   return mStoredList.CreateWebRenderCommands(aBuilder, sc, aParentCommands,
                                              aManager, aDisplayListBuilder);
 }
 
 bool
 nsDisplayTransform::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
                                      mozilla::layers::WebRenderLayerScrollData* aLayerData)
 {