blob: 9f2eb41d9d47bc4f6ed0a37e77abbbae18b31451 [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"
JungHoon Lee897c21ef2018-08-27 20:18:1712#include "base/stl_util.h"
ssid334fb87a2015-01-27 20:12:0713#include "base/trace_event/trace_event.h"
Yi Gub0422c42020-01-13 17:00:3614#include "cc/animation/animation.h"
loyso3338dfb2016-03-09 03:07:3215#include "cc/animation/animation_host.h"
[email protected]95e4e1a02013-03-18 07:09:0916#include "cc/animation/animation_id_provider.h"
loyso841229002015-12-21 10:03:2417#include "cc/animation/animation_timeline.h"
18#include "cc/animation/element_animations.h"
Fady Samuelc296f5fb2017-07-21 04:02:1919#include "components/viz/common/frame_sinks/begin_frame_args.h"
[email protected]116302fc2012-05-05 21:45:4120#include "ui/compositor/compositor.h"
21#include "ui/compositor/layer.h"
22#include "ui/compositor/layer_animation_delegate.h"
23#include "ui/compositor/layer_animation_observer.h"
24#include "ui/compositor/layer_animation_sequence.h"
[email protected]9034a282014-06-05 03:11:4725#include "ui/compositor/layer_animator_collection.h"
[email protected]0ed187e2011-10-21 20:07:4226
[email protected]a48f30d2012-10-30 00:35:4127#define SAFE_INVOKE_VOID(function, running_anim, ...) \
28 if (running_anim.is_sequence_alive()) \
29 function(running_anim.sequence(), ##__VA_ARGS__)
30#define SAFE_INVOKE_BOOL(function, running_anim) \
31 ((running_anim.is_sequence_alive()) \
32 ? function(running_anim.sequence()) \
33 : false)
34#define SAFE_INVOKE_PTR(function, running_anim) \
35 ((running_anim.is_sequence_alive()) \
36 ? function(running_anim.sequence()) \
37 : NULL)
38
[email protected]21445e472011-10-21 20:36:3239namespace ui {
[email protected]0ed187e2011-10-21 20:07:4240
[email protected]b4db9372011-10-24 14:44:1941namespace {
42
Daniel Bratellc2fecad52017-12-21 22:36:2243const int kLayerAnimatorDefaultTransitionDurationMs = 120;
[email protected]1778cbc2012-09-06 04:31:1944
[email protected]9861f1752012-06-01 07:16:1445} // namespace
46
[email protected]b4db9372011-10-24 14:44:1947// LayerAnimator public --------------------------------------------------------
48
49LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
50 : delegate_(NULL),
51 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
[email protected]0d316252014-01-20 15:31:1952 is_transition_duration_locked_(false),
[email protected]b4db9372011-10-24 14:44:1953 transition_duration_(transition_duration),
[email protected]ffb15d12013-09-15 17:29:3054 tween_type_(gfx::Tween::LINEAR),
[email protected]b4db9372011-10-24 14:44:1955 is_started_(false),
[email protected]d064ef82012-11-13 10:26:5956 disable_timer_for_test_(false),
varkha62ba671d2017-01-25 19:09:4657 adding_animations_(false),
58 animation_metrics_reporter_(nullptr) {
Yi Gub0422c42020-01-13 17:00:3659 animation_ =
60 cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId());
[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;
Yi Guaa830ff2018-02-22 03:09:1170 DCHECK(!animation_->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() {
Daniel Bratellc2fecad52017-12-21 22:36:2280 return new LayerAnimator(base::TimeDelta::FromMilliseconds(
81 kLayerAnimatorDefaultTransitionDurationMs));
[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.
Francois Doray91e63fb72017-11-08 14:21:5290#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
91 void LayerAnimator::Set##name(type value) { \
92 base::TimeDelta duration = GetTransitionDuration(); \
93 if (duration.is_zero() && delegate() && \
94 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
95 StopAnimatingProperty(LayerAnimationElement::property); \
96 delegate()->Set##name##FromAnimation( \
97 value, PropertyChangeReason::NOT_FROM_ANIMATION); \
98 return; \
99 } \
100 std::unique_ptr<LayerAnimationElement> element = \
101 LayerAnimationElement::Create##name##Element(value, duration); \
102 element->set_tween_type(tween_type_); \
103 StartAnimation(new LayerAnimationSequence(std::move(element))); \
104 } \
105 \
106 member_type LayerAnimator::GetTarget##name() const { \
107 LayerAnimationElement::TargetValue target(delegate()); \
108 GetTargetValue(&target); \
109 return target.member; \
danakj25c52c32016-04-12 21:51:08110 }
[email protected]fe7074c62011-10-28 15:22:54111
Nico Weber3a6c6372019-02-21 14:26:18112ANIMATED_PROPERTY(const gfx::Transform&,
113 TRANSFORM,
114 Transform,
115 gfx::Transform,
116 transform)
117ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds)
118ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity)
119ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility)
120ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness)
121ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale)
122ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color)
Malay Keshavb8ac9e572019-07-03 00:26:55123ANIMATED_PROPERTY(const gfx::Rect&, CLIP, ClipRect, gfx::Rect, clip_rect)
Jun Mukaia343db33b2019-07-17 23:25:50124ANIMATED_PROPERTY(const gfx::RoundedCornersF&,
125 ROUNDED_CORNERS,
126 RoundedCorners,
127 gfx::RoundedCornersF,
128 rounded_corners)
Nico Weber3a6c6372019-02-21 14:26:18129
130#undef ANIMATED_PROPERTY
[email protected]e81480f1f2012-10-11 23:06:45131
[email protected]0d316252014-01-20 15:31:19132base::TimeDelta LayerAnimator::GetTransitionDuration() const {
133 return transition_duration_;
134}
135
[email protected]e876c272011-11-02 16:42:45136void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
[email protected]9034a282014-06-05 03:11:47137 if (delegate_ && is_started_) {
138 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
139 if (collection)
140 collection->StopAnimator(this);
141 }
loyso1fbd9f92015-12-17 07:43:13142 SwitchToLayer(delegate ? delegate->GetCcLayer() : nullptr);
[email protected]b4db9372011-10-24 14:44:19143 delegate_ = delegate;
[email protected]9034a282014-06-05 03:11:47144 if (delegate_ && is_started_) {
145 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
146 if (collection)
147 collection->StartAnimator(this);
148 }
[email protected]b4db9372011-10-24 14:44:19149}
150
loyso1fbd9f92015-12-17 07:43:13151void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
loysoe2fed922016-03-09 04:41:55152 if (delegate_)
Yi Guaa830ff2018-02-22 03:09:11153 DetachLayerFromAnimation();
loysoe2fed922016-03-09 04:41:55154 if (new_layer)
Yi Guaa830ff2018-02-22 03:09:11155 AttachLayerToAnimation(new_layer->id());
loyso841229002015-12-21 10:03:24156}
157
loysocc8e3db2016-10-04 05:22:03158void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24159 DCHECK(compositor);
loyso841229002015-12-21 10:03:24160
loysoe2fed922016-03-09 04:41:55161 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
162 DCHECK(timeline);
Yi Guaa830ff2018-02-22 03:09:11163 timeline->AttachAnimation(animation_);
loysoe2fed922016-03-09 04:41:55164
loysocc8e3db2016-10-04 05:22:03165 DCHECK(delegate_->GetCcLayer());
Yi Guaa830ff2018-02-22 03:09:11166 AttachLayerToAnimation(delegate_->GetCcLayer()->id());
loyso841229002015-12-21 10:03:24167}
168
loysocc8e3db2016-10-04 05:22:03169void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24170 DCHECK(compositor);
loyso3338dfb2016-03-09 03:07:32171
loysode0a0022016-04-15 02:28:38172 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
173 DCHECK(timeline);
174
Yi Guaa830ff2018-02-22 03:09:11175 DetachLayerFromAnimation();
176 timeline->DetachAnimation(animation_);
loyso841229002015-12-21 10:03:24177}
178
Yi Guaa830ff2018-02-22 03:09:11179void LayerAnimator::AttachLayerToAnimation(int layer_id) {
vollickef2ae922016-06-29 17:54:27180 // For ui, layer and element ids are equivalent.
chrishtrc3daf272017-05-11 11:08:02181 cc::ElementId element_id(layer_id);
Yi Guaa830ff2018-02-22 03:09:11182 if (!animation_->element_id())
183 animation_->AttachElement(element_id);
loyso841229002015-12-21 10:03:24184 else
Yi Guaa830ff2018-02-22 03:09:11185 DCHECK_EQ(animation_->element_id(), element_id);
loyso841229002015-12-21 10:03:24186
Yi Guaa830ff2018-02-22 03:09:11187 animation_->set_animation_delegate(this);
loyso841229002015-12-21 10:03:24188}
189
Yi Guaa830ff2018-02-22 03:09:11190void LayerAnimator::DetachLayerFromAnimation() {
191 animation_->set_animation_delegate(nullptr);
loyso841229002015-12-21 10:03:24192
Yi Guaa830ff2018-02-22 03:09:11193 if (animation_->element_id())
194 animation_->DetachElement();
loyso841229002015-12-21 10:03:24195}
196
Yi Gu4e1dce32018-07-04 20:52:15197void LayerAnimator::AddThreadedAnimation(
198 std::unique_ptr<cc::KeyframeModel> animation) {
199 animation_->AddKeyframeModel(std::move(animation));
loyso841229002015-12-21 10:03:24200}
201
Yi Gu4e1dce32018-07-04 20:52:15202void LayerAnimator::RemoveThreadedAnimation(int keyframe_model_id) {
203 animation_->RemoveKeyframeModel(keyframe_model_id);
loyso1fbd9f92015-12-17 07:43:13204}
205
Yi Gub0422c42020-01-13 17:00:36206cc::Animation* LayerAnimator::GetAnimationForTesting() const {
Yi Guaa830ff2018-02-22 03:09:11207 return animation_.get();
loysod4127442016-02-03 02:29:40208}
209
[email protected]b4db9372011-10-24 14:44:19210void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58211 scoped_refptr<LayerAnimator> retain(this);
varkha62ba671d2017-01-25 19:09:46212 if (animation_metrics_reporter_)
213 animation->SetAnimationMetricsReporter(animation_metrics_reporter_);
[email protected]e876c272011-11-02 16:42:45214 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19215 if (!StartSequenceImmediately(animation)) {
216 // Attempt to preempt a running animation.
217 switch (preemption_strategy_) {
218 case IMMEDIATELY_SET_NEW_TARGET:
219 ImmediatelySetNewTarget(animation);
220 break;
221 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
222 ImmediatelyAnimateToNewTarget(animation);
223 break;
224 case ENQUEUE_NEW_ANIMATION:
225 EnqueueNewAnimation(animation);
226 break;
227 case REPLACE_QUEUED_ANIMATIONS:
228 ReplaceQueuedAnimations(animation);
229 break;
[email protected]7fca53d42011-09-29 15:38:12230 }
[email protected]b4db9372011-10-24 14:44:19231 }
232 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54233 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19234}
235
236void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58237 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45238 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19239 if (is_animating()) {
Ian Vollick37e51bd12018-12-18 14:32:09240 animation_queue_.push_back(
241 std::unique_ptr<LayerAnimationSequence>(animation));
[email protected]b4db9372011-10-24 14:44:19242 ProcessQueue();
243 } else {
244 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12245 }
[email protected]fe7074c62011-10-28 15:22:54246 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29247}
248
[email protected]d064ef82012-11-13 10:26:59249void LayerAnimator::StartTogether(
250 const std::vector<LayerAnimationSequence*>& animations) {
251 scoped_refptr<LayerAnimator> retain(this);
252 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
253 std::vector<LayerAnimationSequence*>::const_iterator iter;
254 for (iter = animations.begin(); iter != animations.end(); ++iter) {
255 StartAnimation(*iter);
256 }
257 return;
258 }
[email protected]d764fd3d2012-11-15 20:07:51259
[email protected]d064ef82012-11-13 10:26:59260 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51261 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47262 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
263 if (collection && collection->HasActiveAnimators())
264 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51265 else
abhishek.ka7215854d2015-05-26 06:13:17266 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51267 }
[email protected]d064ef82012-11-13 10:26:59268
269 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24270 LayerAnimationElement::AnimatableProperties animated_properties =
271 LayerAnimationElement::UNKNOWN;
272
[email protected]d064ef82012-11-13 10:26:59273 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24274 for (iter = animations.begin(); iter != animations.end(); ++iter)
275 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59276
277 // Starting a zero duration pause that affects all the animated properties
278 // will prevent any of the sequences from animating until there are no
279 // running animations that affect any of these properties, as well as
280 // handle preemption strategy.
281 StartAnimation(new LayerAnimationSequence(
282 LayerAnimationElement::CreatePauseElement(animated_properties,
283 base::TimeDelta())));
284
[email protected]bf912272013-02-23 01:54:16285 bool wait_for_group_start = false;
286 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15287 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16288 int group_id = cc::AnimationIdProvider::NextGroupId();
289
[email protected]d064ef82012-11-13 10:26:59290 // These animations (provided they don't animate any common properties) will
291 // now animate together if trivially scheduled.
292 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16293 (*iter)->set_animation_group_id(group_id);
294 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59295 ScheduleAnimation(*iter);
296 }
297
298 adding_animations_ = false;
299 UpdateAnimationState();
300}
301
302
[email protected]b4db9372011-10-24 14:44:19303void LayerAnimator::ScheduleTogether(
304 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58305 scoped_refptr<LayerAnimator> retain(this);
306
[email protected]b4db9372011-10-24 14:44:19307 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24308 LayerAnimationElement::AnimatableProperties animated_properties =
309 LayerAnimationElement::UNKNOWN;
310
[email protected]b4db9372011-10-24 14:44:19311 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24312 for (iter = animations.begin(); iter != animations.end(); ++iter)
313 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29314
[email protected]b4db9372011-10-24 14:44:19315 // Scheduling a zero duration pause that affects all the animated properties
316 // will prevent any of the sequences from animating until there are no
317 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31318 ScheduleAnimation(new LayerAnimationSequence(
319 LayerAnimationElement::CreatePauseElement(animated_properties,
320 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29321
[email protected]bf912272013-02-23 01:54:16322 bool wait_for_group_start = false;
323 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15324 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16325
326 int group_id = cc::AnimationIdProvider::NextGroupId();
327
[email protected]b4db9372011-10-24 14:44:19328 // These animations (provided they don't animate any common properties) will
329 // now animate together if trivially scheduled.
330 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16331 (*iter)->set_animation_group_id(group_id);
332 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19333 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29334 }
[email protected]fe7074c62011-10-28 15:22:54335
336 UpdateAnimationState();
337}
338
[email protected]2a88c702012-09-04 23:15:02339void LayerAnimator::SchedulePauseForProperties(
340 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24341 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02342 ScheduleAnimation(new ui::LayerAnimationSequence(
343 ui::LayerAnimationElement::CreatePauseElement(
344 properties_to_pause, duration)));
345}
346
Francois Dorayeef012b62017-10-26 20:02:59347bool LayerAnimator::IsAnimatingOnePropertyOf(
348 LayerAnimationElement::AnimatableProperties properties) const {
349 for (auto& layer_animation_sequence : animation_queue_) {
350 if (layer_animation_sequence->properties() & properties)
[email protected]e876c272011-11-02 16:42:45351 return true;
[email protected]e876c272011-11-02 16:42:45352 }
353 return false;
[email protected]7fca53d42011-09-29 15:38:12354}
355
[email protected]b4db9372011-10-24 14:44:19356void LayerAnimator::StopAnimatingProperty(
357 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58358 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19359 while (true) {
[email protected]a48f30d2012-10-30 00:35:41360 // GetRunningAnimation purges deleted animations before searching, so we are
361 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19362 RunningAnimation* running = GetRunningAnimation(property);
363 if (!running)
364 break;
[email protected]a48f30d2012-10-30 00:35:41365 // As was mentioned above, this sequence must be alive.
366 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14367 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41368 }
[email protected]b4db9372011-10-24 14:44:19369}
370
[email protected]e876c272011-11-02 16:42:45371void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
Francois Doray29ecd3aa2017-11-07 15:40:18372 if (!observers_.HasObserver(observer)) {
[email protected]e876c272011-11-02 16:42:45373 observers_.AddObserver(observer);
Francois Doray29ecd3aa2017-11-07 15:40:18374 for (auto& layer_animation_sequence : animation_queue_)
375 layer_animation_sequence->AddObserver(observer);
376 }
[email protected]e876c272011-11-02 16:42:45377}
378
379void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
380 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54381 // Remove the observer from all sequences as well.
382 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
383 queue_iter != animation_queue_.end(); ++queue_iter) {
384 (*queue_iter)->RemoveObserver(observer);
385 }
[email protected]e876c272011-11-02 16:42:45386}
387
wutao4f1c0d5d2017-10-05 01:02:43388void LayerAnimator::AddOwnedObserver(
389 std::unique_ptr<ImplicitAnimationObserver> animation_observer) {
390 owned_observer_list_.push_back(std::move(animation_observer));
391}
392
393void LayerAnimator::RemoveAndDestroyOwnedObserver(
394 ImplicitAnimationObserver* animation_observer) {
JungHoon Lee897c21ef2018-08-27 20:18:17395 base::EraseIf(owned_observer_list_,[animation_observer](
396 const std::unique_ptr<ImplicitAnimationObserver>& other) {
397 return other.get() == animation_observer;
398 });
wutao4f1c0d5d2017-10-05 01:02:43399}
400
[email protected]bf912272013-02-23 01:54:16401void LayerAnimator::OnThreadedAnimationStarted(
loyso79c0bfc2016-04-18 23:46:42402 base::TimeTicks monotonic_time,
403 cc::TargetProperty::Type target_property,
404 int group_id) {
[email protected]bf912272013-02-23 01:54:16405 LayerAnimationElement::AnimatableProperty property =
loyso79c0bfc2016-04-18 23:46:42406 LayerAnimationElement::ToAnimatableProperty(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
loyso79c0bfc2016-04-18 23:46:42413 if (running->sequence()->animation_group_id() != group_id)
[email protected]bf912272013-02-23 01:54:16414 return;
415
loyso79c0bfc2016-04-18 23:46:42416 running->sequence()->OnThreadedAnimationStarted(monotonic_time,
417 target_property, group_id);
[email protected]bf912272013-02-23 01:54:16418 if (!running->sequence()->waiting_for_group_start())
419 return;
420
loyso79c0bfc2016-04-18 23:46:42421 base::TimeTicks start_time = monotonic_time;
[email protected]bf912272013-02-23 01:54:16422
423 running->sequence()->set_waiting_for_group_start(false);
424
425 // The call to GetRunningAnimation made above already purged deleted
426 // animations, so we are guaranteed that all the animations we iterate
427 // over now are alive.
jdoerriedcef4b12018-10-10 12:04:32428 for (auto iter = running_animations_.begin();
[email protected]bf912272013-02-23 01:54:16429 iter != running_animations_.end(); ++iter) {
430 // Ensure that each sequence is only Started once, regardless of the
431 // number of sequences in the group that have threaded first elements.
loyso79c0bfc2016-04-18 23:46:42432 if (((*iter).sequence()->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15433 !(*iter).sequence()->IsFirstElementThreaded(delegate_) &&
[email protected]bf912272013-02-23 01:54:16434 (*iter).sequence()->waiting_for_group_start()) {
435 (*iter).sequence()->set_start_time(start_time);
436 (*iter).sequence()->set_waiting_for_group_start(false);
437 (*iter).sequence()->Start(delegate());
438 }
439 }
440}
441
[email protected]9034a282014-06-05 03:11:47442void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
443 if (is_animating() && !is_started_) {
444 collection->StartAnimator(this);
445 is_started_ = true;
446 }
447}
448
449void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
bruthig33b1edab2016-03-02 02:22:35450 if (is_started_) {
[email protected]9034a282014-06-05 03:11:47451 collection->StopAnimator(this);
452 is_started_ = false;
453 }
454}
455
[email protected]d59a3692012-04-10 20:27:31456// LayerAnimator protected -----------------------------------------------------
457
[email protected]5d86a112012-09-23 00:21:58458void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38459 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16460 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58461 return;
462
[email protected]3d75fed2012-12-15 18:47:38463 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31464}
465
[email protected]a48f30d2012-10-30 00:35:41466void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30467 if (!delegate())
468 return;
469
470 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41471}
472
[email protected]d59a3692012-04-10 20:27:31473bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
474 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
475 queue_iter != animation_queue_.end(); ++queue_iter) {
476 if ((*queue_iter).get() == sequence)
477 return true;
478 }
479 return false;
480}
481
[email protected]b4db9372011-10-24 14:44:19482// LayerAnimator private -------------------------------------------------------
483
484void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31485 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58486 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31487
[email protected]b4db9372011-10-24 14:44:19488 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19489
[email protected]a48f30d2012-10-30 00:35:41490 PurgeDeletedAnimations();
491
[email protected]f5cd9e52011-11-03 21:38:08492 // We need to make a copy of the running animations because progressing them
493 // and finishing them may indirectly affect the collection of running
494 // animations.
495 RunningAnimations running_animations_copy = running_animations_;
496 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41497 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31498 continue;
499
[email protected]3d75fed2012-12-15 18:47:38500 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14501 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
502 } else {
[email protected]3d75fed2012-12-15 18:47:38503 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14504 }
[email protected]b4db9372011-10-24 14:44:19505 }
[email protected]b4db9372011-10-24 14:44:19506}
507
[email protected]6f110e42012-12-18 00:21:14508void LayerAnimator::StopAnimatingInternal(bool abort) {
509 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55510 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14511 // We're going to attempt to finish the first running animation. Let's
512 // ensure that it's valid.
513 PurgeDeletedAnimations();
514
515 // If we've purged all running animations, attempt to start one up.
516 if (running_animations_.empty())
517 ProcessQueue();
518
519 DCHECK(!running_animations_.empty());
520
521 // Still no luck, let's just bail and clear all animations.
522 if (running_animations_.empty()) {
523 ClearAnimationsInternal();
524 break;
525 }
526
527 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
528 }
529}
530
[email protected]b4db9372011-10-24 14:44:19531void LayerAnimator::UpdateAnimationState() {
532 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12533 return;
534
[email protected]b4db9372011-10-24 14:44:19535 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47536 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
537 if (collection) {
538 if (should_start && !is_started_)
539 collection->StartAnimator(this);
540 else if (!should_start && is_started_)
541 collection->StopAnimator(this);
542 is_started_ = should_start;
543 } else {
544 is_started_ = false;
545 }
[email protected]710a98d2011-06-23 20:13:29546}
547
[email protected]f5cd9e52011-11-03 21:38:08548LayerAnimationSequence* LayerAnimator::RemoveAnimation(
549 LayerAnimationSequence* sequence) {
Ian Vollick37e51bd12018-12-18 14:32:09550 std::unique_ptr<LayerAnimationSequence> to_return;
[email protected]f5cd9e52011-11-03 21:38:08551
[email protected]bf912272013-02-23 01:54:16552 bool is_running = false;
553
[email protected]f5cd9e52011-11-03 21:38:08554 // First remove from running animations
jdoerriedcef4b12018-10-10 12:04:32555 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19556 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41557 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19558 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16559 is_running = true;
[email protected]b4db9372011-10-24 14:44:19560 break;
[email protected]21445e472011-10-21 20:36:32561 }
562 }
[email protected]b4db9372011-10-24 14:44:19563
564 // Then remove from the queue
565 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
566 queue_iter != animation_queue_.end(); ++queue_iter) {
Ian Vollick37e51bd12018-12-18 14:32:09567 if (queue_iter->get() == sequence) {
568 to_return = std::move(*queue_iter);
[email protected]b4db9372011-10-24 14:44:19569 animation_queue_.erase(queue_iter);
570 break;
571 }
572 }
[email protected]f5cd9e52011-11-03 21:38:08573
wutao914b06e62017-09-28 17:41:15574 if (!to_return.get() || !to_return->waiting_for_group_start() ||
575 !to_return->IsFirstElementThreaded(delegate_))
[email protected]bf912272013-02-23 01:54:16576 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) &&
wutao914b06e62017-09-28 17:41:15586 (*queue_iter)->IsFirstElementThreaded(delegate_)) {
[email protected]bf912272013-02-23 01:54:16587 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);
danakj25c52c32016-04-12 21:51:08612 std::unique_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]);
danakj25c52c32016-04-12 21:51:08636 std::unique_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();
jdoerriedcef4b12018-10-10 12:04:32652 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19653 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) {
Ian Vollick37e51bd12018-12-18 14:32:09665 if (queue_iter->get() == animation) {
[email protected]b4db9372011-10-24 14:44:19666 found_sequence = true;
667 break;
668 }
669 }
670
Ian Vollick37e51bd12018-12-18 14:32:09671 if (!found_sequence) {
672 animation_queue_.push_front(
673 std::unique_ptr<LayerAnimationSequence>(animation));
674 }
[email protected]b4db9372011-10-24 14:44:19675}
676
677void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08678 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19679 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08680 // progress them to the end and remove them. Note, Aborting or Progressing
681 // animations may affect the collection of running animations, so we need to
682 // operate on a copy.
683 RunningAnimations running_animations_copy = running_animations_;
684 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41685 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31686 continue;
687
[email protected]712f4b642013-03-14 07:09:15688 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19689 sequence->properties())) {
danakj25c52c32016-04-12 21:51:08690 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41691 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08692 if (abort)
[email protected]bf912272013-02-23 01:54:16693 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08694 else
[email protected]a48f30d2012-10-30 00:35:41695 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19696 }
697 }
698
[email protected]f5cd9e52011-11-03 21:38:08699 // Same for the queued animations that haven't been started. Again, we'll
700 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41701 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08702 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
703 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41704 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08705
706 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19707 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31708 continue;
709
[email protected]712f4b642013-03-14 07:09:15710 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
danakj25c52c32016-04-12 21:51:08711 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]7ffde472013-06-04 06:42:19712 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19713 if (abort)
[email protected]bf912272013-02-23 01:54:16714 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19715 else
[email protected]7ffde472013-06-04 06:42:19716 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19717 }
718 }
719}
720
721void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41722 // Need to detect if our sequence gets destroyed.
723 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
724 sequence->AsWeakPtr();
725
[email protected]b4db9372011-10-24 14:44:19726 const bool abort = false;
727 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19728 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41729 return;
730
[email protected]d3ba37ab2012-02-09 19:53:13731 LayerAnimationSequence* removed = RemoveAnimation(sequence);
732 DCHECK(removed == NULL || removed == sequence);
[email protected]7ffde472013-06-04 06:42:19733 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41734 return;
735
[email protected]4a386e42012-12-05 01:19:30736 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19737 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41738 return;
739
740 delete sequence;
[email protected]b4db9372011-10-24 14:44:19741}
742
743void LayerAnimator::ImmediatelyAnimateToNewTarget(
744 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41745 // Need to detect if our sequence gets destroyed.
746 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
747 sequence->AsWeakPtr();
748
[email protected]b4db9372011-10-24 14:44:19749 const bool abort = true;
750 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19751 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41752 return;
753
[email protected]b4db9372011-10-24 14:44:19754 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19755 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41756 return;
757
[email protected]b4db9372011-10-24 14:44:19758 StartSequenceImmediately(sequence);
759}
760
761void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
762 // It is assumed that if there was no conflicting animation, we would
763 // not have been called. No need to check for a collision; just
764 // add to the queue.
Ian Vollick37e51bd12018-12-18 14:32:09765 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19766 ProcessQueue();
767}
768
769void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41770 // Need to detect if our sequence gets destroyed.
771 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
772 sequence->AsWeakPtr();
773
[email protected]b4db9372011-10-24 14:44:19774 // Remove all animations that aren't running. Note: at each iteration i is
775 // incremented or an element is removed from the queue, so
776 // animation_queue_.size() - i is always decreasing and we are always making
777 // progress towards the loop terminating.
778 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19779 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41780 break;
781
782 PurgeDeletedAnimations();
783
[email protected]b4db9372011-10-24 14:44:19784 bool is_running = false;
785 for (RunningAnimations::const_iterator iter = running_animations_.begin();
786 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41787 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19788 is_running = true;
789 break;
790 }
791 }
[email protected]a48f30d2012-10-30 00:35:41792
[email protected]b4db9372011-10-24 14:44:19793 if (!is_running)
[email protected]300548c2012-06-17 08:54:55794 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19795 else
796 ++i;
797 }
Ian Vollick37e51bd12018-12-18 14:32:09798 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19799 ProcessQueue();
800}
801
802void LayerAnimator::ProcessQueue() {
803 bool started_sequence = false;
804 do {
805 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19806 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24807 LayerAnimationElement::AnimatableProperties animated =
808 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19809 for (RunningAnimations::const_iterator iter = running_animations_.begin();
810 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41811 if (!(*iter).is_sequence_alive())
812 continue;
[email protected]e03193d2014-01-14 03:10:24813
814 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19815 }
816
817 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08818 // property or a property that will be animated before it. Note: starting
819 // the animation may indirectly cause more animations to be started, so we
820 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41821 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19822 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08823 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41824 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08825
826 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19827 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41828 continue;
829
[email protected]712f4b642013-03-14 07:09:15830 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41831 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19832 started_sequence = true;
833 break;
834 }
835
836 // Animation couldn't be started. Add its properties to the collection so
837 // that we don't start a conflicting animation. For example, if our queue
838 // has the elements { {T,B}, {B} } (that is, an element that animates both
839 // the transform and the bounds followed by an element that animates the
840 // bounds), and we're currently animating the transform, we can't start
841 // the first element because it animates the transform, too. We cannot
842 // start the second element, either, because the first element animates
843 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24844 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19845 }
846
847 // If we started a sequence, try again. We may be able to start several.
848 } while (started_sequence);
849}
850
851bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41852 PurgeDeletedAnimations();
853
[email protected]b4db9372011-10-24 14:44:19854 // Ensure that no one is animating one of the sequence's properties already.
855 for (RunningAnimations::const_iterator iter = running_animations_.begin();
856 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15857 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19858 return false;
859 }
860
charliea3be839702015-01-26 17:35:41861 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47862 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19863 // last_tick_time() from there to ensure animations started during the same
864 // event complete at the same time.
865 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47866 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59867 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19868 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47869 else if (collection && collection->HasActiveAnimators())
870 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19871 else
abhishek.ka7215854d2015-05-26 06:13:17872 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19873
[email protected]bf912272013-02-23 01:54:16874 if (!sequence->animation_group_id())
875 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
bruthig4a12c2b2016-11-05 00:19:18876
[email protected]a48f30d2012-10-30 00:35:41877 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38878 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19879
880 // Need to keep a reference to the animation.
881 AddToQueueIfNotPresent(sequence);
882
bruthig4a12c2b2016-11-05 00:19:18883 if (!sequence->waiting_for_group_start() ||
wutao914b06e62017-09-28 17:41:15884 sequence->IsFirstElementThreaded(delegate_)) {
bruthig4a12c2b2016-11-05 00:19:18885 sequence->set_start_time(start_time);
886 sequence->Start(delegate());
887 }
888
[email protected]b4db9372011-10-24 14:44:19889 // Ensure that animations get stepped at their start time.
890 Step(start_time);
891
892 return true;
[email protected]710a98d2011-06-23 20:13:29893}
894
[email protected]fe7074c62011-10-28 15:22:54895void LayerAnimator::GetTargetValue(
896 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13897 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
898 iter != animation_queue_.end(); ++iter) {
899 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54900 }
901}
902
[email protected]e876c272011-11-02 16:42:45903void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
dchengd38152e2016-10-13 18:21:37904 for (LayerAnimationObserver& observer : observers_)
905 sequence->AddObserver(&observer);
[email protected]e876c272011-11-02 16:42:45906 sequence->OnScheduled();
907}
908
[email protected]0d316252014-01-20 15:31:19909void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
910 if (is_transition_duration_locked_)
911 return;
912 transition_duration_ = duration;
[email protected]9861f1752012-06-01 07:16:14913}
914
[email protected]5d86a112012-09-23 00:21:58915void LayerAnimator::ClearAnimationsInternal() {
[email protected]a48f30d2012-10-30 00:35:41916 PurgeDeletedAnimations();
917
[email protected]5d86a112012-09-23 00:21:58918 // Abort should never affect the set of running animations, but just in case
919 // clients are badly behaved, we will use a copy of the running animations.
920 RunningAnimations running_animations_copy = running_animations_;
921 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41922 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]5d86a112012-09-23 00:21:58923 continue;
924
danakj25c52c32016-04-12 21:51:08925 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41926 RemoveAnimation(running_animations_copy[i].sequence()));
[email protected]5d86a112012-09-23 00:21:58927 if (removed.get())
[email protected]bf912272013-02-23 01:54:16928 removed->Abort(delegate());
[email protected]5d86a112012-09-23 00:21:58929 }
930 // This *should* have cleared the list of running animations.
931 DCHECK(running_animations_.empty());
932 running_animations_.clear();
933 animation_queue_.clear();
934 UpdateAnimationState();
935}
936
[email protected]a48f30d2012-10-30 00:35:41937void LayerAnimator::PurgeDeletedAnimations() {
938 for (size_t i = 0; i < running_animations_.size();) {
939 if (!running_animations_[i].is_sequence_alive())
940 running_animations_.erase(running_animations_.begin() + i);
941 else
942 i++;
943 }
944}
945
[email protected]9034a282014-06-05 03:11:47946LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
947 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
948}
949
Ian Vollickba1f85922017-07-21 18:10:03950void LayerAnimator::NotifyAnimationStarted(base::TimeTicks monotonic_time,
951 int target_property,
952 int group) {
953 OnThreadedAnimationStarted(
954 monotonic_time, static_cast<cc::TargetProperty::Type>(target_property),
955 group);
loyso1fbd9f92015-12-17 07:43:13956}
957
[email protected]a48f30d2012-10-30 00:35:41958LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38959 const base::WeakPtr<LayerAnimationSequence>& sequence)
960 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41961}
962
vmpstr0ae825e72016-02-25 20:31:31963LayerAnimator::RunningAnimation::RunningAnimation(
964 const RunningAnimation& other) = default;
965
[email protected]a48f30d2012-10-30 00:35:41966LayerAnimator::RunningAnimation::~RunningAnimation() { }
967
[email protected]710a98d2011-06-23 20:13:29968} // namespace ui