diff options
author | ajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 18:47:38 +0000 |
---|---|---|
committer | ajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 18:47:38 +0000 |
commit | 3d75fedec4f4d01c0fb52c61a7fb0adb2b64c377 (patch) | |
tree | c0dd20b995735c4227b8c24519347e27c0f31941 /ui/compositor | |
parent | 8da1670a91dab1c2d7ad5a83c3e66da94503bb15 (diff) | |
download | chromium_src-3d75fedec4f4d01c0fb52c61a7fb0adb2b64c377.zip chromium_src-3d75fedec4f4d01c0fb52c61a7fb0adb2b64c377.tar.gz chromium_src-3d75fedec4f4d01c0fb52c61a7fb0adb2b64c377.tar.bz2 |
Make ui::LayerAnimationSequence and ui::LayerAnimationElement use absolute times
Currently, LayerAnimationSequences and LayerAnimationElements only know
about the relative offset from the start of the animation. However, for threaded
UI animations, a LayerAnimationElement will need to know its absolute start
time: in order to compute the delay incurred by dispatching the animation to the
compositor thread, it will need to compare its own start time with that of the
dispatched animation.
BUG=164206
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/11465026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173301 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/compositor')
-rw-r--r-- | ui/compositor/layer_animation_element.cc | 13 | ||||
-rw-r--r-- | ui/compositor/layer_animation_element.h | 19 | ||||
-rw-r--r-- | ui/compositor/layer_animation_element_unittest.cc | 73 | ||||
-rw-r--r-- | ui/compositor/layer_animation_sequence.cc | 35 | ||||
-rw-r--r-- | ui/compositor/layer_animation_sequence.h | 21 | ||||
-rw-r--r-- | ui/compositor/layer_animation_sequence_unittest.cc | 59 | ||||
-rw-r--r-- | ui/compositor/layer_animator.cc | 21 | ||||
-rw-r--r-- | ui/compositor/layer_animator.h | 8 | ||||
-rw-r--r-- | ui/compositor/layer_animator_unittest.cc | 4 |
9 files changed, 163 insertions, 90 deletions
diff --git a/ui/compositor/layer_animation_element.cc b/ui/compositor/layer_animation_element.cc index ef18104..6c9aa39 100644 --- a/ui/compositor/layer_animation_element.cc +++ b/ui/compositor/layer_animation_element.cc @@ -405,8 +405,10 @@ LayerAnimationElement::LayerAnimationElement( LayerAnimationElement::~LayerAnimationElement() { } -bool LayerAnimationElement::Progress(base::TimeDelta elapsed, +bool LayerAnimationElement::Progress(base::TimeTicks now, LayerAnimationDelegate* delegate) { + DCHECK(start_time_ != base::TimeTicks()); + base::TimeDelta elapsed = now - start_time_; if (first_frame_) OnStart(delegate); double t = 1.0; @@ -417,8 +419,9 @@ bool LayerAnimationElement::Progress(base::TimeDelta elapsed, return need_draw; } -bool LayerAnimationElement::IsFinished(base::TimeDelta elapsed, +bool LayerAnimationElement::IsFinished(base::TimeTicks time, base::TimeDelta* total_duration) { + base::TimeDelta elapsed = time - start_time_; if (elapsed >= duration_) { *total_duration = duration_; return true; @@ -427,7 +430,11 @@ bool LayerAnimationElement::IsFinished(base::TimeDelta elapsed, } bool LayerAnimationElement::ProgressToEnd(LayerAnimationDelegate* delegate) { - return Progress(duration_, delegate); + if (first_frame_) + OnStart(delegate); + bool need_draw = OnProgress(1.0, delegate); + first_frame_ = true; + return need_draw; } void LayerAnimationElement::GetTargetValue(TargetValue* target) const { diff --git a/ui/compositor/layer_animation_element.h b/ui/compositor/layer_animation_element.h index 2a80698..9b65844 100644 --- a/ui/compositor/layer_animation_element.h +++ b/ui/compositor/layer_animation_element.h @@ -113,14 +113,20 @@ class COMPOSITOR_EXPORT LayerAnimationElement { SkColor color, base::TimeDelta duration); - // Updates the delegate to the appropriate value for |elapsed|. Returns true + // Sets the start time for the animation. This must be called before the first + // call to {Progress, IsFinished}. Once the animation is finished, this must + // be called again in order to restart the animation. + void set_start_time(base::TimeTicks start_time) { start_time_ = start_time; } + base::TimeTicks start_time() const { return start_time_; } + + // Updates the delegate to the appropriate value for |now|. Returns true // if a redraw is required. - bool Progress(base::TimeDelta elapsed, LayerAnimationDelegate* delegate); + bool Progress(base::TimeTicks now, LayerAnimationDelegate* delegate); - // If calling Progress now, with the given elapsed time, will finish the - // animation, returns true and sets |total_duration| to the actual duration - // for this animation, incuding any queueing delays. - bool IsFinished(base::TimeDelta elapsed, base::TimeDelta* total_duration); + // If calling Progress now, with the given time, will finish the animation, + // returns true and sets |end_duration| to the actual duration for this + // animation, incuding any queueing delays. + bool IsFinished(base::TimeTicks time, base::TimeDelta* total_duration); // Updates the delegate to the end of the animation. Returns true if a // redraw is required. @@ -155,6 +161,7 @@ class COMPOSITOR_EXPORT LayerAnimationElement { bool first_frame_; const AnimatableProperties properties_; + base::TimeTicks start_time_; const base::TimeDelta duration_; Tween::Type tween_type_; diff --git a/ui/compositor/layer_animation_element_unittest.cc b/ui/compositor/layer_animation_element_unittest.cc index 41f9a47..5912023 100644 --- a/ui/compositor/layer_animation_element_unittest.cc +++ b/ui/compositor/layer_animation_element_unittest.cc @@ -26,20 +26,23 @@ TEST(LayerAnimationElementTest, TransformElement) { gfx::Transform start_transform, target_transform, middle_transform; start_transform.Rotate(-30.0); target_transform.Rotate(30.0); + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateTransformElement(target_transform, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetTransformFromAnimation(start_transform); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); CheckApproximatelyEqual(middle_transform, delegate.GetTransformForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); CheckApproximatelyEqual(target_transform, delegate.GetTransformForAnimation()); } @@ -49,7 +52,7 @@ TEST(LayerAnimationElementTest, TransformElement) { CheckApproximatelyEqual(target_transform, target_value.transform); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -61,18 +64,21 @@ TEST(LayerAnimationElementTest, BoundsElement) { start = target = middle = gfx::Rect(0, 0, 50, 50); start.set_x(-90); target.set_x(90); + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateBoundsElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetBoundsFromAnimation(start); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); CheckApproximatelyEqual(start, delegate.GetBoundsForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); CheckApproximatelyEqual(middle, delegate.GetBoundsForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation()); } @@ -81,7 +87,7 @@ TEST(LayerAnimationElementTest, BoundsElement) { CheckApproximatelyEqual(target, target_value.bounds); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -92,17 +98,20 @@ TEST(LayerAnimationElementTest, OpacityElement) { float start = 0.0; float middle = 0.5; float target = 1.0; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateOpacityElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetOpacityFromAnimation(start); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); EXPECT_FLOAT_EQ(middle, delegate.GetOpacityForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); } @@ -111,7 +120,7 @@ TEST(LayerAnimationElementTest, OpacityElement) { EXPECT_FLOAT_EQ(target, target_value.opacity); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -121,17 +130,20 @@ TEST(LayerAnimationElementTest, VisibilityElement) { TestLayerAnimationDelegate delegate; bool start = true; bool target = false; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateVisibilityElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetVisibilityFromAnimation(start); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); EXPECT_TRUE(delegate.GetVisibilityForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); EXPECT_TRUE(delegate.GetVisibilityForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); EXPECT_FALSE(delegate.GetVisibilityForAnimation()); } @@ -140,7 +152,7 @@ TEST(LayerAnimationElementTest, VisibilityElement) { EXPECT_FALSE(target_value.visibility); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -151,17 +163,20 @@ TEST(LayerAnimationElementTest, BrightnessElement) { float start = 0.0; float middle = 0.5; float target = 1.0; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateBrightnessElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetBrightnessFromAnimation(start); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation()); } @@ -170,7 +185,7 @@ TEST(LayerAnimationElementTest, BrightnessElement) { EXPECT_FLOAT_EQ(target, target_value.brightness); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -181,17 +196,20 @@ TEST(LayerAnimationElementTest, GrayscaleElement) { float start = 0.0; float middle = 0.5; float target = 1.0; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( LayerAnimationElement::CreateGrayscaleElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + element->set_start_time(start_time); delegate.SetGrayscaleFromAnimation(start); - element->Progress(base::TimeDelta(), &delegate); + element->Progress(start_time, &delegate); EXPECT_FLOAT_EQ(start, delegate.GetGrayscaleForAnimation()); - element->Progress(delta/2, &delegate); + element->Progress(start_time + delta/2, &delegate); EXPECT_FLOAT_EQ(middle, delegate.GetGrayscaleForAnimation()); - element->Progress(delta, &delegate); + element->Progress(start_time + delta, &delegate); EXPECT_FLOAT_EQ(target, delegate.GetGrayscaleForAnimation()); } @@ -200,7 +218,7 @@ TEST(LayerAnimationElementTest, GrayscaleElement) { EXPECT_FLOAT_EQ(target, target_value.grayscale); base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } @@ -213,6 +231,7 @@ TEST(LayerAnimationElementTest, PauseElement) { properties.insert(LayerAnimationElement::OPACITY); properties.insert(LayerAnimationElement::BRIGHTNESS); properties.insert(LayerAnimationElement::GRAYSCALE); + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); scoped_ptr<LayerAnimationElement> element( @@ -221,7 +240,9 @@ TEST(LayerAnimationElementTest, PauseElement) { TestLayerAnimationDelegate delegate; TestLayerAnimationDelegate copy = delegate; - element->Progress(delta, &delegate); + start_time += delta; + element->set_start_time(start_time); + element->Progress(start_time + delta, &delegate); // Nothing should have changed. CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), @@ -237,7 +258,7 @@ TEST(LayerAnimationElementTest, PauseElement) { // Pause should last for |delta|. base::TimeDelta element_duration; - EXPECT_TRUE(element->IsFinished(delta, &element_duration)); + EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration)); EXPECT_EQ(delta, element_duration); } diff --git a/ui/compositor/layer_animation_sequence.cc b/ui/compositor/layer_animation_sequence.cc index 8850fe0..a997c38 100644 --- a/ui/compositor/layer_animation_sequence.cc +++ b/ui/compositor/layer_animation_sequence.cc @@ -31,20 +31,25 @@ LayerAnimationSequence::~LayerAnimationSequence() { DetachedFromSequence(this, true)); } -void LayerAnimationSequence::Progress(base::TimeDelta elapsed, +void LayerAnimationSequence::Progress(base::TimeTicks now, LayerAnimationDelegate* delegate) { bool redraw_required = false; if (elements_.empty()) return; + if (last_element_ == 0) + last_start_ = start_time_; + size_t current_index = last_element_ % elements_.size(); base::TimeDelta element_duration; - while ((is_cyclic_ || last_element_ < elements_.size()) && - elements_[current_index]->IsFinished(elapsed - last_start_, - &element_duration)) { + while (is_cyclic_ || last_element_ < elements_.size()) { + elements_[current_index]->set_start_time(last_start_); + if (!elements_[current_index]->IsFinished(now, &element_duration)) + break; + // Let the element we're passing finish. - if (elements_[current_index]->Progress(elapsed - last_start_, delegate)) + if (elements_[current_index]->Progress(now, delegate)) redraw_required = true; last_start_ += element_duration; ++last_element_; @@ -52,7 +57,7 @@ void LayerAnimationSequence::Progress(base::TimeDelta elapsed, } if (is_cyclic_ || last_element_ < elements_.size()) { - if (elements_[current_index]->Progress(elapsed - last_start_, delegate)) + if (elements_[current_index]->Progress(now, delegate)) redraw_required = true; } @@ -63,24 +68,28 @@ void LayerAnimationSequence::Progress(base::TimeDelta elapsed, if (!is_cyclic_ && last_element_ == elements_.size()) { last_element_ = 0; - last_start_ = base::TimeDelta::FromMilliseconds(0); NotifyEnded(); } } -bool LayerAnimationSequence::IsFinished(base::TimeDelta elapsed) { +bool LayerAnimationSequence::IsFinished(base::TimeTicks time) { if (is_cyclic_) return false; if (elements_.empty()) return true; - base::TimeDelta current_start = last_start_; + if (last_element_ == 0) + last_start_ = start_time_; + + base::TimeTicks current_start = last_start_; size_t current_index = last_element_; base::TimeDelta element_duration; - while ((current_index < elements_.size()) && - elements_[current_index]->IsFinished(elapsed - current_start, - &element_duration)) { + while (current_index < elements_.size()) { + elements_[current_index]->set_start_time(current_start); + if (!elements_[current_index]->IsFinished(time, &element_duration)) + break; + current_start += element_duration; ++current_index; } @@ -107,7 +116,6 @@ void LayerAnimationSequence::ProgressToEnd(LayerAnimationDelegate* delegate) { if (!is_cyclic_) { last_element_ = 0; - last_start_ = base::TimeDelta::FromMilliseconds(0); NotifyEnded(); } } @@ -128,7 +136,6 @@ void LayerAnimationSequence::Abort() { ++current_index; } last_element_ = 0; - last_start_ = base::TimeDelta::FromMilliseconds(0); NotifyAborted(); } diff --git a/ui/compositor/layer_animation_sequence.h b/ui/compositor/layer_animation_sequence.h index dcf5b63..9691ee7 100644 --- a/ui/compositor/layer_animation_sequence.h +++ b/ui/compositor/layer_animation_sequence.h @@ -41,13 +41,19 @@ class COMPOSITOR_EXPORT LayerAnimationSequence explicit LayerAnimationSequence(LayerAnimationElement* element); virtual ~LayerAnimationSequence(); - // Updates the delegate to the appropriate value for |elapsed|. Requests a + // Sets the start time for the animation. This must be called before the + // first call to {Progress, IsFinished}. Once the animation is finished, this + // must be called again in order to restart the animation. + void set_start_time(base::TimeTicks start_time) { start_time_ = start_time; } + base::TimeTicks start_time() const { return start_time_; } + + // Updates the delegate to the appropriate value for |now|. Requests a // redraw if it is required. - void Progress(base::TimeDelta elapsed, LayerAnimationDelegate* delegate); + void Progress(base::TimeTicks now, LayerAnimationDelegate* delegate); - // Returns true if calling Progress now, with the given elapsed time, will - // finish the animation. - bool IsFinished(base::TimeDelta elapsed); + // Returns true if calling Progress now, with the given time, will finish + // the animation. + bool IsFinished(base::TimeTicks time); // Updates the delegate to the end of the animation; if this sequence is // cyclic, updates the delegate to the end of one cycle of the sequence. @@ -115,7 +121,10 @@ class COMPOSITOR_EXPORT LayerAnimationSequence // These are used when animating to efficiently find the next element. size_t last_element_; - base::TimeDelta last_start_; + base::TimeTicks last_start_; + + // The start time of the current run of the sequence. + base::TimeTicks start_time_; // These parties are notified when layer animations end. ObserverList<LayerAnimationObserver> observers_; diff --git a/ui/compositor/layer_animation_sequence_unittest.cc b/ui/compositor/layer_animation_sequence_unittest.cc index 233dea3..a6bb402 100644 --- a/ui/compositor/layer_animation_sequence_unittest.cc +++ b/ui/compositor/layer_animation_sequence_unittest.cc @@ -24,7 +24,10 @@ namespace { // Check that the sequence behaves sanely when it contains no elements. TEST(LayerAnimationSequenceTest, NoElement) { LayerAnimationSequence sequence; - EXPECT_TRUE(sequence.IsFinished(base::TimeDelta())); + base::TimeTicks start_time; + start_time += base::TimeDelta::FromSeconds(1); + sequence.set_start_time(start_time); + EXPECT_TRUE(sequence.IsFinished(start_time)); EXPECT_TRUE(sequence.properties().size() == 0); LayerAnimationElement::AnimatableProperties properties; EXPECT_FALSE(sequence.HasCommonProperty(properties)); @@ -38,24 +41,29 @@ TEST(LayerAnimationSequenceTest, SingleElement) { float start = 0.0f; float middle = 0.5f; float target = 1.0f; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); sequence.AddElement( LayerAnimationElement::CreateOpacityElement(target, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + sequence.set_start_time(start_time); delegate.SetOpacityFromAnimation(start); - sequence.Progress(base::TimeDelta::FromMilliseconds(0), &delegate); + sequence.Progress(start_time, &delegate); EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(500), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(500), + &delegate); EXPECT_FLOAT_EQ(middle, delegate.GetOpacityForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(1000), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(1000), + &delegate); EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation()); } EXPECT_TRUE(sequence.properties().size() == 1); EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::OPACITY) != sequence.properties().end()); - EXPECT_TRUE(sequence.IsFinished(delta)); + EXPECT_TRUE(sequence.IsFinished(start_time + delta)); } // Check that the sequences progresses the delegate as expected when it contains @@ -66,6 +74,7 @@ TEST(LayerAnimationSequenceTest, MultipleElement) { float start_opacity = 0.0f; float middle_opacity = 0.5f; float target_opacity = 1.0f; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); sequence.AddElement( LayerAnimationElement::CreateOpacityElement(target_opacity, delta)); @@ -85,19 +94,24 @@ TEST(LayerAnimationSequenceTest, MultipleElement) { LayerAnimationElement::CreateTransformElement(target_transform, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta + delta + delta; + sequence.set_start_time(start_time); delegate.SetOpacityFromAnimation(start_opacity); delegate.SetTransformFromAnimation(start_transform); - sequence.Progress(base::TimeDelta::FromMilliseconds(0), &delegate); + sequence.Progress(start_time, &delegate); EXPECT_FLOAT_EQ(start_opacity, delegate.GetOpacityForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(500), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(500), + &delegate); EXPECT_FLOAT_EQ(middle_opacity, delegate.GetOpacityForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(1000), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(1000), + &delegate); EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation()); TestLayerAnimationDelegate copy = delegate; // In the middle of the pause -- nothing should have changed. - sequence.Progress(base::TimeDelta::FromMilliseconds(1500), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(1500), + &delegate); CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), copy.GetBoundsForAnimation()); CheckApproximatelyEqual(delegate.GetTransformForAnimation(), @@ -106,13 +120,16 @@ TEST(LayerAnimationSequenceTest, MultipleElement) { copy.GetOpacityForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(2000), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(2000), + &delegate); CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(2500), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(2500), + &delegate); CheckApproximatelyEqual(middle_transform, delegate.GetTransformForAnimation()); - sequence.Progress(base::TimeDelta::FromMilliseconds(3000), &delegate); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(3000), + &delegate); CheckApproximatelyEqual(target_transform, delegate.GetTransformForAnimation()); } @@ -124,7 +141,7 @@ TEST(LayerAnimationSequenceTest, MultipleElement) { sequence.properties().end()); EXPECT_TRUE(sequence.properties().find(LayerAnimationElement::BOUNDS) != sequence.properties().end()); - EXPECT_TRUE(sequence.IsFinished(delta + delta + delta)); + EXPECT_TRUE(sequence.IsFinished(start_time + delta + delta + delta)); } // Check that a sequence can still be aborted if it has cycled many times. @@ -133,6 +150,7 @@ TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) { TestLayerAnimationDelegate delegate; float start_opacity = 0.0f; float target_opacity = 1.0f; + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); sequence.AddElement( LayerAnimationElement::CreateOpacityElement(target_opacity, delta)); @@ -144,13 +162,19 @@ TEST(LayerAnimationSequenceTest, AbortingCyclicSequence) { delegate.SetOpacityFromAnimation(start_opacity); - sequence.Progress(base::TimeDelta::FromMilliseconds(101000), &delegate); + start_time += delta; + sequence.set_start_time(start_time); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(101000), + &delegate); EXPECT_FLOAT_EQ(target_opacity, delegate.GetOpacityForAnimation()); sequence.Abort(); // Should be able to reuse the sequence after aborting. delegate.SetOpacityFromAnimation(start_opacity); - sequence.Progress(base::TimeDelta::FromMilliseconds(100000), &delegate); + start_time += base::TimeDelta::FromMilliseconds(101000); + sequence.set_start_time(start_time); + sequence.Progress(start_time + base::TimeDelta::FromMilliseconds(100000), + &delegate); EXPECT_FLOAT_EQ(start_opacity, delegate.GetOpacityForAnimation()); } @@ -177,16 +201,19 @@ TEST(LayerAnimationSequenceTest, SetTarget) { } TEST(LayerAnimationSequenceTest, AddObserver) { + base::TimeTicks start_time; base::TimeDelta delta = base::TimeDelta::FromSeconds(1); LayerAnimationSequence sequence; sequence.AddElement( LayerAnimationElement::CreateOpacityElement(1.0f, delta)); for (int i = 0; i < 2; ++i) { + start_time += delta; + sequence.set_start_time(start_time); TestLayerAnimationObserver observer; TestLayerAnimationDelegate delegate; sequence.AddObserver(&observer); EXPECT_TRUE(!observer.last_ended_sequence()); - sequence.Progress(delta, &delegate); + sequence.Progress(start_time + delta, &delegate); EXPECT_EQ(observer.last_ended_sequence(), &sequence); sequence.RemoveObserver(&observer); } diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc index 98261fe..ca6b781 100644 --- a/ui/compositor/layer_animator.cc +++ b/ui/compositor/layer_animator.cc @@ -325,11 +325,11 @@ void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { // LayerAnimator protected ----------------------------------------------------- void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence, - base::TimeDelta delta) { + base::TimeTicks now) { if (!delegate()) return; - sequence->Progress(delta, delegate()); + sequence->Progress(now, delegate()); } void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) { @@ -367,11 +367,10 @@ void LayerAnimator::Step(base::TimeTicks now) { if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) continue; - base::TimeDelta delta = now - running_animations_copy[i].start_time(); - if (running_animations_copy[i].sequence()->IsFinished(delta)) { + if (running_animations_copy[i].sequence()->IsFinished(now)) { SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i]); } else - SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], delta); + SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now); } } @@ -440,7 +439,8 @@ void LayerAnimator::FinishAnyAnimationWithZeroDuration() { if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i])) continue; - if (running_animations_copy[i].sequence()->IsFinished(base::TimeDelta())) { + if (running_animations_copy[i].sequence()->IsFinished( + running_animations_copy[i].sequence()->start_time())) { SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]); scoped_ptr<LayerAnimationSequence> removed( SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i])); @@ -680,8 +680,9 @@ bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) { else start_time = base::TimeTicks::Now(); + sequence->set_start_time(start_time); running_animations_.push_back( - RunningAnimation(sequence->AsWeakPtr(), start_time)); + RunningAnimation(sequence->AsWeakPtr())); // Need to keep a reference to the animation. AddToQueueIfNotPresent(sequence); @@ -747,10 +748,8 @@ void LayerAnimator::PurgeDeletedAnimations() { } LayerAnimator::RunningAnimation::RunningAnimation( - const base::WeakPtr<LayerAnimationSequence>& sequence, - base::TimeTicks start_time) - : sequence_(sequence), - start_time_(start_time) { + const base::WeakPtr<LayerAnimationSequence>& sequence) + : sequence_(sequence) { } LayerAnimator::RunningAnimation::~RunningAnimation() { } diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h index 6c24008c..c16d59a 100644 --- a/ui/compositor/layer_animator.h +++ b/ui/compositor/layer_animator.h @@ -201,7 +201,7 @@ class COMPOSITOR_EXPORT LayerAnimator // Virtual for testing. virtual void ProgressAnimation(LayerAnimationSequence* sequence, - base::TimeDelta delta); + base::TimeTicks now); void ProgressAnimationToEnd(LayerAnimationSequence* sequence); @@ -212,20 +212,16 @@ class COMPOSITOR_EXPORT LayerAnimator friend class base::RefCounted<LayerAnimator>; friend class ScopedLayerAnimationSettings; - // We need to keep track of the start time of every running animation. class RunningAnimation { public: - RunningAnimation(const base::WeakPtr<LayerAnimationSequence>& sequence, - base::TimeTicks start_time); + RunningAnimation(const base::WeakPtr<LayerAnimationSequence>& sequence); ~RunningAnimation(); bool is_sequence_alive() const { return !!sequence_; } LayerAnimationSequence* sequence() const { return sequence_.get(); } - base::TimeTicks start_time() const { return start_time_; } private: base::WeakPtr<LayerAnimationSequence> sequence_; - base::TimeTicks start_time_; // Copy and assign are allowed. }; diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc index e1eb67c..912262e 100644 --- a/ui/compositor/layer_animator_unittest.cc +++ b/ui/compositor/layer_animator_unittest.cc @@ -108,9 +108,9 @@ class TestLayerAnimator : public LayerAnimator { virtual ~TestLayerAnimator() {} virtual void ProgressAnimation(LayerAnimationSequence* sequence, - base::TimeDelta delta) OVERRIDE { + base::TimeTicks now) OVERRIDE { EXPECT_TRUE(HasAnimation(sequence)); - LayerAnimator::ProgressAnimation(sequence, delta); + LayerAnimator::ProgressAnimation(sequence, now); } private: |