diff options
author | ajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-31 16:32:46 +0000 |
---|---|---|
committer | ajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-31 16:32:46 +0000 |
commit | adf425df60d1feef4d62a10d42ce84e3e791b116 (patch) | |
tree | 2e7c2f9d7bbe901854917062f7afbad6f7b056db /cc | |
parent | 988ed713b014dc55b3e82fa659a2136e360283ac (diff) | |
download | chromium_src-adf425df60d1feef4d62a10d42ce84e3e791b116.zip chromium_src-adf425df60d1feef4d62a10d42ce84e3e791b116.tar.gz chromium_src-adf425df60d1feef4d62a10d42ce84e3e791b116.tar.bz2 |
cc: Identify animations that affect scale
This adds a HasAnimationThatAffectsScale method to
LayerAnimationController.
BUG=224913
Review URL: https://codereview.chromium.org/213493004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/animation/animation_curve.h | 3 | ||||
-rw-r--r-- | cc/animation/keyframed_animation_curve.cc | 8 | ||||
-rw-r--r-- | cc/animation/keyframed_animation_curve.h | 1 | ||||
-rw-r--r-- | cc/animation/keyframed_animation_curve_unittest.cc | 31 | ||||
-rw-r--r-- | cc/animation/layer_animation_controller.cc | 15 | ||||
-rw-r--r-- | cc/animation/layer_animation_controller.h | 2 | ||||
-rw-r--r-- | cc/animation/layer_animation_controller_unittest.cc | 55 | ||||
-rw-r--r-- | cc/animation/transform_operations.cc | 11 | ||||
-rw-r--r-- | cc/animation/transform_operations.h | 3 | ||||
-rw-r--r-- | cc/animation/transform_operations_unittest.cc | 59 | ||||
-rw-r--r-- | cc/test/animation_test_common.cc | 2 | ||||
-rw-r--r-- | cc/test/animation_test_common.h | 1 |
12 files changed, 191 insertions, 0 deletions
diff --git a/cc/animation/animation_curve.h b/cc/animation/animation_curve.h index 0ae2640..4c15225 100644 --- a/cc/animation/animation_curve.h +++ b/cc/animation/animation_curve.h @@ -75,6 +75,9 @@ class CC_EXPORT TransformAnimationCurve : public AnimationCurve { virtual bool AnimatedBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const = 0; + // Returns true if this animation affects scale. + virtual bool AffectsScale() const = 0; + // Partial Animation implementation. virtual CurveType Type() const OVERRIDE; }; diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc index 39266b1..2fce022 100644 --- a/cc/animation/keyframed_animation_curve.cc +++ b/cc/animation/keyframed_animation_curve.cc @@ -333,6 +333,14 @@ bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( return true; } +bool KeyframedTransformAnimationCurve::AffectsScale() const { + for (size_t i = 0; i < keyframes_.size(); ++i) { + if (keyframes_[i]->Value().AffectsScale()) + return true; + } + return false; +} + scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve:: Create() { return make_scoped_ptr(new KeyframedFilterAnimationCurve); diff --git a/cc/animation/keyframed_animation_curve.h b/cc/animation/keyframed_animation_curve.h index ade65b7..ceb900f 100644 --- a/cc/animation/keyframed_animation_curve.h +++ b/cc/animation/keyframed_animation_curve.h @@ -183,6 +183,7 @@ class CC_EXPORT KeyframedTransformAnimationCurve virtual gfx::Transform GetValue(double t) const OVERRIDE; virtual bool AnimatedBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const OVERRIDE; + virtual bool AffectsScale() const OVERRIDE; private: KeyframedTransformAnimationCurve(); diff --git a/cc/animation/keyframed_animation_curve_unittest.cc b/cc/animation/keyframed_animation_curve_unittest.cc index 0e6fbbf..1fb14966 100644 --- a/cc/animation/keyframed_animation_curve_unittest.cc +++ b/cc/animation/keyframed_animation_curve_unittest.cc @@ -451,5 +451,36 @@ TEST(KeyframedAnimationCurveTest, AnimatedBounds) { bounds.ToString()); } +// Tests that animations that affect scale are correctly identified. +TEST(KeyframedAnimationCurveTest, AffectsScale) { + scoped_ptr<KeyframedTransformAnimationCurve> curve( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve->AddKeyframe(TransformKeyframe::Create( + 0.0, operations1, scoped_ptr<TimingFunction>())); + operations1.AppendTranslate(2.0, 3.0, -1.0); + TransformOperations operations2; + operations2.AppendTranslate(4.0, 1.0, 2.0); + curve->AddKeyframe(TransformKeyframe::Create( + 1.0, operations2, scoped_ptr<TimingFunction>())); + + EXPECT_FALSE(curve->AffectsScale()); + + TransformOperations operations3; + operations3.AppendScale(2.f, 2.f, 2.f); + curve->AddKeyframe(TransformKeyframe::Create( + 2.0, operations3, scoped_ptr<TimingFunction>())); + + EXPECT_TRUE(curve->AffectsScale()); + + TransformOperations operations4; + operations3.AppendTranslate(2.f, 2.f, 2.f); + curve->AddKeyframe(TransformKeyframe::Create( + 3.0, operations4, scoped_ptr<TimingFunction>())); + + EXPECT_TRUE(curve->AffectsScale()); +} + } // namespace } // namespace cc diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc index f255db5..12f5355 100644 --- a/cc/animation/layer_animation_controller.cc +++ b/cc/animation/layer_animation_controller.cc @@ -437,6 +437,21 @@ bool LayerAnimationController::TransformAnimationBoundsForBox( return true; } +bool LayerAnimationController::HasAnimationThatAffectsScale() const { + for (size_t i = 0; i < active_animations_.size(); ++i) { + if (active_animations_[i]->is_finished() || + active_animations_[i]->target_property() != Animation::Transform) + continue; + + const TransformAnimationCurve* transform_animation_curve = + active_animations_[i]->curve()->ToTransformAnimationCurve(); + if (transform_animation_curve->AffectsScale()) + return true; + } + + return false; +} + void LayerAnimationController::PushNewAnimationsToImplThread( LayerAnimationController* controller_impl) const { // Any new animations owned by the main thread's controller are cloned and diff --git a/cc/animation/layer_animation_controller.h b/cc/animation/layer_animation_controller.h index 9562c0a..0aba413 100644 --- a/cc/animation/layer_animation_controller.h +++ b/cc/animation/layer_animation_controller.h @@ -119,6 +119,8 @@ class CC_EXPORT LayerAnimationController bool TransformAnimationBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const; + bool HasAnimationThatAffectsScale() const; + protected: friend class base::RefCounted<LayerAnimationController>; diff --git a/cc/animation/layer_animation_controller_unittest.cc b/cc/animation/layer_animation_controller_unittest.cc index 5b79ccb..32e5d49 100644 --- a/cc/animation/layer_animation_controller_unittest.cc +++ b/cc/animation/layer_animation_controller_unittest.cc @@ -1677,5 +1677,60 @@ TEST(LayerAnimationControllerTest, FinishedAndAbortedEventsForGroup) { EXPECT_EQ(Animation::Opacity, (*events)[1].target_property); } +TEST(LayerAnimationControllerTest, HasAnimationThatAffectsScale) { + scoped_refptr<LayerAnimationController> controller_impl( + LayerAnimationController::Create(0)); + + EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); + + controller_impl->AddAnimation(CreateAnimation( + scoped_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)).Pass(), + 1, + Animation::Opacity)); + + // Opacity animations don't affect scale. + EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); + + scoped_ptr<KeyframedTransformAnimationCurve> curve1( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations1; + curve1->AddKeyframe(TransformKeyframe::Create( + 0.0, operations1, scoped_ptr<TimingFunction>())); + operations1.AppendTranslate(10.0, 15.0, 0.0); + curve1->AddKeyframe(TransformKeyframe::Create( + 1.0, operations1, scoped_ptr<TimingFunction>())); + + scoped_ptr<Animation> animation(Animation::Create( + curve1.PassAs<AnimationCurve>(), 2, 2, Animation::Transform)); + controller_impl->AddAnimation(animation.Pass()); + + // Translations don't affect scale. + EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); + + scoped_ptr<KeyframedTransformAnimationCurve> curve2( + KeyframedTransformAnimationCurve::Create()); + + TransformOperations operations2; + curve2->AddKeyframe(TransformKeyframe::Create( + 0.0, operations2, scoped_ptr<TimingFunction>())); + operations2.AppendScale(2.0, 3.0, 4.0); + curve2->AddKeyframe(TransformKeyframe::Create( + 1.0, operations2, scoped_ptr<TimingFunction>())); + + animation = Animation::Create( + curve2.PassAs<AnimationCurve>(), 3, 3, Animation::Transform); + controller_impl->AddAnimation(animation.Pass()); + + EXPECT_TRUE(controller_impl->HasAnimationThatAffectsScale()); + + controller_impl->GetAnimation(3, Animation::Transform) + ->SetRunState(Animation::Finished, 0.0); + + // Only unfinished animations should be considered by + // HasAnimationThatAffectsScale. + EXPECT_FALSE(controller_impl->HasAnimationThatAffectsScale()); +} + } // namespace } // namespace cc diff --git a/cc/animation/transform_operations.cc b/cc/animation/transform_operations.cc index f8abe44..5b20436 100644 --- a/cc/animation/transform_operations.cc +++ b/cc/animation/transform_operations.cc @@ -78,6 +78,17 @@ bool TransformOperations::BlendedBoundsForBox(const gfx::BoxF& box, return true; } +bool TransformOperations::AffectsScale() const { + for (size_t i = 0; i < operations_.size(); ++i) { + if (operations_[i].type == TransformOperation::TransformOperationScale) + return true; + if (operations_[i].type == TransformOperation::TransformOperationMatrix && + !operations_[i].matrix.IsIdentityOrTranslation()) + return true; + } + return false; +} + bool TransformOperations::MatchesTypes(const TransformOperations& other) const { if (IsIdentity() || other.IsIdentity()) return true; diff --git a/cc/animation/transform_operations.h b/cc/animation/transform_operations.h index 7c50934..7d42cea 100644 --- a/cc/animation/transform_operations.h +++ b/cc/animation/transform_operations.h @@ -57,6 +57,9 @@ class CC_EXPORT TransformOperations { SkMScalar max_progress, gfx::BoxF* bounds) const; + // Returns true if these operations affect scale. + bool AffectsScale() const; + // Returns true if this operation and its descendants have the same types // as other and its descendants. bool MatchesTypes(const TransformOperations& other) const; diff --git a/cc/animation/transform_operations_unittest.cc b/cc/animation/transform_operations_unittest.cc index 831ce71..8dad032 100644 --- a/cc/animation/transform_operations_unittest.cc +++ b/cc/animation/transform_operations_unittest.cc @@ -1258,5 +1258,64 @@ TEST(TransformOperationTest, BlendedBoundsForSequence) { bounds.ToString()); } +TEST(TransformOperationTest, AffectsScaleWithSingleOperation) { + TransformOperations empty_operations; + EXPECT_FALSE(empty_operations.AffectsScale()); + + TransformOperations identity; + identity.AppendIdentity(); + EXPECT_FALSE(identity.AffectsScale()); + + TransformOperations translate; + translate.AppendTranslate(1.f, 2.f, 3.f); + EXPECT_FALSE(translate.AffectsScale()); + + TransformOperations rotate; + rotate.AppendRotate(1.f, 2.f, 3.f, 4.f); + EXPECT_FALSE(rotate.AffectsScale()); + + TransformOperations scale; + scale.AppendScale(1.f, 2.f, 3.f); + EXPECT_TRUE(scale.AffectsScale()); + + TransformOperations skew; + skew.AppendSkew(1.f, 2.f); + EXPECT_FALSE(skew.AffectsScale()); + + TransformOperations perspective; + perspective.AppendPerspective(1.f); + EXPECT_FALSE(perspective.AffectsScale()); + + TransformOperations identity_matrix; + identity_matrix.AppendMatrix(gfx::Transform()); + EXPECT_FALSE(identity_matrix.AffectsScale()); + + TransformOperations translation_matrix; + gfx::Transform translation_transform; + translation_transform.Translate3d(1.f, 2.f, 3.f); + translation_matrix.AppendMatrix(translation_transform); + EXPECT_FALSE(translation_matrix.AffectsScale()); + + TransformOperations scaling_matrix; + gfx::Transform scaling_transform; + scaling_transform.Scale(2.f, 2.f); + scaling_matrix.AppendMatrix(scaling_transform); + EXPECT_TRUE(scaling_matrix.AffectsScale()); +} + +TEST(TransformOperationTest, AffectsScaleWithMultipleOperations) { + TransformOperations operations1; + operations1.AppendSkew(1.f, 2.f); + operations1.AppendTranslate(1.f, 2.f, 3.f); + operations1.AppendIdentity(); + EXPECT_FALSE(operations1.AffectsScale()); + + TransformOperations operations2; + operations2.AppendPerspective(2.f); + operations2.AppendScale(1.f, 2.f, 3.f); + operations2.AppendTranslate(3.f, 2.f, 1.f); + EXPECT_TRUE(operations2.AffectsScale()); +} + } // namespace } // namespace cc diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc index 712b06c..3dcaf23 100644 --- a/cc/test/animation_test_common.cc +++ b/cc/test/animation_test_common.cc @@ -168,6 +168,8 @@ bool FakeTransformTransition::AnimatedBoundsForBox(const gfx::BoxF& box, return false; } +bool FakeTransformTransition::AffectsScale() const { return false; } + scoped_ptr<AnimationCurve> FakeTransformTransition::Clone() const { return make_scoped_ptr(new FakeTransformTransition(*this)) .PassAs<AnimationCurve>(); diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h index bb57339..7732c2d9 100644 --- a/cc/test/animation_test_common.h +++ b/cc/test/animation_test_common.h @@ -43,6 +43,7 @@ class FakeTransformTransition : public TransformAnimationCurve { virtual gfx::Transform GetValue(double time) const OVERRIDE; virtual bool AnimatedBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const OVERRIDE; + virtual bool AffectsScale() const OVERRIDE; virtual scoped_ptr<AnimationCurve> Clone() const OVERRIDE; |