blob: d41e09149f271a2d472932ae47f2b213b744f348 [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2012 The Chromium Authors
[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"
David Sandersde5fee542022-03-23 02:47:4413#include "base/observer_list.h"
ssid334fb87a2015-01-27 20:12:0714#include "base/trace_event/trace_event.h"
Yi Gub0422c42020-01-13 17:00:3615#include "cc/animation/animation.h"
loyso3338dfb2016-03-09 03:07:3216#include "cc/animation/animation_host.h"
[email protected]95e4e1a02013-03-18 07:09:0917#include "cc/animation/animation_id_provider.h"
loyso841229002015-12-21 10:03:2418#include "cc/animation/animation_timeline.h"
19#include "cc/animation/element_animations.h"
Fady Samuelc296f5fb2017-07-21 04:02:1920#include "components/viz/common/frame_sinks/begin_frame_args.h"
[email protected]116302fc2012-05-05 21:45:4121#include "ui/compositor/compositor.h"
22#include "ui/compositor/layer.h"
23#include "ui/compositor/layer_animation_delegate.h"
24#include "ui/compositor/layer_animation_observer.h"
25#include "ui/compositor/layer_animation_sequence.h"
[email protected]9034a282014-06-05 03:11:4726#include "ui/compositor/layer_animator_collection.h"
[email protected]0ed187e2011-10-21 20:07:4227
[email protected]a48f30d2012-10-30 00:35:4128#define SAFE_INVOKE_VOID(function, running_anim, ...) \
29 if (running_anim.is_sequence_alive()) \
30 function(running_anim.sequence(), ##__VA_ARGS__)
31#define SAFE_INVOKE_BOOL(function, running_anim) \
32 ((running_anim.is_sequence_alive()) \
33 ? function(running_anim.sequence()) \
34 : false)
Bartek Nowierskieb07a5e2020-06-03 06:45:1735#define SAFE_INVOKE_PTR(function, running_anim) \
36 ((running_anim.is_sequence_alive()) ? function(running_anim.sequence()) \
37 : nullptr)
[email protected]a48f30d2012-10-30 00:35:4138
[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)
Allen Bauer8a3cd652021-09-13 22:20:0350 : transition_duration_(transition_duration) {
Yi Gub0422c42020-01-13 17:00:3651 animation_ =
52 cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId());
[email protected]710a98d2011-06-23 20:13:2953}
54
55LayerAnimator::~LayerAnimator() {
[email protected]a48f30d2012-10-30 00:35:4156 for (size_t i = 0; i < running_animations_.size(); ++i) {
57 if (running_animations_[i].is_sequence_alive())
58 running_animations_[i].sequence()->OnAnimatorDestroyed();
59 }
[email protected]5d86a112012-09-23 00:21:5860 ClearAnimationsInternal();
Bartek Nowierskieb07a5e2020-06-03 06:45:1761 delegate_ = nullptr;
Yi Guaa830ff2018-02-22 03:09:1162 DCHECK(!animation_->animation_timeline());
[email protected]710a98d2011-06-23 20:13:2963}
64
[email protected]b4db9372011-10-24 14:44:1965// static
66LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
Peter Kastinge5a38ed2021-10-02 03:06:3567 return new LayerAnimator(base::Milliseconds(0));
[email protected]b4db9372011-10-24 14:44:1968}
69
70// static
71LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
Peter Kastinge5a38ed2021-10-02 03:06:3572 return new LayerAnimator(
73 base::Milliseconds(kLayerAnimatorDefaultTransitionDurationMs));
[email protected]b4db9372011-10-24 14:44:1974}
75
[email protected]7713e242012-11-15 17:43:1976// This macro provides the implementation for the setter and getter (well,
77// the getter of the target value) for an animated property. For example,
78// it is used for the implementations of SetTransform and GetTargetTransform.
79// It is worth noting that SetFoo avoids invoking the usual animation machinery
80// if the transition duration is zero -- in this case we just set the property
81// on the layer animation delegate immediately.
Francois Doray91e63fb72017-11-08 14:21:5282#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
83 void LayerAnimator::Set##name(type value) { \
84 base::TimeDelta duration = GetTransitionDuration(); \
85 if (duration.is_zero() && delegate() && \
86 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
David Black4304b5a2021-10-29 15:58:4587 /* Stopping an animation may result in destruction of `this`. */ \
88 const auto weak_ptr = weak_ptr_factory_.GetWeakPtr(); \
Francois Doray91e63fb72017-11-08 14:21:5289 StopAnimatingProperty(LayerAnimationElement::property); \
David Black4304b5a2021-10-29 15:58:4590 if (!weak_ptr || !delegate()) \
Toni Barzic8be24e0e22021-03-12 07:48:4291 return; \
Francois Doray91e63fb72017-11-08 14:21:5292 delegate()->Set##name##FromAnimation( \
93 value, PropertyChangeReason::NOT_FROM_ANIMATION); \
94 return; \
95 } \
96 std::unique_ptr<LayerAnimationElement> element = \
97 LayerAnimationElement::Create##name##Element(value, duration); \
98 element->set_tween_type(tween_type_); \
99 StartAnimation(new LayerAnimationSequence(std::move(element))); \
100 } \
101 \
102 member_type LayerAnimator::GetTarget##name() const { \
103 LayerAnimationElement::TargetValue target(delegate()); \
104 GetTargetValue(&target); \
105 return target.member; \
danakj25c52c32016-04-12 21:51:08106 }
[email protected]fe7074c62011-10-28 15:22:54107
Nico Weber3a6c6372019-02-21 14:26:18108ANIMATED_PROPERTY(const gfx::Transform&,
109 TRANSFORM,
110 Transform,
111 gfx::Transform,
112 transform)
113ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds)
114ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity)
115ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility)
116ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness)
117ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale)
118ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color)
Malay Keshavb8ac9e572019-07-03 00:26:55119ANIMATED_PROPERTY(const gfx::Rect&, CLIP, ClipRect, gfx::Rect, clip_rect)
Jun Mukaia343db33b2019-07-17 23:25:50120ANIMATED_PROPERTY(const gfx::RoundedCornersF&,
121 ROUNDED_CORNERS,
122 RoundedCorners,
123 gfx::RoundedCornersF,
124 rounded_corners)
Sasha McIntosh93a0e962022-03-31 20:02:41125ANIMATED_PROPERTY(const gfx::LinearGradient&,
126 GRADIENT_MASK,
127 GradientMask,
128 gfx::LinearGradient,
129 gradient_mask)
Nico Weber3a6c6372019-02-21 14:26:18130
131#undef ANIMATED_PROPERTY
[email protected]e81480f1f2012-10-11 23:06:45132
[email protected]0d316252014-01-20 15:31:19133base::TimeDelta LayerAnimator::GetTransitionDuration() const {
134 return transition_duration_;
135}
136
[email protected]e876c272011-11-02 16:42:45137void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
[email protected]9034a282014-06-05 03:11:47138 if (delegate_ && is_started_) {
139 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
140 if (collection)
141 collection->StopAnimator(this);
142 }
loyso1fbd9f92015-12-17 07:43:13143 SwitchToLayer(delegate ? delegate->GetCcLayer() : nullptr);
[email protected]b4db9372011-10-24 14:44:19144 delegate_ = delegate;
[email protected]9034a282014-06-05 03:11:47145 if (delegate_ && is_started_) {
146 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
147 if (collection)
148 collection->StartAnimator(this);
149 }
[email protected]b4db9372011-10-24 14:44:19150}
151
loyso1fbd9f92015-12-17 07:43:13152void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
loysoe2fed922016-03-09 04:41:55153 if (delegate_)
Yi Guaa830ff2018-02-22 03:09:11154 DetachLayerFromAnimation();
loysoe2fed922016-03-09 04:41:55155 if (new_layer)
Yi Guaa830ff2018-02-22 03:09:11156 AttachLayerToAnimation(new_layer->id());
loyso841229002015-12-21 10:03:24157}
158
loysocc8e3db2016-10-04 05:22:03159void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24160 DCHECK(compositor);
loyso841229002015-12-21 10:03:24161
loysoe2fed922016-03-09 04:41:55162 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
163 DCHECK(timeline);
Yi Guaa830ff2018-02-22 03:09:11164 timeline->AttachAnimation(animation_);
loysoe2fed922016-03-09 04:41:55165
loysocc8e3db2016-10-04 05:22:03166 DCHECK(delegate_->GetCcLayer());
Yi Guaa830ff2018-02-22 03:09:11167 AttachLayerToAnimation(delegate_->GetCcLayer()->id());
Xiyuan Xiaadecd672020-02-25 17:00:57168
169 for (auto& layer_animation_sequence : animation_queue_)
170 layer_animation_sequence->OnAnimatorAttached(delegate());
loyso841229002015-12-21 10:03:24171}
172
loysocc8e3db2016-10-04 05:22:03173void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
loyso841229002015-12-21 10:03:24174 DCHECK(compositor);
loyso3338dfb2016-03-09 03:07:32175
loysode0a0022016-04-15 02:28:38176 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
177 DCHECK(timeline);
178
Yi Guaa830ff2018-02-22 03:09:11179 DetachLayerFromAnimation();
180 timeline->DetachAnimation(animation_);
Xiyuan Xiaadecd672020-02-25 17:00:57181
182 for (auto& layer_animation_sequence : animation_queue_)
183 layer_animation_sequence->OnAnimatorDetached();
loyso841229002015-12-21 10:03:24184}
185
Yi Guaa830ff2018-02-22 03:09:11186void LayerAnimator::AttachLayerToAnimation(int layer_id) {
vollickef2ae922016-06-29 17:54:27187 // For ui, layer and element ids are equivalent.
chrishtrc3daf272017-05-11 11:08:02188 cc::ElementId element_id(layer_id);
Yi Guaa830ff2018-02-22 03:09:11189 if (!animation_->element_id())
190 animation_->AttachElement(element_id);
loyso841229002015-12-21 10:03:24191 else
Yi Guaa830ff2018-02-22 03:09:11192 DCHECK_EQ(animation_->element_id(), element_id);
loyso841229002015-12-21 10:03:24193
Yi Guaa830ff2018-02-22 03:09:11194 animation_->set_animation_delegate(this);
loyso841229002015-12-21 10:03:24195}
196
Yi Guaa830ff2018-02-22 03:09:11197void LayerAnimator::DetachLayerFromAnimation() {
198 animation_->set_animation_delegate(nullptr);
loyso841229002015-12-21 10:03:24199
Yi Guaa830ff2018-02-22 03:09:11200 if (animation_->element_id())
201 animation_->DetachElement();
loyso841229002015-12-21 10:03:24202}
203
Yi Gu4e1dce32018-07-04 20:52:15204void LayerAnimator::AddThreadedAnimation(
205 std::unique_ptr<cc::KeyframeModel> animation) {
206 animation_->AddKeyframeModel(std::move(animation));
loyso841229002015-12-21 10:03:24207}
208
Yi Gu4e1dce32018-07-04 20:52:15209void LayerAnimator::RemoveThreadedAnimation(int keyframe_model_id) {
210 animation_->RemoveKeyframeModel(keyframe_model_id);
loyso1fbd9f92015-12-17 07:43:13211}
212
Yi Gub0422c42020-01-13 17:00:36213cc::Animation* LayerAnimator::GetAnimationForTesting() const {
Yi Guaa830ff2018-02-22 03:09:11214 return animation_.get();
loysod4127442016-02-03 02:29:40215}
216
[email protected]b4db9372011-10-24 14:44:19217void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58218 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45219 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19220 if (!StartSequenceImmediately(animation)) {
221 // Attempt to preempt a running animation.
222 switch (preemption_strategy_) {
223 case IMMEDIATELY_SET_NEW_TARGET:
224 ImmediatelySetNewTarget(animation);
225 break;
226 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
227 ImmediatelyAnimateToNewTarget(animation);
228 break;
229 case ENQUEUE_NEW_ANIMATION:
230 EnqueueNewAnimation(animation);
231 break;
232 case REPLACE_QUEUED_ANIMATIONS:
233 ReplaceQueuedAnimations(animation);
234 break;
[email protected]7fca53d42011-09-29 15:38:12235 }
[email protected]b4db9372011-10-24 14:44:19236 }
237 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54238 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19239}
240
241void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58242 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c272011-11-02 16:42:45243 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19244 if (is_animating()) {
Ian Vollick37e51bd12018-12-18 14:32:09245 animation_queue_.push_back(
246 std::unique_ptr<LayerAnimationSequence>(animation));
[email protected]b4db9372011-10-24 14:44:19247 ProcessQueue();
248 } else {
249 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12250 }
[email protected]fe7074c62011-10-28 15:22:54251 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29252}
253
[email protected]d064ef82012-11-13 10:26:59254void LayerAnimator::StartTogether(
255 const std::vector<LayerAnimationSequence*>& animations) {
256 scoped_refptr<LayerAnimator> retain(this);
257 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
258 std::vector<LayerAnimationSequence*>::const_iterator iter;
259 for (iter = animations.begin(); iter != animations.end(); ++iter) {
260 StartAnimation(*iter);
261 }
262 return;
263 }
[email protected]d764fd3d2012-11-15 20:07:51264
[email protected]d064ef82012-11-13 10:26:59265 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51266 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47267 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
268 if (collection && collection->HasActiveAnimators())
269 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51270 else
abhishek.ka7215854d2015-05-26 06:13:17271 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51272 }
[email protected]d064ef82012-11-13 10:26:59273
274 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24275 LayerAnimationElement::AnimatableProperties animated_properties =
276 LayerAnimationElement::UNKNOWN;
277
[email protected]d064ef82012-11-13 10:26:59278 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24279 for (iter = animations.begin(); iter != animations.end(); ++iter)
280 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59281
282 // Starting a zero duration pause that affects all the animated properties
283 // will prevent any of the sequences from animating until there are no
284 // running animations that affect any of these properties, as well as
285 // handle preemption strategy.
286 StartAnimation(new LayerAnimationSequence(
287 LayerAnimationElement::CreatePauseElement(animated_properties,
288 base::TimeDelta())));
289
[email protected]bf912272013-02-23 01:54:16290 bool wait_for_group_start = false;
291 for (iter = animations.begin(); iter != animations.end(); ++iter)
Robert Flack763bb3a12022-08-12 17:41:17292 wait_for_group_start |=
293 delegate_ && (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16294 int group_id = cc::AnimationIdProvider::NextGroupId();
295
[email protected]d064ef82012-11-13 10:26:59296 // These animations (provided they don't animate any common properties) will
297 // now animate together if trivially scheduled.
298 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16299 (*iter)->set_animation_group_id(group_id);
300 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59301 ScheduleAnimation(*iter);
302 }
303
304 adding_animations_ = false;
305 UpdateAnimationState();
306}
307
308
[email protected]b4db9372011-10-24 14:44:19309void LayerAnimator::ScheduleTogether(
310 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58311 scoped_refptr<LayerAnimator> retain(this);
312
[email protected]b4db9372011-10-24 14:44:19313 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24314 LayerAnimationElement::AnimatableProperties animated_properties =
315 LayerAnimationElement::UNKNOWN;
316
[email protected]b4db9372011-10-24 14:44:19317 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24318 for (iter = animations.begin(); iter != animations.end(); ++iter)
319 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29320
[email protected]b4db9372011-10-24 14:44:19321 // Scheduling a zero duration pause that affects all the animated properties
322 // will prevent any of the sequences from animating until there are no
323 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31324 ScheduleAnimation(new LayerAnimationSequence(
325 LayerAnimationElement::CreatePauseElement(animated_properties,
326 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29327
[email protected]bf912272013-02-23 01:54:16328 bool wait_for_group_start = false;
329 for (iter = animations.begin(); iter != animations.end(); ++iter)
Robert Flack763bb3a12022-08-12 17:41:17330 wait_for_group_start |=
331 delegate_ && (*iter)->IsFirstElementThreaded(delegate_);
[email protected]bf912272013-02-23 01:54:16332
333 int group_id = cc::AnimationIdProvider::NextGroupId();
334
[email protected]b4db9372011-10-24 14:44:19335 // These animations (provided they don't animate any common properties) will
336 // now animate together if trivially scheduled.
337 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16338 (*iter)->set_animation_group_id(group_id);
339 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19340 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29341 }
[email protected]fe7074c62011-10-28 15:22:54342
343 UpdateAnimationState();
344}
345
[email protected]2a88c702012-09-04 23:15:02346void LayerAnimator::SchedulePauseForProperties(
347 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24348 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02349 ScheduleAnimation(new ui::LayerAnimationSequence(
350 ui::LayerAnimationElement::CreatePauseElement(
351 properties_to_pause, duration)));
352}
353
Francois Dorayeef012b62017-10-26 20:02:59354bool LayerAnimator::IsAnimatingOnePropertyOf(
355 LayerAnimationElement::AnimatableProperties properties) const {
356 for (auto& layer_animation_sequence : animation_queue_) {
357 if (layer_animation_sequence->properties() & properties)
[email protected]e876c272011-11-02 16:42:45358 return true;
[email protected]e876c272011-11-02 16:42:45359 }
360 return false;
[email protected]7fca53d42011-09-29 15:38:12361}
362
[email protected]b4db9372011-10-24 14:44:19363void LayerAnimator::StopAnimatingProperty(
364 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58365 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19366 while (true) {
[email protected]a48f30d2012-10-30 00:35:41367 // GetRunningAnimation purges deleted animations before searching, so we are
368 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19369 RunningAnimation* running = GetRunningAnimation(property);
370 if (!running)
371 break;
[email protected]a48f30d2012-10-30 00:35:41372 // As was mentioned above, this sequence must be alive.
373 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14374 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41375 }
[email protected]b4db9372011-10-24 14:44:19376}
377
[email protected]e876c272011-11-02 16:42:45378void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
Francois Doray29ecd3aa2017-11-07 15:40:18379 if (!observers_.HasObserver(observer)) {
[email protected]e876c272011-11-02 16:42:45380 observers_.AddObserver(observer);
Francois Doray29ecd3aa2017-11-07 15:40:18381 for (auto& layer_animation_sequence : animation_queue_)
382 layer_animation_sequence->AddObserver(observer);
383 }
[email protected]e876c272011-11-02 16:42:45384}
385
386void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
387 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54388 // Remove the observer from all sequences as well.
389 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
390 queue_iter != animation_queue_.end(); ++queue_iter) {
391 (*queue_iter)->RemoveObserver(observer);
392 }
[email protected]e876c272011-11-02 16:42:45393}
394
wutao4f1c0d5d2017-10-05 01:02:43395void LayerAnimator::AddOwnedObserver(
396 std::unique_ptr<ImplicitAnimationObserver> animation_observer) {
397 owned_observer_list_.push_back(std::move(animation_observer));
398}
399
400void LayerAnimator::RemoveAndDestroyOwnedObserver(
401 ImplicitAnimationObserver* animation_observer) {
JungHoon Lee897c21ef2018-08-27 20:18:17402 base::EraseIf(owned_observer_list_,[animation_observer](
403 const std::unique_ptr<ImplicitAnimationObserver>& other) {
404 return other.get() == animation_observer;
405 });
wutao4f1c0d5d2017-10-05 01:02:43406}
407
Allen Bauer8a3cd652021-09-13 22:20:03408base::CallbackListSubscription LayerAnimator::AddSequenceScheduledCallback(
409 SequenceScheduledCallback callback) {
410 return sequence_scheduled_callbacks_.Add(std::move(callback));
411}
412
[email protected]bf912272013-02-23 01:54:16413void LayerAnimator::OnThreadedAnimationStarted(
loyso79c0bfc2016-04-18 23:46:42414 base::TimeTicks monotonic_time,
415 cc::TargetProperty::Type target_property,
416 int group_id) {
[email protected]bf912272013-02-23 01:54:16417 LayerAnimationElement::AnimatableProperty property =
loyso79c0bfc2016-04-18 23:46:42418 LayerAnimationElement::ToAnimatableProperty(target_property);
[email protected]bf912272013-02-23 01:54:16419
420 RunningAnimation* running = GetRunningAnimation(property);
421 if (!running)
422 return;
423 DCHECK(running->is_sequence_alive());
424
loyso79c0bfc2016-04-18 23:46:42425 if (running->sequence()->animation_group_id() != group_id)
[email protected]bf912272013-02-23 01:54:16426 return;
427
loyso79c0bfc2016-04-18 23:46:42428 running->sequence()->OnThreadedAnimationStarted(monotonic_time,
429 target_property, group_id);
[email protected]bf912272013-02-23 01:54:16430 if (!running->sequence()->waiting_for_group_start())
431 return;
432
loyso79c0bfc2016-04-18 23:46:42433 base::TimeTicks start_time = monotonic_time;
[email protected]bf912272013-02-23 01:54:16434
435 running->sequence()->set_waiting_for_group_start(false);
436
437 // The call to GetRunningAnimation made above already purged deleted
438 // animations, so we are guaranteed that all the animations we iterate
439 // over now are alive.
jdoerriedcef4b12018-10-10 12:04:32440 for (auto iter = running_animations_.begin();
[email protected]bf912272013-02-23 01:54:16441 iter != running_animations_.end(); ++iter) {
442 // Ensure that each sequence is only Started once, regardless of the
443 // number of sequences in the group that have threaded first elements.
loyso79c0bfc2016-04-18 23:46:42444 if (((*iter).sequence()->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15445 !(*iter).sequence()->IsFirstElementThreaded(delegate_) &&
[email protected]bf912272013-02-23 01:54:16446 (*iter).sequence()->waiting_for_group_start()) {
447 (*iter).sequence()->set_start_time(start_time);
448 (*iter).sequence()->set_waiting_for_group_start(false);
449 (*iter).sequence()->Start(delegate());
450 }
451 }
452}
453
[email protected]9034a282014-06-05 03:11:47454void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
L. David Baron138321d2022-05-24 22:30:24455 DCHECK_EQ(collection, GetLayerAnimatorCollection());
[email protected]9034a282014-06-05 03:11:47456 if (is_animating() && !is_started_) {
457 collection->StartAnimator(this);
458 is_started_ = true;
459 }
460}
461
462void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
L. David Baron138321d2022-05-24 22:30:24463 DCHECK_EQ(collection, GetLayerAnimatorCollection());
bruthig33b1edab2016-03-02 02:22:35464 if (is_started_) {
[email protected]9034a282014-06-05 03:11:47465 collection->StopAnimator(this);
466 is_started_ = false;
467 }
L. David Baron138321d2022-05-24 22:30:24468 DCHECK(!animation_->element_animations() ||
469 !animation_->element_animations()->HasTickingKeyframeEffect());
[email protected]9034a282014-06-05 03:11:47470}
471
[email protected]d59a3692012-04-10 20:27:31472// LayerAnimator protected -----------------------------------------------------
473
[email protected]5d86a112012-09-23 00:21:58474void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38475 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16476 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58477 return;
478
[email protected]3d75fed2012-12-15 18:47:38479 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31480}
481
[email protected]a48f30d2012-10-30 00:35:41482void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30483 if (!delegate())
484 return;
485
486 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41487}
488
[email protected]d59a3692012-04-10 20:27:31489bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
490 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
491 queue_iter != animation_queue_.end(); ++queue_iter) {
492 if ((*queue_iter).get() == sequence)
493 return true;
494 }
495 return false;
496}
497
[email protected]b4db9372011-10-24 14:44:19498// LayerAnimator private -------------------------------------------------------
499
500void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31501 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58502 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31503
[email protected]b4db9372011-10-24 14:44:19504 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19505
[email protected]a48f30d2012-10-30 00:35:41506 PurgeDeletedAnimations();
507
[email protected]f5cd9e52011-11-03 21:38:08508 // We need to make a copy of the running animations because progressing them
509 // and finishing them may indirectly affect the collection of running
510 // animations.
511 RunningAnimations running_animations_copy = running_animations_;
512 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41513 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31514 continue;
515
[email protected]3d75fed2012-12-15 18:47:38516 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14517 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
518 } else {
[email protected]3d75fed2012-12-15 18:47:38519 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14520 }
[email protected]b4db9372011-10-24 14:44:19521 }
[email protected]b4db9372011-10-24 14:44:19522}
523
[email protected]6f110e42012-12-18 00:21:14524void LayerAnimator::StopAnimatingInternal(bool abort) {
525 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55526 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14527 // We're going to attempt to finish the first running animation. Let's
528 // ensure that it's valid.
529 PurgeDeletedAnimations();
530
531 // If we've purged all running animations, attempt to start one up.
532 if (running_animations_.empty())
533 ProcessQueue();
534
535 DCHECK(!running_animations_.empty());
536
537 // Still no luck, let's just bail and clear all animations.
538 if (running_animations_.empty()) {
539 ClearAnimationsInternal();
540 break;
541 }
542
543 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
544 }
545}
546
[email protected]b4db9372011-10-24 14:44:19547void LayerAnimator::UpdateAnimationState() {
548 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12549 return;
550
[email protected]b4db9372011-10-24 14:44:19551 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47552 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
553 if (collection) {
554 if (should_start && !is_started_)
555 collection->StartAnimator(this);
556 else if (!should_start && is_started_)
557 collection->StopAnimator(this);
558 is_started_ = should_start;
559 } else {
560 is_started_ = false;
561 }
[email protected]710a98d2011-06-23 20:13:29562}
563
[email protected]f5cd9e52011-11-03 21:38:08564LayerAnimationSequence* LayerAnimator::RemoveAnimation(
565 LayerAnimationSequence* sequence) {
Ian Vollick37e51bd12018-12-18 14:32:09566 std::unique_ptr<LayerAnimationSequence> to_return;
[email protected]f5cd9e52011-11-03 21:38:08567
[email protected]bf912272013-02-23 01:54:16568 bool is_running = false;
569
[email protected]f5cd9e52011-11-03 21:38:08570 // First remove from running animations
jdoerriedcef4b12018-10-10 12:04:32571 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19572 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41573 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19574 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16575 is_running = true;
[email protected]b4db9372011-10-24 14:44:19576 break;
[email protected]21445e472011-10-21 20:36:32577 }
578 }
[email protected]b4db9372011-10-24 14:44:19579
580 // Then remove from the queue
581 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
582 queue_iter != animation_queue_.end(); ++queue_iter) {
Ian Vollick37e51bd12018-12-18 14:32:09583 if (queue_iter->get() == sequence) {
584 to_return = std::move(*queue_iter);
[email protected]b4db9372011-10-24 14:44:19585 animation_queue_.erase(queue_iter);
586 break;
587 }
588 }
[email protected]f5cd9e52011-11-03 21:38:08589
Elaine Chiena2c1d702021-09-08 22:50:38590 // Do not continue and attempt to start other sequences if the delegate is
591 // nullptr.
592 // TODO(crbug.com/1247769): Guard other uses of delegate_ in this class.
593 if (!delegate())
594 return to_return.release();
595
wutao914b06e62017-09-28 17:41:15596 if (!to_return.get() || !to_return->waiting_for_group_start() ||
597 !to_return->IsFirstElementThreaded(delegate_))
[email protected]bf912272013-02-23 01:54:16598 return to_return.release();
599
600 // The removed sequence may have been responsible for making other sequences
601 // wait for a group start. If no other sequences in the group have a
602 // threaded first element, the group no longer needs the additional wait.
603 bool is_wait_still_needed = false;
604 int group_id = to_return->animation_group_id();
605 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
606 queue_iter != animation_queue_.end(); ++queue_iter) {
607 if (((*queue_iter)->animation_group_id() == group_id) &&
wutao914b06e62017-09-28 17:41:15608 (*queue_iter)->IsFirstElementThreaded(delegate_)) {
[email protected]bf912272013-02-23 01:54:16609 is_wait_still_needed = true;
610 break;
611 }
612 }
613
614 if (is_wait_still_needed)
615 return to_return.release();
616
617 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
618 queue_iter != animation_queue_.end(); ++queue_iter) {
619 if ((*queue_iter)->animation_group_id() == group_id &&
620 (*queue_iter)->waiting_for_group_start()) {
621 (*queue_iter)->set_waiting_for_group_start(false);
622 if (is_running) {
623 (*queue_iter)->set_start_time(last_step_time_);
624 (*queue_iter)->Start(delegate());
625 }
626 }
627 }
[email protected]f5cd9e52011-11-03 21:38:08628 return to_return.release();
[email protected]0ed187e2011-10-21 20:07:42629}
630
[email protected]6f110e42012-12-18 00:21:14631void LayerAnimator::FinishAnimation(
632 LayerAnimationSequence* sequence, bool abort) {
[email protected]5d86a112012-09-23 00:21:58633 scoped_refptr<LayerAnimator> retain(this);
danakj25c52c32016-04-12 21:51:08634 std::unique_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
[email protected]6f110e42012-12-18 00:21:14635 if (abort)
[email protected]bf912272013-02-23 01:54:16636 sequence->Abort(delegate());
[email protected]6f110e42012-12-18 00:21:14637 else
638 ProgressAnimationToEnd(sequence);
ljagielski20570982015-01-07 20:32:55639 if (!delegate())
640 return;
[email protected]b4db9372011-10-24 14:44:19641 ProcessQueue();
642 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32643}
[email protected]0ed187e2011-10-21 20:07:42644
[email protected]b4db9372011-10-24 14:44:19645void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
[email protected]5d86a112012-09-23 00:21:58646 scoped_refptr<LayerAnimator> retain(this);
[email protected]2ddfe432011-11-07 19:26:30647 // Special case: if we've started a 0 duration animation, just finish it now
648 // and get rid of it. We need to make a copy because Progress may indirectly
649 // cause new animations to start running.
[email protected]f5cd9e52011-11-03 21:38:08650 RunningAnimations running_animations_copy = running_animations_;
651 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41652 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31653 continue;
654
[email protected]3d75fed2012-12-15 18:47:38655 if (running_animations_copy[i].sequence()->IsFinished(
656 running_animations_copy[i].sequence()->start_time())) {
[email protected]a48f30d2012-10-30 00:35:41657 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
danakj25c52c32016-04-12 21:51:08658 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41659 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]b4db9372011-10-24 14:44:19660 }
661 }
662 ProcessQueue();
663 UpdateAnimationState();
[email protected]21445e472011-10-21 20:36:32664}
[email protected]0ed187e2011-10-21 20:07:42665
[email protected]b4db9372011-10-24 14:44:19666void LayerAnimator::ClearAnimations() {
[email protected]5d86a112012-09-23 00:21:58667 scoped_refptr<LayerAnimator> retain(this);
668 ClearAnimationsInternal();
[email protected]b4db9372011-10-24 14:44:19669}
670
671LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
672 LayerAnimationElement::AnimatableProperty property) {
[email protected]a48f30d2012-10-30 00:35:41673 PurgeDeletedAnimations();
jdoerriedcef4b12018-10-10 12:04:32674 for (auto iter = running_animations_.begin();
[email protected]b4db9372011-10-24 14:44:19675 iter != running_animations_.end(); ++iter) {
[email protected]e03193d2014-01-14 03:10:24676 if ((*iter).sequence()->properties() & property)
[email protected]b4db9372011-10-24 14:44:19677 return &(*iter);
678 }
Bartek Nowierskieb07a5e2020-06-03 06:45:17679 return nullptr;
[email protected]b4db9372011-10-24 14:44:19680}
681
682void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
683 // If we don't have the animation in the queue yet, add it.
684 bool found_sequence = false;
685 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
686 queue_iter != animation_queue_.end(); ++queue_iter) {
Ian Vollick37e51bd12018-12-18 14:32:09687 if (queue_iter->get() == animation) {
[email protected]b4db9372011-10-24 14:44:19688 found_sequence = true;
689 break;
690 }
691 }
692
Ian Vollick37e51bd12018-12-18 14:32:09693 if (!found_sequence) {
694 animation_queue_.push_front(
695 std::unique_ptr<LayerAnimationSequence>(animation));
696 }
[email protected]b4db9372011-10-24 14:44:19697}
698
699void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08700 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19701 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08702 // progress them to the end and remove them. Note, Aborting or Progressing
703 // animations may affect the collection of running animations, so we need to
704 // operate on a copy.
705 RunningAnimations running_animations_copy = running_animations_;
706 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41707 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31708 continue;
709
[email protected]712f4b642013-03-14 07:09:15710 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19711 sequence->properties())) {
danakj25c52c32016-04-12 21:51:08712 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41713 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08714 if (abort)
[email protected]bf912272013-02-23 01:54:16715 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08716 else
[email protected]a48f30d2012-10-30 00:35:41717 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19718 }
719 }
720
[email protected]f5cd9e52011-11-03 21:38:08721 // Same for the queued animations that haven't been started. Again, we'll
722 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41723 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08724 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
725 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41726 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08727
728 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19729 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31730 continue;
731
[email protected]712f4b642013-03-14 07:09:15732 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
danakj25c52c32016-04-12 21:51:08733 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]7ffde472013-06-04 06:42:19734 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19735 if (abort)
[email protected]bf912272013-02-23 01:54:16736 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19737 else
[email protected]7ffde472013-06-04 06:42:19738 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19739 }
740 }
741}
742
743void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41744 // Need to detect if our sequence gets destroyed.
745 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
746 sequence->AsWeakPtr();
747
[email protected]b4db9372011-10-24 14:44:19748 const bool abort = false;
749 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19750 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41751 return;
752
[email protected]d3ba37ab2012-02-09 19:53:13753 LayerAnimationSequence* removed = RemoveAnimation(sequence);
Bartek Nowierskieb07a5e2020-06-03 06:45:17754 DCHECK(removed == nullptr || removed == 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]4a386e42012-12-05 01:19:30758 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19759 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41760 return;
761
762 delete sequence;
[email protected]b4db9372011-10-24 14:44:19763}
764
765void LayerAnimator::ImmediatelyAnimateToNewTarget(
766 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41767 // Need to detect if our sequence gets destroyed.
768 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
769 sequence->AsWeakPtr();
770
[email protected]b4db9372011-10-24 14:44:19771 const bool abort = true;
772 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19773 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41774 return;
775
[email protected]b4db9372011-10-24 14:44:19776 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19777 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41778 return;
779
[email protected]b4db9372011-10-24 14:44:19780 StartSequenceImmediately(sequence);
781}
782
783void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
784 // It is assumed that if there was no conflicting animation, we would
785 // not have been called. No need to check for a collision; just
786 // add to the queue.
Ian Vollick37e51bd12018-12-18 14:32:09787 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19788 ProcessQueue();
789}
790
791void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41792 // Need to detect if our sequence gets destroyed.
793 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
794 sequence->AsWeakPtr();
795
[email protected]b4db9372011-10-24 14:44:19796 // Remove all animations that aren't running. Note: at each iteration i is
797 // incremented or an element is removed from the queue, so
798 // animation_queue_.size() - i is always decreasing and we are always making
799 // progress towards the loop terminating.
800 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19801 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41802 break;
803
804 PurgeDeletedAnimations();
805
[email protected]b4db9372011-10-24 14:44:19806 bool is_running = false;
807 for (RunningAnimations::const_iterator iter = running_animations_.begin();
808 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41809 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19810 is_running = true;
811 break;
812 }
813 }
[email protected]a48f30d2012-10-30 00:35:41814
[email protected]b4db9372011-10-24 14:44:19815 if (!is_running)
[email protected]300548c2012-06-17 08:54:55816 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19817 else
818 ++i;
819 }
Ian Vollick37e51bd12018-12-18 14:32:09820 animation_queue_.push_back(std::unique_ptr<LayerAnimationSequence>(sequence));
[email protected]b4db9372011-10-24 14:44:19821 ProcessQueue();
822}
823
824void LayerAnimator::ProcessQueue() {
825 bool started_sequence = false;
826 do {
827 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19828 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24829 LayerAnimationElement::AnimatableProperties animated =
830 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19831 for (RunningAnimations::const_iterator iter = running_animations_.begin();
832 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41833 if (!(*iter).is_sequence_alive())
834 continue;
[email protected]e03193d2014-01-14 03:10:24835
836 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19837 }
838
839 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08840 // property or a property that will be animated before it. Note: starting
841 // the animation may indirectly cause more animations to be started, so we
842 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41843 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19844 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08845 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41846 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08847
848 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19849 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41850 continue;
851
[email protected]712f4b642013-03-14 07:09:15852 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41853 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19854 started_sequence = true;
855 break;
856 }
857
858 // Animation couldn't be started. Add its properties to the collection so
859 // that we don't start a conflicting animation. For example, if our queue
860 // has the elements { {T,B}, {B} } (that is, an element that animates both
861 // the transform and the bounds followed by an element that animates the
862 // bounds), and we're currently animating the transform, we can't start
863 // the first element because it animates the transform, too. We cannot
864 // start the second element, either, because the first element animates
865 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24866 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19867 }
868
869 // If we started a sequence, try again. We may be able to start several.
870 } while (started_sequence);
871}
872
873bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41874 PurgeDeletedAnimations();
875
[email protected]b4db9372011-10-24 14:44:19876 // Ensure that no one is animating one of the sequence's properties already.
877 for (RunningAnimations::const_iterator iter = running_animations_.begin();
878 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15879 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19880 return false;
881 }
882
charliea3be839702015-01-26 17:35:41883 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47884 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19885 // last_tick_time() from there to ensure animations started during the same
886 // event complete at the same time.
887 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47888 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59889 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19890 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47891 else if (collection && collection->HasActiveAnimators())
892 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19893 else
abhishek.ka7215854d2015-05-26 06:13:17894 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19895
[email protected]bf912272013-02-23 01:54:16896 if (!sequence->animation_group_id())
897 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
bruthig4a12c2b2016-11-05 00:19:18898
[email protected]a48f30d2012-10-30 00:35:41899 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38900 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19901
902 // Need to keep a reference to the animation.
903 AddToQueueIfNotPresent(sequence);
904
bruthig4a12c2b2016-11-05 00:19:18905 if (!sequence->waiting_for_group_start() ||
wutao914b06e62017-09-28 17:41:15906 sequence->IsFirstElementThreaded(delegate_)) {
bruthig4a12c2b2016-11-05 00:19:18907 sequence->set_start_time(start_time);
908 sequence->Start(delegate());
909 }
910
[email protected]b4db9372011-10-24 14:44:19911 // Ensure that animations get stepped at their start time.
912 Step(start_time);
913
914 return true;
[email protected]710a98d2011-06-23 20:13:29915}
916
[email protected]fe7074c62011-10-28 15:22:54917void LayerAnimator::GetTargetValue(
918 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13919 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
920 iter != animation_queue_.end(); ++iter) {
921 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54922 }
923}
924
[email protected]e876c272011-11-02 16:42:45925void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
Allen Bauer8a3cd652021-09-13 22:20:03926 sequence_scheduled_callbacks_.Notify(sequence);
dchengd38152e2016-10-13 18:21:37927 for (LayerAnimationObserver& observer : observers_)
928 sequence->AddObserver(&observer);
[email protected]e876c272011-11-02 16:42:45929 sequence->OnScheduled();
930}
931
[email protected]0d316252014-01-20 15:31:19932void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
933 if (is_transition_duration_locked_)
934 return;
935 transition_duration_ = duration;
[email protected]9861f1752012-06-01 07:16:14936}
937
[email protected]5d86a112012-09-23 00:21:58938void LayerAnimator::ClearAnimationsInternal() {
[email protected]a48f30d2012-10-30 00:35:41939 PurgeDeletedAnimations();
940
[email protected]5d86a112012-09-23 00:21:58941 // Abort should never affect the set of running animations, but just in case
942 // clients are badly behaved, we will use a copy of the running animations.
943 RunningAnimations running_animations_copy = running_animations_;
944 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41945 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]5d86a112012-09-23 00:21:58946 continue;
947
danakj25c52c32016-04-12 21:51:08948 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41949 RemoveAnimation(running_animations_copy[i].sequence()));
[email protected]5d86a112012-09-23 00:21:58950 if (removed.get())
[email protected]bf912272013-02-23 01:54:16951 removed->Abort(delegate());
[email protected]5d86a112012-09-23 00:21:58952 }
953 // This *should* have cleared the list of running animations.
954 DCHECK(running_animations_.empty());
955 running_animations_.clear();
956 animation_queue_.clear();
957 UpdateAnimationState();
958}
959
[email protected]a48f30d2012-10-30 00:35:41960void LayerAnimator::PurgeDeletedAnimations() {
961 for (size_t i = 0; i < running_animations_.size();) {
962 if (!running_animations_[i].is_sequence_alive())
963 running_animations_.erase(running_animations_.begin() + i);
964 else
965 i++;
966 }
967}
968
[email protected]9034a282014-06-05 03:11:47969LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
Bartek Nowierskieb07a5e2020-06-03 06:45:17970 return delegate_ ? delegate_->GetLayerAnimatorCollection() : nullptr;
[email protected]9034a282014-06-05 03:11:47971}
972
Ian Vollickba1f85922017-07-21 18:10:03973void LayerAnimator::NotifyAnimationStarted(base::TimeTicks monotonic_time,
974 int target_property,
975 int group) {
976 OnThreadedAnimationStarted(
977 monotonic_time, static_cast<cc::TargetProperty::Type>(target_property),
978 group);
loyso1fbd9f92015-12-17 07:43:13979}
980
[email protected]a48f30d2012-10-30 00:35:41981LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38982 const base::WeakPtr<LayerAnimationSequence>& sequence)
983 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41984}
985
vmpstr0ae825e72016-02-25 20:31:31986LayerAnimator::RunningAnimation::RunningAnimation(
987 const RunningAnimation& other) = default;
988
[email protected]a48f30d2012-10-30 00:35:41989LayerAnimator::RunningAnimation::~RunningAnimation() { }
990
[email protected]710a98d2011-06-23 20:13:29991} // namespace ui