Commit f4f62d0e authored by George Steel's avatar George Steel Committed by Commit Bot

[code-health] Standardize TransformOperation::CanBlendWith()

This replaces the existing virtual implementations of
TransformOperation::CanBlendWith() with a single one that compares
PrimitiveType() values, as defined in the spec. Years ago, CanBlendWith
was only used by BlendedBoundsForBox, and returned false on operation
types not supported by that method. As these checks are currently in
BlendedBoundsForBox itself, and CanBlendWith is used in some Blend()
implementations, eliminate the return false cases in favor of the
as-specced primitive type comparison.

As CanBlendWith is now to-spec for all operation types, replace the many
ad-hoc primitive type comparisons with calls to CanBlendWith(). Change
if/return type checks in TransformOperation::Blend() to DCHECKs as the
there is already a type check at the call site in TransformOperations,
so these should always succeed. In the case of SkewTransformOperation,
replace the loose type check (which would allow blending between skewX
and skewY which have different primitive types) with CanBlendWith. This
causes no behavioral change since a primitive type comparison already
existed in the caller.

Change-Id: Ife892b72798fe81d61ff6528deff064f41bdbfbb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432672Reviewed-by: default avatarKevin Ellis <kevers@chromium.org>
Reviewed-by: default avatarIan Vollick <vollick@chromium.org>
Commit-Queue: George Steel <gtsteel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813815}
parent 0467a76f
...@@ -57,8 +57,8 @@ scoped_refptr<TransformOperation> InterpolatedTransformOperation::Blend( ...@@ -57,8 +57,8 @@ scoped_refptr<TransformOperation> InterpolatedTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->IsSameType(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
TransformOperations to_operations; TransformOperations to_operations;
to_operations.Operations().push_back(this); to_operations.Operations().push_back(this);
TransformOperations from_operations; TransformOperations from_operations;
......
...@@ -50,10 +50,6 @@ class PLATFORM_EXPORT InterpolatedTransformOperation final ...@@ -50,10 +50,6 @@ class PLATFORM_EXPORT InterpolatedTransformOperation final
new InterpolatedTransformOperation(from, to, starting_index, progress)); new InterpolatedTransformOperation(from, to, starting_index, progress));
} }
bool CanBlendWith(const TransformOperation& other) const override {
return IsSameType(other);
}
private: private:
OperationType GetType() const override { return kInterpolated; } OperationType GetType() const override { return kInterpolated; }
......
...@@ -93,8 +93,7 @@ scoped_refptr<TransformOperation> Matrix3DTransformOperation::Blend( ...@@ -93,8 +93,7 @@ scoped_refptr<TransformOperation> Matrix3DTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->IsSameType(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
// Convert the TransformOperations into matrices. Fail the blend operation // Convert the TransformOperations into matrices. Fail the blend operation
// if either of the matrices is non-invertible. // if either of the matrices is non-invertible.
......
...@@ -41,10 +41,6 @@ class PLATFORM_EXPORT Matrix3DTransformOperation final ...@@ -41,10 +41,6 @@ class PLATFORM_EXPORT Matrix3DTransformOperation final
TransformationMatrix Matrix() const { return matrix_; } TransformationMatrix Matrix() const { return matrix_; }
bool CanBlendWith(const TransformOperation& other) const override {
return false;
}
static bool IsMatchingOperationType(OperationType type) { static bool IsMatchingOperationType(OperationType type) {
return type == kMatrix3D; return type == kMatrix3D;
} }
......
...@@ -64,8 +64,7 @@ scoped_refptr<TransformOperation> MatrixTransformOperation::Blend( ...@@ -64,8 +64,7 @@ scoped_refptr<TransformOperation> MatrixTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->IsSameType(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
// convert the TransformOperations into matrices // convert the TransformOperations into matrices
TransformationMatrix from_t; TransformationMatrix from_t;
......
...@@ -52,10 +52,6 @@ class PLATFORM_EXPORT MatrixTransformOperation final ...@@ -52,10 +52,6 @@ class PLATFORM_EXPORT MatrixTransformOperation final
return TransformationMatrix(a_, b_, c_, d_, e_, f_); return TransformationMatrix(a_, b_, c_, d_, e_, f_);
} }
bool CanBlendWith(const TransformOperation& other) const override {
return false;
}
static bool IsMatchingOperationType(OperationType type) { static bool IsMatchingOperationType(OperationType type) {
return type == kMatrix; return type == kMatrix;
} }
......
...@@ -40,10 +40,6 @@ class PLATFORM_EXPORT PerspectiveTransformOperation final ...@@ -40,10 +40,6 @@ class PLATFORM_EXPORT PerspectiveTransformOperation final
double Perspective() const { return p_; } double Perspective() const { return p_; }
bool CanBlendWith(const TransformOperation& other) const override {
return IsSameType(other);
}
static bool IsMatchingOperationType(OperationType type) { static bool IsMatchingOperationType(OperationType type) {
return type == kPerspective; return type == kPerspective;
} }
......
...@@ -71,8 +71,7 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Blend( ...@@ -71,8 +71,7 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !IsMatchingOperationType(from->GetType())) DCHECK(!from || CanBlendWith(*from));
return this;
if (blend_to_identity) if (blend_to_identity)
return RotateTransformOperation::Create( return RotateTransformOperation::Create(
...@@ -96,11 +95,6 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Blend( ...@@ -96,11 +95,6 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Blend(
Rotation::Slerp(from_rotate.rotation_, rotation_, progress), type); Rotation::Slerp(from_rotate.rotation_, rotation_, progress), type);
} }
bool RotateTransformOperation::CanBlendWith(
const TransformOperation& other) const {
return other.IsSameType(*this);
}
RotateAroundOriginTransformOperation::RotateAroundOriginTransformOperation( RotateAroundOriginTransformOperation::RotateAroundOriginTransformOperation(
double angle, double angle,
double origin_x, double origin_x,
...@@ -134,8 +128,8 @@ scoped_refptr<TransformOperation> RotateAroundOriginTransformOperation::Blend( ...@@ -134,8 +128,8 @@ scoped_refptr<TransformOperation> RotateAroundOriginTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->IsSameType(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
if (blend_to_identity) { if (blend_to_identity) {
return RotateAroundOriginTransformOperation::Create( return RotateAroundOriginTransformOperation::Create(
Angle() * (1 - progress), origin_x_, origin_y_); Angle() * (1 - progress), origin_x_, origin_y_);
......
...@@ -70,9 +70,8 @@ class PLATFORM_EXPORT RotateTransformOperation : public TransformOperation { ...@@ -70,9 +70,8 @@ class PLATFORM_EXPORT RotateTransformOperation : public TransformOperation {
double& result_angle_a, double& result_angle_a,
double& result_angle_b); double& result_angle_b);
bool CanBlendWith(const TransformOperation& other) const override;
OperationType GetType() const override { return type_; } OperationType GetType() const override { return type_; }
OperationType PrimitiveType() const final { return kRotate3D; } OperationType PrimitiveType() const override { return kRotate3D; }
void Apply(TransformationMatrix& transform, void Apply(TransformationMatrix& transform,
const FloatSize& /*borderBoxSize*/) const override { const FloatSize& /*borderBoxSize*/) const override {
...@@ -130,6 +129,7 @@ class PLATFORM_EXPORT RotateAroundOriginTransformOperation final ...@@ -130,6 +129,7 @@ class PLATFORM_EXPORT RotateAroundOriginTransformOperation final
static bool IsMatchingOperationType(OperationType type) { static bool IsMatchingOperationType(OperationType type) {
return type == kRotateAroundOrigin; return type == kRotateAroundOrigin;
} }
OperationType PrimitiveType() const override { return kRotateAroundOrigin; }
private: private:
RotateAroundOriginTransformOperation(double angle, RotateAroundOriginTransformOperation(double angle,
......
...@@ -63,8 +63,7 @@ scoped_refptr<TransformOperation> ScaleTransformOperation::Blend( ...@@ -63,8 +63,7 @@ scoped_refptr<TransformOperation> ScaleTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->CanBlendWith(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
if (blend_to_identity) if (blend_to_identity)
return ScaleTransformOperation::Create( return ScaleTransformOperation::Create(
...@@ -83,11 +82,4 @@ scoped_refptr<TransformOperation> ScaleTransformOperation::Blend( ...@@ -83,11 +82,4 @@ scoped_refptr<TransformOperation> ScaleTransformOperation::Blend(
blink::Blend(from_z, z_, progress), is_3d ? kScale3D : kScale); blink::Blend(from_z, z_, progress), is_3d ? kScale3D : kScale);
} }
bool ScaleTransformOperation::CanBlendWith(
const TransformOperation& other) const {
return other.GetType() == kScaleX || other.GetType() == kScaleY ||
other.GetType() == kScaleZ || other.GetType() == kScale3D ||
other.GetType() == kScale;
}
} // namespace blink } // namespace blink
...@@ -54,8 +54,6 @@ class PLATFORM_EXPORT ScaleTransformOperation final ...@@ -54,8 +54,6 @@ class PLATFORM_EXPORT ScaleTransformOperation final
double Y() const { return y_; } double Y() const { return y_; }
double Z() const { return z_; } double Z() const { return z_; }
bool CanBlendWith(const TransformOperation& other) const override;
void Apply(TransformationMatrix& transform, const FloatSize&) const override { void Apply(TransformationMatrix& transform, const FloatSize&) const override {
transform.Scale3d(x_, y_, z_); transform.Scale3d(x_, y_, z_);
} }
......
...@@ -37,8 +37,7 @@ scoped_refptr<TransformOperation> SkewTransformOperation::Blend( ...@@ -37,8 +37,7 @@ scoped_refptr<TransformOperation> SkewTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->CanBlendWith(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
if (blend_to_identity) if (blend_to_identity)
return SkewTransformOperation::Create(blink::Blend(angle_x_, 0.0, progress), return SkewTransformOperation::Create(blink::Blend(angle_x_, 0.0, progress),
...@@ -54,10 +53,4 @@ scoped_refptr<TransformOperation> SkewTransformOperation::Blend( ...@@ -54,10 +53,4 @@ scoped_refptr<TransformOperation> SkewTransformOperation::Blend(
blink::Blend(from_angle_y, angle_y_, progress), type_); blink::Blend(from_angle_y, angle_y_, progress), type_);
} }
bool SkewTransformOperation::CanBlendWith(
const TransformOperation& other) const {
return other.GetType() == kSkew || other.GetType() == kSkewX ||
other.GetType() == kSkewY;
}
} // namespace blink } // namespace blink
...@@ -42,8 +42,6 @@ class PLATFORM_EXPORT SkewTransformOperation final : public TransformOperation { ...@@ -42,8 +42,6 @@ class PLATFORM_EXPORT SkewTransformOperation final : public TransformOperation {
double AngleX() const { return angle_x_; } double AngleX() const { return angle_x_; }
double AngleY() const { return angle_y_; } double AngleY() const { return angle_y_; }
bool CanBlendWith(const TransformOperation& other) const override;
static bool IsMatchingOperationType(OperationType type) { static bool IsMatchingOperationType(OperationType type) {
return type == kSkewX || type == kSkewY || type == kSkew; return type == kSkewX || type == kSkewY || type == kSkew;
} }
......
...@@ -92,7 +92,9 @@ class PLATFORM_EXPORT TransformOperation ...@@ -92,7 +92,9 @@ class PLATFORM_EXPORT TransformOperation
bool IsSameType(const TransformOperation& other) const { bool IsSameType(const TransformOperation& other) const {
return other.GetType() == GetType(); return other.GetType() == GetType();
} }
virtual bool CanBlendWith(const TransformOperation& other) const = 0; bool CanBlendWith(const TransformOperation& other) const {
return PrimitiveType() == other.PrimitiveType();
}
virtual bool PreservesAxisAlignment() const { return false; } virtual bool PreservesAxisAlignment() const { return false; }
......
...@@ -98,10 +98,9 @@ wtf_size_t TransformOperations::MatchingPrefixLength( ...@@ -98,10 +98,9 @@ wtf_size_t TransformOperations::MatchingPrefixLength(
wtf_size_t num_operations = wtf_size_t num_operations =
std::min(Operations().size(), other.Operations().size()); std::min(Operations().size(), other.Operations().size());
for (wtf_size_t i = 0; i < num_operations; ++i) { for (wtf_size_t i = 0; i < num_operations; ++i) {
if (Operations()[i]->PrimitiveType() != if (!Operations()[i]->CanBlendWith(*other.Operations()[i])) {
other.Operations()[i]->PrimitiveType()) { // Remaining operations in each operations list require merging for
// Remaining operations in each operations list require matrix/matrix3d // matrix/matrix3d interpolation.
// interpolation.
return i; return i;
} }
} }
......
...@@ -571,6 +571,75 @@ TEST(TransformOperationsTest, PerspectiveOpsTest) { ...@@ -571,6 +571,75 @@ TEST(TransformOperationsTest, PerspectiveOpsTest) {
EXPECT_TRUE(ops.HasNonTrivial3DComponent()); EXPECT_TRUE(ops.HasNonTrivial3DComponent());
} }
TEST(TransformOperationsTest, CanBlendWithSkewTest) {
TransformOperations ops_x, ops_y, ops_skew, ops_skew2;
ops_x.Operations().push_back(
SkewTransformOperation::Create(45, 0, TransformOperation::kSkewX));
ops_y.Operations().push_back(
SkewTransformOperation::Create(0, 45, TransformOperation::kSkewY));
ops_skew.Operations().push_back(
SkewTransformOperation::Create(45, 0, TransformOperation::kSkew));
ops_skew2.Operations().push_back(
SkewTransformOperation::Create(0, 45, TransformOperation::kSkew));
EXPECT_TRUE(ops_x.Operations()[0]->CanBlendWith(*ops_x.Operations()[0]));
EXPECT_TRUE(ops_y.Operations()[0]->CanBlendWith(*ops_y.Operations()[0]));
EXPECT_FALSE(ops_x.Operations()[0]->CanBlendWith(*ops_y.Operations()[0]));
EXPECT_FALSE(ops_x.Operations()[0]->CanBlendWith(*ops_skew.Operations()[0]));
EXPECT_FALSE(ops_y.Operations()[0]->CanBlendWith(*ops_skew.Operations()[0]));
EXPECT_TRUE(
ops_skew.Operations()[0]->CanBlendWith(*ops_skew2.Operations()[0]));
ASSERT_TRUE(IsA<SkewTransformOperation>(
*ops_skew.Blend(ops_skew2, 0.5).Operations()[0]));
ASSERT_TRUE(IsA<Matrix3DTransformOperation>(
*ops_x.Blend(ops_y, 0.5).Operations()[0]));
}
TEST(TransformOperationsTest, CanBlendWithMatrixTest) {
TransformOperations ops_a, ops_b;
ops_a.Operations().push_back(
MatrixTransformOperation::Create(1, 0, 0, 1, 0, 0));
ops_a.Operations().push_back(
RotateTransformOperation::Create(0, TransformOperation::kRotate));
ops_b.Operations().push_back(
MatrixTransformOperation::Create(2, 0, 0, 2, 0, 0));
ops_b.Operations().push_back(
RotateTransformOperation::Create(360, TransformOperation::kRotate));
EXPECT_TRUE(ops_a.Operations()[0]->CanBlendWith(*ops_b.Operations()[0]));
TransformOperations ops_blended = ops_a.Blend(ops_b, 0.5);
ASSERT_EQ(ops_blended.Operations().size(), 2u);
ASSERT_TRUE(IsA<MatrixTransformOperation>(*ops_blended.Operations()[0]));
ASSERT_TRUE(IsA<RotateTransformOperation>(*ops_blended.Operations()[1]));
EXPECT_EQ(To<RotateTransformOperation>(*ops_blended.Operations()[1]).Angle(),
180.0);
}
TEST(TransformOperationsTest, CanBlendWithMatrix3DTest) {
TransformOperations ops_a, ops_b;
ops_a.Operations().push_back(Matrix3DTransformOperation::Create(
TransformationMatrix(1, 0, 0, 1, 0, 0)));
ops_a.Operations().push_back(
RotateTransformOperation::Create(0, TransformOperation::kRotate));
ops_b.Operations().push_back(Matrix3DTransformOperation::Create(
TransformationMatrix(2, 0, 0, 2, 0, 0)));
ops_b.Operations().push_back(
RotateTransformOperation::Create(360, TransformOperation::kRotate));
EXPECT_TRUE(ops_a.Operations()[0]->CanBlendWith(*ops_b.Operations()[0]));
TransformOperations ops_blended = ops_a.Blend(ops_b, 0.5);
ASSERT_EQ(ops_blended.Operations().size(), 2u);
ASSERT_TRUE(IsA<Matrix3DTransformOperation>(*ops_blended.Operations()[0]));
ASSERT_TRUE(IsA<RotateTransformOperation>(*ops_blended.Operations()[1]));
EXPECT_EQ(To<RotateTransformOperation>(*ops_blended.Operations()[1]).Angle(),
180.0);
}
TEST(TransformOperationsTest, InterpolatedTransformBlendIdentityTest) { TEST(TransformOperationsTest, InterpolatedTransformBlendIdentityTest) {
// When interpolating transform lists of differing lengths, the length of the // When interpolating transform lists of differing lengths, the length of the
// shorter list behaves as if it is padded with identity transforms. // shorter list behaves as if it is padded with identity transforms.
......
...@@ -74,8 +74,7 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Blend( ...@@ -74,8 +74,7 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Blend(
const TransformOperation* from, const TransformOperation* from,
double progress, double progress,
bool blend_to_identity) { bool blend_to_identity) {
if (from && !from->CanBlendWith(*this)) DCHECK(!from || CanBlendWith(*from));
return this;
const Length zero_length = Length::Fixed(0); const Length zero_length = Length::Fixed(0);
if (blend_to_identity) { if (blend_to_identity) {
...@@ -97,13 +96,6 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Blend( ...@@ -97,13 +96,6 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Blend(
blink::Blend(from_z, z_, progress), is_3d ? kTranslate3D : kTranslate); blink::Blend(from_z, z_, progress), is_3d ? kTranslate3D : kTranslate);
} }
bool TranslateTransformOperation::CanBlendWith(
const TransformOperation& other) const {
return other.GetType() == kTranslate || other.GetType() == kTranslateX ||
other.GetType() == kTranslateY || other.GetType() == kTranslateZ ||
other.GetType() == kTranslate3D;
}
scoped_refptr<TranslateTransformOperation> scoped_refptr<TranslateTransformOperation>
TranslateTransformOperation::ZoomTranslate(double factor) { TranslateTransformOperation::ZoomTranslate(double factor) {
return Create(x_.Zoom(factor), y_.Zoom(factor), z_ * factor, type_); return Create(x_.Zoom(factor), y_.Zoom(factor), z_ * factor, type_);
......
...@@ -52,7 +52,6 @@ class PLATFORM_EXPORT TranslateTransformOperation final ...@@ -52,7 +52,6 @@ class PLATFORM_EXPORT TranslateTransformOperation final
return *this == static_cast<const TransformOperation&>(other); return *this == static_cast<const TransformOperation&>(other);
} }
bool CanBlendWith(const TransformOperation& other) const override;
bool DependsOnBoxSize() const override { bool DependsOnBoxSize() const override {
return x_.IsPercentOrCalc() || y_.IsPercentOrCalc(); return x_.IsPercentOrCalc() || y_.IsPercentOrCalc();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment