Correct handling of [0px,1px) values of perspective and perspective().

This makes a number of fixes to handling small values of the perspective
CSS property and the perspective() transform function to match the
css-transforms-2 specification (the latest updates to which come from
the resolutions in https://github.com/w3c/csswg-drafts/issues/413):

 * Accept zero values of the perspective property at parse time.  (They
   were already accepted for the perspective function.)

   Zero values are currently accepted by Gecko, but it treats them as
   the identity matrix (that is, as infinite perspective) rather than
   clamping to 1px.

 * Use -1.0 rather than 0.0 as the internal representation of
   perspective: none.

 * For rendering of both the perspective property and the perspective()
   transform function, treat values smaller than 1px as 1px.

 * For interpolation of the perspective() transform function,
   treat values smaller than 1px as 1px.  This is an additional
   clarification to the resolution that I proposed in
   https://github.com/w3c/csswg-drafts/issues/6320.

 * When handling the perspective() transform function when finding the
   resolved value of the transform property (which is a matrix() or
   matrix3d() value), treat values smaller than 1px as 1px.  (Resolved
   values are the results of getComputedStyle().)  This is an additional
   clarification that I proposed in
   https://github.com/w3c/csswg-drafts/issues/6346.

Note that interpolation and resolved values of the perspective property
since both interpolation and resolved values match the specified values.
In the case of interpolation that was resolved specifically in
https://github.com/w3c/csswg-drafts/issues/3084.

It also substantially simplifies PerspectiveTransformOperation::Blend,
although I *believe* the only substantive change is the clamping of its
inputs to be 1px or larger.

Parts of this are somewhat risky, since previously transform:
perspective(0) was treated as the identity matrix and perspective: 0 was
a syntax error, whereas this makes both be treated as very substantial
transform (perspective from 1px away).  The old behavior of transform:
perspective(0) was interoperable across browsers.  The old behavior of
perspective: 0 was different in Gecko (where it was valid syntax, but
like transform: perspective(0) was treated as the identity matrix), but
the old behaviors across browsers still had in common that they all led
to the identity matrix (whether valid or invalid syntax), which is not
true of the new behavior.  The risk for handling of values in (0px, 1px)
is probably less substantial since those were already treated as extreme
transforms, and this makes them less extreme.

There are thus three possible less-risky alternatives, from more risk
(but less than this) to lowest risk:

 * Use this patch, but omit the changes to perspective: 0 and
   perspective(0) except for the change that makes perspective: 0 valid,
   but treat perspective: 0 as an identity transform like Gecko does.

 * Use this patch, but omit all the changes to perspective: 0px and
   perspective(0).

 * Change the behavior only when DBL_TRUE_MIN <= perspective < DBL_MIN,
   by treating perspective (property or function) as DBL_MIN in those
   cases.

However, it's worth trying this riskier alternative and following the
CSS Working Group's decision because that decision was made for good
reasons.  Taking this approach has two advantages:

 (1) It eliminates the only case where the valid values of a CSS
     property are an open range (a range exclusive of its endpoint),
     which creates difficulties for defining clamping of values to the
     valid range, which is important to CSS both for calc() and for
     animations (e.g., when the timing function result is outside of
     [0, 1]).

 (2) It eliminates a discontinuity in behavior at zero.  Discontinuities
     in behavior cause animations that cross the discontinuity to behave
     poorly.

Fixed: 1205161
Change-Id: Ie11a3d27d32e6ce16c39d670f6423a6710ba0971
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2924023
Commit-Queue: David Baron <dbaron@chromium.org>
Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#889344}
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 508cbd0..fee8861 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -3323,7 +3323,7 @@
       interpolable: true,
       field_group: "*",
       field_template: "primitive",
-      default_value: "0.0",
+      default_value: "-1.0",
       type_name: "float",
       converter: "ConvertPerspective",
       keywords: ["none"],
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index 9a8b361..f57abae 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -5374,20 +5374,18 @@
   if (range.Peek().Id() == CSSValueID::kNone)
     return css_parsing_utils::ConsumeIdent(range);
   CSSPrimitiveValue* parsed_value =
-      css_parsing_utils::ConsumeLength(range, context, kValueRangeAll);
+      css_parsing_utils::ConsumeLength(range, context, kValueRangeNonNegative);
   bool use_legacy_parsing = localContext.UseAliasParsing();
   if (!parsed_value && use_legacy_parsing) {
     double perspective;
-    if (!css_parsing_utils::ConsumeNumberRaw(range, context, perspective))
+    if (!css_parsing_utils::ConsumeNumberRaw(range, context, perspective) ||
+        perspective < 0.0)
       return nullptr;
     context.Count(WebFeature::kUnitlessPerspectiveInPerspectiveProperty);
     parsed_value = CSSNumericLiteralValue::Create(
         perspective, CSSPrimitiveValue::UnitType::kPixels);
   }
-  if (parsed_value &&
-      (parsed_value->IsCalculated() || parsed_value->GetDoubleValue() > 0))
-    return parsed_value;
-  return nullptr;
+  return parsed_value;
 }
 
 const CSSValue* Perspective::CSSValueFromComputedStyleInternal(
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 4a6f5f66..3fb5588 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1995,7 +1995,7 @@
 
     TransformationMatrix perspective_matrix;
     perspective_matrix.ApplyPerspective(
-        container_object->StyleRef().Perspective());
+        container_object->StyleRef().UsedPerspective());
     perspective_matrix.ApplyTransformOrigin(perspective_origin.X(),
                                             perspective_origin.Y(), 0);
 
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 2fad389..d52faa7 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -3339,7 +3339,7 @@
 
     TransformationMatrix perspective_matrix;
     perspective_matrix.ApplyPerspective(
-        container_object->StyleRef().Perspective());
+        container_object->StyleRef().UsedPerspective());
     perspective_matrix.ApplyTransformOrigin(perspective_origin.X(),
                                             perspective_origin.Y(), 0);
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 394c787..6191746 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1917,7 +1917,7 @@
       // most transform nodes do.
       TransformPaintPropertyNode::State state{
           TransformPaintPropertyNode::TransformAndOrigin(
-              TransformationMatrix().ApplyPerspective(style.Perspective()),
+              TransformationMatrix().ApplyPerspective(style.UsedPerspective()),
               PerspectiveOrigin(To<LayoutBox>(object_)) +
                   FloatSize(context_.current.paint_offset))};
       state.flags.flattens_inherited_transform =
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 467e9b0..9643112 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -26,6 +26,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_H_
 
