Commit f6711179 authored by samli's avatar samli Committed by Commit bot

CC: Add fill mode to compositor animations

BUG=415241

Review URL: https://codereview.chromium.org/579863004

Cr-Commit-Position: refs/heads/master@{#295614}
parent 336bb313
...@@ -67,6 +67,7 @@ Animation::Animation(scoped_ptr<AnimationCurve> curve, ...@@ -67,6 +67,7 @@ Animation::Animation(scoped_ptr<AnimationCurve> curve,
iteration_start_(0), iteration_start_(0),
direction_(Normal), direction_(Normal),
playback_rate_(1), playback_rate_(1),
fill_mode_(FillModeNone),
needs_synchronized_start_time_(false), needs_synchronized_start_time_(false),
received_finished_event_(false), received_finished_event_(false),
suspended_(false), suspended_(false),
...@@ -159,13 +160,13 @@ bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const { ...@@ -159,13 +160,13 @@ bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const {
.InSecondsF(); .InSecondsF();
} }
double Animation::TrimTimeToCurrentIteration( bool Animation::InEffect(base::TimeTicks monotonic_time) const {
base::TimeTicks monotonic_time) const { return ConvertToActiveTime(monotonic_time) >= 0 ||
base::TimeTicks trimmed = monotonic_time + time_offset_; (fill_mode_ == FillModeBoth || fill_mode_ == FillModeBackwards);
}
// Check for valid parameters double Animation::ConvertToActiveTime(base::TimeTicks monotonic_time) const {
DCHECK(playback_rate_); base::TimeTicks trimmed = monotonic_time + time_offset_;
DCHECK_GE(iteration_start_, 0);
// If we're paused, time is 'stuck' at the pause time. // If we're paused, time is 'stuck' at the pause time.
if (run_state_ == Paused) if (run_state_ == Paused)
...@@ -181,7 +182,16 @@ double Animation::TrimTimeToCurrentIteration( ...@@ -181,7 +182,16 @@ double Animation::TrimTimeToCurrentIteration(
needs_synchronized_start_time()) needs_synchronized_start_time())
trimmed = base::TimeTicks() + time_offset_; trimmed = base::TimeTicks() + time_offset_;
double active_time = (trimmed - base::TimeTicks()).InSecondsF(); return (trimmed - base::TimeTicks()).InSecondsF();
}
double Animation::TrimTimeToCurrentIteration(
base::TimeTicks monotonic_time) const {
// Check for valid parameters
DCHECK(playback_rate_);
DCHECK_GE(iteration_start_, 0);
double active_time = ConvertToActiveTime(monotonic_time);
// Return 0 if we are before the start of the animation // Return 0 if we are before the start of the animation
if (active_time < 0) if (active_time < 0)
...@@ -254,6 +264,7 @@ scoped_ptr<Animation> Animation::CloneAndInitialize( ...@@ -254,6 +264,7 @@ scoped_ptr<Animation> Animation::CloneAndInitialize(
to_return->time_offset_ = time_offset_; to_return->time_offset_ = time_offset_;
to_return->direction_ = direction_; to_return->direction_ = direction_;
to_return->playback_rate_ = playback_rate_; to_return->playback_rate_ = playback_rate_;
to_return->fill_mode_ = fill_mode_;
DCHECK(!to_return->is_controlling_instance_); DCHECK(!to_return->is_controlling_instance_);
to_return->is_controlling_instance_ = true; to_return->is_controlling_instance_ = true;
return to_return.Pass(); return to_return.Pass();
......
...@@ -51,6 +51,13 @@ class CC_EXPORT Animation { ...@@ -51,6 +51,13 @@ class CC_EXPORT Animation {
enum Direction { Normal, Reverse, Alternate, AlternateReverse }; enum Direction { Normal, Reverse, Alternate, AlternateReverse };
enum FillMode {
FillModeNone,
FillModeForwards,
FillModeBackwards,
FillModeBoth
};
static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve, static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve,
int animation_id, int animation_id,
int group_id, int group_id,
...@@ -94,6 +101,9 @@ class CC_EXPORT Animation { ...@@ -94,6 +101,9 @@ class CC_EXPORT Animation {
Direction direction() { return direction_; } Direction direction() { return direction_; }
void set_direction(Direction direction) { direction_ = direction; } void set_direction(Direction direction) { direction_ = direction; }
FillMode fill_mode() { return fill_mode_; }
void set_fill_mode(FillMode fill_mode) { fill_mode_ = fill_mode; }
double playback_rate() { return playback_rate_; } double playback_rate() { return playback_rate_; }
void set_playback_rate(double playback_rate) { void set_playback_rate(double playback_rate) {
playback_rate_ = playback_rate; playback_rate_ = playback_rate;
...@@ -106,6 +116,8 @@ class CC_EXPORT Animation { ...@@ -106,6 +116,8 @@ class CC_EXPORT Animation {
run_state_ == WaitingForDeletion; run_state_ == WaitingForDeletion;
} }
bool InEffect(base::TimeTicks monotonic_time) const;
AnimationCurve* curve() { return curve_.get(); } AnimationCurve* curve() { return curve_.get(); }
const AnimationCurve* curve() const { return curve_.get(); } const AnimationCurve* curve() const { return curve_.get(); }
...@@ -157,6 +169,8 @@ class CC_EXPORT Animation { ...@@ -157,6 +169,8 @@ class CC_EXPORT Animation {
int group_id, int group_id,
TargetProperty target_property); TargetProperty target_property);
double ConvertToActiveTime(base::TimeTicks monotonic_time) const;
scoped_ptr<AnimationCurve> curve_; scoped_ptr<AnimationCurve> curve_;
// IDs are not necessarily unique. // IDs are not necessarily unique.
...@@ -176,6 +190,7 @@ class CC_EXPORT Animation { ...@@ -176,6 +190,7 @@ class CC_EXPORT Animation {
base::TimeTicks start_time_; base::TimeTicks start_time_;
Direction direction_; Direction direction_;
double playback_rate_; double playback_rate_;
FillMode fill_mode_;
// The time offset effectively pushes the start of the animation back in time. // 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 // This is used for resuming paused animations -- an animation is added with a
......
...@@ -666,5 +666,51 @@ TEST(AnimationTest, ...@@ -666,5 +666,51 @@ TEST(AnimationTest,
EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(3.5))); EXPECT_EQ(1.0, anim->TrimTimeToCurrentIteration(TicksFromSecondsF(3.5)));
} }
TEST(AnimationTest, InEffectFillMode) {
scoped_ptr<Animation> anim(CreateAnimation(1));
anim->set_fill_mode(Animation::FillModeNone);
EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeForwards);
EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeBackwards);
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeBoth);
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
}
TEST(AnimationTest, InEffectFillModePlayback) {
scoped_ptr<Animation> anim(CreateAnimation(1, 1, -1));
anim->set_fill_mode(Animation::FillModeNone);
EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeForwards);
EXPECT_FALSE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeBackwards);
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
anim->set_fill_mode(Animation::FillModeBoth);
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(-1.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(0.0)));
EXPECT_TRUE(anim->InEffect(TicksFromSecondsF(1.0)));
}
} // namespace } // namespace
} // namespace cc } // namespace cc
...@@ -144,6 +144,9 @@ void LayerAnimationController::AccumulatePropertyUpdates( ...@@ -144,6 +144,9 @@ void LayerAnimationController::AccumulatePropertyUpdates(
if (!animation->is_impl_only()) if (!animation->is_impl_only())
continue; continue;
if (!animation->InEffect(monotonic_time))
continue;
double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time); double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
switch (animation->target_property()) { switch (animation->target_property()) {
case Animation::Opacity: { case Animation::Opacity: {
...@@ -835,6 +838,9 @@ void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) { ...@@ -835,6 +838,9 @@ void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
if (animations_[i]->run_state() == Animation::Starting || if (animations_[i]->run_state() == Animation::Starting ||
animations_[i]->run_state() == Animation::Running || animations_[i]->run_state() == Animation::Running ||
animations_[i]->run_state() == Animation::Paused) { animations_[i]->run_state() == Animation::Paused) {
if (!animations_[i]->InEffect(monotonic_time))
continue;
double trimmed = double trimmed =
animations_[i]->TrimTimeToCurrentIteration(monotonic_time); animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
......
...@@ -79,7 +79,6 @@ WebCompositorAnimationImpl::targetProperty() const { ...@@ -79,7 +79,6 @@ WebCompositorAnimationImpl::targetProperty() const {
animation_->target_property()); animation_->target_property());
} }
#if WEB_ANIMATION_SUPPORTS_FRACTIONAL_ITERATIONS
double WebCompositorAnimationImpl::iterations() const { double WebCompositorAnimationImpl::iterations() const {
return animation_->iterations(); return animation_->iterations();
} }
...@@ -87,15 +86,6 @@ double WebCompositorAnimationImpl::iterations() const { ...@@ -87,15 +86,6 @@ double WebCompositorAnimationImpl::iterations() const {
void WebCompositorAnimationImpl::setIterations(double n) { void WebCompositorAnimationImpl::setIterations(double n) {
animation_->set_iterations(n); animation_->set_iterations(n);
} }
#else
int WebCompositorAnimationImpl::iterations() const {
return animation_->iterations();
}
void WebCompositorAnimationImpl::setIterations(int n) {
animation_->set_iterations(n);
}
#endif
double WebCompositorAnimationImpl::iterationStart() const { double WebCompositorAnimationImpl::iterationStart() const {
return animation_->iteration_start(); return animation_->iteration_start();
...@@ -164,6 +154,41 @@ void WebCompositorAnimationImpl::setPlaybackRate(double playback_rate) { ...@@ -164,6 +154,41 @@ void WebCompositorAnimationImpl::setPlaybackRate(double playback_rate) {
animation_->set_playback_rate(playback_rate); animation_->set_playback_rate(playback_rate);
} }
#if WEB_ANIMATION_SUPPORTS_FILL_MODE
blink::WebCompositorAnimation::FillMode WebCompositorAnimationImpl::fillMode()
const {
switch (animation_->fill_mode()) {
case cc::Animation::FillModeNone:
return FillModeNone;
case cc::Animation::FillModeForwards:
return FillModeForwards;
case cc::Animation::FillModeBackwards:
return FillModeBackwards;
case cc::Animation::FillModeBoth:
return FillModeBoth;
default:
NOTREACHED();
}
return FillModeNone;
}
void WebCompositorAnimationImpl::setFillMode(FillMode fill_mode) {
switch (fill_mode) {
case FillModeNone:
animation_->set_fill_mode(cc::Animation::FillModeNone);
break;
case FillModeForwards:
animation_->set_fill_mode(cc::Animation::FillModeForwards);
break;
case FillModeBackwards:
animation_->set_fill_mode(cc::Animation::FillModeBackwards);
break;
case FillModeBoth:
animation_->set_fill_mode(cc::Animation::FillModeBoth);
break;
}
}
#endif
scoped_ptr<cc::Animation> WebCompositorAnimationImpl::PassAnimation() { scoped_ptr<cc::Animation> WebCompositorAnimationImpl::PassAnimation() {
animation_->set_needs_synchronized_start_time(true); animation_->set_needs_synchronized_start_time(true);
return animation_.Pass(); return animation_.Pass();
......
...@@ -31,13 +31,8 @@ class WebCompositorAnimationImpl : public blink::WebCompositorAnimation { ...@@ -31,13 +31,8 @@ class WebCompositorAnimationImpl : public blink::WebCompositorAnimation {
// blink::WebCompositorAnimation implementation // blink::WebCompositorAnimation implementation
virtual int id(); virtual int id();
virtual TargetProperty targetProperty() const; virtual TargetProperty targetProperty() const;
#if WEB_ANIMATION_SUPPORTS_FRACTIONAL_ITERATIONS
virtual double iterations() const; virtual double iterations() const;
virtual void setIterations(double iterations); virtual void setIterations(double iterations);
#else
virtual int iterations() const;
virtual void setIterations(int iterations);
#endif
virtual double iterationStart() const; virtual double iterationStart() const;
virtual void setIterationStart(double iteration_start); virtual void setIterationStart(double iteration_start);
virtual double startTime() const; virtual double startTime() const;
...@@ -48,7 +43,10 @@ class WebCompositorAnimationImpl : public blink::WebCompositorAnimation { ...@@ -48,7 +43,10 @@ class WebCompositorAnimationImpl : public blink::WebCompositorAnimation {
virtual void setDirection(Direction); virtual void setDirection(Direction);
virtual double playbackRate() const; virtual double playbackRate() const;
virtual void setPlaybackRate(double playback_rate); virtual void setPlaybackRate(double playback_rate);
#if WEB_ANIMATION_SUPPORTS_FILL_MODE
virtual FillMode fillMode() const;
virtual void setFillMode(blink::WebCompositorAnimation::FillMode fill_mode);
#endif
scoped_ptr<cc::Animation> PassAnimation(); scoped_ptr<cc::Animation> PassAnimation();
private: private:
......
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