blob: e7a1b00543ea93db6dc626e1298e157511863bdb [file] [log] [blame]
[email protected]b7a1b662012-01-18 14:12:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]710a98d2011-06-23 20:13:292// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]116302fc2012-05-05 21:45:415#include "ui/compositor/layer_animator.h"
[email protected]710a98d2011-06-23 20:13:296
avi87b8b582015-12-24 21:35:257#include <stddef.h>
8
[email protected]710a98d2011-06-23 20:13:299#include "base/logging.h"
[email protected]b4db9372011-10-24 14:44:1910#include "base/memory/scoped_ptr.h"
ssid334fb87a2015-01-27 20:12:0711#include "base/trace_event/trace_event.h"
loysoe926437dd2016-01-14 22:55:3012#include "cc/animation/animation_events.h"
[email protected]95e4e1a02013-03-18 07:09:0913#include "cc/animation/animation_id_provider.h"
loyso841229002015-12-21 10:03:2414#include "cc/animation/animation_player.h"
15#include "cc/animation/animation_timeline.h"
16#include "cc/animation/element_animations.h"
17#include "cc/layers/layer_settings.h"
[email protected]de2cf8c2013-10-25 19:46:4618#include "cc/output/begin_frame_args.h"
[email protected]116302fc2012-05-05 21:45:4119#include "ui/compositor/compositor.h"
20#include "ui/compositor/layer.h"
21#include "ui/compositor/layer_animation_delegate.h"
22#include "ui/compositor/layer_animation_observer.h"
23#include "ui/compositor/layer_animation_sequence.h"
[email protected]9034a282014-06-05 03:11:4724#include "ui/compositor/layer_animator_collection.h"
[email protected]0ed187e2011-10-21 20:07:4225
[email protected]a48f30d2012-10-30 00:35:4126#define SAFE_INVOKE_VOID(function, running_anim, ...) \
27 if (running_anim.is_sequence_alive()) \
28 function(running_anim.sequence(), ##__VA_ARGS__)
29#define SAFE_INVOKE_BOOL(function, running_anim) \
30 ((running_anim.is_sequence_alive()) \
31 ? function(running_anim.sequence()) \
32 : false)
33#define SAFE_INVOKE_PTR(function, running_anim) \
34 ((running_anim.is_sequence_alive()) \
35 ? function(running_anim.sequence()) \
36 : NULL)
37
[email protected]21445e472011-10-21 20:36:3238namespace ui {
[email protected]0ed187e2011-10-21 20:07:4239
[email protected]b4db9372011-10-24 14:44:1940namespace {
41
[email protected]98e2ed22012-11-21 14:02:2342const int kDefaultTransitionDurationMs = 120;
[email protected]1778cbc2012-09-06 04:31:1943
[email protected]9861f1752012-06-01 07:16:1444} // namespace
45
[email protected]b4db9372011-10-24 14:44:1946// LayerAnimator public --------------------------------------------------------
47
48LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
49 : delegate_(NULL),
50 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
[email protected]0d316252014-01-20 15:31:1951 is_transition_duration_locked_(false),
[email protected]b4db9372011-10-24 14:44:1952 transition_duration_(transition_duration),
[email protected]ffb15d12013-09-15 17:29:3053 tween_type_(gfx::Tween::LINEAR),
[email protected]b4db9372011-10-24 14:44:1954 is_started_(false),
[email protected]d064ef82012-11-13 10:26:5955 disable_timer_for_test_(false),
56 adding_animations_(false) {
loyso841229002015-12-21 10:03:2457 if (Layer::UILayerSettings().use_compositor_animation_timelines) {
58 animation_player_ =
59 cc::AnimationPlayer::Create(cc::AnimationIdProvider::NextPlayerId());
60 }
[email protected]710a98d2011-06-23 20:13:2961}
62
63LayerAnimator::~LayerAnimator() {
[email protected]a48f30d2012-10-30 00:35:4164 for (size_t i = 0; i < running_animations_.size(); ++i) {
65 if (running_animations_[i].is_sequence_alive())
66 running_animations_[i].sequence()->OnAnimatorDestroyed();
67 }
[email protected]5d86a112012-09-23 00:21:5868 ClearAnimationsInternal();
69 delegate_ = NULL;
loysoea534372016-02-03 05:20:1970 DCHECK(!animation_player_ || !animation_player_->animation_timeline());
[email protected]710a98d2011-06-23 20:13:2971}
72
[email protected]b4db9372011-10-24 14:44:1973// static
74LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
75 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
76}
77
78// static
79LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
[email protected]98e2ed22012-11-21 14:02:2380 return new LayerAnimator(
81 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
[email protected]b4db9372011-10-24 14:44:1982}
83
[email protected]7713e242012-11-15 17:43:1984// This macro provides the implementation for the setter and getter (well,
85// the getter of the target value) for an animated property. For example,
86// it is used for the implementations of SetTransform and GetTargetTransform.
87// It is worth noting that SetFoo avoids invoking the usual animation machinery
88// if the transition duration is zero -- in this case we just set the property
89// on the layer animation delegate immediately.
90#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
91void LayerAnimator::Set##name(type value) { \
92 base::TimeDelta duration = GetTransitionDuration(); \
[email protected]df55f232012-11-20 22:35:4393 if (duration == base::TimeDelta() && delegate() && \
94 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
[email protected]7713e242012-11-15 17:43:1995 StopAnimatingProperty(LayerAnimationElement::property); \
96 delegate()->Set##name##FromAnimation(value); \
97 return; \
98 } \
99 scoped_ptr<LayerAnimationElement> element( \
100 LayerAnimationElement::Create##name##Element(value, duration)); \
101 element->set_tween_type(tween_type_); \
102 StartAnimation(new LayerAnimationSequence(element.release())); \
103} \
104 \
105member_type LayerAnimator::GetTarget##name() const { \
106 LayerAnimationElement::TargetValue target(delegate()); \
107 GetTargetValue(&target); \
108 return target.member; \
[email protected]fe7074c62011-10-28 15:22:54109}
110
[email protected]7713e242012-11-15 17:43:19111ANIMATED_PROPERTY(
112 const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform);
113ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds);
114ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity);
115ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
116ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
117ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
118ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
[email protected]e81480f1f2012-10-11 23:06:45119
[email protected]0d316252014-01-20 15:31:19120base::TimeDelta LayerAnimator::GetTransitionDuration() const {
121 return transition_duration_;
122}
123
[email protected]e876c272011-11-02 16:42:45124void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
[email protected]9034a282014-06-05 03:11:47125 if (delegate_ && is_started_) {
126 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
127 if (collection)
128 collection->StopAnimator(this);
129 }
loyso1fbd9f92015-12-17 07:43:13130 SwitchToLayer(delegate ? delegate->GetCcLayer() : nullptr);
[email protected]b4db9372011-10-24 14:44:19131 delegate_ = delegate;
[email protected]9034a282014-06-05 03:11:47132 if (delegate_ && is_started_) {
133 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
134 if (collection)
135 collection->StartAnimator(this);
136 }
[email protected]b4db9372011-10-24 14:44:19137}
138
loyso1fbd9f92015-12-17 07:43:13139void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
140 if (delegate_) {
loyso841229002015-12-21 10:03:24141 if (animation_player_)
142 DetachLayerFromAnimationPlayer();
143 else
144 delegate_->GetCcLayer()->RemoveLayerAnimationEventObserver(this);
loyso1fbd9f92015-12-17 07:43:13145 }
loyso841229002015-12-21 10:03:24146 if (new_layer) {
147 if (animation_player_)
148 AttachLayerToAnimationPlayer(new_layer->id());
149 else
150 new_layer->AddLayerAnimationEventObserver(this);
151 }
152}
153
154void LayerAnimator::SetCompositor(Compositor* compositor) {
155 DCHECK(compositor);
156 if (animation_player_) {
157 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
158 DCHECK(timeline);
159 timeline->AttachPlayer(animation_player_);
160
161 DCHECK(delegate_->GetCcLayer());
162 AttachLayerToAnimationPlayer(delegate_->GetCcLayer()->id());
163 }
164}
165
166void LayerAnimator::ResetCompositor(Compositor* compositor) {
167 DCHECK(compositor);
168 if (animation_player_) {
169 DetachLayerFromAnimationPlayer();
170
171 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
172 DCHECK(timeline);
173 timeline->DetachPlayer(animation_player_);
174 }
175}
176
177void LayerAnimator::AttachLayerToAnimationPlayer(int layer_id) {
178 DCHECK(animation_player_);
179
180 if (!animation_player_->layer_id())
181 animation_player_->AttachLayer(layer_id);
182 else
183 DCHECK_EQ(animation_player_->layer_id(), layer_id);
184
185 if (animation_player_->element_animations()) {
186 animation_player_->element_animations()
187 ->layer_animation_controller()
188 ->AddEventObserver(this);
189 }
190}
191
192void LayerAnimator::DetachLayerFromAnimationPlayer() {
193 DCHECK(animation_player_);
194
195 if (animation_player_->element_animations()) {
196 animation_player_->element_animations()
197 ->layer_animation_controller()
198 ->RemoveEventObserver(this);
199 }
200
201 if (animation_player_->layer_id())
202 animation_player_->DetachLayer();
203}
204
205void LayerAnimator::AddThreadedAnimation(scoped_ptr<cc::Animation> animation) {
206 DCHECK(animation_player_);
207 animation_player_->AddAnimation(std::move(animation));
208}
209
210void LayerAnimator::RemoveThreadedAnimation(int animation_id) {
211 DCHECK(animation_player_);
212 animation_player_->RemoveAnimation(animation_id);
loyso1fbd9f92015-12-17 07:43:13213}
214
loyso1fe980f2016-01-18 23:58:15215bool LayerAnimator::HasPendingThreadedAnimationsForTesting() const {
216 DCHECK(animation_player_);
217 return animation_player_->has_pending_animations_for_testing();
218}
219
loysod4127442016-02-03 02:29:40220cc::AnimationPlayer* LayerAnimator::GetAnimationPlayerForTesting() const {
221 return animation_player_.get();
222}
223
[email protected]b4db9372011-10-24 14:44:19224void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58225 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45226 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19227 if (!StartSequenceImmediately(animation)) {
228 // Attempt to preempt a running animation.
229 switch (preemption_strategy_) {
230 case IMMEDIATELY_SET_NEW_TARGET:
231 ImmediatelySetNewTarget(animation);
232 break;
233 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
234 ImmediatelyAnimateToNewTarget(animation);
235 break;
236 case ENQUEUE_NEW_ANIMATION:
237 EnqueueNewAnimation(animation);
238 break;
239 case REPLACE_QUEUED_ANIMATIONS:
240 ReplaceQueuedAnimations(animation);
241 break;
242 case BLEND_WITH_CURRENT_ANIMATION: {
243 // TODO(vollick) Add support for blended sequences and use them here.
244 NOTIMPLEMENTED();
245 break;
246 }
[email protected]7fca53d42011-09-29 15:38:12247 }
[email protected]b4db9372011-10-24 14:44:19248 }
249 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54250 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19251}
252
253void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58254 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45255 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19256 if (is_animating()) {
257 animation_queue_.push_back(make_linked_ptr(animation));
258 ProcessQueue();
259 } else {
260 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12261 }
[email protected]fe7074c62011-10-28 15:22:54262 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29263}
264
[email protected]d064ef82012-11-13 10:26:59265void LayerAnimator::StartTogether(
266 const std::vector<LayerAnimationSequence*>& animations) {
267 scoped_refptr<LayerAnimator> retain(this);
268 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
269 std::vector<LayerAnimationSequence*>::const_iterator iter;
270 for (iter = animations.begin(); iter != animations.end(); ++iter) {
271 StartAnimation(*iter);
272 }
273 return;
274 }
[email protected]d764fd3d2012-11-15 20:07:51275
[email protected]d064ef82012-11-13 10:26:59276 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51277 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47278 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
279 if (collection && collection->HasActiveAnimators())
280 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51281 else
abhishek.ka7215854d2015-05-26 06:13:17282 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51283 }
[email protected]d064ef82012-11-13 10:26:59284
285 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24286 LayerAnimationElement::AnimatableProperties animated_properties =
287 LayerAnimationElement::UNKNOWN;
288
[email protected]d064ef82012-11-13 10:26:59289 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24290 for (iter = animations.begin(); iter != animations.end(); ++iter)
291 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59292
293 // Starting a zero duration pause that affects all the animated properties
294 // will prevent any of the sequences from animating until there are no
295 // running animations that affect any of these properties, as well as
296 // handle preemption strategy.
297 StartAnimation(new LayerAnimationSequence(
298 LayerAnimationElement::CreatePauseElement(animated_properties,
299 base::TimeDelta())));
300
[email protected]bf912272013-02-23 01:54:16301 bool wait_for_group_start = false;
302 for (iter = animations.begin(); iter != animations.end(); ++iter)
303 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
304
305 int group_id = cc::AnimationIdProvider::NextGroupId();
306
[email protected]d064ef82012-11-13 10:26:59307 // These animations (provided they don't animate any common properties) will
308 // now animate together if trivially scheduled.
309 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16310 (*iter)->set_animation_group_id(group_id);
311 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59312 ScheduleAnimation(*iter);
313 }
314
315 adding_animations_ = false;
316 UpdateAnimationState();
317}
318
319
[email protected]b4db9372011-10-24 14:44:19320void LayerAnimator::ScheduleTogether(
321 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58322 scoped_refptr<LayerAnimator> retain(this);
323
[email protected]b4db9372011-10-24 14:44:19324 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24325 LayerAnimationElement::AnimatableProperties animated_properties =
326 LayerAnimationElement::UNKNOWN;
327
[email protected]b4db9372011-10-24 14:44:19328 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24329 for (iter = animations.begin(); iter != animations.end(); ++iter)
330 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29331
[email protected]b4db9372011-10-24 14:44:19332 // Scheduling a zero duration pause that affects all the animated properties
333 // will prevent any of the sequences from animating until there are no
334 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31335 ScheduleAnimation(new LayerAnimationSequence(
336 LayerAnimationElement::CreatePauseElement(animated_properties,
337 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29338
[email protected]bf912272013-02-23 01:54:16339 bool wait_for_group_start = false;
340 for (iter = animations.begin(); iter != animations.end(); ++iter)
341 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
342
343 int group_id = cc::AnimationIdProvider::NextGroupId();
344
[email protected]b4db9372011-10-24 14:44:19345 // These animations (provided they don't animate any common properties) will
346 // now animate together if trivially scheduled.
347 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16348 (*iter)->set_animation_group_id(group_id);
349 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19350 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29351 }
[email protected]fe7074c62011-10-28 15:22:54352
353 UpdateAnimationState();
354}
355
[email protected]2a88c702012-09-04 23:15:02356void LayerAnimator::SchedulePauseForProperties(
357 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24358 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02359 ScheduleAnimation(new ui::LayerAnimationSequence(
360 ui::LayerAnimationElement::CreatePauseElement(
361 properties_to_pause, duration)));
362}
363
[email protected]e876c272011-11-02 16:42:45364bool LayerAnimator::IsAnimatingProperty(
365 LayerAnimationElement::AnimatableProperty property) const {
366 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
367 queue_iter != animation_queue_.end(); ++queue_iter) {
[email protected]e03193d2014-01-14 03:10:24368 if ((*queue_iter)->properties() & property)
[email protected]e876c272011-11-02 16:42:45369 return true;
[email protected]e876c272011-11-02 16:42:45370 }
371 return false;
[email protected]7fca53d42011-09-29 15:38:12372}
373
[email protected]b4db9372011-10-24 14:44:19374void LayerAnimator::StopAnimatingProperty(
375 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58376 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19377 while (true) {
[email protected]a48f30d2012-10-30 00:35:41378 // GetRunningAnimation purges deleted animations before searching, so we are
379 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19380 RunningAnimation* running = GetRunningAnimation(property);
381 if (!running)
382 break;
[email protected]a48f30d2012-10-30 00:35:41383 // As was mentioned above, this sequence must be alive.
384 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14385 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41386 }
[email protected]b4db9372011-10-24 14:44:19387}
388
[email protected]e876c272011-11-02 16:42:45389void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
390 if (!observers_.HasObserver(observer))
391 observers_.AddObserver(observer);
392}
393
394void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
395 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54396 // Remove the observer from all sequences as well.
397 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
398 queue_iter != animation_queue_.end(); ++queue_iter) {
399 (*queue_iter)->RemoveObserver(observer);
400 }
[email protected]e876c272011-11-02 16:42:45401}
402
[email protected]bf912272013-02-23 01:54:16403void LayerAnimator::OnThreadedAnimationStarted(
404 const cc::AnimationEvent& event) {
405 LayerAnimationElement::AnimatableProperty property =
[email protected]cb67b822013-03-12 02:49:22406 LayerAnimationElement::ToAnimatableProperty(event.target_property);
[email protected]bf912272013-02-23 01:54:16407
408 RunningAnimation* running = GetRunningAnimation(property);
409 if (!running)
410 return;
411 DCHECK(running->is_sequence_alive());
412
[email protected]cb67b822013-03-12 02:49:22413 if (running->sequence()->animation_group_id() != event.group_id)
[email protected]bf912272013-02-23 01:54:16414 return;
415
416 running->sequence()->OnThreadedAnimationStarted(event);
417 if (!running->sequence()->waiting_for_group_start())
418 return;
419
[email protected]ac22516a2014-05-15 17:31:36420 base::TimeTicks start_time = event.monotonic_time;
[email protected]bf912272013-02-23 01:54:16421
422 running->sequence()->set_waiting_for_group_start(false);
423
424 // The call to GetRunningAnimation made above already purged deleted
425 // animations, so we are guaranteed that all the animations we iterate
426 // over now are alive.
427 for (RunningAnimations::iterator iter = running_animations_.begin();
428 iter != running_animations_.end(); ++iter) {
429 // Ensure that each sequence is only Started once, regardless of the
430 // number of sequences in the group that have threaded first elements.
[email protected]cb67b822013-03-12 02:49:22431 if (((*iter).sequence()->animation_group_id() == event.group_id) &&
[email protected]bf912272013-02-23 01:54:16432 !(*iter).sequence()->IsFirstElementThreaded() &&
433 (*iter).sequence()->waiting_for_group_start()) {
434 (*iter).sequence()->set_start_time(start_time);
435 (*iter).sequence()->set_waiting_for_group_start(false);
436 (*iter).sequence()->Start(delegate());
437 }
438 }
439}
440
[email protected]9034a282014-06-05 03:11:47441void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
442 if (is_animating() && !is_started_) {
443 collection->StartAnimator(this);
444 is_started_ = true;
445 }
446}
447
448void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
449 if (is_animating() && is_started_) {
450 collection->StopAnimator(this);
451 is_started_ = false;
452 }
453}
454
[email protected]d59a3692012-04-10 20:27:31455// LayerAnimator protected -----------------------------------------------------
456
[email protected]5d86a112012-09-23 00:21:58457void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38458 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16459 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58460 return;
461
[email protected]3d75fed2012-12-15 18:47:38462 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31463}
464
[email protected]a48f30d2012-10-30 00:35:41465void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30466 if (!delegate())
467 return;
468
469 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41470}
471
[email protected]d59a3692012-04-10 20:27:31472bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
473 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
474 queue_iter != animation_queue_.end(); ++queue_iter) {
475 if ((*queue_iter).get() == sequence)
476 return true;
477 }
478 return false;
479}
480
[email protected]b4db9372011-10-24 14:44:19481// LayerAnimator private -------------------------------------------------------
482
483void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31484 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58485 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31486
[email protected]b4db9372011-10-24 14:44:19487 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19488
[email protected]a48f30d2012-10-30 00:35:41489 PurgeDeletedAnimations();
490
[email protected]f5cd9e52011-11-03 21:38:08491 // We need to make a copy of the running animations because progressing them
492 // and finishing them may indirectly affect the collection of running
493 // animations.
494 RunningAnimations running_animations_copy = running_animations_;
495 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41496 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31497 continue;
498
[email protected]3d75fed2012-12-15 18:47:38499 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14500 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
501 } else {
[email protected]3d75fed2012-12-15 18:47:38502 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14503 }
[email protected]b4db9372011-10-24 14:44:19504 }
[email protected]b4db9372011-10-24 14:44:19505}
506
[email protected]6f110e42012-12-18 00:21:14507void LayerAnimator::StopAnimatingInternal(bool abort) {
508 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55509 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14510 // We're going to attempt to finish the first running animation. Let's
511 // ensure that it's valid.
512 PurgeDeletedAnimations();
513
514 // If we've purged all running animations, attempt to start one up.
515 if (running_animations_.empty())
516 ProcessQueue();
517
518 DCHECK(!running_animations_.empty());
519
520 // Still no luck, let's just bail and clear all animations.
521 if (running_animations_.empty()) {
522 ClearAnimationsInternal();
523 break;
524 }
525
526 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
527 }
528}
529
[email protected]b4db9372011-10-24 14:44:19530void LayerAnimator::UpdateAnimationState() {
531 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12532 return;
533
[email protected]b4db9372011-10-24 14:44:19534 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47535 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
536 if (collection) {
537 if (should_start && !is_started_)
538 collection->StartAnimator(this);
539 else if (!should_start && is_started_)
540 collection->StopAnimator(this);
541 is_started_ = should_start;
542 } else {
543 is_started_ = false;
544 }
[email protected]710a98d2011-06-23 20:13:29545}
546
[email protected]f5cd9e52011-11-03 21:38:08547LayerAnimationSequence* LayerAnimator::RemoveAnimation(
548 LayerAnimationSequence* sequence) {
549 linked_ptr<LayerAnimationSequence> to_return;
550
[email protected]bf912272013-02-23 01:54:16551 bool is_running = false;
552
[email protected]f5cd9e52011-11-03 21:38:08553 // First remove from running animations
[email protected]b4db9372011-10-24 14:44:19554 for (RunningAnimations::iterator iter = running_animations_.begin();
555 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41556 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19557 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16558 is_running = true;
[email protected]b4db9372011-10-24 14:44:19559 break;
[email protected]21445e472011-10-21 20:36:32560 }
561 }
[email protected]b4db9372011-10-24 14:44:19562
563 // Then remove from the queue
564 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
565 queue_iter != animation_queue_.end(); ++queue_iter) {
566 if ((*queue_iter) == sequence) {
[email protected]f5cd9e52011-11-03 21:38:08567 to_return = *queue_iter;
[email protected]b4db9372011-10-24 14:44:19568 animation_queue_.erase(queue_iter);
569 break;
570 }
571 }
[email protected]f5cd9e52011-11-03 21:38:08572
[email protected]bf912272013-02-23 01:54:16573 if (!to_return.get() ||
574 !to_return->waiting_for_group_start() ||
575 !to_return->IsFirstElementThreaded())
576 return to_return.release();
577
578 // The removed sequence may have been responsible for making other sequences
579 // wait for a group start. If no other sequences in the group have a
580 // threaded first element, the group no longer needs the additional wait.
581 bool is_wait_still_needed = false;
582 int group_id = to_return->animation_group_id();
583 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
584 queue_iter != animation_queue_.end(); ++queue_iter) {
585 if (((*queue_iter)->animation_group_id() == group_id) &&
586 (*queue_iter)->IsFirstElementThreaded()) {
587 is_wait_still_needed = true;
588 break;
589 }
590 }
591
592 if (is_wait_still_needed)
593 return to_return.release();
594
595 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
596 queue_iter != animation_queue_.end(); ++queue_iter) {
597 if ((*queue_iter)->animation_group_id() == group_id &&
598 (*queue_iter)->waiting_for_group_start()) {
599 (*queue_iter)->set_waiting_for_group_start(false);
600 if (is_running) {
601 (*queue_iter)->set_start_time(last_step_time_);
602 (*queue_iter)->Start(delegate());
603 }
604 }
605 }
[email protected]f5cd9e52011-11-03 21:38:08606 return to_return.release();
[email protected]0ed187e2011-10-21 20:07:42607}
608
[email protected]6f110e42012-12-18 00:21:14609void LayerAnimator::FinishAnimation(
610 LayerAnimationSequence* sequence, bool abort) {
[email protected]5d86a112012-09-23 00:21:58611 scoped_refptr<LayerAnimator> retain(this);
[email protected]f5cd9e52011-11-03 21:38:08612 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
[email protected]6f110e42012-12-18 00:21:14613 if (abort)
[email protected]bf912272013-02-23 01:54:16614 sequence->Abort(delegate());
[email protected]6f110e42012-12-18 00:21:14615 else
616 ProgressAnimationToEnd(sequence);
ljagielski20570982015-01-07 20:32:55617 if (!delegate())
618 return;
[email protected]b4db9372011-10-24 14:44:19619 ProcessQueue();
620 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32621}
[email protected]0ed187e2011-10-21 20:07:42622
[email protected]b4db9372011-10-24 14:44:19623void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
[email protected]5d86a112012-09-23 00:21:58624 scoped_refptr<LayerAnimator> retain(this);
[email protected]2ddfe432011-11-07 19:26:30625 // Special case: if we've started a 0 duration animation, just finish it now
626 // and get rid of it. We need to make a copy because Progress may indirectly
627 // cause new animations to start running.
[email protected]f5cd9e52011-11-03 21:38:08628 RunningAnimations running_animations_copy = running_animations_;
629 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41630 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31631 continue;
632
[email protected]3d75fed2012-12-15 18:47:38633 if (running_animations_copy[i].sequence()->IsFinished(
634 running_animations_copy[i].sequence()->start_time())) {
[email protected]a48f30d2012-10-30 00:35:41635 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]f5cd9e52011-11-03 21:38:08636 scoped_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41637 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]b4db9372011-10-24 14:44:19638 }
639 }
640 ProcessQueue();
641 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32642}
[email protected]0ed187e2011-10-21 20:07:42643
[email protected]b4db9372011-10-24 14:44:19644void LayerAnimator::ClearAnimations() {
[email protected]5d86a112012-09-23 00:21:58645 scoped_refptr<LayerAnimator> retain(this);
646 ClearAnimationsInternal();
[email protected]b4db9372011-10-24 14:44:19647}
648
649LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
650 LayerAnimationElement::AnimatableProperty property) {
[email protected]a48f30d2012-10-30 00:35:41651 PurgeDeletedAnimations();
[email protected]b4db9372011-10-24 14:44:19652 for (RunningAnimations::iterator iter = running_animations_.begin();
653 iter != running_animations_.end(); ++iter) {
[email protected]e03193d2014-01-14 03:10:24654 if ((*iter).sequence()->properties() & property)
[email protected]b4db9372011-10-24 14:44:19655 return &(*iter);
656 }
657 return NULL;
658}
659
660void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
661 // If we don't have the animation in the queue yet, add it.
662 bool found_sequence = false;
663 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
664 queue_iter != animation_queue_.end(); ++queue_iter) {
665 if ((*queue_iter) == animation) {
666 found_sequence = true;
667 break;
668 }
669 }
670
671 if (!found_sequence)
672 animation_queue_.push_front(make_linked_ptr(animation));
673}
674
675void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08676 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19677 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08678 // progress them to the end and remove them. Note, Aborting or Progressing
679 // animations may affect the collection of running animations, so we need to
680 // operate on a copy.
681 RunningAnimations running_animations_copy = running_animations_;
682 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41683 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31684 continue;
685
[email protected]712f4b642013-03-14 07:09:15686 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19687 sequence->properties())) {
[email protected]f5cd9e52011-11-03 21:38:08688 scoped_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41689 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08690 if (abort)
[email protected]bf912272013-02-23 01:54:16691 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08692 else
[email protected]a48f30d2012-10-30 00:35:41693 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19694 }
695 }
696
[email protected]f5cd9e52011-11-03 21:38:08697 // Same for the queued animations that haven't been started. Again, we'll
698 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41699 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08700 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
701 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41702 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08703
704 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19705 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31706 continue;
707
[email protected]712f4b642013-03-14 07:09:15708 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
[email protected]7ffde472013-06-04 06:42:19709 scoped_ptr<LayerAnimationSequence> removed(
710 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19711 if (abort)
[email protected]bf912272013-02-23 01:54:16712 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19713 else
[email protected]7ffde472013-06-04 06:42:19714 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19715 }
716 }
717}
718
719void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41720 // Need to detect if our sequence gets destroyed.
721 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
722 sequence->AsWeakPtr();
723
[email protected]b4db9372011-10-24 14:44:19724 const bool abort = false;
725 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19726 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41727 return;
728
[email protected]d3ba37ab2012-02-09 19:53:13729 LayerAnimationSequence* removed = RemoveAnimation(sequence);
730 DCHECK(removed == NULL || removed == sequence);
[email protected]7ffde472013-06-04 06:42:19731 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41732 return;
733
[email protected]4a386e42012-12-05 01:19:30734 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19735 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41736 return;
737
738 delete sequence;
[email protected]b4db9372011-10-24 14:44:19739}
740
741void LayerAnimator::ImmediatelyAnimateToNewTarget(
742 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41743 // Need to detect if our sequence gets destroyed.
744 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
745 sequence->AsWeakPtr();
746
[email protected]b4db9372011-10-24 14:44:19747 const bool abort = true;
748 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19749 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41750 return;
751
[email protected]b4db9372011-10-24 14:44:19752 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19753 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41754 return;
755
[email protected]b4db9372011-10-24 14:44:19756 StartSequenceImmediately(sequence);
757}
758
759void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
760 // It is assumed that if there was no conflicting animation, we would
761 // not have been called. No need to check for a collision; just
762 // add to the queue.
763 animation_queue_.push_back(make_linked_ptr(sequence));
764 ProcessQueue();
765}
766
767void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41768 // Need to detect if our sequence gets destroyed.
769 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
770 sequence->AsWeakPtr();
771
[email protected]b4db9372011-10-24 14:44:19772 // Remove all animations that aren't running. Note: at each iteration i is
773 // incremented or an element is removed from the queue, so
774 // animation_queue_.size() - i is always decreasing and we are always making
775 // progress towards the loop terminating.
776 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19777 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41778 break;
779
780 PurgeDeletedAnimations();
781
[email protected]b4db9372011-10-24 14:44:19782 bool is_running = false;
783 for (RunningAnimations::const_iterator iter = running_animations_.begin();
784 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41785 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19786 is_running = true;
787 break;
788 }
789 }
[email protected]a48f30d2012-10-30 00:35:41790
[email protected]b4db9372011-10-24 14:44:19791 if (!is_running)
[email protected]300548c2012-06-17 08:54:55792 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19793 else
794 ++i;
795 }
796 animation_queue_.push_back(make_linked_ptr(sequence));
797 ProcessQueue();
798}
799
800void LayerAnimator::ProcessQueue() {
801 bool started_sequence = false;
802 do {
803 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19804 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24805 LayerAnimationElement::AnimatableProperties animated =
806 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19807 for (RunningAnimations::const_iterator iter = running_animations_.begin();
808 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41809 if (!(*iter).is_sequence_alive())
810 continue;
[email protected]e03193d2014-01-14 03:10:24811
812 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19813 }
814
815 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08816 // property or a property that will be animated before it. Note: starting
817 // the animation may indirectly cause more animations to be started, so we
818 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41819 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19820 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08821 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41822 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08823
824 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19825 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41826 continue;
827
[email protected]712f4b642013-03-14 07:09:15828 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41829 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19830 started_sequence = true;
831 break;
832 }
833
834 // Animation couldn't be started. Add its properties to the collection so
835 // that we don't start a conflicting animation. For example, if our queue
836 // has the elements { {T,B}, {B} } (that is, an element that animates both
837 // the transform and the bounds followed by an element that animates the
838 // bounds), and we're currently animating the transform, we can't start
839 // the first element because it animates the transform, too. We cannot
840 // start the second element, either, because the first element animates
841 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24842 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19843 }
844
845 // If we started a sequence, try again. We may be able to start several.
846 } while (started_sequence);
847}
848
849bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41850 PurgeDeletedAnimations();
851
[email protected]b4db9372011-10-24 14:44:19852 // Ensure that no one is animating one of the sequence's properties already.
853 for (RunningAnimations::const_iterator iter = running_animations_.begin();
854 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15855 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19856 return false;
857 }
858
charliea3be839702015-01-26 17:35:41859 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47860 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19861 // last_tick_time() from there to ensure animations started during the same
862 // event complete at the same time.
863 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47864 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59865 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19866 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47867 else if (collection && collection->HasActiveAnimators())
868 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19869 else
abhishek.ka7215854d2015-05-26 06:13:17870 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19871
[email protected]bf912272013-02-23 01:54:16872 if (!sequence->animation_group_id())
873 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
874 if (!sequence->waiting_for_group_start() ||
875 sequence->IsFirstElementThreaded()) {
876 sequence->set_start_time(start_time);
877 sequence->Start(delegate());
878 }
[email protected]a48f30d2012-10-30 00:35:41879 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38880 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19881
882 // Need to keep a reference to the animation.
883 AddToQueueIfNotPresent(sequence);
884
885 // Ensure that animations get stepped at their start time.
886 Step(start_time);
887
888 return true;
[email protected]710a98d2011-06-23 20:13:29889}
890
[email protected]fe7074c62011-10-28 15:22:54891void LayerAnimator::GetTargetValue(
892 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13893 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
894 iter != animation_queue_.end(); ++iter) {
895 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54896 }
897}
898
[email protected]e876c272011-11-02 16:42:45899void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
900 if (observers_.might_have_observers()) {
brettw5a1613dc2015-06-02 05:34:43901 base::ObserverListBase<LayerAnimationObserver>::Iterator it(&observers_);
[email protected]e876c272011-11-02 16:42:45902 LayerAnimationObserver* obs;
903 while ((obs = it.GetNext()) != NULL) {
904 sequence->AddObserver(obs);
905 }
906 }
907 sequence->OnScheduled();
908}
909
[email protected]0d316252014-01-20 15:31:19910void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
911 if (is_transition_duration_locked_)
912 return;
913 transition_duration_ = duration;
[email protected]9861f1752012-06-01 07:16:14914}
915
[email protected]5d86a112012-09-23 00:21:58916void LayerAnimator::ClearAnimationsInternal() {
[email protected]a48f30d2012-10-30 00:35:41917 PurgeDeletedAnimations();
918
[email protected]5d86a112012-09-23 00:21:58919 // Abort should never affect the set of running animations, but just in case
920 // clients are badly behaved, we will use a copy of the running animations.
921 RunningAnimations running_animations_copy = running_animations_;
922 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41923 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]5d86a112012-09-23 00:21:58924 continue;
925
926 scoped_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41927 RemoveAnimation(running_animations_copy[i].sequence()));
[email protected]5d86a112012-09-23 00:21:58928 if (removed.get())
[email protected]bf912272013-02-23 01:54:16929 removed->Abort(delegate());
[email protected]5d86a112012-09-23 00:21:58930 }
931 // This *should* have cleared the list of running animations.
932 DCHECK(running_animations_.empty());
933 running_animations_.clear();
934 animation_queue_.clear();
935 UpdateAnimationState();
936}
937
[email protected]a48f30d2012-10-30 00:35:41938void LayerAnimator::PurgeDeletedAnimations() {
939 for (size_t i = 0; i < running_animations_.size();) {
940 if (!running_animations_[i].is_sequence_alive())
941 running_animations_.erase(running_animations_.begin() + i);
942 else
943 i++;
944 }
945}
946
[email protected]9034a282014-06-05 03:11:47947LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
948 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
949}
950
loyso1fbd9f92015-12-17 07:43:13951void LayerAnimator::OnAnimationStarted(const cc::AnimationEvent& event) {
952 OnThreadedAnimationStarted(event);
953}
954
[email protected]a48f30d2012-10-30 00:35:41955LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38956 const base::WeakPtr<LayerAnimationSequence>& sequence)
957 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41958}
959
vmpstr0ae825e72016-02-25 20:31:31960LayerAnimator::RunningAnimation::RunningAnimation(
961 const RunningAnimation& other) = default;
962
[email protected]a48f30d2012-10-30 00:35:41963LayerAnimator::RunningAnimation::~RunningAnimation() { }
964
[email protected]710a98d2011-06-23 20:13:29965} // namespace ui