+#include <algorithm>
 #include <memory>
 #include "base/types/pass_key.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -1931,7 +1932,12 @@
   }
 
   // Perspective utility functions.
-  bool HasPerspective() const { return Perspective() > 0; }
+  bool HasPerspective() const { return Perspective() >= 0; }
+
+  float UsedPerspective() const {
+    DCHECK(HasPerspective());
+    return std::max(1.0f, Perspective());
+  }
 
   // Outline utility functions.
   // HasOutline is insufficient to determine whether Node has an outline.
diff --git a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
index 83fe6f2b..66c77ff 100644
--- a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
+++ b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
@@ -25,6 +25,7 @@
 
 #include "third_party/blink/renderer/platform/transforms/perspective_transform_operation.h"
 
+#include <algorithm>
 #include "third_party/blink/renderer/platform/geometry/blend.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 
@@ -33,18 +34,15 @@
 scoped_refptr<TransformOperation> PerspectiveTransformOperation::Accumulate(
     const TransformOperation& other) {
   DCHECK(other.IsSameType(*this));
-  double other_p = To<PerspectiveTransformOperation>(other).p_;
-
-  if (p_ == 0 && other_p == 0)
-    return nullptr;
+  double other_p = To<PerspectiveTransformOperation>(other).UsedPerspective();
+  double p = UsedPerspective();
 
   // We want to solve:
   //   -1/p + -1/p' == -1/p'', where we know p and p'.
   //
   // This can be rewritten as:
   //   p'' == (p * p') / (p + p')
-  double p = (p_ * other_p) / (p_ + other_p);
-  return PerspectiveTransformOperation::Create(p);
+  return PerspectiveTransformOperation::Create((p * other_p) / (p + other_p));
 }
 
 scoped_refptr<TransformOperation> PerspectiveTransformOperation::Blend(
@@ -54,34 +52,27 @@
   if (from && !from->IsSameType(*this))
     return this;
 
+  // https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions
+  // says that we should run matrix decomposition and then run the rules for
+  // interpolation of matrices, but we know what those rules are going to
+  // yield, so just do that directly.
+  double from_p_inverse, to_p_inverse;
   if (blend_to_identity) {
-    // FIXME: this seems wrong.  https://bugs.webkit.org/show_bug.cgi?id=52700
-    double p = blink::Blend(p_, 1., progress);
-    return PerspectiveTransformOperation::Create(clampTo<int>(p, 0));
+    from_p_inverse = 1.0 / UsedPerspective();
+    to_p_inverse = 0.0;
+  } else {
+    if (from) {
+      const PerspectiveTransformOperation* from_op =
+          static_cast<const PerspectiveTransformOperation*>(from);
+      from_p_inverse = 1.0 / from_op->UsedPerspective();
+    } else {
+      from_p_inverse = 0.0;
+    }
+    to_p_inverse = 1.0 / UsedPerspective();
   }
-
-  const PerspectiveTransformOperation* from_op =
-      static_cast<const PerspectiveTransformOperation*>(from);
-
-  TransformationMatrix from_t;
-  TransformationMatrix to_t;
-  from_t.ApplyPerspective(from_op ? from_op->p_ : 0);
-  to_t.ApplyPerspective(p_);
-  to_t.Blend(from_t, progress);
-
-  TransformationMatrix::DecomposedType decomp;
-  if (!to_t.Decompose(decomp)) {
-    // If we can't decompose, bail out of interpolation.
-    const PerspectiveTransformOperation* used_operation =
-        progress > 0.5 ? this : from_op;
-    return PerspectiveTransformOperation::Create(used_operation->Perspective());
-  }
-
-  if (decomp.perspective_z) {
-    double val = -1.0 / decomp.perspective_z;
-    return PerspectiveTransformOperation::Create(clampTo<double>(val, 0));
-  }
-  return PerspectiveTransformOperation::Create(0);
+  double p =
+      1.0 / std::max(0.0, blink::Blend(from_p_inverse, to_p_inverse, progress));
+  return PerspectiveTransformOperation::Create(clampTo<double>(p, 0));
 }
 
 scoped_refptr<TransformOperation> PerspectiveTransformOperation::Zoom(
diff --git a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
index cae996b..2db2120 100644
--- a/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
+++ b/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
@@ -26,6 +26,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_PERSPECTIVE_TRANSFORM_OPERATION_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_PERSPECTIVE_TRANSFORM_OPERATION_H_
 
+#include <algorithm>
 #include "third_party/blink/renderer/platform/transforms/transform_operation.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 
@@ -40,6 +41,8 @@
 
   double Perspective() const { return p_; }
 
+  double UsedPerspective() const { return std::max(1.0, p_); }
+
   static bool IsMatchingOperationType(OperationType type) {
     return type == kPerspective;
   }
@@ -56,7 +59,7 @@
   }
 
   void Apply(TransformationMatrix& transform, const FloatSize&) const override {
-    transform.ApplyPerspective(p_);
+    transform.ApplyPerspective(UsedPerspective());
   }
 
   scoped_refptr<TransformOperation> Accumulate(
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index d5af246..a157f509 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5446,11 +5446,9 @@
 
 crbug.com/943503 external/wpt/css/css-transforms/transform3d-perspective-003.html [ Failure ]
 crbug.com/943503 external/wpt/css/css-transforms/transform3d-perspective-004.html [ Failure ]
-crbug.com/943503 external/wpt/css/css-transforms/transform3d-perspective-005.html [ Failure ]
 
 crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-perspective-003.html [ Pass ]
 crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-perspective-004.html [ Pass ]
-crbug.com/943503 virtual/transform-interop/external/wpt/css/css-transforms/transform3d-perspective-005.html [ Pass ]
 
 # Swiftshader issue.
 crbug.com/1048149 external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-non-integer-innerwidth.html [ Crash Timeout ]
diff --git a/third_party/blink/web_tests/animations/interpolation/webkit-perspective-interpolation.html b/third_party/blink/web_tests/animations/interpolation/webkit-perspective-interpolation.html
index 5c79eb3..1b7f010 100644
--- a/third_party/blink/web_tests/animations/interpolation/webkit-perspective-interpolation.html
+++ b/third_party/blink/web_tests/animations/interpolation/webkit-perspective-interpolation.html
@@ -32,7 +32,7 @@
   from: '50px',
   to: '100px'
 }, [
-  {at: -20, is: 'none'}, // perspective does not accept 0 or negative values
+  {at: -20, is: '0px'},
   {at: -0.3, is: '35px'},
   {at: 0, is: '50px'},
   {at: 0.3, is: '65px'},
diff --git a/third_party/blink/web_tests/animations/responsive/animations-responsive-perspective.html b/third_party/blink/web_tests/animations/responsive/animations-responsive-perspective.html
index 6f45c9e9..411c760 100644
--- a/third_party/blink/web_tests/animations/responsive/animations-responsive-perspective.html
+++ b/third_party/blink/web_tests/animations/responsive/animations-responsive-perspective.html
@@ -26,11 +26,11 @@
 
     player.currentTime = 5;
     element.style.fontSize = '40px';
-    assert_equals(getComputedStyle(element).perspective, 'none');
+    assert_equals(getComputedStyle(element).perspective, '0px');
 
     player.currentTime = 7.5;
-    assert_equals(getComputedStyle(element).perspective, 'none');
-}, 'perspective clamped to none');
+    assert_equals(getComputedStyle(element).perspective, '0px');
+}, 'perspective clamped to 0px');
 
 test(function() {
     container.style.perspective = 'none';
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation-expected.txt
deleted file mode 100644
index 26e1427..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation-expected.txt
+++ /dev/null
@@ -1,184 +0,0 @@
-This is a testharness.js-based test.
-Found 180 tests; 164 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL CSS Transitions: property <perspective> from neutral to [20px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Transitions: property <perspective> from neutral to [20px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (-0.3) should be [7px]
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (0) should be [10px]
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (0.3) should be [13px]
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (0.6) should be [16px]
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (1) should be [20px]
-PASS CSS Transitions: property <perspective> from neutral to [20px] at (1.5) should be [25px]
-FAIL CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (-0.3) should be [7px]
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (0) should be [10px]
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (0.3) should be [13px]
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (0.6) should be [16px]
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (1) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from neutral to [20px] at (1.5) should be [25px]
-FAIL CSS Animations: property <perspective> from neutral to [20px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Animations: property <perspective> from neutral to [20px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Animations: property <perspective> from neutral to [20px] at (-0.3) should be [7px]
-PASS CSS Animations: property <perspective> from neutral to [20px] at (0) should be [10px]
-PASS CSS Animations: property <perspective> from neutral to [20px] at (0.3) should be [13px]
-PASS CSS Animations: property <perspective> from neutral to [20px] at (0.6) should be [16px]
-PASS CSS Animations: property <perspective> from neutral to [20px] at (1) should be [20px]
-PASS CSS Animations: property <perspective> from neutral to [20px] at (1.5) should be [25px]
-FAIL Web Animations: property <perspective> from neutral to [20px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL Web Animations: property <perspective> from neutral to [20px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS Web Animations: property <perspective> from neutral to [20px] at (-0.3) should be [7px]
-PASS Web Animations: property <perspective> from neutral to [20px] at (0) should be [10px]
-PASS Web Animations: property <perspective> from neutral to [20px] at (0.3) should be [13px]
-PASS Web Animations: property <perspective> from neutral to [20px] at (0.6) should be [16px]
-PASS Web Animations: property <perspective> from neutral to [20px] at (1) should be [20px]
-PASS Web Animations: property <perspective> from neutral to [20px] at (1.5) should be [25px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (-0.3) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (0) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (0.3) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (0.5) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (0.6) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (1) should be [20px]
-PASS CSS Transitions: property <perspective> from [initial] to [20px] at (1.5) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (-0.3) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (0) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (0.3) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (0.5) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (0.6) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (1) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [initial] to [20px] at (1.5) should be [20px]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (-0.3) should be [initial]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (0) should be [initial]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (0.3) should be [initial]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (0.5) should be [20px]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (0.6) should be [20px]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (1) should be [20px]
-PASS CSS Animations: property <perspective> from [initial] to [20px] at (1.5) should be [20px]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (-0.3) should be [initial]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (0) should be [initial]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (0.3) should be [initial]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (0.5) should be [20px]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (0.6) should be [20px]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (1) should be [20px]
-PASS Web Animations: property <perspective> from [initial] to [20px] at (1.5) should be [20px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (-20) should be [230px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (-1) should be [40px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (-0.3) should be [33px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (0) should be [30px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (0.3) should be [27px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (0.6) should be [24px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (1) should be [20px]
-PASS CSS Transitions: property <perspective> from [inherit] to [20px] at (1.5) should be [15px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (-20) should be [230px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (-1) should be [40px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (-0.3) should be [33px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (0) should be [30px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (0.3) should be [27px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (0.6) should be [24px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (1) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [inherit] to [20px] at (1.5) should be [15px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (-20) should be [230px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (-1) should be [40px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (-0.3) should be [33px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (0) should be [30px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (0.3) should be [27px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (0.6) should be [24px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (1) should be [20px]
-PASS CSS Animations: property <perspective> from [inherit] to [20px] at (1.5) should be [15px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (-20) should be [230px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (-1) should be [40px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (-0.3) should be [33px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (0) should be [30px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (0.3) should be [27px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (0.6) should be [24px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (1) should be [20px]
-PASS Web Animations: property <perspective> from [inherit] to [20px] at (1.5) should be [15px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (-0.3) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (0) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (0.3) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (0.5) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (0.6) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (1) should be [20px]
-PASS CSS Transitions: property <perspective> from [unset] to [20px] at (1.5) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (-0.3) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (0) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (0.3) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (0.5) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (0.6) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (1) should be [20px]
-PASS CSS Transitions with transition: all: property <perspective> from [unset] to [20px] at (1.5) should be [20px]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (-0.3) should be [unset]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (0) should be [unset]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (0.3) should be [unset]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (0.5) should be [20px]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (0.6) should be [20px]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (1) should be [20px]
-PASS CSS Animations: property <perspective> from [unset] to [20px] at (1.5) should be [20px]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (-0.3) should be [unset]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (0) should be [unset]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (0.3) should be [unset]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (0.5) should be [20px]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (0.6) should be [20px]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (1) should be [20px]
-PASS Web Animations: property <perspective> from [unset] to [20px] at (1.5) should be [20px]
-FAIL CSS Transitions: property <perspective> from [50px] to [100px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Transitions: property <perspective> from [50px] to [100px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (-0.3) should be [35px]
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (0) should be [50px]
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (0.3) should be [65px]
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (0.6) should be [80px]
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (1) should be [100px]
-PASS CSS Transitions: property <perspective> from [50px] to [100px] at (1.5) should be [125px]
-FAIL CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (-0.3) should be [35px]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (0) should be [50px]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (0.3) should be [65px]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (0.6) should be [80px]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (1) should be [100px]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [100px] at (1.5) should be [125px]
-FAIL CSS Animations: property <perspective> from [50px] to [100px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL CSS Animations: property <perspective> from [50px] to [100px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (-0.3) should be [35px]
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (0) should be [50px]
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (0.3) should be [65px]
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (0.6) should be [80px]
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (1) should be [100px]
-PASS CSS Animations: property <perspective> from [50px] to [100px] at (1.5) should be [125px]
-FAIL Web Animations: property <perspective> from [50px] to [100px] at (-20) should be [0px] assert_equals: expected "10px " but got "none "
-FAIL Web Animations: property <perspective> from [50px] to [100px] at (-1) should be [0px] assert_equals: expected "10px " but got "none "
-PASS Web Animations: property <perspective> from [50px] to [100px] at (-0.3) should be [35px]
-PASS Web Animations: property <perspective> from [50px] to [100px] at (0) should be [50px]
-PASS Web Animations: property <perspective> from [50px] to [100px] at (0.3) should be [65px]
-PASS Web Animations: property <perspective> from [50px] to [100px] at (0.6) should be [80px]
-PASS Web Animations: property <perspective> from [50px] to [100px] at (1) should be [100px]
-PASS Web Animations: property <perspective> from [50px] to [100px] at (1.5) should be [125px]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (-0.3) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (0) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (0.3) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (0.5) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (0.6) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (1) should be [none]
-PASS CSS Transitions: property <perspective> from [50px] to [none] at (1.5) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (-0.3) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (0) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (0.3) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (0.5) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (0.6) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (1) should be [none]
-PASS CSS Transitions with transition: all: property <perspective> from [50px] to [none] at (1.5) should be [none]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (-0.3) should be [50px]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (0) should be [50px]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (0.3) should be [50px]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (0.5) should be [none]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (0.6) should be [none]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (1) should be [none]
-PASS CSS Animations: property <perspective> from [50px] to [none] at (1.5) should be [none]
-PASS Web Animations: property <perspective> from [50px] to [none] at (-0.3) should be [50px]
-PASS Web Animations: property <perspective> from [50px] to [none] at (0) should be [50px]
-PASS Web Animations: property <perspective> from [50px] to [none] at (0.3) should be [50px]
-PASS Web Animations: property <perspective> from [50px] to [none] at (0.5) should be [none]
-PASS Web Animations: property <perspective> from [50px] to [none] at (0.6) should be [none]
-PASS Web Animations: property <perspective> from [50px] to [none] at (1) should be [none]
-PASS Web Animations: property <perspective> from [50px] to [none] at (1.5) should be [none]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html
index 93eec76..d3f165d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/perspective-interpolation.html
@@ -92,6 +92,21 @@
   {at: 1.5, expect: '125px'},
 ]);
 
+test_interpolation({
+  property: 'perspective',
+  from: '0px', // Test that there's no special handling of 0px, as for perspective()
+  to: '10px',
+}, [
+  {at: -20, expect: '0px'}, // perspective does not accept negative values
+  {at: -1, expect: '0px'}, // perspective does not accept negative values
+  {at: -0.3, expect: '0px'},
+  {at: 0, expect: '0px'},
+  {at: 0.3, expect: '3px'},
+  {at: 0.6, expect: '6px'},
+  {at: 1, expect: '10px'},
+  {at: 1.5, expect: '15px'},
+]);
+
 test_no_interpolation({
   property: 'perspective',
   from: '50px',
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2-ref.html
index 64969c4..bea389a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2-ref.html
@@ -5,18 +5,22 @@
 <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">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
 <style type="text/css">
 .parent {
   transform: perspective(0px);
+  transform-style: preserve-3d;
+  transform-origin: top left;
 }
 .parent > div {
-  width: 200px;
-  height: 200px;
+  width: 100px;
+  height: 100px;
   position: absolute;
 }
 .child-3d {
   background: green;
-  transform: translateZ(1px);
+  transform: translateZ(0.5px);
 }
 </style>
 </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2.html
index 59565ff..a94de82b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-2.html
@@ -5,6 +5,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="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
 <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-perspective">
 <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">
@@ -12,18 +14,21 @@
 <style type="text/css">
 .parent {
   perspective: 0px;
+  perspective-origin: top left;
 }
 .parent > div {
-  width: 200px;
-  height: 200px;
   position: absolute;
 }
 .child-2d {
   background: red;
+  width: 200px;
+  height: 200px;
 }
 .child-3d {
+  width: 100px;
+  height: 100px;
   background: green;
-  transform: translateZ(1px);
+  transform: translateZ(0.5px);
 }
 </style>
 </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-3.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-3.html
new file mode 100644
index 0000000..0c46bd0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero-3.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset=UTF-8>
+<title>CSS Test: perspective(0)</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#perspective-property">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
+<meta name="assert" content="perspective: 0 should be clamped to 1px">
+<link rel="match" href="reference/green.html">
+<style>
+#outer {
+  width: 100px;
+  height: 100px;
+  background: red;
+  perspective: 0;
+  perspective-origin: top left;
+}
+#inner {
+  width: 50px;
+  height: 50px;
+  background: green;
+  /* perspective: 0 should be treated as perspective(1px), which should
+   * cause this box to be much larger. */
+  transform: translateZ(0.5px);
+}
+</style>
+<p>Pass if there is NO red below:</p>
+<div id="outer"><div id="inner"></div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero.html
index f0044ad0..93d2b63 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/perspective-zero.html
@@ -3,29 +3,28 @@
 <title>CSS Test: transform: perspective(0)</title>
 <link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
 <link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
 <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#funcdef-perspective">
-<meta name="assert" content="perspective(0) should behave like identity transform function.">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
+<meta name="assert" content="perspective(0) should be clamped to 1px">
 <link rel="match" href="reference/green.html">
 <style>
-#cover-me, #test {
+#cover-me {
   width: 100px;
   height: 100px;
-}
-#cover-me {
   background: red;
   position: relative;
   margin-bottom: -100px;
 }
 #test {
   background: green;
-  /* This should be an identity transform, since perspective(0) must be
-   * treated as perspective(infinity), and consequently translateZ()
-   * doesn't have any effect, so that it covers up #cover-me.
-   * If perspective(0) is invalid, #test would not create a stacking
-   * context, and #cover-me would be placed on top of #test showing red.
-   * If perspective(0) is handled as perspective(epsilon), #test would
-   * be invisible. */
-  transform: perspective(0) translateZ(50px);
+  transform-origin: top left;
+  width: 50px;
+  height: 50px;
+  /* perspective(0) should be treated as perspective(1px), which should
+   * cause this box to be much larger. */
+  transform: perspective(0) translateZ(0.5px);
 }
 </style>
 <p>Pass if there is NO red below:</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-005.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-005.html
index 92b2efa..f23375d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-005.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/transform3d-perspective-005.html
@@ -4,16 +4,19 @@
     <title>CSS Test (Transforms): 'perspective: 1000px' on Grandparent and
     'perspective: 0px' on Parent</title>
     <link rel="author" title="Aryeh Gregor" href="mailto:ayg@aryeh.name">
+    <link rel="author" title="L. David Baron" href="https://dbaron.org/">
+    <link rel="author" title="Google" href="http://www.google.com/">
     <link rel="help" href="http://www.w3.org/TR/css-transforms-2/#perspective-property">
+    <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/413">
     <meta name="assert" content="This tests that 'perspective: 0px' behaves the
-    same as no perspective being specified at all (it's a parse error).">
+    same as perspective: 1px.">
     <link rel="match" href="transform-lime-square-ref.html">
   </head>
   <body>
     <div style="perspective: 1000px">
-      <div style="perspective: 0px">
-        <div style="height: 100px; width: 100px; background: lime;
-          transform: rotatex(45deg) scaley(1.41421356); transform-origin: top">
+      <div style="perspective: 0px; perspective-origin: 50px bottom">
+        <div style="height: 50px; width: 50px; background: lime;
+          transform: translate3d(25px, 25px, 0.5px)">
         </div>
       </div>
     </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/perspective-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/perspective-expected.txt
deleted file mode 100644
index 5b71d48..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/perspective-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-PASS Can set 'perspective' to CSS-wide keywords
-PASS Can set 'perspective' to var() references
-PASS Can set 'perspective' to the 'none' keyword
-FAIL Can set 'perspective' to a length assert_equals: expected "CSSUnitValue" but got "CSSKeywordValue"
-PASS Setting 'perspective' to a percent throws TypeError
-PASS Setting 'perspective' to a time throws TypeError
-PASS Setting 'perspective' to an angle throws TypeError
-PASS Setting 'perspective' to a flexible length throws TypeError
-PASS Setting 'perspective' to a number throws TypeError
-PASS Setting 'perspective' to a position throws TypeError
-PASS Setting 'perspective' to a URL throws TypeError
-PASS Setting 'perspective' to a transform throws TypeError
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js
index dba946d..6f39020 100644
--- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js
+++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js
@@ -1074,6 +1074,7 @@
       const target = createTestElement(t, setup);
       const animation = target.animate(
         {
+          // perspective(0) is treated as perspective(1px)
           [idlName]: ['perspective(0)', 'perspective(10px)'],
         },
         1000
@@ -1081,7 +1082,7 @@
       testAnimationSampleMatrices(animation, idlName,
         [{ time: 500,  expected: [ 1, 0, 0, 0,
                                    0, 1, 0, 0,
-                                   0, 0, 1, -0.05,
+                                   0, 0, 1, -0.55,
                                    0, 0, 0, 1 ] }]);
     }, `${property}: perspective`);
 
diff --git a/third_party/blink/web_tests/transforms/3d/general/3dtransform-values-expected.txt b/third_party/blink/web_tests/transforms/3d/general/3dtransform-values-expected.txt
index 321d233..07fd510 100644
--- a/third_party/blink/web_tests/transforms/3d/general/3dtransform-values-expected.txt
+++ b/third_party/blink/web_tests/transforms/3d/general/3dtransform-values-expected.txt
@@ -15,7 +15,7 @@
 transform "perspective(400em)" expected "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00015625, 0, 0, 0, 1)" : PASS
 transform "perspective(50%)" expected "none" : PASS
 transform "perspective(-400)" expected "none" : PASS
-transform "perspective(0)" expected "matrix(1, 0, 0, 1, 0, 0)" : PASS
+transform "perspective(0)" expected "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1)" : PASS
 transform "perspective(400deg)" expected "none" : PASS
 transform "perspective(banana)" expected "none" : PASS
 
diff --git a/third_party/blink/web_tests/transforms/3d/general/3dtransform-values.html b/third_party/blink/web_tests/transforms/3d/general/3dtransform-values.html
index 78883c57..d256bd7c 100644
--- a/third_party/blink/web_tests/transforms/3d/general/3dtransform-values.html
+++ b/third_party/blink/web_tests/transforms/3d/general/3dtransform-values.html
@@ -43,7 +43,7 @@
       { 'transform' : 'perspective(400em)', 'result' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.00015625, 0, 0, 0, 1)' },
       { 'transform' : 'perspective(50%)', 'result' : 'none' },
       { 'transform' : 'perspective(-400)', 'result' : 'none' },
-      { 'transform' : 'perspective(0)', 'result' : 'matrix(1, 0, 0, 1, 0, 0)' },
+      { 'transform' : 'perspective(0)', 'result' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1)' },
       { 'transform' : 'perspective(400deg)', 'result' : 'none' }, // unit must be length
       { 'transform' : 'perspective(banana)', 'result' : 'none' }, // unit must be length
     ];
diff --git a/third_party/blink/web_tests/transforms/perspective-parsing.html b/third_party/blink/web_tests/transforms/perspective-parsing.html
index 276076a..a5e666b 100644
--- a/third_party/blink/web_tests/transforms/perspective-parsing.html
+++ b/third_party/blink/web_tests/transforms/perspective-parsing.html
@@ -12,8 +12,8 @@
 expect('none').parsesAs('none').isComputedTo('none');
 expect('1px').parsesAs('1px').isComputedTo('1px');
 
-expect('0').isInvalid();
-expect('0px').isInvalid();
+expect('0').parsesAs('0px').isComputedTo('0px');
+expect('0px').parsesAs('0px').isComputedTo('0px');
 expect('5').isInvalid();
 expect('-1px').isInvalid();
 expect('50%').isInvalid();
diff --git a/third_party/blink/web_tests/transforms/webkit-perspective-parsing.html b/third_party/blink/web_tests/transforms/webkit-perspective-parsing.html
index fd58244..749dce9 100644
--- a/third_party/blink/web_tests/transforms/webkit-perspective-parsing.html
+++ b/third_party/blink/web_tests/transforms/webkit-perspective-parsing.html
@@ -12,8 +12,8 @@
 expect('none').parsesAs('none').isComputedTo('none');
 expect('1px').parsesAs('1px').isComputedTo('1px');
 
-expect('0').isInvalid();
-expect('0px').isInvalid();
+expect('0').parsesAs('0px').isComputedTo('0px');
+expect('0px').parsesAs('0px').isComputedTo('0px');
 expect('5').parsesAs('5px');
 expect('-1px').isInvalid();
 expect('50%').isInvalid();
@@ -21,7 +21,7 @@
 expect('calc(0px)').parsesAs('calc(0px)');
 expect('calc(1px)').parsesAs('calc(1px)');
 expect('calc(-1)').isInvalid();
-expect('calc(0)').isInvalid();
+expect('calc(0)').parsesAs('0px');
 expect('calc(1)').parsesAs('1px');
 expect('calc(10em - 10px)').parsesAs('calc(10em - 10px)');
 </script>