summaryrefslogtreecommitdiffstats
path: root/cc/animation
diff options
context:
space:
mode:
authora.renevier@samsung.com <a.renevier@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-01 19:25:35 +0000
committera.renevier@samsung.com <a.renevier@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-01 19:25:35 +0000
commit753af8970fc08d7e8377822b3eb309e303b4087b (patch)
tree752762d3545f7f5560ef7c602d59ec42924fdca7 /cc/animation
parent56fa88601bb49fba7d998c51efb6f5c7ed8d4ea7 (diff)
downloadchromium_src-753af8970fc08d7e8377822b3eb309e303b4087b.zip
chromium_src-753af8970fc08d7e8377822b3eb309e303b4087b.tar.gz
chromium_src-753af8970fc08d7e8377822b3eb309e303b4087b.tar.bz2
Handle direction control in compositor Animations
This patch is the compositor side. The blink side is handled in issue #178263006 Handle reverse animations in the compositor. Currently, compositor only understand alternate direction. And in order to reverse an animation, it needs to be passed a reversed timing function. This patch introduces a Direction enum parameter in animation. BUG=348071 Review URL: https://codereview.chromium.org/227733004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267606 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/animation')
-rw-r--r--cc/animation/animation.cc46
-rw-r--r--cc/animation/animation.h12
-rw-r--r--cc/animation/animation_unittest.cc87
3 files changed, 116 insertions, 29 deletions
diff --git a/cc/animation/animation.cc b/cc/animation/animation.cc
index 1af35d2..be0e291 100644
--- a/cc/animation/animation.cc
+++ b/cc/animation/animation.cc
@@ -65,7 +65,7 @@ Animation::Animation(scoped_ptr<AnimationCurve> curve,
run_state_(WaitingForTargetAvailability),
iterations_(1),
start_time_(0),
- alternates_direction_(false),
+ direction_(Normal),
time_offset_(0),
needs_synchronized_start_time_(false),
received_finished_event_(false),
@@ -176,8 +176,8 @@ double Animation::TrimTimeToCurrentIteration(double monotonic_time) const {
needs_synchronized_start_time())
trimmed = time_offset_;
- // Zero is always the start of the animation.
- if (trimmed <= 0)
+ // Return 0 if we are before the start of the animation
+ if (trimmed < 0)
return 0;
// Always return zero if we have no iterations.
@@ -188,26 +188,32 @@ double Animation::TrimTimeToCurrentIteration(double monotonic_time) const {
if (curve_->Duration() <= 0)
return 0;
- // If less than an iteration duration, just return trimmed.
- if (trimmed < curve_->Duration())
- return trimmed;
-
- // If greater than or equal to the total duration, return iteration duration.
- if (iterations_ >= 0 && trimmed >= curve_->Duration() * iterations_) {
- if (alternates_direction_ && !(iterations_ % 2))
- return 0;
- return curve_->Duration();
- }
+ // check if we are past active interval
+ bool is_past_total_duration =
+ (iterations_ > 0 && trimmed >= curve_->Duration() * iterations_);
// We need to know the current iteration if we're alternating.
- int iteration = static_cast<int>(trimmed / curve_->Duration());
+ int iteration = 0;
+
+ // If we are past the active interval, return iteration duration.
+ if (is_past_total_duration) {
+ iteration = iterations_;
+ trimmed = curve_->Duration();
+ } else {
+ iteration = static_cast<int>(trimmed / curve_->Duration());
+ // Calculate x where trimmed = x + n * curve_->Duration() for some positive
+ // integer n.
+ trimmed = fmod(trimmed, curve_->Duration());
+ }
- // Calculate x where trimmed = x + n * curve_->Duration() for some positive
- // integer n.
- trimmed = fmod(trimmed, curve_->Duration());
+ // check if we are running the animation in reverse direction for the current
+ // iteration
+ bool reverse = (direction_ == Reverse) ||
+ (direction_ == Alternate && iteration % 2 == 1) ||
+ (direction_ == AlternateReverse && iteration % 2 == 0);
- // If we're alternating and on an odd iteration, reverse the direction.
- if (alternates_direction_ && iteration % 2 == 1)
+ // if we are running the animation in reverse direction, reverse the result
+ if (reverse)
return curve_->Duration() - trimmed;
return trimmed;
@@ -223,7 +229,7 @@ scoped_ptr<Animation> Animation::CloneAndInitialize(
to_return->pause_time_ = pause_time_;
to_return->total_paused_time_ = total_paused_time_;
to_return->time_offset_ = time_offset_;
- to_return->alternates_direction_ = alternates_direction_;
+ to_return->direction_ = direction_;
DCHECK(!to_return->is_controlling_instance_);
to_return->is_controlling_instance_ = true;
return to_return.Pass();
diff --git a/cc/animation/animation.h b/cc/animation/animation.h
index ecc48b5..e4476ff 100644
--- a/cc/animation/animation.h
+++ b/cc/animation/animation.h
@@ -48,6 +48,8 @@ class CC_EXPORT Animation {
TargetPropertyEnumSize
};
+ enum Direction { Normal, Reverse, Alternate, AlternateReverse };
+
static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve,
int animation_id,
int group_id,
@@ -78,12 +80,8 @@ class CC_EXPORT Animation {
void Suspend(double monotonic_time);
void Resume(double monotonic_time);
- // If alternates_direction is true, on odd numbered iterations we reverse the
- // curve.
- bool alternates_direction() const { return alternates_direction_; }
- void set_alternates_direction(bool alternates) {
- alternates_direction_ = alternates;
- }
+ Direction direction() { return direction_; }
+ void set_direction(Direction direction) { direction_ = direction; }
bool IsFinishedAt(double monotonic_time) const;
bool is_finished() const {
@@ -158,7 +156,7 @@ class CC_EXPORT Animation {
RunState run_state_;
int iterations_;
double start_time_;
- bool alternates_direction_;
+ Direction direction_;
// The time offset effectively pushes the start of the animation back in time.
// This is used for resuming paused animations -- an animation is added with a
diff --git a/cc/animation/animation_unittest.cc b/cc/animation/animation_unittest.cc
index 8223cee..7a9019d 100644
--- a/cc/animation/animation_unittest.cc
+++ b/cc/animation/animation_unittest.cc
@@ -49,15 +49,39 @@ TEST(AnimationTest, TrimTimeInfiniteIterations) {
EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(1.5));
}
-TEST(AnimationTest, TrimTimeAlternating) {
+TEST(AnimationTest, TrimTimeReverse) {
scoped_ptr<Animation> anim(CreateAnimation(-1));
- anim->set_alternates_direction(true);
+ anim->set_direction(Animation::Reverse);
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0));
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(1.0));
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25));
+}
+
+TEST(AnimationTest, TrimTimeAlternate) {
+ scoped_ptr<Animation> anim(CreateAnimation(-1));
+ anim->set_direction(Animation::Alternate);
EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.25));
EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.75));
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0));
EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1.25));
}
+TEST(AnimationTest, TrimTimeAlternateReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(-1));
+ anim->set_direction(Animation::AlternateReverse);
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(0.75));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0));
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1.25));
+}
+
TEST(AnimationTest, TrimTimeStartTime) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->set_start_time(4);
@@ -68,6 +92,17 @@ TEST(AnimationTest, TrimTimeStartTime) {
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(6.0));
}
+TEST(AnimationTest, TrimTimeStartTimeReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(1));
+ anim->set_start_time(4);
+ anim->set_direction(Animation::Reverse);
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(6.0));
+}
+
TEST(AnimationTest, TrimTimeTimeOffset) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->set_time_offset(4);
@@ -78,6 +113,17 @@ TEST(AnimationTest, TrimTimeTimeOffset) {
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1.0));
}
+TEST(AnimationTest, TrimTimeTimeOffsetReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(1));
+ anim->set_time_offset(4);
+ anim->set_start_time(4);
+ anim->set_direction(Animation::Reverse);
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1.0));
+}
+
TEST(AnimationTest, TrimTimeNegativeTimeOffset) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->set_time_offset(-4);
@@ -88,6 +134,17 @@ TEST(AnimationTest, TrimTimeNegativeTimeOffset) {
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(5.0));
}
+TEST(AnimationTest, TrimTimeNegativeTimeOffsetReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(1));
+ anim->set_time_offset(-4);
+ anim->set_direction(Animation::Reverse);
+
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(4.0));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(4.5));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(5.0));
+}
+
TEST(AnimationTest, TrimTimePauseResume) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->SetRunState(Animation::Running, 0.0);
@@ -100,6 +157,19 @@ TEST(AnimationTest, TrimTimePauseResume) {
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5));
}
+TEST(AnimationTest, TrimTimePauseResumeReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(1));
+ anim->set_direction(Animation::Reverse);
+ anim->SetRunState(Animation::Running, 0.0);
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(0.5, anim->TrimTimeToCurrentIteration(0.5));
+ anim->SetRunState(Animation::Paused, 0.25);
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0));
+ anim->SetRunState(Animation::Running, 1024.0);
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(1024.0));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.75));
+}
+
TEST(AnimationTest, TrimTimeSuspendResume) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->SetRunState(Animation::Running, 0.0);
@@ -112,6 +182,19 @@ TEST(AnimationTest, TrimTimeSuspendResume) {
EXPECT_EQ(1, anim->TrimTimeToCurrentIteration(1024.5));
}
+TEST(AnimationTest, TrimTimeSuspendResumeReverse) {
+ scoped_ptr<Animation> anim(CreateAnimation(1));
+ anim->set_direction(Animation::Reverse);
+ anim->SetRunState(Animation::Running, 0.0);
+ EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(0.0));
+ EXPECT_EQ(0.75, anim->TrimTimeToCurrentIteration(0.25));
+ anim->Suspend(0.75);
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0));
+ anim->Resume(1024);
+ EXPECT_EQ(0.25, anim->TrimTimeToCurrentIteration(1024.0));
+ EXPECT_EQ(0, anim->TrimTimeToCurrentIteration(1024.25));
+}
+
TEST(AnimationTest, TrimTimeZeroDuration) {
scoped_ptr<Animation> anim(CreateAnimation(0, 0));
anim->SetRunState(Animation::Running, 0.0);