summaryrefslogtreecommitdiffstats
path: root/ui/compositor
diff options
context:
space:
mode:
authorajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-15 18:47:38 +0000
committerajuma@chromium.org <ajuma@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-15 18:47:38 +0000
commit3d75fedec4f4d01c0fb52c61a7fb0adb2b64c377 (patch)
treec0dd20b995735c4227b8c24519347e27c0f31941 /ui/compositor
parent8da1670a91dab1c2d7ad5a83c3e66da94503bb15 (diff)
downloadchromium_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.cc13
-rw-r--r--ui/compositor/layer_animation_element.h19
-rw-r--r--ui/compositor/layer_animation_element_unittest.cc73
-rw-r--r--ui/compositor/layer_animation_sequence.cc35
-rw-r--r--ui/compositor/layer_animation_sequence.h21
-rw-r--r--ui/compositor/layer_animation_sequence_unittest.cc59
-rw-r--r--ui/compositor/layer_animator.cc21
-rw-r--r--ui/compositor/layer_animator.h8
-rw-r--r--ui/compositor/layer_animator_unittest.cc4
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: