Bug 1342229 - Handle perspective: 0 and perspective(0) similarly. r=mattwoodrow, r=xidorn, a=lizzard
authorMiko Mynttinen <mikokm@gmail.com>
Wed, 22 Feb 2017 20:58:45 +0100
changeset 379340 8bb9ee1f4d82b15808c0e60c76b8ce53d555c89e
parent 379339 f7dd6b79aa87c6e048f0dabc7e3b7cf1fd350186
child 379341 4b4a2a430c62de7204392ea83df41fae2ea00cd3
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, xidorn, lizzard
bugs1342229
milestone53.0
Bug 1342229 - Handle perspective: 0 and perspective(0) similarly. r=mattwoodrow, r=xidorn, a=lizzard MozReview-Commit-ID: 5RHjdcGqg7t
layout/painting/nsDisplayList.cpp
layout/reftests/w3c-css/submitted/transforms/perspective-zero-2-ref.html
layout/reftests/w3c-css/submitted/transforms/perspective-zero-2.html
layout/reftests/w3c-css/submitted/transforms/reftest.list
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3021,17 +3021,17 @@ nsDisplayBackgroundImage::GetLayerState(
     MOZ_ASSERT(shouldLayerize == ONLY_FOR_SCALING, "unhandled ImageLayerization value?");
 
     MOZ_ASSERT(mImage);
     int32_t imageWidth;
     int32_t imageHeight;
     mImage->GetWidth(&imageWidth);
     mImage->GetHeight(&imageHeight);
     NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
-  
+
     int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
     LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(GetDestRect(), appUnitsPerDevPixel);
 
     const LayerRect destLayerRect = destRect * aParameters.Scale();
 
     // Calculate the scaling factor for the frame.
     const gfxSize scale = gfxSize(destLayerRect.width / imageWidth,
                                   destLayerRect.height / imageHeight);
@@ -3528,17 +3528,17 @@ nsDisplayImageContainer::ConfigureLayer(
   // the ImageContainer's size rather than the image's intrinsic size.
   // XXX(seth): In reality, since the size of the ImageContainer may change
   // asynchronously, this is not enough. Bug 1183378 will provide a more
   // complete fix, but this solution is safe in more cases than simply relying
   // on the intrinsic size.
   IntSize containerSize = aLayer->GetContainer()
                         ? aLayer->GetContainer()->GetCurrentSize()
                         : IntSize(imageWidth, imageHeight);
-  
+
   const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
   const LayoutDeviceRect destRect =
     LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
 
   const LayoutDevicePoint p = destRect.TopLeft();
   Matrix transform = Matrix::Translation(p.x, p.y);
   transform.PreScale(destRect.width / containerSize.width,
                      destRect.height / containerSize.height);
@@ -5959,17 +5959,17 @@ nsDisplayTransform::ComputePerspectiveMa
 
   /* Grab the values for perspective and perspective-origin (if present) */
 
   const nsStyleDisplay* cbDisplay = cbFrame->StyleDisplay();
   if (cbDisplay->mChildPerspective.GetUnit() != eStyleUnit_Coord) {
     return false;
   }
   nscoord perspective = cbDisplay->mChildPerspective.GetCoordValue();
-  if (perspective < 0) {
+  if (perspective < std::numeric_limits<Float>::epsilon()) {
     return true;
   }
 
   TransformReferenceBox refBox(cbFrame);
 
   /* Allows us to access named variables by index. */
   Point3D perspectiveOrigin;
   gfx::Float* coords[2] = {&perspectiveOrigin.x, &perspectiveOrigin.y};
@@ -6012,20 +6012,19 @@ nsDisplayTransform::ComputePerspectiveMa
             NSAppUnitsToFloatPixels(frameToCbOffset.y, aAppUnitsPerPixel),
             0.0f);
 
   /* Move the perspective origin to be relative to aFrame, instead of relative
    * to the containing block which is how it was specified in the style system.
    */
   perspectiveOrigin += frameToCbGfxOffset;
 
-  Float perspectivePx = std::max(NSAppUnitsToFloatPixels(perspective,
-                                                         aAppUnitsPerPixel),
-                                 std::numeric_limits<Float>::epsilon());
-  aOutMatrix._34 = -1.0 / perspectivePx;
+  aOutMatrix._34 =
+    -1.0 / NSAppUnitsToFloatPixels(perspective, aAppUnitsPerPixel);
+
   aOutMatrix.ChangeBasis(perspectiveOrigin);
   return true;
 }
 
 nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame,
                                                                        float aAppUnitsPerPixel,
                                                                        const nsRect* aBoundsOverride)
   : mFrame(aFrame)
@@ -6446,18 +6445,20 @@ nsDisplayTransform::MayBeAnimated(nsDisp
 
 nsDisplayItem::LayerState
 nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
                                   LayerManager* aManager,
                                   const ContainerLayerParameters& aParameters) {
   // If the transform is 3d, the layer takes part in preserve-3d
   // sorting, or the layer is a separator then we *always* want this
   // to be an active layer.
+  // Checking HasPerspective() is needed to handle perspective value 0 when
+  // the transform is 2D.
   if (!GetTransform().Is2D() || mFrame->Combines3DTransformWithAncestors() ||
-      mIsTransformSeparator) {
+      mIsTransformSeparator || mFrame->HasPerspective()) {
     return LAYER_ACTIVE_FORCE;
   }
 
   if (MayBeAnimated(aBuilder)) {
     // Returns LAYER_ACTIVE_FORCE to avoid flatterning the layer for async
     // animations.
     return LAYER_ACTIVE_FORCE;
   }
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/transforms/perspective-zero-2-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>CSS transforms: perspective: 0px reference</title>
+<link rel="author" title="Miko Mynttinen" href="mailto:mmynttinen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style type="text/css">
+.parent {
+  transform: perspective(0px);
+}
+.parent > div {
+  width: 200px;
+  height: 200px;
+  position: absolute;
+}
+.child-3d {
+  background: green;
+  transform: translateZ(1px);
+}
+</style>
+</head>
+<body>
+<p>Test passes if there is only green below.</p>
+<div class="parent">
+  <div class="child-3d"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/transforms/perspective-zero-2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>CSS transforms: perspective: 0px</title>
+<link rel="author" title="Miko Mynttinen" href="mailto:mmynttinen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
+<meta name="assert" content="Test checks that perspective: 0px behaves like transform: perspective(0) on parent container">
+<link rel="match" href="perspective-zero-2-ref.html">
+<style type="text/css">
+.parent {
+  perspective: 0px;
+}
+.parent > div {
+  width: 200px;
+  height: 200px;
+  position: absolute;
+}
+.child-2d {
+  background: red;
+}
+.child-3d {
+  background: green;
+  transform: translateZ(1px);
+}
+</style>
+</head>
+<body>
+<p>Test passes if there is only green below.</p>
+<div class="parent">
+  <div class="child-2d"></div>
+  <div class="child-3d"></div>
+</div>
+</body>
+</html>
--- a/layout/reftests/w3c-css/submitted/transforms/reftest.list
+++ b/layout/reftests/w3c-css/submitted/transforms/reftest.list
@@ -1,5 +1,6 @@
 == transform-containing-block-dynamic-1a.html containing-block-dynamic-1-ref.html
 == transform-containing-block-dynamic-1b.html containing-block-dynamic-1-ref.html
 == perspective-containing-block-dynamic-1a.html containing-block-dynamic-1-ref.html
 == perspective-containing-block-dynamic-1b.html containing-block-dynamic-1-ref.html
 == perspective-zero.html green.html
+== perspective-zero-2.html perspective-zero-2-ref.html