blob: 5809b9db569b651fd374f10660d6b532793540bf [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
danakj25c52c32016-04-12 21:51:089#include <memory>
10
[email protected]710a98d2011-06-23 20:13:2911#include "base/logging.h"
ssid334fb87a2015-01-27 20:12:0712#include "base/trace_event/trace_event.h"
loyso3338dfb2016-03-09 03:07:3213#include "cc/animation/animation_host.h"
[email protected]95e4e1a02013-03-18 07:09:0914#include "cc/animation/animation_id_provider.h"
loyso841229002015-12-21 10:03:2415#include "cc/animation/animation_timeline.h"
16#include "cc/animation/element_animations.h"
Yi Guaa830ff2018-02-22 03:09:1117#include "cc/animation/single_keyframe_effect_animation.h"
Fady Samuelc296f5fb2017-07-21 04:02:1918#include "components/viz/common/frame_sinks/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
Daniel Bratellc2fecad52017-12-21 22:36:2242const int kLayerAnimatorDefaultTransitionDurationMs = 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),
varkha62ba671d2017-01-25 19:09:4656 adding_animations_(false),
57 animation_metrics_reporter_(nullptr) {
Yi Guaa830ff2018-02-22 03:09:1158 animation_ = cc::SingleKeyframeEffectAnimation::Create(
59 cc::AnimationIdProvider::NextAnimationId());
[email protected]710a98d2011-06-23 20:13:2960}
61
62LayerAnimator::~LayerAnimator() {
[email protected]a48f30d2012-10-30 00:35:4163 for (size_t i = 0; i < running_animations_.size(); ++i) {
64 if (running_animations_[i].is_sequence_alive())
65 running_animations_[i].sequence()->OnAnimatorDestroyed();
66 }
[email protected]5d86a112012-09-23 00:21:5867 ClearAnimationsInternal();
68 delegate_ = NULL;
Yi Guaa830ff2018-02-22 03:09:1169 DCHECK(!animation_->animation_timeline());
[email protected]710a98d2011-06-23 20:13:2970}
71
[email protected]b4db9372011-10-24 14:44:1972// static
73LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
74 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
75}
76
77// static
78LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
Daniel Bratellc2fecad52017-12-21 22:36:2279 return new LayerAnimator(base::TimeDelta::FromMilliseconds(
80 kLayerAnimatorDefaultTransitionDurationMs));
[email protected]b4db9372011-10-24 14:44:1981}
82
[email protected]7713e242012-11-15 17:43:1983// This macro provides the implementation for the setter and getter (well,
84// the getter of the target value) for an animated property. For example,
85// it is used for the implementations of SetTransform and GetTargetTransform.
86// It is worth noting that SetFoo avoids invoking the usual animation machinery
87// if the transition duration is zero -- in this case we just set the property
88// on the layer animation delegate immediately.
Francois Doray91e63fb72017-11-08 14:21:5289#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
90 void LayerAnimator::Set##name(type value) { \
91 base::TimeDelta duration = GetTransitionDuration(); \
92 if (duration.is_zero() && delegate() && \
93 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
94 StopAnimatingProperty(LayerAnimationElement::property); \
95 delegate()->Set##name##FromAnimation( \
96 value, PropertyChangeReason::NOT_FROM_ANIMATION); \
97 return; \
98 } \
99 std::unique_ptr<LayerAnimationElement> element = \
100 LayerAnimationElement::Create##name##Element(value, duration); \
101 element->set_tween_type(tween_type_); \
102 StartAnimation(new LayerAnimationSequence(std::move(element))); \
103 } \
104 \
105 member_type LayerAnimator::GetTarget##name() const { \
106 LayerAnimationElement::TargetValue target(delegate()); \
107 GetTargetValue(&target); \
108 return target.member; \
danakj25c52c32016-04-12 21:51:08109 }
[email protected]fe7074c62011-10-28 15:22:54110
[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) {
loysoe2fed922016-03-09 04:41:55140 if (delegate_)
Yi Guaa830ff2018-02-22 03:09:11141 DetachLayerFromAnimation();
loysoe2fed922016-03-09 04:41:55142 if (new_layer)
Yi Guaa830ff2018-02-22 03:09:11143 AttachLayerToAnimation(new_layer->id());
loyso841229002015-12-21 10:03:24144}
145
loysocc8e3db2016-10-04 05:22:03146void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24147 DCHECK(compositor);
loyso841229002015-12-21 10:03:24148
loysoe2fed922016-03-09 04:41:55149 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
150 DCHECK(timeline);
Yi Guaa830ff2018-02-22 03:09:11151 timeline->AttachAnimation(animation_);
loysoe2fed922016-03-09 04:41:55152
loysocc8e3db2016-10-04 05:22:03153 DCHECK(delegate_->GetCcLayer());
Yi Guaa830ff2018-02-22 03:09:11154 AttachLayerToAnimation(delegate_->GetCcLayer()->id());
loyso841229002015-12-21 10:03:24155}
156
loysocc8e3db2016-10-04 05:22:03157void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24158 DCHECK(compositor);
loyso3338dfb2016-03-09 03:07:32159
loysode0a0022016-04-15 02:28:38160 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
161 DCHECK(timeline);
162
Yi Guaa830ff2018-02-22 03:09:11163 DetachLayerFromAnimation();
164 timeline->DetachAnimation(animation_);
loyso841229002015-12-21 10:03:24165}
166
Yi Guaa830ff2018-02-22 03:09:11167void LayerAnimator::AttachLayerToAnimation(int layer_id) {
vollickef2ae922016-06-29 17:54:27168 // For ui, layer and element ids are equivalent.
chrishtrc3daf272017-05-11 11:08:02169 cc::ElementId element_id(layer_id);
Yi Guaa830ff2018-02-22 03:09:11170 if (!animation_->element_id())
171 animation_->AttachElement(element_id);
loyso841229002015-12-21 10:03:24172 else
Yi Guaa830ff2018-02-22 03:09:11173 DCHECK_EQ(animation_->element_id(), element_id);
loyso841229002015-12-21 10:03:24174
Yi Guaa830ff2018-02-22 03:09:11175 animation_->set_animation_delegate(this);
loyso841229002015-12-21 10:03:24176}
177
Yi Guaa830ff2018-02-22 03:09:11178void LayerAnimator::DetachLayerFromAnimation() {
179 animation_->set_animation_delegate(nullptr);
loyso841229002015-12-21 10:03:24180
Yi Guaa830ff2018-02-22 03:09:11181 if (animation_->element_id())
182 animation_->DetachElement();
loyso841229002015-12-21 10:03:24183}
184
Yi Gu4e1dce32018-07-04 20:52:15185void LayerAnimator::AddThreadedAnimation(
186 std::unique_ptr<cc::KeyframeModel> animation) {
187 animation_->AddKeyframeModel(std::move(animation));
loyso841229002015-12-21 10:03:24188}
189
Yi Gu4e1dce32018-07-04 20:52:15190void LayerAnimator::RemoveThreadedAnimation(int keyframe_model_id) {
191 animation_->RemoveKeyframeModel(keyframe_model_id);
loyso1fbd9f92015-12-17 07:43:13192}
193
Yi Guaa830ff2018-02-22 03:09:11194cc::SingleKeyframeEffectAnimation* LayerAnimator::GetAnimationForTesting()
195 const {
196 return animation_.get();
loysod4127442016-02-03 02:29:40197}
198
[email protected]b4db9372011-10-24 14:44:19199void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58200 scoped_refptr<LayerAnimator> retain(this);
varkha62ba671d2017-01-25 19:09:46201 if (animation_metrics_reporter_)
202 animation->SetAnimationMetricsReporter(animation_metrics_reporter_);
[email protected]e876c272011-11-02 16:42:45203 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19204 if (!StartSequenceImmediately(animation)) {
205 // Attempt to preempt a running animation.
206 switch (preemption_strategy_) {
207 case IMMEDIATELY_SET_NEW_TARGET:
208 ImmediatelySetNewTarget(animation);
209 break;
210 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
211 ImmediatelyAnimateToNewTarget(animation);
212 break;
213 case ENQUEUE_NEW_ANIMATION:
214 EnqueueNewAnimation(animation);
215 break;
216 case REPLACE_QUEUED_ANIMATIONS:
217 ReplaceQueuedAnimations(animation);
218 break;
[email protected]7fca53d42011-09-29 15:38:12219 }
[email protected]b4db9372011-10-24 14:44:19220 }
221 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54222 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19223}
224
225void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58226 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45227 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19228 if (is_animating()) {
229 animation_queue_.push_back(make_linked_ptr(animation));
230 ProcessQueue();
231 } else {
232 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12233 }
[email protected]fe7074c62011-10-28 15:22:54234 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29235}
236
[email protected]d064ef82012-11-13 10:26:59237void LayerAnimator::StartTogether(
238 const std::vector<LayerAnimationSequence*>& animations) {
239 scoped_refptr<LayerAnimator> retain(this);
240 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
241 std::vector<LayerAnimationSequence*>::const_iterator iter;
242 for (iter = animations.begin(); iter != animations.end(); ++iter) {
243 StartAnimation(*iter);
244 }
245 return;
246 }
[email protected]d764fd3d2012-11-15 20:07:51247
[email protected]d064ef82012-11-13 10:26:59248 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51249 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47250 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
251 if (collection && collection->HasActiveAnimators())
252 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51253 else
abhishek.ka7215854d2015-05-26 06:13:17254 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51255 }
[email protected]d064ef82012-11-13 10:26:59256
257 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24258 LayerAnimationElement::AnimatableProperties animated_properties =
259 LayerAnimationElement::UNKNOWN;
260
[email protected]d064ef82012-11-13 10:26:59261 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24262 for (iter = animations.begin(); iter != animations.end(); ++iter)
263 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59264
265 // Starting a zero duration pause that affects all the animated properties
266 // will prevent any of the sequences from animating until there are no
267 // running animations that affect any of these properties, as well as
268 // handle preemption strategy.
269 StartAnimation(new LayerAnimationSequence(
270 LayerAnimationElement::CreatePauseElement(animated_properties,
271 base::TimeDelta())));
272
[email protected]bf912272013-02-23 01:54:16273 bool wait_for_group_start = false;
274 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15275 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16276 int group_id = cc::AnimationIdProvider::NextGroupId();
277
[email protected]d064ef82012-11-13 10:26:59278 // These animations (provided they don't animate any common properties) will
279 // now animate together if trivially scheduled.
280 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16281 (*iter)->set_animation_group_id(group_id);
282 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59283 ScheduleAnimation(*iter);
284 }
285
286 adding_animations_ = false;
287 UpdateAnimationState();
288}
289
290
[email protected]b4db9372011-10-24 14:44:19291void LayerAnimator::ScheduleTogether(
292 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58293 scoped_refptr<LayerAnimator> retain(this);
294
[email protected]b4db9372011-10-24 14:44:19295 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24296 LayerAnimationElement::AnimatableProperties animated_properties =
297 LayerAnimationElement::UNKNOWN;
298
[email protected]b4db9372011-10-24 14:44:19299 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24300 for (iter = animations.begin(); iter != animations.end(); ++iter)
301 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29302
[email protected]b4db9372011-10-24 14:44:19303 // Scheduling a zero duration pause that affects all the animated properties
304 // will prevent any of the sequences from animating until there are no
305 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31306 ScheduleAnimation(new LayerAnimationSequence(
307 LayerAnimationElement::CreatePauseElement(animated_properties,
308 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29309
[email protected]bf912272013-02-23 01:54:16310 bool wait_for_group_start = false;
311 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15312 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16313
314 int group_id = cc::AnimationIdProvider::NextGroupId();
315
[email protected]b4db9372011-10-24 14:44:19316 // These animations (provided they don't animate any common properties) will
317 // now animate together if trivially scheduled.
318 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16319 (*iter)->set_animation_group_id(group_id);
320 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19321 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29322 }
[email protected]fe7074c62011-10-28 15:22:54323
324 UpdateAnimationState();
325}
326
[email protected]2a88c702012-09-04 23:15:02327void LayerAnimator::SchedulePauseForProperties(
328 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24329 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02330 ScheduleAnimation(new ui::LayerAnimationSequence(
331 ui::LayerAnimationElement::CreatePauseElement(
332 properties_to_pause, duration)));
333}
334
Francois Dorayeef012b62017-10-26 20:02:59335bool LayerAnimator::IsAnimatingOnePropertyOf(
336 LayerAnimationElement::AnimatableProperties properties) const {
337 for (auto& layer_animation_sequence : animation_queue_) {
338 if (layer_animation_sequence->properties() & properties)
[email protected]e876c272011-11-02 16:42:45339 return true;
[email protected]e876c272011-11-02 16:42:45340 }
341 return false;
[email protected]7fca53d42011-09-29 15:38:12342}
343
[email protected]b4db9372011-10-24 14:44:19344void LayerAnimator::StopAnimatingProperty(
345 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58346 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19347 while (true) {
[email protected]a48f30d2012-10-30 00:35:41348 // GetRunningAnimation purges deleted animations before searching, so we are
349 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19350 RunningAnimation* running = GetRunningAnimation(property);
351 if (!running)
352 break;
[email protected]a48f30d2012-10-30 00:35:41353 // As was mentioned above, this sequence must be alive.
354 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14355 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41356 }
[email protected]b4db9372011-10-24 14:44:19357}
358
[email protected]e876c272011-11-02 16:42:45359void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
Francois Doray29ecd3aa2017-11-07 15:40:18360 if (!observers_.HasObserver(observer)) {
[email protected]e876c272011-11-02 16:42:45361 observers_.AddObserver(observer);
Francois Doray29ecd3aa2017-11-07 15:40:18362 for (auto& layer_animation_sequence : animation_queue_)
363 layer_animation_sequence->AddObserver(observer);
364 }
[email protected]e876c272011-11-02 16:42:45365}
366
367void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
368 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54369 // Remove the observer from all sequences as well.
370 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
371 queue_iter != animation_queue_.end(); ++queue_iter) {
372 (*queue_iter)->RemoveObserver(observer);
373 }
[email protected]e876c272011-11-02 16:42:45374}
375
wutao4f1c0d5d2017-10-05 01:02:43376void LayerAnimator::AddOwnedObserver(
377 std::unique_ptr<ImplicitAnimationObserver> animation_observer) {
378 owned_observer_list_.push_back(std::move(animation_observer));
379}
380
381void LayerAnimator::RemoveAndDestroyOwnedObserver(
382 ImplicitAnimationObserver* animation_observer) {
383 owned_observer_list_.erase(
384 std::remove_if(
385 owned_observer_list_.begin(), owned_observer_list_.end(),
386 [animation_observer](
387 const std::unique_ptr<ImplicitAnimationObserver>& other) {
388 return other.get() == animation_observer;
389 }),
390 owned_observer_list_.end());
391}
392
[email protected]bf912272013-02-23 01:54:16393void LayerAnimator::OnThreadedAnimationStarted(
loyso79c0bfc2016-04-18 23:46:42394 base::TimeTicks monotonic_time,
395 cc::TargetProperty::Type target_property,
396 int group_id) {
[email protected]bf912272013-02-23 01:54:16397 LayerAnimationElement::AnimatableProperty property =
loyso79c0bfc2016-04-18 23:46:42398 LayerAnimationElement::ToAnimatableProperty(target_property);
[email protected]bf912272013-02-23 01:54:16399
400 RunningAnimation* running = GetRunningAnimation(property);
401 if (!running)
402 return;
403 DCHECK(running->is_sequence_alive());
404
loyso79c0bfc2016-04-18 23:46:42405 if (running->sequence()->animation_group_id() != group_id)
[email protected]bf912272013-02-23 01:54:16406 return;
407
loyso79c0bfc2016-04-18 23:46:42408 running->sequence()->OnThreadedAnimationStarted(monotonic_time,
409 target_property, group_id);
[email protected]bf912272013-02-23 01:54:16410 if (!running->sequence()->waiting_for_group_start())
411 return;
412
loyso79c0bfc2016-04-18 23:46:42413 base::TimeTicks start_time = monotonic_time;
[email protected]bf912272013-02-23 01:54:16414
415 running->sequence()->set_waiting_for_group_start(false);
416
417 // The call to GetRunningAnimation made above already purged deleted
418 // animations, so we are guaranteed that all the animations we iterate
419 // over now are alive.
420 for (RunningAnimations::iterator iter = running_animations_.begin();
421 iter != running_animations_.end(); ++iter) {
422 // Ensure that each sequence is only Started once, regardless of the
423 // number of sequences in the group that have threaded first elements.
loyso79c0bfc2016-04-18 23:46:42424 if (((*iter).sequence()->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15425 !(*iter).sequence()->IsFirstElementThreaded(delegate_) &&
[email protected]bf912272013-02-23 01:54:16426 (*iter).sequence()->waiting_for_group_start()) {
427 (*iter).sequence()->set_start_time(start_time);
428 (*iter).sequence()->set_waiting_for_group_start(false);
429 (*iter).sequence()->Start(delegate());
430 }
431 }
432}
433
[email protected]9034a282014-06-05 03:11:47434void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
435 if (is_animating() && !is_started_) {
436 collection->StartAnimator(this);
437 is_started_ = true;
438 }
439}
440
441void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
bruthig33b1edab2016-03-02 02:22:35442 if (is_started_) {
[email protected]9034a282014-06-05 03:11:47443 collection->StopAnimator(this);
444 is_started_ = false;
445 }
446}
447
[email protected]d59a3692012-04-10 20:27:31448// LayerAnimator protected -----------------------------------------------------
449
[email protected]5d86a112012-09-23 00:21:58450void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38451 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16452 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58453 return;
454
[email protected]3d75fed2012-12-15 18:47:38455 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31456}
457
[email protected]a48f30d2012-10-30 00:35:41458void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30459 if (!delegate())
460 return;
461
462 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41463}
464
[email protected]d59a3692012-04-10 20:27:31465bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
466 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
467 queue_iter != animation_queue_.end(); ++queue_iter) {
468 if ((*queue_iter).get() == sequence)
469 return true;
470 }
471 return false;
472}
473
[email protected]b4db9372011-10-24 14:44:19474// LayerAnimator private -------------------------------------------------------
475
476void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31477 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58478 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31479
[email protected]b4db9372011-10-24 14:44:19480 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19481
[email protected]a48f30d2012-10-30 00:35:41482 PurgeDeletedAnimations();
483
[email protected]f5cd9e52011-11-03 21:38:08484 // We need to make a copy of the running animations because progressing them
485 // and finishing them may indirectly affect the collection of running
486 // animations.
487 RunningAnimations running_animations_copy = running_animations_;
488 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41489 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31490 continue;
491
[email protected]3d75fed2012-12-15 18:47:38492 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14493 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
494 } else {
[email protected]3d75fed2012-12-15 18:47:38495 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14496 }
[email protected]b4db9372011-10-24 14:44:19497 }
[email protected]b4db9372011-10-24 14:44:19498}
499
[email protected]6f110e42012-12-18 00:21:14500void LayerAnimator::StopAnimatingInternal(bool abort) {
501 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55502 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14503 // We're going to attempt to finish the first running animation. Let's
504 // ensure that it's valid.
505 PurgeDeletedAnimations();
506
507 // If we've purged all running animations, attempt to start one up.
508 if (running_animations_.empty())
509 ProcessQueue();
510
511 DCHECK(!running_animations_.empty());
512
513 // Still no luck, let's just bail and clear all animations.
514 if (running_animations_.empty()) {
515 ClearAnimationsInternal();
516 break;
517 }
518
519 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
520 }
521}
522
[email protected]b4db9372011-10-24 14:44:19523void LayerAnimator::UpdateAnimationState() {
524 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12525 return;
526
[email protected]b4db9372011-10-24 14:44:19527 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47528 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
529 if (collection) {
530 if (should_start && !is_started_)
531 collection->StartAnimator(this);
532 else if (!should_start && is_started_)
533 collection->StopAnimator(this);
534 is_started_ = should_start;
535 } else {
536 is_started_ = false;
537 }
[email protected]710a98d2011-06-23 20:13:29538}
539
[email protected]f5cd9e52011-11-03 21:38:08540LayerAnimationSequence* LayerAnimator::RemoveAnimation(
541 LayerAnimationSequence* sequence) {
542 linked_ptr<LayerAnimationSequence> to_return;
543
[email protected]bf912272013-02-23 01:54:16544 bool is_running = false;
545
[email protected]f5cd9e52011-11-03 21:38:08546 // First remove from running animations
[email protected]b4db9372011-10-24 14:44:19547 for (RunningAnimations::iterator iter = running_animations_.begin();
548 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41549 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19550 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16551 is_running = true;
[email protected]b4db9372011-10-24 14:44:19552 break;
[email protected]21445e472011-10-21 20:36:32553 }
554 }
[email protected]b4db9372011-10-24 14:44:19555
556 // Then remove from the queue
557 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
558 queue_iter != animation_queue_.end(); ++queue_iter) {
559 if ((*queue_iter) == sequence) {
[email protected]f5cd9e52011-11-03 21:38:08560 to_return = *queue_iter;
[email protected]b4db9372011-10-24 14:44:19561 animation_queue_.erase(queue_iter);
562 break;
563 }
564 }
[email protected]f5cd9e52011-11-03 21:38:08565
wutao914b06e62017-09-28 17:41:15566 if (!to_return.get() || !to_return->waiting_for_group_start() ||
567 !to_return->IsFirstElementThreaded(delegate_))
[email protected]bf912272013-02-23 01:54:16568 return to_return.release();
569
570 // The removed sequence may have been responsible for making other sequences
571 // wait for a group start. If no other sequences in the group have a
572 // threaded first element, the group no longer needs the additional wait.
573 bool is_wait_still_needed = false;
574 int group_id = to_return->animation_group_id();
575 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
576 queue_iter != animation_queue_.end(); ++queue_iter) {
577 if (((*queue_iter)->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15578 (*queue_iter)->IsFirstElementThreaded(delegate_)) {
[email protected]bf912272013-02-23 01:54:16579 is_wait_still_needed = true;
580 break;
581 }
582 }
583
584 if (is_wait_still_needed)
585 return to_return.release();
586
587 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
588 queue_iter != animation_queue_.end(); ++queue_iter) {
589 if ((*queue_iter)->animation_group_id() == group_id &&
590 (*queue_iter)->waiting_for_group_start()) {
591 (*queue_iter)->set_waiting_for_group_start(false);
592 if (is_running) {
593 (*queue_iter)->set_start_time(last_step_time_);
594 (*queue_iter)->Start(delegate());
595 }
596 }
597 }
[email protected]f5cd9e52011-11-03 21:38:08598 return to_return.release();
[email protected]0ed187e2011-10-21 20:07:42599}
600
[email protected]6f110e42012-12-18 00:21:14601void LayerAnimator::FinishAnimation(
602 LayerAnimationSequence* sequence, bool abort) {
[email protected]5d86a112012-09-23 00:21:58603 scoped_refptr<LayerAnimator> retain(this);
danakj25c52c32016-04-12 21:51:08604 std::unique_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
[email protected]6f110e42012-12-18 00:21:14605 if (abort)
[email protected]bf912272013-02-23 01:54:16606 sequence->Abort(delegate());
[email protected]6f110e42012-12-18 00:21:14607 else
608 ProgressAnimationToEnd(sequence);
ljagielski20570982015-01-07 20:32:55609 if (!delegate())
610 return;
[email protected]b4db9372011-10-24 14:44:19611 ProcessQueue();
612 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32613}
[email protected]0ed187e2011-10-21 20:07:42614
[email protected]b4db9372011-10-24 14:44:19615void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
[email protected]5d86a112012-09-23 00:21:58616 scoped_refptr<LayerAnimator> retain(this);
[email protected]2ddfe432011-11-07 19:26:30617 // Special case: if we've started a 0 duration animation, just finish it now
618 // and get rid of it. We need to make a copy because Progress may indirectly
619 // cause new animations to start running.
[email protected]f5cd9e52011-11-03 21:38:08620 RunningAnimations running_animations_copy = running_animations_;
621 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41622 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31623 continue;
624
[email protected]3d75fed2012-12-15 18:47:38625 if (running_animations_copy[i].sequence()->IsFinished(
626 running_animations_copy[i].sequence()->start_time())) {
[email protected]a48f30d2012-10-30 00:35:41627 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
danakj25c52c32016-04-12 21:51:08628 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41629 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]b4db9372011-10-24 14:44:19630 }
631 }
632 ProcessQueue();
633 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32634}
[email protected]0ed187e2011-10-21 20:07:42635
[email protected]b4db9372011-10-24 14:44:19636void LayerAnimator::ClearAnimations() {
[email protected]5d86a112012-09-23 00:21:58637 scoped_refptr<LayerAnimator> retain(this);
638 ClearAnimationsInternal();
[email protected]b4db9372011-10-24 14:44:19639}
640
641LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
642 LayerAnimationElement::AnimatableProperty property) {
[email protected]a48f30d2012-10-30 00:35:41643 PurgeDeletedAnimations();
[email protected]b4db9372011-10-24 14:44:19644 for (RunningAnimations::iterator iter = running_animations_.begin();
645 iter != running_animations_.end(); ++iter) {
[email protected]e03193d2014-01-14 03:10:24646 if ((*iter).sequence()->properties() & property)
[email protected]b4db9372011-10-24 14:44:19647 return &(*iter);
648 }
649 return NULL;
650}
651
652void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
653 // If we don't have the animation in the queue yet, add it.
654 bool found_sequence = false;
655 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
656 queue_iter != animation_queue_.end(); ++queue_iter) {
657 if ((*queue_iter) == animation) {
658 found_sequence = true;
659 break;
660 }
661 }
662
663 if (!found_sequence)
664 animation_queue_.push_front(make_linked_ptr(animation));
665}
666
667void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08668 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19669 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08670 // progress them to the end and remove them. Note, Aborting or Progressing
671 // animations may affect the collection of running animations, so we need to
672 // operate on a copy.
673 RunningAnimations running_animations_copy = running_animations_;
674 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41675 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31676 continue;
677
[email protected]712f4b642013-03-14 07:09:15678 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19679 sequence->properties())) {
danakj25c52c32016-04-12 21:51:08680 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41681 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08682 if (abort)
[email protected]bf912272013-02-23 01:54:16683 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08684 else
[email protected]a48f30d2012-10-30 00:35:41685 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19686 }
687 }
688
[email protected]f5cd9e52011-11-03 21:38:08689 // Same for the queued animations that haven't been started. Again, we'll
690 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41691 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08692 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
693 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41694 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08695
696 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19697 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31698 continue;
699
[email protected]712f4b642013-03-14 07:09:15700 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
danakj25c52c32016-04-12 21:51:08701 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]7ffde472013-06-04 06:42:19702 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19703 if (abort)
[email protected]bf912272013-02-23 01:54:16704 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19705 else
[email protected]7ffde472013-06-04 06:42:19706 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19707 }
708 }
709}
710
711void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41712 // Need to detect if our sequence gets destroyed.
713 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
714 sequence->AsWeakPtr();
715
[email protected]b4db9372011-10-24 14:44:19716 const bool abort = false;
717 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19718 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41719 return;
720
[email protected]d3ba37ab2012-02-09 19:53:13721 LayerAnimationSequence* removed = RemoveAnimation(sequence);
722 DCHECK(removed == NULL || removed == sequence);
[email protected]7ffde472013-06-04 06:42:19723 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41724 return;
725
[email protected]4a386e42012-12-05 01:19:30726 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19727 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41728 return;
729
730 delete sequence;
[email protected]b4db9372011-10-24 14:44:19731}
732
733void LayerAnimator::ImmediatelyAnimateToNewTarget(
734 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41735 // Need to detect if our sequence gets destroyed.
736 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
737 sequence->AsWeakPtr();
738
[email protected]b4db9372011-10-24 14:44:19739 const bool abort = true;
740 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19741 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41742 return;
743
[email protected]b4db9372011-10-24 14:44:19744 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19745 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41746 return;
747
[email protected]b4db9372011-10-24 14:44:19748 StartSequenceImmediately(sequence);
749}
750
751void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
752 // It is assumed that if there was no conflicting animation, we would
753 // not have been called. No need to check for a collision; just
754 // add to the queue.
755 animation_queue_.push_back(make_linked_ptr(sequence));
756 ProcessQueue();
757}
758
759void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41760 // Need to detect if our sequence gets destroyed.
761 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
762 sequence->AsWeakPtr();
763
[email protected]b4db9372011-10-24 14:44:19764 // Remove all animations that aren't running. Note: at each iteration i is
765 // incremented or an element is removed from the queue, so
766 // animation_queue_.size() - i is always decreasing and we are always making
767 // progress towards the loop terminating.
768 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19769 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41770 break;
771
772 PurgeDeletedAnimations();
773
[email protected]b4db9372011-10-24 14:44:19774 bool is_running = false;
775 for (RunningAnimations::const_iterator iter = running_animations_.begin();
776 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41777 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19778 is_running = true;
779 break;
780 }
781 }
[email protected]a48f30d2012-10-30 00:35:41782
[email protected]b4db9372011-10-24 14:44:19783 if (!is_running)
[email protected]300548c2012-06-17 08:54:55784 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19785 else
786 ++i;
787 }
788 animation_queue_.push_back(make_linked_ptr(sequence));
789 ProcessQueue();
790}
791
792void LayerAnimator::ProcessQueue() {
793 bool started_sequence = false;
794 do {
795 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19796 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24797 LayerAnimationElement::AnimatableProperties animated =
798 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19799 for (RunningAnimations::const_iterator iter = running_animations_.begin();
800 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41801 if (!(*iter).is_sequence_alive())
802 continue;
[email protected]e03193d2014-01-14 03:10:24803
804 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19805 }
806
807 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08808 // property or a property that will be animated before it. Note: starting
809 // the animation may indirectly cause more animations to be started, so we
810 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41811 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19812 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08813 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41814 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08815
816 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19817 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41818 continue;
819
[email protected]712f4b642013-03-14 07:09:15820 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41821 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19822 started_sequence = true;
823 break;
824 }
825
826 // Animation couldn't be started. Add its properties to the collection so
827 // that we don't start a conflicting animation. For example, if our queue
828 // has the elements { {T,B}, {B} } (that is, an element that animates both
829 // the transform and the bounds followed by an element that animates the
830 // bounds), and we're currently animating the transform, we can't start
831 // the first element because it animates the transform, too. We cannot
832 // start the second element, either, because the first element animates
833 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24834 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19835 }
836
837 // If we started a sequence, try again. We may be able to start several.
838 } while (started_sequence);
839}
840
841bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41842 PurgeDeletedAnimations();
843
[email protected]b4db9372011-10-24 14:44:19844 // Ensure that no one is animating one of the sequence's properties already.
845 for (RunningAnimations::const_iterator iter = running_animations_.begin();
846 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15847 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19848 return false;
849 }
850
charliea3be839702015-01-26 17:35:41851 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47852 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19853 // last_tick_time() from there to ensure animations started during the same
854 // event complete at the same time.
855 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47856 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59857 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19858 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47859 else if (collection && collection->HasActiveAnimators())
860 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19861 else
abhishek.ka7215854d2015-05-26 06:13:17862 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19863
[email protected]bf912272013-02-23 01:54:16864 if (!sequence->animation_group_id())
865 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
bruthig4a12c2b2016-11-05 00:19:18866
[email protected]a48f30d2012-10-30 00:35:41867 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38868 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19869
870 // Need to keep a reference to the animation.
871 AddToQueueIfNotPresent(sequence);
872
bruthig4a12c2b2016-11-05 00:19:18873 if (!sequence->waiting_for_group_start() ||
wutao914b06e62017-09-28 17:41:15874 sequence->IsFirstElementThreaded(delegate_)) {
bruthig4a12c2b2016-11-05 00:19:18875 sequence->set_start_time(start_time);
876 sequence->Start(delegate());
877 }
878
[email protected]b4db9372011-10-24 14:44:19879 // Ensure that animations get stepped at their start time.
880 Step(start_time);
881
882 return true;
[email protected]710a98d2011-06-23 20:13:29883}
884
[email protected]fe7074c62011-10-28 15:22:54885void LayerAnimator::GetTargetValue(
886 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13887 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
888 iter != animation_queue_.end(); ++iter) {
889 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54890 }
891}
892
[email protected]e876c272011-11-02 16:42:45893void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
dchengd38152e2016-10-13 18:21:37894 for (LayerAnimationObserver& observer : observers_)
895 sequence->AddObserver(&observer);
[email protected]e876c272011-11-02 16:42:45896 sequence->OnScheduled();
897}
898
[email protected]0d316252014-01-20 15:31:19899void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
900 if (is_transition_duration_locked_)
901 return;
902 transition_duration_ = duration;
[email protected]9861f1752012-06-01 07:16:14903}
904
[email protected]5d86a112012-09-23 00:21:58905void LayerAnimator::ClearAnimationsInternal() {
[email protected]a48f30d2012-10-30 00:35:41906 PurgeDeletedAnimations();
907
[email protected]5d86a112012-09-23 00:21:58908 // Abort should never affect the set of running animations, but just in case
909 // clients are badly behaved, we will use a copy of the running animations.
910 RunningAnimations running_animations_copy = running_animations_;
911 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41912 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]5d86a112012-09-23 00:21:58913 continue;
914
danakj25c52c32016-04-12 21:51:08915 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41916 RemoveAnimation(running_animations_copy[i].sequence()));
[email protected]5d86a112012-09-23 00:21:58917 if (removed.get())
[email protected]bf912272013-02-23 01:54:16918 removed->Abort(delegate());
[email protected]5d86a112012-09-23 00:21:58919 }
920 // This *should* have cleared the list of running animations.
921 DCHECK(running_animations_.empty());
922 running_animations_.clear();
923 animation_queue_.clear();
924 UpdateAnimationState();
925}
926
[email protected]a48f30d2012-10-30 00:35:41927void LayerAnimator::PurgeDeletedAnimations() {
928 for (size_t i = 0; i < running_animations_.size();) {
929 if (!running_animations_[i].is_sequence_alive())
930 running_animations_.erase(running_animations_.begin() + i);
931 else
932 i++;
933 }
934}
935
[email protected]9034a282014-06-05 03:11:47936LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
937 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
938}
939
Ian Vollickba1f85922017-07-21 18:10:03940void LayerAnimator::NotifyAnimationStarted(base::TimeTicks monotonic_time,
941 int target_property,
942 int group) {
943 OnThreadedAnimationStarted(
944 monotonic_time, static_cast<cc::TargetProperty::Type>(target_property),
945 group);
loyso1fbd9f92015-12-17 07:43:13946}
947
[email protected]a48f30d2012-10-30 00:35:41948LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38949 const base::WeakPtr<LayerAnimationSequence>& sequence)
950 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41951}
952
vmpstr0ae825e72016-02-25 20:31:31953LayerAnimator::RunningAnimation::RunningAnimation(
954 const RunningAnimation& other) = default;
955
[email protected]a48f30d2012-10-30 00:35:41956LayerAnimator::RunningAnimation::~RunningAnimation() { }
957
[email protected]710a98d2011-06-23 20:13:29958} // namespace ui