blob: 23c6bb80e4fa983ceab17bf9b85e138bd15f359b [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
Hans Wennborg8586102b2020-05-05 13:43:2911#include "base/check_op.h"
Lei Zhang74ab63802021-07-03 22:11:3812#include "base/containers/cxx20_erase.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)
Bartek Nowierskieb07a5e2020-06-03 06:45:1734#define SAFE_INVOKE_PTR(function, running_anim) \
35 ((running_anim.is_sequence_alive()) ? function(running_anim.sequence()) \
36 : nullptr)
[email protected]a48f30d2012-10-30 00:35:4137
[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)
Allen Bauer8a3cd652021-09-13 22:20:0349 : transition_duration_(transition_duration) {
Yi Gub0422c42020-01-13 17:00:3650 animation_ =
51 cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId());
[email protected]710a98d2011-06-23 20:13:2952}
53
54LayerAnimator::~LayerAnimator() {
[email protected]a48f30d2012-10-30 00:35:4155 for (size_t i = 0; i < running_animations_.size(); ++i) {
56 if (running_animations_[i].is_sequence_alive())
57 running_animations_[i].sequence()->OnAnimatorDestroyed();
58 }
[email protected]5d86a112012-09-23 00:21:5859 ClearAnimationsInternal();
Bartek Nowierskieb07a5e2020-06-03 06:45:1760 delegate_ = nullptr;
Yi Guaa830ff2018-02-22 03:09:1161 DCHECK(!animation_->animation_timeline());
[email protected]710a98d2011-06-23 20:13:2962}
63
[email protected]b4db9372011-10-24 14:44:1964// static
65LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
66 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
67}
68
69// static
70LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
Daniel Bratellc2fecad52017-12-21 22:36:2271 return new LayerAnimator(base::TimeDelta::FromMilliseconds(
72 kLayerAnimatorDefaultTransitionDurationMs));
[email protected]b4db9372011-10-24 14:44:1973}
74
[email protected]7713e242012-11-15 17:43:1975// This macro provides the implementation for the setter and getter (well,
76// the getter of the target value) for an animated property. For example,
77// it is used for the implementations of SetTransform and GetTargetTransform.
78// It is worth noting that SetFoo avoids invoking the usual animation machinery
79// if the transition duration is zero -- in this case we just set the property
80// on the layer animation delegate immediately.
Francois Doray91e63fb72017-11-08 14:21:5281#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
82 void LayerAnimator::Set##name(type value) { \
83 base::TimeDelta duration = GetTransitionDuration(); \
84 if (duration.is_zero() && delegate() && \
85 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
86 StopAnimatingProperty(LayerAnimationElement::property); \
Toni Barzic8be24e0e22021-03-12 07:48:4287 if (!delegate()) \
88 return; \
Francois Doray91e63fb72017-11-08 14:21:5289 delegate()->Set##name##FromAnimation( \
90 value, PropertyChangeReason::NOT_FROM_ANIMATION); \
91 return; \
92 } \
93 std::unique_ptr<LayerAnimationElement> element = \
94 LayerAnimationElement::Create##name##Element(value, duration); \
95 element->set_tween_type(tween_type_); \
96 StartAnimation(new LayerAnimationSequence(std::move(element))); \
97 } \
98 \
99 member_type LayerAnimator::GetTarget##name() const { \
100 LayerAnimationElement::TargetValue target(delegate()); \
101 GetTargetValue(&target); \
102 return target.member; \
danakj25c52c32016-04-12 21:51:08103 }
[email protected]fe7074c62011-10-28 15:22:54104
Nico Weber3a6c6372019-02-21 14:26:18105ANIMATED_PROPERTY(const gfx::Transform&,
106 TRANSFORM,
107 Transform,
108 gfx::Transform,
109 transform)
110ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds)
111ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity)
112ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility)
113ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness)
114ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale)
115ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color)
Malay Keshavb8ac9e572019-07-03 00:26:55116ANIMATED_PROPERTY(const gfx::Rect&, CLIP, ClipRect, gfx::Rect, clip_rect)
Jun Mukaia343db33b2019-07-17 23:25:50117ANIMATED_PROPERTY(const gfx::RoundedCornersF&,
118 ROUNDED_CORNERS,
119 RoundedCorners,
120 gfx::RoundedCornersF,
121 rounded_corners)
Nico Weber3a6c6372019-02-21 14:26:18122
123#undef ANIMATED_PROPERTY
[email protected]e81480f1f2012-10-11 23:06:45124
[email protected]0d316252014-01-20 15:31:19125base::TimeDelta LayerAnimator::GetTransitionDuration() const {
126 return transition_duration_;
127}
128
[email protected]e876c272011-11-02 16:42:45129void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
[email protected]9034a282014-06-05 03:11:47130 if (delegate_ && is_started_) {
131 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
132 if (collection)
133 collection->StopAnimator(this);
134 }
loyso1fbd9f92015-12-17 07:43:13135 SwitchToLayer(delegate ? delegate->GetCcLayer() : nullptr);
[email protected]b4db9372011-10-24 14:44:19136 delegate_ = delegate;
[email protected]9034a282014-06-05 03:11:47137 if (delegate_ && is_started_) {
138 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
139 if (collection)
140 collection->StartAnimator(this);
141 }
[email protected]b4db9372011-10-24 14:44:19142}
143
loyso1fbd9f92015-12-17 07:43:13144void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
loysoe2fed922016-03-09 04:41:55145 if (delegate_)
Yi Guaa830ff2018-02-22 03:09:11146 DetachLayerFromAnimation();
loysoe2fed922016-03-09 04:41:55147 if (new_layer)
Yi Guaa830ff2018-02-22 03:09:11148 AttachLayerToAnimation(new_layer->id());
loyso841229002015-12-21 10:03:24149}
150
loysocc8e3db2016-10-04 05:22:03151void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24152 DCHECK(compositor);
loyso841229002015-12-21 10:03:24153
loysoe2fed922016-03-09 04:41:55154 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
155 DCHECK(timeline);
Yi Guaa830ff2018-02-22 03:09:11156 timeline->AttachAnimation(animation_);
loysoe2fed922016-03-09 04:41:55157
loysocc8e3db2016-10-04 05:22:03158 DCHECK(delegate_->GetCcLayer());
Yi Guaa830ff2018-02-22 03:09:11159 AttachLayerToAnimation(delegate_->GetCcLayer()->id());
Xiyuan Xiaadecd672020-02-25 17:00:57160
161 for (auto& layer_animation_sequence : animation_queue_)
162 layer_animation_sequence->OnAnimatorAttached(delegate());
loyso841229002015-12-21 10:03:24163}
164
loysocc8e3db2016-10-04 05:22:03165void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24166 DCHECK(compositor);
loyso3338dfb2016-03-09 03:07:32167
loysode0a0022016-04-15 02:28:38168 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
169 DCHECK(timeline);
170
Yi Guaa830ff2018-02-22 03:09:11171 DetachLayerFromAnimation();
172 timeline->DetachAnimation(animation_);
Xiyuan Xiaadecd672020-02-25 17:00:57173
174 for (auto& layer_animation_sequence : animation_queue_)
175 layer_animation_sequence->OnAnimatorDetached();
loyso841229002015-12-21 10:03:24176}
177
Yi Guaa830ff2018-02-22 03:09:11178void LayerAnimator::AttachLayerToAnimation(int layer_id) {
vollickef2ae922016-06-29 17:54:27179 // For ui, layer and element ids are equivalent.
chrishtrc3daf272017-05-11 11:08:02180 cc::ElementId element_id(layer_id);
Yi Guaa830ff2018-02-22 03:09:11181 if (!animation_->element_id())
182 animation_->AttachElement(element_id);
loyso841229002015-12-21 10:03:24183 else
Yi Guaa830ff2018-02-22 03:09:11184 DCHECK_EQ(animation_->element_id(), element_id);
loyso841229002015-12-21 10:03:24185
Yi Guaa830ff2018-02-22 03:09:11186 animation_->set_animation_delegate(this);
loyso841229002015-12-21 10:03:24187}
188
Yi Guaa830ff2018-02-22 03:09:11189void LayerAnimator::DetachLayerFromAnimation() {
190 animation_->set_animation_delegate(nullptr);
loyso841229002015-12-21 10:03:24191
Yi Guaa830ff2018-02-22 03:09:11192 if (animation_->element_id())
193 animation_->DetachElement();
loyso841229002015-12-21 10:03:24194}
195
Yi Gu4e1dce32018-07-04 20:52:15196void LayerAnimator::AddThreadedAnimation(
197 std::unique_ptr<cc::KeyframeModel> animation) {
198 animation_->AddKeyframeModel(std::move(animation));
loyso841229002015-12-21 10:03:24199}
200
Yi Gu4e1dce32018-07-04 20:52:15201void LayerAnimator::RemoveThreadedAnimation(int keyframe_model_id) {
202 animation_->RemoveKeyframeModel(keyframe_model_id);
loyso1fbd9f92015-12-17 07:43:13203}
204
Yi Gub0422c42020-01-13 17:00:36205cc::Animation* LayerAnimator::GetAnimationForTesting() const {
Yi Guaa830ff2018-02-22 03:09:11206 return animation_.get();
loysod4127442016-02-03 02:29:40207}
208
[email protected]b4db9372011-10-24 14:44:19209void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58210 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45211 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19212 if (!StartSequenceImmediately(animation)) {
213 // Attempt to preempt a running animation.
214 switch (preemption_strategy_) {
215 case IMMEDIATELY_SET_NEW_TARGET:
216 ImmediatelySetNewTarget(animation);
217 break;
218 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
219 ImmediatelyAnimateToNewTarget(animation);
220 break;
221 case ENQUEUE_NEW_ANIMATION:
222 EnqueueNewAnimation(animation);
223 break;
224 case REPLACE_QUEUED_ANIMATIONS:
225 ReplaceQueuedAnimations(animation);
226 break;
[email protected]7fca53d42011-09-29 15:38:12227 }
[email protected]b4db9372011-10-24 14:44:19228 }
229 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54230 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19231}
232
233void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58234 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45235 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19236 if (is_animating()) {
Ian Vollick37e51bd12018-12-18 14:32:09237 animation_queue_.push_back(
238 std::unique_ptr<LayerAnimationSequence>(animation));
[email protected]b4db9372011-10-24 14:44:19239 ProcessQueue();
240 } else {
241 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12242 }
[email protected]fe7074c62011-10-28 15:22:54243 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29244}
245
[email protected]d064ef82012-11-13 10:26:59246void LayerAnimator::StartTogether(
247 const std::vector<LayerAnimationSequence*>& animations) {
248 scoped_refptr<LayerAnimator> retain(this);
249 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
250 std::vector<LayerAnimationSequence*>::const_iterator iter;
251 for (iter = animations.begin(); iter != animations.end(); ++iter) {
252 StartAnimation(*iter);
253 }
254 return;
255 }
[email protected]d764fd3d2012-11-15 20:07:51256
[email protected]d064ef82012-11-13 10:26:59257 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51258 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47259 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
260 if (collection && collection->HasActiveAnimators())
261 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51262 else
abhishek.ka7215854d2015-05-26 06:13:17263 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51264 }
[email protected]d064ef82012-11-13 10:26:59265
266 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24267 LayerAnimationElement::AnimatableProperties animated_properties =
268 LayerAnimationElement::UNKNOWN;
269
[email protected]d064ef82012-11-13 10:26:59270 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24271 for (iter = animations.begin(); iter != animations.end(); ++iter)
272 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59273
274 // Starting a zero duration pause that affects all the animated properties
275 // will prevent any of the sequences from animating until there are no
276 // running animations that affect any of these properties, as well as
277 // handle preemption strategy.
278 StartAnimation(new LayerAnimationSequence(
279 LayerAnimationElement::CreatePauseElement(animated_properties,
280 base::TimeDelta())));
281
[email protected]bf912272013-02-23 01:54:16282 bool wait_for_group_start = false;
283 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15284 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16285 int group_id = cc::AnimationIdProvider::NextGroupId();
286
[email protected]d064ef82012-11-13 10:26:59287 // These animations (provided they don't animate any common properties) will
288 // now animate together if trivially scheduled.
289 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16290 (*iter)->set_animation_group_id(group_id);
291 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59292 ScheduleAnimation(*iter);
293 }
294
295 adding_animations_ = false;
296 UpdateAnimationState();
297}
298
299
[email protected]b4db9372011-10-24 14:44:19300void LayerAnimator::ScheduleTogether(
301 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58302 scoped_refptr<LayerAnimator> retain(this);
303
[email protected]b4db9372011-10-24 14:44:19304 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24305 LayerAnimationElement::AnimatableProperties animated_properties =
306 LayerAnimationElement::UNKNOWN;
307
[email protected]b4db9372011-10-24 14:44:19308 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24309 for (iter = animations.begin(); iter != animations.end(); ++iter)
310 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29311
[email protected]b4db9372011-10-24 14:44:19312 // Scheduling a zero duration pause that affects all the animated properties
313 // will prevent any of the sequences from animating until there are no
314 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31315 ScheduleAnimation(new LayerAnimationSequence(
316 LayerAnimationElement::CreatePauseElement(animated_properties,
317 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29318
[email protected]bf912272013-02-23 01:54:16319 bool wait_for_group_start = false;
320 for (iter = animations.begin(); iter != animations.end(); ++iter)
wutao914b06e62017-09-28 17:41:15321 wait_for_group_start |= (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16322
323 int group_id = cc::AnimationIdProvider::NextGroupId();
324
[email protected]b4db9372011-10-24 14:44:19325 // These animations (provided they don't animate any common properties) will
326 // now animate together if trivially scheduled.
327 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16328 (*iter)->set_animation_group_id(group_id);
329 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19330 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29331 }
[email protected]fe7074c62011-10-28 15:22:54332
333 UpdateAnimationState();
334}
335
[email protected]2a88c702012-09-04 23:15:02336void LayerAnimator::SchedulePauseForProperties(
337 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24338 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02339 ScheduleAnimation(new ui::LayerAnimationSequence(
340 ui::LayerAnimationElement::CreatePauseElement(
341 properties_to_pause, duration)));
342}
343
Francois Dorayeef012b62017-10-26 20:02:59344bool LayerAnimator::IsAnimatingOnePropertyOf(
345 LayerAnimationElement::AnimatableProperties properties) const {
346 for (auto& layer_animation_sequence : animation_queue_) {
347 if (layer_animation_sequence->properties() & properties)
[email protected]e876c272011-11-02 16:42:45348 return true;
[email protected]e876c272011-11-02 16:42:45349 }
350 return false;
[email protected]7fca53d42011-09-29 15:38:12351}
352
[email protected]b4db9372011-10-24 14:44:19353void LayerAnimator::StopAnimatingProperty(
354 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58355 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19356 while (true) {
[email protected]a48f30d2012-10-30 00:35:41357 // GetRunningAnimation purges deleted animations before searching, so we are
358 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19359 RunningAnimation* running = GetRunningAnimation(property);
360 if (!running)
361 break;
[email protected]a48f30d2012-10-30 00:35:41362 // As was mentioned above, this sequence must be alive.
363 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14364 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41365 }
[email protected]b4db9372011-10-24 14:44:19366}
367
[email protected]e876c272011-11-02 16:42:45368void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
Francois Doray29ecd3aa2017-11-07 15:40:18369 if (!observers_.HasObserver(observer)) {
[email protected]e876c272011-11-02 16:42:45370 observers_.AddObserver(observer);
Francois Doray29ecd3aa2017-11-07 15:40:18371 for (auto& layer_animation_sequence : animation_queue_)
372 layer_animation_sequence->AddObserver(observer);
373 }
[email protected]e876c272011-11-02 16:42:45374}
375
376void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
377 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54378 // Remove the observer from all sequences as well.
379 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
380 queue_iter != animation_queue_.end(); ++queue_iter) {
381 (*queue_iter)->RemoveObserver(observer);
382 }
[email protected]e876c272011-11-02 16:42:45383}
384
wutao4f1c0d5d2017-10-05 01:02:43385void LayerAnimator::AddOwnedObserver(
386 std::unique_ptr<ImplicitAnimationObserver> animation_observer) {
387 owned_observer_list_.push_back(std::move(animation_observer));
388}
389
390void LayerAnimator::RemoveAndDestroyOwnedObserver(
391 ImplicitAnimationObserver* animation_observer) {
JungHoon Lee897c21ef2018-08-27 20:18:17392 base::EraseIf(owned_observer_list_,[animation_observer](
393 const std::unique_ptr<ImplicitAnimationObserver>& other) {
394 return other.get() == animation_observer;
395 });
wutao4f1c0d5d2017-10-05 01:02:43396}
397
Allen Bauer8a3cd652021-09-13 22:20:03398base::CallbackListSubscription LayerAnimator::AddSequenceScheduledCallback(
399 SequenceScheduledCallback callback) {
400 return sequence_scheduled_callbacks_.Add(std::move(callback));
401}
402
[email protected]bf912272013-02-23 01:54:16403void LayerAnimator::OnThreadedAnimationStarted(
loyso79c0bfc2016-04-18 23:46:42404 base::TimeTicks monotonic_time,
405 cc::TargetProperty::Type target_property,
406 int group_id) {
[email protected]bf912272013-02-23 01:54:16407 LayerAnimationElement::AnimatableProperty property =
loyso79c0bfc2016-04-18 23:46:42408 LayerAnimationElement::ToAnimatableProperty(target_property);
[email protected]bf912272013-02-23 01:54:16409
410 RunningAnimation* running = GetRunningAnimation(property);
411 if (!running)
412 return;
413 DCHECK(running->is_sequence_alive());
414
loyso79c0bfc2016-04-18 23:46:42415 if (running->sequence()->animation_group_id() != group_id)
[email protected]bf912272013-02-23 01:54:16416 return;
417
loyso79c0bfc2016-04-18 23:46:42418 running->sequence()->OnThreadedAnimationStarted(monotonic_time,
419 target_property, group_id);
[email protected]bf912272013-02-23 01:54:16420 if (!running->sequence()->waiting_for_group_start())
421 return;
422
loyso79c0bfc2016-04-18 23:46:42423 base::TimeTicks start_time = monotonic_time;
[email protected]bf912272013-02-23 01:54:16424
425 running->sequence()->set_waiting_for_group_start(false);
426
427 // The call to GetRunningAnimation made above already purged deleted
428 // animations, so we are guaranteed that all the animations we iterate
429 // over now are alive.
jdoerriedcef4b12018-10-10 12:04:32430 for (auto iter = running_animations_.begin();
[email protected]bf912272013-02-23 01:54:16431 iter != running_animations_.end(); ++iter) {
432 // Ensure that each sequence is only Started once, regardless of the
433 // number of sequences in the group that have threaded first elements.
loyso79c0bfc2016-04-18 23:46:42434 if (((*iter).sequence()->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15435 !(*iter).sequence()->IsFirstElementThreaded(delegate_) &&
[email protected]bf912272013-02-23 01:54:16436 (*iter).sequence()->waiting_for_group_start()) {
437 (*iter).sequence()->set_start_time(start_time);
438 (*iter).sequence()->set_waiting_for_group_start(false);
439 (*iter).sequence()->Start(delegate());
440 }
441 }
442}
443
[email protected]9034a282014-06-05 03:11:47444void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
445 if (is_animating() && !is_started_) {
446 collection->StartAnimator(this);
447 is_started_ = true;
448 }
449}
450
451void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
bruthig33b1edab2016-03-02 02:22:35452 if (is_started_) {
[email protected]9034a282014-06-05 03:11:47453 collection->StopAnimator(this);
454 is_started_ = false;
455 }
456}
457
[email protected]d59a3692012-04-10 20:27:31458// LayerAnimator protected -----------------------------------------------------
459
[email protected]5d86a112012-09-23 00:21:58460void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38461 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16462 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58463 return;
464
[email protected]3d75fed2012-12-15 18:47:38465 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31466}
467
[email protected]a48f30d2012-10-30 00:35:41468void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30469 if (!delegate())
470 return;
471
472 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41473}
474
[email protected]d59a3692012-04-10 20:27:31475bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
476 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
477 queue_iter != animation_queue_.end(); ++queue_iter) {
478 if ((*queue_iter).get() == sequence)
479 return true;
480 }
481 return false;
482}
483
[email protected]b4db9372011-10-24 14:44:19484// LayerAnimator private -------------------------------------------------------
485
486void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31487 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58488 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31489
[email protected]b4db9372011-10-24 14:44:19490 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19491
[email protected]a48f30d2012-10-30 00:35:41492 PurgeDeletedAnimations();
493
[email protected]f5cd9e52011-11-03 21:38:08494 // We need to make a copy of the running animations because progressing them
495 // and finishing them may indirectly affect the collection of running
496 // animations.
497 RunningAnimations running_animations_copy = running_animations_;
498 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41499 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31500 continue;
501
[email protected]3d75fed2012-12-15 18:47:38502 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14503 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
504 } else {
[email protected]3d75fed2012-12-15 18:47:38505 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14506 }
[email protected]b4db9372011-10-24 14:44:19507 }
[email protected]b4db9372011-10-24 14:44:19508}
509
[email protected]6f110e42012-12-18 00:21:14510void LayerAnimator::StopAnimatingInternal(bool abort) {
511 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55512 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14513 // We're going to attempt to finish the first running animation. Let's
514 // ensure that it's valid.
515 PurgeDeletedAnimations();
516
517 // If we've purged all running animations, attempt to start one up.
518 if (running_animations_.empty())
519 ProcessQueue();
520
521 DCHECK(!running_animations_.empty());
522
523 // Still no luck, let's just bail and clear all animations.
524 if (running_animations_.empty()) {
525 ClearAnimationsInternal();
526 break;
527 }
528
529 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
530 }
531}
532
[email protected]b4db9372011-10-24 14:44:19533void LayerAnimator::UpdateAnimationState() {
534 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12535 return;
536
[email protected]b4db9372011-10-24 14:44:19537 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47538 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
539 if (collection) {
540 if (should_start && !is_started_)
541 collection->StartAnimator(this);
542 else if (!should_start && is_started_)
543 collection->StopAnimator(this);
544 is_started_ = should_start;
545 } else {
546 is_started_ = false;
547 }
[email protected]710a98d2011-06-23 20:13:29548}
549
[email protected]f5cd9e52011-11-03 21:38:08550LayerAnimationSequence* LayerAnimator::RemoveAnimation(
551 LayerAnimationSequence* sequence) {
Ian Vollick37e51bd12018-12-18 14:32:09552 std::unique_ptr<LayerAnimationSequence> to_return;
[email protected]f5cd9e52011-11-03 21:38:08553
[email protected]bf912272013-02-23 01:54:16554 bool is_running = false;
555
[email protected]f5cd9e52011-11-03 21:38:08556 // First remove from running animations
jdoerriedcef4b12018-10-10 12:04:32557 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19558 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41559 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19560 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16561 is_running = true;
[email protected]b4db9372011-10-24 14:44:19562 break;
[email protected]21445e472011-10-21 20:36:32563 }
564 }
[email protected]b4db9372011-10-24 14:44:19565
566 // Then remove from the queue
567 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
568 queue_iter != animation_queue_.end(); ++queue_iter) {
Ian Vollick37e51bd12018-12-18 14:32:09569 if (queue_iter->get() == sequence) {
570 to_return = std::move(*queue_iter);
[email protected]b4db9372011-10-24 14:44:19571 animation_queue_.erase(queue_iter);
572 break;
573 }
574 }
[email protected]f5cd9e52011-11-03 21:38:08575
Elaine Chiena2c1d702021-09-08 22:50:38576 // Do not continue and attempt to start other sequences if the delegate is
577 // nullptr.
578 // TODO(crbug.com/1247769): Guard other uses of delegate_ in this class.
579 if (!delegate())
580 return to_return.release();
581
wutao914b06e62017-09-28 17:41:15582 if (!to_return.get() || !to_return->waiting_for_group_start() ||
583 !to_return->IsFirstElementThreaded(delegate_))
[email protected]bf912272013-02-23 01:54:16584 return to_return.release();
585
586 // The removed sequence may have been responsible for making other sequences
587 // wait for a group start. If no other sequences in the group have a
588 // threaded first element, the group no longer needs the additional wait.
589 bool is_wait_still_needed = false;
590 int group_id = to_return->animation_group_id();
591 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
592 queue_iter != animation_queue_.end(); ++queue_iter) {
593 if (((*queue_iter)->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15594 (*queue_iter)->IsFirstElementThreaded(delegate_)) {
[email protected]bf912272013-02-23 01:54:16595 is_wait_still_needed = true;
596 break;
597 }
598 }
599
600 if (is_wait_still_needed)
601 return to_return.release();
602
603 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
604 queue_iter != animation_queue_.end(); ++queue_iter) {
605 if ((*queue_iter)->animation_group_id() == group_id &&
606 (*queue_iter)->waiting_for_group_start()) {
607 (*queue_iter)->set_waiting_for_group_start(false);
608 if (is_running) {
609 (*queue_iter)->set_start_time(last_step_time_);
610 (*queue_iter)->Start(delegate());
611 }
612 }
613 }
[email protected]f5cd9e52011-11-03 21:38:08614 return to_return.release();
[email protected]0ed187e2011-10-21 20:07:42615}
616
[email protected]6f110e42012-12-18 00:21:14617void LayerAnimator::FinishAnimation(
618 LayerAnimationSequence* sequence, bool abort) {
[email protected]5d86a112012-09-23 00:21:58619 scoped_refptr<LayerAnimator> retain(this);
danakj25c52c32016-04-12 21:51:08620 std::unique_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
[email protected]6f110e42012-12-18 00:21:14621 if (abort)
[email protected]bf912272013-02-23 01:54:16622 sequence->Abort(delegate());
[email protected]6f110e42012-12-18 00:21:14623 else
624 ProgressAnimationToEnd(sequence);
ljagielski20570982015-01-07 20:32:55625 if (!delegate())
626 return;
[email protected]b4db9372011-10-24 14:44:19627 ProcessQueue();
628 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32629}
[email protected]0ed187e2011-10-21 20:07:42630
[email protected]b4db9372011-10-24 14:44:19631void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
[email protected]5d86a112012-09-23 00:21:58632 scoped_refptr<LayerAnimator> retain(this);
[email protected]2ddfe432011-11-07 19:26:30633 // Special case: if we've started a 0 duration animation, just finish it now
634 // and get rid of it. We need to make a copy because Progress may indirectly
635 // cause new animations to start running.
[email protected]f5cd9e52011-11-03 21:38:08636 RunningAnimations running_animations_copy = running_animations_;
637 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41638 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31639 continue;
640
[email protected]3d75fed2012-12-15 18:47:38641 if (running_animations_copy[i].sequence()->IsFinished(
642 running_animations_copy[i].sequence()->start_time())) {
[email protected]a48f30d2012-10-30 00:35:41643 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
danakj25c52c32016-04-12 21:51:08644 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41645 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]b4db9372011-10-24 14:44:19646 }
647 }
648 ProcessQueue();
649 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32650}
[email protected]0ed187e2011-10-21 20:07:42651
[email protected]b4db9372011-10-24 14:44:19652void LayerAnimator::ClearAnimations() {
[email protected]5d86a112012-09-23 00:21:58653 scoped_refptr<LayerAnimator> retain(this);
654 ClearAnimationsInternal();
[email protected]b4db9372011-10-24 14:44:19655}
656
657LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
658 LayerAnimationElement::AnimatableProperty property) {
[email protected]a48f30d2012-10-30 00:35:41659 PurgeDeletedAnimations();
jdoerriedcef4b12018-10-10 12:04:32660 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19661 iter != running_animations_.end(); ++iter) {
[email protected]e03193d2014-01-14 03:10:24662 if ((*iter).sequence()->properties() & property)
[email protected]b4db9372011-10-24 14:44:19663 return &(*iter);
664 }
Bartek Nowierskieb07a5e2020-06-03 06:45:17665 return nullptr;
[email protected]b4db9372011-10-24 14:44:19666}
667
668void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
669 // If we don't have the animation in the queue yet, add it.
670 bool found_sequence = false;
671 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
672 queue_iter != animation_queue_.end(); ++queue_iter) {
Ian Vollick37e51bd12018-12-18 14:32:09673 if (queue_iter->get() == animation) {
[email protected]b4db9372011-10-24 14:44:19674 found_sequence = true;
675 break;
676 }
677 }
678
Ian Vollick37e51bd12018-12-18 14:32:09679 if (!found_sequence) {
680 animation_queue_.push_front(
681 std::unique_ptr<LayerAnimationSequence>(animation));
682 }
[email protected]b4db9372011-10-24 14:44:19683}
684
685void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08686 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19687 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08688 // progress them to the end and remove them. Note, Aborting or Progressing
689 // animations may affect the collection of running animations, so we need to
690 // operate on a copy.
691 RunningAnimations running_animations_copy = running_animations_;
692 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41693 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31694 continue;
695
[email protected]712f4b642013-03-14 07:09:15696 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19697 sequence->properties())) {
danakj25c52c32016-04-12 21:51:08698 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41699 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08700 if (abort)
[email protected]bf912272013-02-23 01:54:16701 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08702 else
[email protected]a48f30d2012-10-30 00:35:41703 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19704 }
705 }
706
[email protected]f5cd9e52011-11-03 21:38:08707 // Same for the queued animations that haven't been started. Again, we'll
708 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41709 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08710 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
711 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41712 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08713
714 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19715 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31716 continue;
717
[email protected]712f4b642013-03-14 07:09:15718 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
danakj25c52c32016-04-12 21:51:08719 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]7ffde472013-06-04 06:42:19720 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19721 if (abort)
[email protected]bf912272013-02-23 01:54:16722 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19723 else
[email protected]7ffde472013-06-04 06:42:19724 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19725 }
726 }
727}
728
729void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41730 // Need to detect if our sequence gets destroyed.
731 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
732 sequence->AsWeakPtr();
733
[email protected]b4db9372011-10-24 14:44:19734 const bool abort = false;
735 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19736 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41737 return;
738
[email protected]d3ba37ab2012-02-09 19:53:13739 LayerAnimationSequence* removed = RemoveAnimation(sequence);
Bartek Nowierskieb07a5e2020-06-03 06:45:17740 DCHECK(removed == nullptr || removed == sequence);
[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]4a386e42012-12-05 01:19:30744 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19745 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41746 return;
747
748 delete sequence;
[email protected]b4db9372011-10-24 14:44:19749}
750
751void LayerAnimator::ImmediatelyAnimateToNewTarget(
752 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41753 // Need to detect if our sequence gets destroyed.
754 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
755 sequence->AsWeakPtr();
756
[email protected]b4db9372011-10-24 14:44:19757 const bool abort = true;
758 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19759 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41760 return;
761
[email protected]b4db9372011-10-24 14:44:19762 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19763 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41764 return;
765
[email protected]b4db9372011-10-24 14:44:19766 StartSequenceImmediately(sequence);
767}
768
769void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
770 // It is assumed that if there was no conflicting animation, we would
771 // not have been called. No need to check for a collision; just
772 // add to the queue.
Ian Vollick37e51bd12018-12-18 14:32:09773 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19774 ProcessQueue();
775}
776
777void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41778 // Need to detect if our sequence gets destroyed.
779 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
780 sequence->AsWeakPtr();
781
[email protected]b4db9372011-10-24 14:44:19782 // Remove all animations that aren't running. Note: at each iteration i is
783 // incremented or an element is removed from the queue, so
784 // animation_queue_.size() - i is always decreasing and we are always making
785 // progress towards the loop terminating.
786 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19787 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41788 break;
789
790 PurgeDeletedAnimations();
791
[email protected]b4db9372011-10-24 14:44:19792 bool is_running = false;
793 for (RunningAnimations::const_iterator iter = running_animations_.begin();
794 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41795 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19796 is_running = true;
797 break;
798 }
799 }
[email protected]a48f30d2012-10-30 00:35:41800
[email protected]b4db9372011-10-24 14:44:19801 if (!is_running)
[email protected]300548c2012-06-17 08:54:55802 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19803 else
804 ++i;
805 }
Ian Vollick37e51bd12018-12-18 14:32:09806 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19807 ProcessQueue();
808}
809
810void LayerAnimator::ProcessQueue() {
811 bool started_sequence = false;
812 do {
813 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19814 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24815 LayerAnimationElement::AnimatableProperties animated =
816 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19817 for (RunningAnimations::const_iterator iter = running_animations_.begin();
818 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41819 if (!(*iter).is_sequence_alive())
820 continue;
[email protected]e03193d2014-01-14 03:10:24821
822 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19823 }
824
825 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08826 // property or a property that will be animated before it. Note: starting
827 // the animation may indirectly cause more animations to be started, so we
828 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41829 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19830 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08831 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41832 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08833
834 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19835 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41836 continue;
837
[email protected]712f4b642013-03-14 07:09:15838 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41839 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19840 started_sequence = true;
841 break;
842 }
843
844 // Animation couldn't be started. Add its properties to the collection so
845 // that we don't start a conflicting animation. For example, if our queue
846 // has the elements { {T,B}, {B} } (that is, an element that animates both
847 // the transform and the bounds followed by an element that animates the
848 // bounds), and we're currently animating the transform, we can't start
849 // the first element because it animates the transform, too. We cannot
850 // start the second element, either, because the first element animates
851 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24852 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19853 }
854
855 // If we started a sequence, try again. We may be able to start several.
856 } while (started_sequence);
857}
858
859bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41860 PurgeDeletedAnimations();
861
[email protected]b4db9372011-10-24 14:44:19862 // Ensure that no one is animating one of the sequence's properties already.
863 for (RunningAnimations::const_iterator iter = running_animations_.begin();
864 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15865 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19866 return false;
867 }
868
charliea3be839702015-01-26 17:35:41869 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47870 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19871 // last_tick_time() from there to ensure animations started during the same
872 // event complete at the same time.
873 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47874 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59875 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19876 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47877 else if (collection && collection->HasActiveAnimators())
878 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19879 else
abhishek.ka7215854d2015-05-26 06:13:17880 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19881
[email protected]bf912272013-02-23 01:54:16882 if (!sequence->animation_group_id())
883 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
bruthig4a12c2b2016-11-05 00:19:18884
[email protected]a48f30d2012-10-30 00:35:41885 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38886 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19887
888 // Need to keep a reference to the animation.
889 AddToQueueIfNotPresent(sequence);
890
bruthig4a12c2b2016-11-05 00:19:18891 if (!sequence->waiting_for_group_start() ||
wutao914b06e62017-09-28 17:41:15892 sequence->IsFirstElementThreaded(delegate_)) {
bruthig4a12c2b2016-11-05 00:19:18893 sequence->set_start_time(start_time);
894 sequence->Start(delegate());
895 }
896
[email protected]b4db9372011-10-24 14:44:19897 // Ensure that animations get stepped at their start time.
898 Step(start_time);
899
900 return true;
[email protected]710a98d2011-06-23 20:13:29901}
902
[email protected]fe7074c62011-10-28 15:22:54903void LayerAnimator::GetTargetValue(
904 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13905 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
906 iter != animation_queue_.end(); ++iter) {
907 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54908 }
909}
910
[email protected]e876c272011-11-02 16:42:45911void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
Allen Bauer8a3cd652021-09-13 22:20:03912 sequence_scheduled_callbacks_.Notify(sequence);
dchengd38152e2016-10-13 18:21:37913 for (LayerAnimationObserver& observer : observers_)
914 sequence->AddObserver(&observer);
[email protected]e876c272011-11-02 16:42:45915 sequence->OnScheduled();
916}
917
[email protected]0d316252014-01-20 15:31:19918void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
919 if (is_transition_duration_locked_)
920 return;
921 transition_duration_ = duration;
[email protected]9861f1752012-06-01 07:16:14922}
923
[email protected]5d86a112012-09-23 00:21:58924void LayerAnimator::ClearAnimationsInternal() {
[email protected]a48f30d2012-10-30 00:35:41925 PurgeDeletedAnimations();
926
[email protected]5d86a112012-09-23 00:21:58927 // Abort should never affect the set of running animations, but just in case
928 // clients are badly behaved, we will use a copy of the running animations.
929 RunningAnimations running_animations_copy = running_animations_;
930 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41931 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]5d86a112012-09-23 00:21:58932 continue;
933
danakj25c52c32016-04-12 21:51:08934 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41935 RemoveAnimation(running_animations_copy[i].sequence()));
[email protected]5d86a112012-09-23 00:21:58936 if (removed.get())
[email protected]bf912272013-02-23 01:54:16937 removed->Abort(delegate());
[email protected]5d86a112012-09-23 00:21:58938 }
939 // This *should* have cleared the list of running animations.
940 DCHECK(running_animations_.empty());
941 running_animations_.clear();
942 animation_queue_.clear();
943 UpdateAnimationState();
944}
945
[email protected]a48f30d2012-10-30 00:35:41946void LayerAnimator::PurgeDeletedAnimations() {
947 for (size_t i = 0; i < running_animations_.size();) {
948 if (!running_animations_[i].is_sequence_alive())
949 running_animations_.erase(running_animations_.begin() + i);
950 else
951 i++;
952 }
953}
954
[email protected]9034a282014-06-05 03:11:47955LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
Bartek Nowierskieb07a5e2020-06-03 06:45:17956 return delegate_ ? delegate_->GetLayerAnimatorCollection() : nullptr;
[email protected]9034a282014-06-05 03:11:47957}
958
Ian Vollickba1f85922017-07-21 18:10:03959void LayerAnimator::NotifyAnimationStarted(base::TimeTicks monotonic_time,
960 int target_property,
961 int group) {
962 OnThreadedAnimationStarted(
963 monotonic_time, static_cast<cc::TargetProperty::Type>(target_property),
964 group);
loyso1fbd9f92015-12-17 07:43:13965}
966
[email protected]a48f30d2012-10-30 00:35:41967LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38968 const base::WeakPtr<LayerAnimationSequence>& sequence)
969 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41970}
971
vmpstr0ae825e72016-02-25 20:31:31972LayerAnimator::RunningAnimation::RunningAnimation(
973 const RunningAnimation& other) = default;
974
[email protected]a48f30d2012-10-30 00:35:41975LayerAnimator::RunningAnimation::~RunningAnimation() { }
976
[email protected]710a98d2011-06-23 20:13:29977} // namespace ui