Bug 1342229 - Handle perspective: 0 and perspective(0) similarly draft
authorMiko Mynttinen <mikokm@gmail.com>
Wed, 22 Feb 2017 20:58:45 +0100
changeset 493500 70420d07a01431560b9eb35c01e9364ebf85481d
parent 493168 9732cd019a8b94c49a275661320c1b742635a3d6
child 547876 4629ea2f59e31854e32dc9168114276f52a2f0be
push id47779
push userbmo:mikokm@gmail.com
push dateSat, 04 Mar 2017 10:05:29 +0000
bugs1342229
milestone54.0a1
Bug 1342229 - Handle perspective: 0 and perspective(0) similarly 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
@@ -3326,17 +3326,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);
@@ -3826,17 +3826,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);
@@ -6487,17 +6487,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};
@@ -6540,20 +6540,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)
@@ -6966,18 +6965,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 reference/green.html
+== perspective-zero-2.html perspective-zero-2-ref.html