Bug 1637067. Make the StackingContextHelper constructor handle transforms that cannot be drawn 2d the same as ChooseScale. r=jrmuizel
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 20 May 2020 08:16:04 +0000
changeset 531579 80fd72570c40b2c14324462646a26052eebc4c7a
parent 531578 14b1591d2a170964a6a0c5e198f0c49fce900e5e
child 531580 58f80ec5f2af040f8a3f0fb92db1923179f88c94
push id37440
push userabutkovits@mozilla.com
push dateFri, 22 May 2020 09:43:16 +0000
treeherdermozilla-central@fbf71e4d2e21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1637067, 1449958
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1637067. Make the StackingContextHelper constructor handle transforms that cannot be drawn 2d the same as ChooseScale. r=jrmuizel In StackingContextHelper::StackingContextHelper we want to handle the case of "no passed in transform" differently from "passed in transform but it cannot be drawn 2d". This is a little tricky because ChooseScale always has a transform passed in: in the non-wr case it is a scaling matrix by the parent scale. We could call ChooseScale if canDraw2D is false and get the same value for mScale but we also need to keep mInheritedTransform in sync. This issue arose before: https://bugzilla.mozilla.org/show_bug.cgi?id=1449958#c3 And we want to be careful not to regress that bug, that bug was concerning content without a transform, so we should be good. The testcase has a parent element with rotateY(-80deg) and a child element with rotateY(80deg), the combined transform is flat with no scaling even though each transform individually would have a very small x scale. There's no way to choose a good scale by looking at each transform individually, and since we only currently store transforms as 2d matrices we can't look at the full combined transform in order to choose a scale. Thus we must use a unit scale, like ChooseScale does. Differential Revision: https://phabricator.services.mozilla.com/D75289
gfx/layers/wr/StackingContextHelper.cpp
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -28,37 +28,44 @@ StackingContextHelper::StackingContextHe
     : mBuilder(&aBuilder),
       mScale(1.0f, 1.0f),
       mDeferredTransformItem(aParams.mDeferredTransformItem),
       mRasterizeLocally(aParams.mRasterizeLocally ||
                         aParentSC.mRasterizeLocally) {
   mOrigin = aParentSC.mOrigin + aBounds.TopLeft();
   // Compute scale for fallback rendering. We don't try to guess a scale for 3d
   // transformed items
-  gfx::Matrix transform2d;
-  if (aParams.mBoundTransform &&
-      aParams.mBoundTransform->CanDraw2D(&transform2d) &&
-      aParams.reference_frame_kind != wr::WrReferenceFrameKind::Perspective &&
-      !aContainerFrame->Combines3DTransformWithAncestors()) {
-    mInheritedTransform = transform2d * aParentSC.mInheritedTransform;
+
+  if (aParams.mBoundTransform) {
+    gfx::Matrix transform2d;
+    bool canDraw2D = aParams.mBoundTransform->CanDraw2D(&transform2d);
+    if (canDraw2D &&
+        aParams.reference_frame_kind != wr::WrReferenceFrameKind::Perspective &&
+        !aContainerFrame->Combines3DTransformWithAncestors()) {
+      mInheritedTransform = transform2d * aParentSC.mInheritedTransform;
 
-    int32_t apd = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
-    nsRect r = LayoutDevicePixel::ToAppUnits(aBounds, apd);
-    mScale = FrameLayerBuilder::ChooseScale(
-        aContainerFrame, aContainerItem, r, aParentSC.mScale.width,
-        aParentSC.mScale.height, mInheritedTransform,
-        /* aCanDraw2D = */ true);
+      int32_t apd = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
+      nsRect r = LayoutDevicePixel::ToAppUnits(aBounds, apd);
+      mScale = FrameLayerBuilder::ChooseScale(
+          aContainerFrame, aContainerItem, r, aParentSC.mScale.width,
+          aParentSC.mScale.height, mInheritedTransform,
+          /* aCanDraw2D = */ true);
+    } else {
+      mScale = gfx::Size(1.0f, 1.0f);
+      mInheritedTransform = gfx::Matrix::Scaling(1.f, 1.f);
+    }
 
     if (aParams.mAnimated) {
       mSnappingSurfaceTransform =
           gfx::Matrix::Scaling(mScale.width, mScale.height);
     } else {
       mSnappingSurfaceTransform =
           transform2d * aParentSC.mSnappingSurfaceTransform;
     }
+
   } else {
     mInheritedTransform = aParentSC.mInheritedTransform;
     mScale = aParentSC.mScale;
   }
 
   auto rasterSpace =
       mRasterizeLocally
           ? wr::RasterSpace::Local(std::max(mScale.width, mScale.height))