mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1723266 - Return an infinite perspective in TransformOperation::Perspective::to_animated_zero. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D122919
This commit is contained in:
parent
0fe8b4b2b6
commit
0c573563cc
@ -34,12 +34,15 @@ namespace nsStyleTransformMatrix {
|
||||
// The operator passed to Servo backend.
|
||||
enum class MatrixTransformOperator : uint8_t { Interpolate, Accumulate };
|
||||
|
||||
// Function for applying perspective() transform function. We treat
|
||||
// any value smaller than epsilon as perspective(infinity), which
|
||||
// follows CSSWG's resolution on perspective(0). See bug 1316236.
|
||||
// Function for applying perspective() transform function.
|
||||
inline void ApplyPerspectiveToMatrix(mozilla::gfx::Matrix4x4& aMatrix,
|
||||
float aDepth) {
|
||||
aMatrix.Perspective(std::max(aDepth, 1.0f));
|
||||
// TODO(Bug 1725207): Infinite perspective values from stylo are being
|
||||
// serialized as FLOAT_MAX, so we have to explicitly check for that case
|
||||
// and treat it as infinity (which is the identity matrix).
|
||||
if (!std::isinf(aDepth) && aDepth != std::numeric_limits<float>::max()) {
|
||||
aMatrix.Perspective(std::max(aDepth, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1112,8 +1112,12 @@ impl Animate for ComputedTransformOperation {
|
||||
|
||||
let decomposed = decompose_3d_matrix(interpolated)?;
|
||||
let perspective_z = decomposed.perspective.2;
|
||||
let used_value = if perspective_z == 0. {
|
||||
0.
|
||||
// Clamp results outside of the -1 to 0 range so that we get perspective
|
||||
// function values between 1 and infinity.
|
||||
let used_value = if perspective_z >= 0. {
|
||||
std::f32::INFINITY
|
||||
} else if perspective_z <= -1. {
|
||||
1.
|
||||
} else {
|
||||
-1. / perspective_z
|
||||
};
|
||||
|
@ -516,8 +516,8 @@ impl ToAnimatedZero for TransformOperation {
|
||||
generic::TransformOperation::Rotate(_) => {
|
||||
Ok(generic::TransformOperation::Rotate(Angle::zero()))
|
||||
},
|
||||
generic::TransformOperation::Perspective(ref l) => Ok(
|
||||
generic::TransformOperation::Perspective(l.to_animated_zero()?),
|
||||
generic::TransformOperation::Perspective(_) => Ok(
|
||||
generic::TransformOperation::Perspective(Length::new(std::f32::INFINITY))
|
||||
),
|
||||
generic::TransformOperation::AccumulateMatrix { .. } |
|
||||
generic::TransformOperation::InterpolateMatrix { .. } => {
|
||||
|
@ -582,10 +582,10 @@ impl<T: ToMatrix> Transform<T> {
|
||||
/// Return the transform matrix from a perspective length.
|
||||
#[inline]
|
||||
pub fn create_perspective_matrix(d: CSSFloat) -> Transform3D<CSSFloat> {
|
||||
if d < 0.0 {
|
||||
Transform3D::identity()
|
||||
} else {
|
||||
if d.is_finite() {
|
||||
Transform3D::perspective(d.max(1.))
|
||||
} else {
|
||||
Transform3D::identity()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,6 +110,19 @@ test_interpolation({
|
||||
{at: 1, expect: `scaleZ(2) perspective(${interpolatePerspective(400, 500, 1)}px)`},
|
||||
{at: 2, expect: `scaleZ(3) perspective(${interpolatePerspective(400, 500, 2)}px)`},
|
||||
]);
|
||||
// Test that the transform identity function for perspective is perspective(none)
|
||||
test_interpolation({
|
||||
property: 'transform',
|
||||
from: 'scaleZ(2)',
|
||||
to: 'scaleZ(2) perspective(500px)',
|
||||
comparisonFunction: compareWithPerspective
|
||||
}, [
|
||||
{at: -1, expect: `scaleZ(2)`},
|
||||
{at: 0, expect: `scaleZ(2)`},
|
||||
{at: 0.5, expect: `scaleZ(2) perspective(1000px)`},
|
||||
{at: 1, expect: `scaleZ(2) perspective(500px)`},
|
||||
{at: 2, expect: `scaleZ(2) perspective(250px)`},
|
||||
]);
|
||||
|
||||
// Rotate
|
||||
test_interpolation({
|
||||
|
@ -13,7 +13,7 @@
|
||||
// Addition and accumulation of perspective values are very similar, but not
|
||||
// identical. We can test the difference by constructing a scenario where a
|
||||
// perspective parameter would go negative in one case (and thus be clamped
|
||||
// to 1), and would not go negative in the other case.
|
||||
// to 0), and would not go negative in the other case.
|
||||
//
|
||||
// In the test below, the values differ at 1.5 progress. The reason for this
|
||||
// is that at 1.5 progress, the addition case (which uses concatenation)
|
||||
@ -23,7 +23,7 @@
|
||||
//
|
||||
// Since perspective cannot go negative, this is clamped to:
|
||||
//
|
||||
// perspective(10px) perspective(1px)
|
||||
// perspective(10px) perspective(none)
|
||||
//
|
||||
// The accumulation case, on the other hand, combines the components
|
||||
// and so ends up blending from perspective(5px) to perspective(8.33...px) at
|
||||
@ -44,7 +44,7 @@ test_composition({
|
||||
{at: 0.5, expect: 'perspective(6.15px)'},
|
||||
{at: 0.75, expect: 'perspective(7.06px)'},
|
||||
{at: 1, expect: 'perspective(8.33px)'},
|
||||
{at: 1.5, expect: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1.1, 0, 0, 0, 1)'},
|
||||
{at: 1.5, expect: 'perspective(10px)'},
|
||||
]);
|
||||
|
||||
// ------------ Accumulation tests --------------
|
||||
|
Loading…
Reference in New Issue
Block a user