author | Boris Chiou <boris.chiou@gmail.com> |
Mon, 03 Oct 2016 16:04:24 +0800 | |
changeset 319300 | 6f417fc0c45dafc11140c31820689514f1b213b1 |
parent 319299 | 00e8df3987f90a27f85232eb38cdfe920ff7dad9 |
child 319301 | 89e37cf072fe2bfae86de8d985bfe8f9502a3d40 |
push id | 30869 |
push user | philringnalda@gmail.com |
push date | Wed, 26 Oct 2016 04:57:48 +0000 |
treeherder | mozilla-central@9471b3c49b2c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | birtles |
bugs | 1272549 |
milestone | 52.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
|
--- a/layout/style/StyleAnimationValue.cpp +++ b/layout/style/StyleAnimationValue.cpp @@ -917,20 +917,47 @@ ComputeTransformDistance(nsCSSValue::Arr // cos(theta/2) = (q1 dot q2) / (|q1| * |q2|) = q1 dot q2. gfxQuaternion q1(vector1, a1->Item(4).GetAngleValueInRadians()); gfxQuaternion q2(vector2, a2->Item(4).GetAngleValueInRadians()); distance = 2.0 * acos(clamped(q1.DotProduct(q2), -1.0, 1.0)); distance = distance * distance; } break; } - case eCSSKeyword_perspective: - // TODO: This will be fixed in the later patch. - distance = 0.0; + case eCSSKeyword_perspective: { + MOZ_ASSERT(a1->Count() == 2, "unexpected count"); + MOZ_ASSERT(a2->Count() == 2, "unexpected count"); + + // We convert a perspective function into an equivalent matrix3d, and + // then do matrix decomposition to get the distance. + // Why don't we just subtract one perspective depth from the other? + // I think it's better to follow the logic of our interpolation, + // which does linear interpolation between two decomposed perspective + // vectors. + // e.g. + // Do interpolation between perspective(100px) and perspective(1000px). + // 1) Convert them into matrix3d, and then do matrix decomposition: + // perspective vector 1: perspective(0, 0, -1/100, 1); + // perspective vector 2: perspective(0, 0, -1/1000, 1); + // 2) Do linear interpolation between these two vectors. + // Therefore, we use the same rule to get the distance as what we do for + // matrix3d. + + auto clampPerspectiveDepth = [](float aDepth) { + // Perspective depth should be positive non-zero value. + return std::max(aDepth, std::numeric_limits<float>::epsilon()); + }; + Matrix4x4 m1; + m1.Perspective(clampPerspectiveDepth(a1->Item(1).GetFloatValue())); + Matrix4x4 m2; + m2.Perspective(clampPerspectiveDepth(a2->Item(1).GetFloatValue())); + + distance = ComputeTransform3DMatrixDistance(m1, m2); break; + } case eCSSKeyword_matrix: { MOZ_ASSERT(a1->Count() == 7, "unexpected count"); MOZ_ASSERT(a2->Count() == 7, "unexpected count"); distance = ComputeTransform2DMatrixDistance( nsStyleTransformMatrix::CSSValueArrayTo2DMatrix(a1), nsStyleTransformMatrix::CSSValueArrayTo2DMatrix(a2)); break;