blob: 2a47bd9ace30403e58be4667cf269eda134b1edd [file] [log] [blame]
[email protected]b7a1b662012-01-18 14:12:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]710a98d2011-06-23 20:13:292// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]116302fc2012-05-05 21:45:415#include "ui/compositor/layer_animator.h"
[email protected]710a98d2011-06-23 20:13:296
avi87b8b582015-12-24 21:35:257#include <stddef.h>
8
danakj25c52c32016-04-12 21:51:089#include <memory>
10
[email protected]710a98d2011-06-23 20:13:2911#include "base/logging.h"
ssid334fb87a2015-01-27 20:12:0712#include "base/trace_event/trace_event.h"
loyso3338dfb2016-03-09 03:07:3213#include "cc/animation/animation_host.h"
[email protected]95e4e1a02013-03-18 07:09:0914#include "cc/animation/animation_id_provider.h"
loyso841229002015-12-21 10:03:2415#include "cc/animation/animation_player.h"
16#include "cc/animation/animation_timeline.h"
17#include "cc/animation/element_animations.h"
[email protected]de2cf8c2013-10-25 19:46:4618#include "cc/output/begin_frame_args.h"
[email protected]116302fc2012-05-05 21:45:4119#include "ui/compositor/compositor.h"
20#include "ui/compositor/layer.h"
21#include "ui/compositor/layer_animation_delegate.h"
22#include "ui/compositor/layer_animation_observer.h"
23#include "ui/compositor/layer_animation_sequence.h"
[email protected]9034a282014-06-05 03:11:4724#include "ui/compositor/layer_animator_collection.h"
[email protected]0ed187e2011-10-21 20:07:4225
[email protected]a48f30d2012-10-30 00:35:4126#define SAFE_INVOKE_VOID(function, running_anim, ...) \
27 if (running_anim.is_sequence_alive()) \
28 function(running_anim.sequence(), ##__VA_ARGS__)
29#define SAFE_INVOKE_BOOL(function, running_anim) \
30 ((running_anim.is_sequence_alive()) \
31 ? function(running_anim.sequence()) \
32 : false)
33#define SAFE_INVOKE_PTR(function, running_anim) \
34 ((running_anim.is_sequence_alive()) \
35 ? function(running_anim.sequence()) \
36 : NULL)
37
[email protected]21445e472011-10-21 20:36:3238namespace ui {
[email protected]0ed187e2011-10-21 20:07:4239
[email protected]b4db9372011-10-24 14:44:1940namespace {
41
[email protected]98e2ed22012-11-21 14:02:2342const int kDefaultTransitionDurationMs = 120;
[email protected]1778cbc2012-09-06 04:31:1943
[email protected]9861f1752012-06-01 07:16:1444} // namespace
45
[email protected]b4db9372011-10-24 14:44:1946// LayerAnimator public --------------------------------------------------------
47
48LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
49 : delegate_(NULL),
50 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
[email protected]0d316252014-01-20 15:31:1951 is_transition_duration_locked_(false),
[email protected]b4db9372011-10-24 14:44:1952 transition_duration_(transition_duration),
[email protected]ffb15d12013-09-15 17:29:3053 tween_type_(gfx::Tween::LINEAR),
[email protected]b4db9372011-10-24 14:44:1954 is_started_(false),
[email protected]d064ef82012-11-13 10:26:5955 disable_timer_for_test_(false),
56 adding_animations_(false) {
loyso53110492016-03-03 00:11:5157 animation_player_ =
58 cc::AnimationPlayer::Create(cc::AnimationIdProvider::NextPlayerId());
[email protected]710a98d2011-06-23 20:13:2959}
60
61LayerAnimator::~LayerAnimator() {
[email protected]a48f30d2012-10-30 00:35:4162 for (size_t i = 0; i < running_animations_.size(); ++i) {
63 if (running_animations_[i].is_sequence_alive())
64 running_animations_[i].sequence()->OnAnimatorDestroyed();
65 }
[email protected]5d86a112012-09-23 00:21:5866 ClearAnimationsInternal();
67 delegate_ = NULL;
loysoe2fed922016-03-09 04:41:5568 DCHECK(!animation_player_->animation_timeline());
[email protected]710a98d2011-06-23 20:13:2969}
70
[email protected]b4db9372011-10-24 14:44:1971// static
72LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
73 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
74}
75
76// static
77LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
[email protected]98e2ed22012-11-21 14:02:2378 return new LayerAnimator(
79 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
[email protected]b4db9372011-10-24 14:44:1980}
81
[email protected]7713e242012-11-15 17:43:1982// This macro provides the implementation for the setter and getter (well,
83// the getter of the target value) for an animated property. For example,
84// it is used for the implementations of SetTransform and GetTargetTransform.
85// It is worth noting that SetFoo avoids invoking the usual animation machinery
86// if the transition duration is zero -- in this case we just set the property
87// on the layer animation delegate immediately.
danakj25c52c32016-04-12 21:51:0888#define ANIMATED_PROPERTY(type, property, name, member_type, member) \
89 void LayerAnimator::Set##name(type value) { \
90 base::TimeDelta duration = GetTransitionDuration(); \
thestig550eecbe2016-04-22 23:55:4791 if (duration.is_zero() && delegate() && \
danakj25c52c32016-04-12 21:51:0892 (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) { \
93 StopAnimatingProperty(LayerAnimationElement::property); \
94 delegate()->Set##name##FromAnimation(value); \
95 return; \
96 } \
97 std::unique_ptr<LayerAnimationElement> element( \
98 LayerAnimationElement::Create##name##Element(value, duration)); \
99 element->set_tween_type(tween_type_); \
100 StartAnimation(new LayerAnimationSequence(element.release())); \
101 } \
102 \
103 member_type LayerAnimator::GetTarget##name() const { \
104 LayerAnimationElement::TargetValue target(delegate()); \
105 GetTargetValue(&target); \
106 return target.member; \
107 }
[email protected]fe7074c62011-10-28 15:22:54108
[email protected]7713e242012-11-15 17:43:19109ANIMATED_PROPERTY(
110 const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform);
111ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds);
112ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity);
113ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
114ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
115ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
116ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
[email protected]e81480f1f2012-10-11 23:06:45117
[email protected]0d316252014-01-20 15:31:19118base::TimeDelta LayerAnimator::GetTransitionDuration() const {
119 return transition_duration_;
120}
121
[email protected]e876c2712011-11-02 16:42:45122void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
[email protected]9034a282014-06-05 03:11:47123 if (delegate_ && is_started_) {
124 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
125 if (collection)
126 collection->StopAnimator(this);
127 }
loyso1fbd9f92015-12-17 07:43:13128 SwitchToLayer(delegate ? delegate->GetCcLayer() : nullptr);
[email protected]b4db9372011-10-24 14:44:19129 delegate_ = delegate;
[email protected]9034a282014-06-05 03:11:47130 if (delegate_ && is_started_) {
131 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
132 if (collection)
133 collection->StartAnimator(this);
134 }
[email protected]b4db9372011-10-24 14:44:19135}
136
loyso1fbd9f92015-12-17 07:43:13137void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
loyso47a0f192016-04-22 00:30:09138 // Release ElementAnimations state for old layer.
139 element_animations_state_ = nullptr;
loyso3338dfb2016-03-09 03:07:32140
loysoe2fed922016-03-09 04:41:55141 if (delegate_)
142 DetachLayerFromAnimationPlayer();
143 if (new_layer)
144 AttachLayerToAnimationPlayer(new_layer->id());
loyso841229002015-12-21 10:03:24145}
146
147void LayerAnimator::SetCompositor(Compositor* compositor) {
148 DCHECK(compositor);
loyso841229002015-12-21 10:03:24149
loysoe2fed922016-03-09 04:41:55150 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
151 DCHECK(timeline);
loyso3338dfb2016-03-09 03:07:32152
loysoe2fed922016-03-09 04:41:55153 DCHECK(delegate_->GetCcLayer());
loyso3338dfb2016-03-09 03:07:32154
loyso47a0f192016-04-22 00:30:09155 // Register ElementAnimations so it will be picked up by
156 // AnimationHost::RegisterPlayerForLayer via
157 // AnimationHost::GetElementAnimationsForLayerId.
158 if (element_animations_state_) {
vollickef2ae922016-06-29 17:54:27159 DCHECK_EQ(element_animations_state_->element_id().primaryId,
loysoe2fed922016-03-09 04:41:55160 delegate_->GetCcLayer()->id());
loyso47a0f192016-04-22 00:30:09161 timeline->animation_host()->RegisterElementAnimations(
162 element_animations_state_.get());
loyso841229002015-12-21 10:03:24163 }
loysoe2fed922016-03-09 04:41:55164
165 timeline->AttachPlayer(animation_player_);
166
167 AttachLayerToAnimationPlayer(delegate_->GetCcLayer()->id());
168
loyso47a0f192016-04-22 00:30:09169 // Release ElementAnimations state.
170 element_animations_state_ = nullptr;
loyso841229002015-12-21 10:03:24171}
172
173void LayerAnimator::ResetCompositor(Compositor* compositor) {
174 DCHECK(compositor);
loyso3338dfb2016-03-09 03:07:32175
loysode0a0022016-04-15 02:28:38176 cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
177 DCHECK(timeline);
178
vollickef2ae922016-06-29 17:54:27179 cc::ElementId element_id(animation_player_->element_id());
loysode0a0022016-04-15 02:28:38180
loyso47a0f192016-04-22 00:30:09181 // Store a reference to ElementAnimations (if any)
182 // so it may be picked up in LayerAnimator::SetCompositor.
vollickef2ae922016-06-29 17:54:27183 if (element_id) {
loyso47a0f192016-04-22 00:30:09184 element_animations_state_ =
vollickef2ae922016-06-29 17:54:27185 timeline->animation_host()->GetElementAnimationsForElementId(
186 element_id);
loyso841229002015-12-21 10:03:24187 }
loysoe2fed922016-03-09 04:41:55188
189 DetachLayerFromAnimationPlayer();
190
loysoe2fed922016-03-09 04:41:55191 timeline->DetachPlayer(animation_player_);
loyso841229002015-12-21 10:03:24192}
193
194void LayerAnimator::AttachLayerToAnimationPlayer(int layer_id) {
vollickef2ae922016-06-29 17:54:27195 // For ui, layer and element ids are equivalent.
196 cc::ElementId element_id(layer_id, 0);
loyso7337a622016-04-26 23:54:30197 if (!animation_player_->element_id())
vollickef2ae922016-06-29 17:54:27198 animation_player_->AttachElement(element_id);
loyso841229002015-12-21 10:03:24199 else
vollickef2ae922016-06-29 17:54:27200 DCHECK_EQ(animation_player_->element_id(), element_id);
loyso841229002015-12-21 10:03:24201
loyso9f6a55e62016-04-27 23:58:25202 animation_player_->set_animation_delegate(this);
loyso841229002015-12-21 10:03:24203}
204
205void LayerAnimator::DetachLayerFromAnimationPlayer() {
loyso9f6a55e62016-04-27 23:58:25206 animation_player_->set_animation_delegate(nullptr);
loyso841229002015-12-21 10:03:24207
loyso7337a622016-04-26 23:54:30208 if (animation_player_->element_id())
loyso9f6a55e62016-04-27 23:58:25209 animation_player_->DetachElement();
loyso841229002015-12-21 10:03:24210}
211
danakj25c52c32016-04-12 21:51:08212void LayerAnimator::AddThreadedAnimation(
213 std::unique_ptr<cc::Animation> animation) {
loyso841229002015-12-21 10:03:24214 animation_player_->AddAnimation(std::move(animation));
215}
216
217void LayerAnimator::RemoveThreadedAnimation(int animation_id) {
loyso841229002015-12-21 10:03:24218 animation_player_->RemoveAnimation(animation_id);
loyso1fbd9f92015-12-17 07:43:13219}
220
loyso1fe980ff2016-01-18 23:58:15221bool LayerAnimator::HasPendingThreadedAnimationsForTesting() const {
loyso1fe980ff2016-01-18 23:58:15222 return animation_player_->has_pending_animations_for_testing();
223}
224
loysod4127442016-02-03 02:29:40225cc::AnimationPlayer* LayerAnimator::GetAnimationPlayerForTesting() const {
226 return animation_player_.get();
227}
228
[email protected]b4db9372011-10-24 14:44:19229void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58230 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c2712011-11-02 16:42:45231 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19232 if (!StartSequenceImmediately(animation)) {
233 // Attempt to preempt a running animation.
234 switch (preemption_strategy_) {
235 case IMMEDIATELY_SET_NEW_TARGET:
236 ImmediatelySetNewTarget(animation);
237 break;
238 case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
239 ImmediatelyAnimateToNewTarget(animation);
240 break;
241 case ENQUEUE_NEW_ANIMATION:
242 EnqueueNewAnimation(animation);
243 break;
244 case REPLACE_QUEUED_ANIMATIONS:
245 ReplaceQueuedAnimations(animation);
246 break;
247 case BLEND_WITH_CURRENT_ANIMATION: {
248 // TODO(vollick) Add support for blended sequences and use them here.
249 NOTIMPLEMENTED();
250 break;
251 }
[email protected]7fca53d42011-09-29 15:38:12252 }
[email protected]b4db9372011-10-24 14:44:19253 }
254 FinishAnyAnimationWithZeroDuration();
[email protected]fe7074c62011-10-28 15:22:54255 UpdateAnimationState();
[email protected]b4db9372011-10-24 14:44:19256}
257
258void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
[email protected]5d86a112012-09-23 00:21:58259 scoped_refptr<LayerAnimator> retain(this);
[email protected]e876c2712011-11-02 16:42:45260 OnScheduled(animation);
[email protected]b4db9372011-10-24 14:44:19261 if (is_animating()) {
262 animation_queue_.push_back(make_linked_ptr(animation));
263 ProcessQueue();
264 } else {
265 StartSequenceImmediately(animation);
[email protected]7fca53d42011-09-29 15:38:12266 }
[email protected]fe7074c62011-10-28 15:22:54267 UpdateAnimationState();
[email protected]710a98d2011-06-23 20:13:29268}
269
[email protected]d064ef82012-11-13 10:26:59270void LayerAnimator::StartTogether(
271 const std::vector<LayerAnimationSequence*>& animations) {
272 scoped_refptr<LayerAnimator> retain(this);
273 if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
274 std::vector<LayerAnimationSequence*>::const_iterator iter;
275 for (iter = animations.begin(); iter != animations.end(); ++iter) {
276 StartAnimation(*iter);
277 }
278 return;
279 }
[email protected]d764fd3d2012-11-15 20:07:51280
[email protected]d064ef82012-11-13 10:26:59281 adding_animations_ = true;
[email protected]d764fd3d2012-11-15 20:07:51282 if (!is_animating()) {
[email protected]9034a282014-06-05 03:11:47283 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
284 if (collection && collection->HasActiveAnimators())
285 last_step_time_ = collection->last_tick_time();
[email protected]d764fd3d2012-11-15 20:07:51286 else
abhishek.ka7215854d2015-05-26 06:13:17287 last_step_time_ = base::TimeTicks::Now();
[email protected]d764fd3d2012-11-15 20:07:51288 }
[email protected]d064ef82012-11-13 10:26:59289
290 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24291 LayerAnimationElement::AnimatableProperties animated_properties =
292 LayerAnimationElement::UNKNOWN;
293
[email protected]d064ef82012-11-13 10:26:59294 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24295 for (iter = animations.begin(); iter != animations.end(); ++iter)
296 animated_properties |= (*iter)->properties();
[email protected]d064ef82012-11-13 10:26:59297
298 // Starting a zero duration pause that affects all the animated properties
299 // will prevent any of the sequences from animating until there are no
300 // running animations that affect any of these properties, as well as
301 // handle preemption strategy.
302 StartAnimation(new LayerAnimationSequence(
303 LayerAnimationElement::CreatePauseElement(animated_properties,
304 base::TimeDelta())));
305
[email protected]bf912272013-02-23 01:54:16306 bool wait_for_group_start = false;
307 for (iter = animations.begin(); iter != animations.end(); ++iter)
308 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
309
310 int group_id = cc::AnimationIdProvider::NextGroupId();
311
[email protected]d064ef82012-11-13 10:26:59312 // These animations (provided they don't animate any common properties) will
313 // now animate together if trivially scheduled.
314 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16315 (*iter)->set_animation_group_id(group_id);
316 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]d064ef82012-11-13 10:26:59317 ScheduleAnimation(*iter);
318 }
319
320 adding_animations_ = false;
321 UpdateAnimationState();
322}
323
324
[email protected]b4db9372011-10-24 14:44:19325void LayerAnimator::ScheduleTogether(
326 const std::vector<LayerAnimationSequence*>& animations) {
[email protected]5d86a112012-09-23 00:21:58327 scoped_refptr<LayerAnimator> retain(this);
328
[email protected]b4db9372011-10-24 14:44:19329 // Collect all the affected properties.
[email protected]e03193d2014-01-14 03:10:24330 LayerAnimationElement::AnimatableProperties animated_properties =
331 LayerAnimationElement::UNKNOWN;
332
[email protected]b4db9372011-10-24 14:44:19333 std::vector<LayerAnimationSequence*>::const_iterator iter;
[email protected]e03193d2014-01-14 03:10:24334 for (iter = animations.begin(); iter != animations.end(); ++iter)
335 animated_properties |= (*iter)->properties();
[email protected]710a98d2011-06-23 20:13:29336
[email protected]b4db9372011-10-24 14:44:19337 // Scheduling a zero duration pause that affects all the animated properties
338 // will prevent any of the sequences from animating until there are no
339 // running animations that affect any of these properties.
[email protected]e4cbcc772012-03-07 18:59:31340 ScheduleAnimation(new LayerAnimationSequence(
341 LayerAnimationElement::CreatePauseElement(animated_properties,
342 base::TimeDelta())));
[email protected]710a98d2011-06-23 20:13:29343
[email protected]bf912272013-02-23 01:54:16344 bool wait_for_group_start = false;
345 for (iter = animations.begin(); iter != animations.end(); ++iter)
346 wait_for_group_start |= (*iter)->IsFirstElementThreaded();
347
348 int group_id = cc::AnimationIdProvider::NextGroupId();
349
[email protected]b4db9372011-10-24 14:44:19350 // These animations (provided they don't animate any common properties) will
351 // now animate together if trivially scheduled.
352 for (iter = animations.begin(); iter != animations.end(); ++iter) {
[email protected]bf912272013-02-23 01:54:16353 (*iter)->set_animation_group_id(group_id);
354 (*iter)->set_waiting_for_group_start(wait_for_group_start);
[email protected]b4db9372011-10-24 14:44:19355 ScheduleAnimation(*iter);
[email protected]710a98d2011-06-23 20:13:29356 }
[email protected]fe7074c62011-10-28 15:22:54357
358 UpdateAnimationState();
359}
360
[email protected]2a88c702012-09-04 23:15:02361void LayerAnimator::SchedulePauseForProperties(
362 base::TimeDelta duration,
[email protected]e03193d2014-01-14 03:10:24363 LayerAnimationElement::AnimatableProperties properties_to_pause) {
[email protected]2a88c702012-09-04 23:15:02364 ScheduleAnimation(new ui::LayerAnimationSequence(
365 ui::LayerAnimationElement::CreatePauseElement(
366 properties_to_pause, duration)));
367}
368
[email protected]e876c2712011-11-02 16:42:45369bool LayerAnimator::IsAnimatingProperty(
370 LayerAnimationElement::AnimatableProperty property) const {
371 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
372 queue_iter != animation_queue_.end(); ++queue_iter) {
[email protected]e03193d2014-01-14 03:10:24373 if ((*queue_iter)->properties() & property)
[email protected]e876c2712011-11-02 16:42:45374 return true;
[email protected]e876c2712011-11-02 16:42:45375 }
376 return false;
[email protected]7fca53d42011-09-29 15:38:12377}
378
[email protected]b4db9372011-10-24 14:44:19379void LayerAnimator::StopAnimatingProperty(
380 LayerAnimationElement::AnimatableProperty property) {
[email protected]5d86a112012-09-23 00:21:58381 scoped_refptr<LayerAnimator> retain(this);
[email protected]b4db9372011-10-24 14:44:19382 while (true) {
[email protected]a48f30d2012-10-30 00:35:41383 // GetRunningAnimation purges deleted animations before searching, so we are
384 // guaranteed to find a live animation if any is returned at all.
[email protected]b4db9372011-10-24 14:44:19385 RunningAnimation* running = GetRunningAnimation(property);
386 if (!running)
387 break;
[email protected]a48f30d2012-10-30 00:35:41388 // As was mentioned above, this sequence must be alive.
389 DCHECK(running->is_sequence_alive());
[email protected]6f110e42012-12-18 00:21:14390 FinishAnimation(running->sequence(), false);
[email protected]a48f30d2012-10-30 00:35:41391 }
[email protected]b4db9372011-10-24 14:44:19392}
393
[email protected]e876c2712011-11-02 16:42:45394void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
395 if (!observers_.HasObserver(observer))
396 observers_.AddObserver(observer);
397}
398
399void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
400 observers_.RemoveObserver(observer);
[email protected]5cc8538d2011-11-07 15:24:54401 // Remove the observer from all sequences as well.
402 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
403 queue_iter != animation_queue_.end(); ++queue_iter) {
404 (*queue_iter)->RemoveObserver(observer);
405 }
[email protected]e876c2712011-11-02 16:42:45406}
407
[email protected]bf912272013-02-23 01:54:16408void LayerAnimator::OnThreadedAnimationStarted(
loyso79c0bfc2016-04-18 23:46:42409 base::TimeTicks monotonic_time,
410 cc::TargetProperty::Type target_property,
411 int group_id) {
[email protected]bf912272013-02-23 01:54:16412 LayerAnimationElement::AnimatableProperty property =
loyso79c0bfc2016-04-18 23:46:42413 LayerAnimationElement::ToAnimatableProperty(target_property);
[email protected]bf912272013-02-23 01:54:16414
415 RunningAnimation* running = GetRunningAnimation(property);
416 if (!running)
417 return;
418 DCHECK(running->is_sequence_alive());
419
loyso79c0bfc2016-04-18 23:46:42420 if (running->sequence()->animation_group_id() != group_id)
[email protected]bf912272013-02-23 01:54:16421 return;
422
loyso79c0bfc2016-04-18 23:46:42423 running->sequence()->OnThreadedAnimationStarted(monotonic_time,
424 target_property, group_id);
[email protected]bf912272013-02-23 01:54:16425 if (!running->sequence()->waiting_for_group_start())
426 return;
427
loyso79c0bfc2016-04-18 23:46:42428 base::TimeTicks start_time = monotonic_time;
[email protected]bf912272013-02-23 01:54:16429
430 running->sequence()->set_waiting_for_group_start(false);
431
432 // The call to GetRunningAnimation made above already purged deleted
433 // animations, so we are guaranteed that all the animations we iterate
434 // over now are alive.
435 for (RunningAnimations::iterator iter = running_animations_.begin();
436 iter != running_animations_.end(); ++iter) {
437 // Ensure that each sequence is only Started once, regardless of the
438 // number of sequences in the group that have threaded first elements.
loyso79c0bfc2016-04-18 23:46:42439 if (((*iter).sequence()->animation_group_id() == group_id) &&
[email protected]bf912272013-02-23 01:54:16440 !(*iter).sequence()->IsFirstElementThreaded() &&
441 (*iter).sequence()->waiting_for_group_start()) {
442 (*iter).sequence()->set_start_time(start_time);
443 (*iter).sequence()->set_waiting_for_group_start(false);
444 (*iter).sequence()->Start(delegate());
445 }
446 }
447}
448
[email protected]9034a282014-06-05 03:11:47449void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
450 if (is_animating() && !is_started_) {
451 collection->StartAnimator(this);
452 is_started_ = true;
453 }
454}
455
456void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
bruthig33b1edab2016-03-02 02:22:35457 if (is_started_) {
[email protected]9034a282014-06-05 03:11:47458 collection->StopAnimator(this);
459 is_started_ = false;
460 }
461}
462
[email protected]d59a3692012-04-10 20:27:31463// LayerAnimator protected -----------------------------------------------------
464
[email protected]5d86a112012-09-23 00:21:58465void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
[email protected]3d75fed2012-12-15 18:47:38466 base::TimeTicks now) {
[email protected]bf912272013-02-23 01:54:16467 if (!delegate() || sequence->waiting_for_group_start())
[email protected]5d86a112012-09-23 00:21:58468 return;
469
[email protected]3d75fed2012-12-15 18:47:38470 sequence->Progress(now, delegate());
[email protected]d59a3692012-04-10 20:27:31471}
472
[email protected]a48f30d2012-10-30 00:35:41473void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
[email protected]4a386e42012-12-05 01:19:30474 if (!delegate())
475 return;
476
477 sequence->ProgressToEnd(delegate());
[email protected]a48f30d2012-10-30 00:35:41478}
479
[email protected]d59a3692012-04-10 20:27:31480bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
481 for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
482 queue_iter != animation_queue_.end(); ++queue_iter) {
483 if ((*queue_iter).get() == sequence)
484 return true;
485 }
486 return false;
487}
488
[email protected]b4db9372011-10-24 14:44:19489// LayerAnimator private -------------------------------------------------------
490
491void LayerAnimator::Step(base::TimeTicks now) {
[email protected]e4cbcc772012-03-07 18:59:31492 TRACE_EVENT0("ui", "LayerAnimator::Step");
[email protected]5d86a112012-09-23 00:21:58493 scoped_refptr<LayerAnimator> retain(this);
[email protected]e4cbcc772012-03-07 18:59:31494
[email protected]b4db9372011-10-24 14:44:19495 last_step_time_ = now;
[email protected]1778cbc2012-09-06 04:31:19496
[email protected]a48f30d2012-10-30 00:35:41497 PurgeDeletedAnimations();
498
[email protected]f5cd9e52011-11-03 21:38:08499 // We need to make a copy of the running animations because progressing them
500 // and finishing them may indirectly affect the collection of running
501 // animations.
502 RunningAnimations running_animations_copy = running_animations_;
503 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41504 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31505 continue;
506
[email protected]3d75fed2012-12-15 18:47:38507 if (running_animations_copy[i].sequence()->IsFinished(now)) {
[email protected]6f110e42012-12-18 00:21:14508 SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
509 } else {
[email protected]3d75fed2012-12-15 18:47:38510 SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
[email protected]6f110e42012-12-18 00:21:14511 }
[email protected]b4db9372011-10-24 14:44:19512 }
[email protected]b4db9372011-10-24 14:44:19513}
514
[email protected]6f110e42012-12-18 00:21:14515void LayerAnimator::StopAnimatingInternal(bool abort) {
516 scoped_refptr<LayerAnimator> retain(this);
ljagielski20570982015-01-07 20:32:55517 while (is_animating() && delegate()) {
[email protected]6f110e42012-12-18 00:21:14518 // We're going to attempt to finish the first running animation. Let's
519 // ensure that it's valid.
520 PurgeDeletedAnimations();
521
522 // If we've purged all running animations, attempt to start one up.
523 if (running_animations_.empty())
524 ProcessQueue();
525
526 DCHECK(!running_animations_.empty());
527
528 // Still no luck, let's just bail and clear all animations.
529 if (running_animations_.empty()) {
530 ClearAnimationsInternal();
531 break;
532 }
533
534 SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
535 }
536}
537
[email protected]b4db9372011-10-24 14:44:19538void LayerAnimator::UpdateAnimationState() {
539 if (disable_timer_for_test_)
[email protected]7fca53d42011-09-29 15:38:12540 return;
541
[email protected]b4db9372011-10-24 14:44:19542 const bool should_start = is_animating();
[email protected]9034a282014-06-05 03:11:47543 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
544 if (collection) {
545 if (should_start && !is_started_)
546 collection->StartAnimator(this);
547 else if (!should_start && is_started_)
548 collection->StopAnimator(this);
549 is_started_ = should_start;
550 } else {
551 is_started_ = false;
552 }
[email protected]710a98d2011-06-23 20:13:29553}
554
[email protected]f5cd9e52011-11-03 21:38:08555LayerAnimationSequence* LayerAnimator::RemoveAnimation(
556 LayerAnimationSequence* sequence) {
557 linked_ptr<LayerAnimationSequence> to_return;
558
[email protected]bf912272013-02-23 01:54:16559 bool is_running = false;
560
[email protected]f5cd9e52011-11-03 21:38:08561 // First remove from running animations
[email protected]b4db9372011-10-24 14:44:19562 for (RunningAnimations::iterator iter = running_animations_.begin();
563 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41564 if ((*iter).sequence() == sequence) {
[email protected]b4db9372011-10-24 14:44:19565 running_animations_.erase(iter);
[email protected]bf912272013-02-23 01:54:16566 is_running = true;
[email protected]b4db9372011-10-24 14:44:19567 break;
[email protected]21445e472011-10-21 20:36:32568 }
569 }
[email protected]b4db9372011-10-24 14:44:19570
571 // Then remove from the queue
572 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
573 queue_iter != animation_queue_.end(); ++queue_iter) {
574 if ((*queue_iter) == sequence) {
[email protected]f5cd9e52011-11-03 21:38:08575 to_return = *queue_iter;
[email protected]b4db9372011-10-24 14:44:19576 animation_queue_.erase(queue_iter);
577 break;
578 }
579 }
[email protected]f5cd9e52011-11-03 21:38:08580
[email protected]bf912272013-02-23 01:54:16581 if (!to_return.get() ||
582 !to_return->waiting_for_group_start() ||
583 !to_return->IsFirstElementThreaded())
584 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) &&
594 (*queue_iter)->IsFirstElementThreaded()) {
595 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();
[email protected]b4db9372011-10-24 14:44:19660 for (RunningAnimations::iterator iter = running_animations_.begin();
661 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 }
665 return NULL;
666}
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) {
673 if ((*queue_iter) == animation) {
674 found_sequence = true;
675 break;
676 }
677 }
678
679 if (!found_sequence)
680 animation_queue_.push_front(make_linked_ptr(animation));
681}
682
683void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
[email protected]f5cd9e52011-11-03 21:38:08684 LayerAnimationSequence* sequence, bool abort) {
[email protected]b4db9372011-10-24 14:44:19685 // For all the running animations, if they animate the same property,
[email protected]f5cd9e52011-11-03 21:38:08686 // progress them to the end and remove them. Note, Aborting or Progressing
687 // animations may affect the collection of running animations, so we need to
688 // operate on a copy.
689 RunningAnimations running_animations_copy = running_animations_;
690 for (size_t i = 0; i < running_animations_copy.size(); ++i) {
[email protected]a48f30d2012-10-30 00:35:41691 if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
[email protected]d59a3692012-04-10 20:27:31692 continue;
693
[email protected]712f4b642013-03-14 07:09:15694 if (running_animations_copy[i].sequence()->HasConflictingProperty(
[email protected]b4db9372011-10-24 14:44:19695 sequence->properties())) {
danakj25c52c32016-04-12 21:51:08696 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]a48f30d2012-10-30 00:35:41697 SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
[email protected]f5cd9e52011-11-03 21:38:08698 if (abort)
[email protected]bf912272013-02-23 01:54:16699 running_animations_copy[i].sequence()->Abort(delegate());
[email protected]f5cd9e52011-11-03 21:38:08700 else
[email protected]a48f30d2012-10-30 00:35:41701 SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
[email protected]b4db9372011-10-24 14:44:19702 }
703 }
704
[email protected]f5cd9e52011-11-03 21:38:08705 // Same for the queued animations that haven't been started. Again, we'll
706 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41707 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]f5cd9e52011-11-03 21:38:08708 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
709 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41710 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08711
712 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19713 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]d59a3692012-04-10 20:27:31714 continue;
715
[email protected]712f4b642013-03-14 07:09:15716 if (sequences[i]->HasConflictingProperty(sequence->properties())) {
danakj25c52c32016-04-12 21:51:08717 std::unique_ptr<LayerAnimationSequence> removed(
[email protected]7ffde472013-06-04 06:42:19718 RemoveAnimation(sequences[i].get()));
[email protected]b4db9372011-10-24 14:44:19719 if (abort)
[email protected]bf912272013-02-23 01:54:16720 sequences[i]->Abort(delegate());
[email protected]b4db9372011-10-24 14:44:19721 else
[email protected]7ffde472013-06-04 06:42:19722 ProgressAnimationToEnd(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19723 }
724 }
725}
726
727void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41728 // Need to detect if our sequence gets destroyed.
729 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
730 sequence->AsWeakPtr();
731
[email protected]b4db9372011-10-24 14:44:19732 const bool abort = false;
733 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19734 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41735 return;
736
[email protected]d3ba37ab2012-02-09 19:53:13737 LayerAnimationSequence* removed = RemoveAnimation(sequence);
738 DCHECK(removed == NULL || removed == sequence);
[email protected]7ffde472013-06-04 06:42:19739 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41740 return;
741
[email protected]4a386e42012-12-05 01:19:30742 ProgressAnimationToEnd(sequence);
[email protected]7ffde472013-06-04 06:42:19743 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41744 return;
745
746 delete sequence;
[email protected]b4db9372011-10-24 14:44:19747}
748
749void LayerAnimator::ImmediatelyAnimateToNewTarget(
750 LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41751 // Need to detect if our sequence gets destroyed.
752 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
753 sequence->AsWeakPtr();
754
[email protected]b4db9372011-10-24 14:44:19755 const bool abort = true;
756 RemoveAllAnimationsWithACommonProperty(sequence, abort);
[email protected]7ffde472013-06-04 06:42:19757 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41758 return;
759
[email protected]b4db9372011-10-24 14:44:19760 AddToQueueIfNotPresent(sequence);
[email protected]7ffde472013-06-04 06:42:19761 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41762 return;
763
[email protected]b4db9372011-10-24 14:44:19764 StartSequenceImmediately(sequence);
765}
766
767void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
768 // It is assumed that if there was no conflicting animation, we would
769 // not have been called. No need to check for a collision; just
770 // add to the queue.
771 animation_queue_.push_back(make_linked_ptr(sequence));
772 ProcessQueue();
773}
774
775void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41776 // Need to detect if our sequence gets destroyed.
777 base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
778 sequence->AsWeakPtr();
779
[email protected]b4db9372011-10-24 14:44:19780 // Remove all animations that aren't running. Note: at each iteration i is
781 // incremented or an element is removed from the queue, so
782 // animation_queue_.size() - i is always decreasing and we are always making
783 // progress towards the loop terminating.
784 for (size_t i = 0; i < animation_queue_.size();) {
[email protected]7ffde472013-06-04 06:42:19785 if (!weak_sequence_ptr.get())
[email protected]a48f30d2012-10-30 00:35:41786 break;
787
788 PurgeDeletedAnimations();
789
[email protected]b4db9372011-10-24 14:44:19790 bool is_running = false;
791 for (RunningAnimations::const_iterator iter = running_animations_.begin();
792 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41793 if ((*iter).sequence() == animation_queue_[i].get()) {
[email protected]b4db9372011-10-24 14:44:19794 is_running = true;
795 break;
796 }
797 }
[email protected]a48f30d2012-10-30 00:35:41798
[email protected]b4db9372011-10-24 14:44:19799 if (!is_running)
[email protected]300548c2012-06-17 08:54:55800 delete RemoveAnimation(animation_queue_[i].get());
[email protected]b4db9372011-10-24 14:44:19801 else
802 ++i;
803 }
804 animation_queue_.push_back(make_linked_ptr(sequence));
805 ProcessQueue();
806}
807
808void LayerAnimator::ProcessQueue() {
809 bool started_sequence = false;
810 do {
811 started_sequence = false;
[email protected]b4db9372011-10-24 14:44:19812 // Build a list of all currently animated properties.
[email protected]e03193d2014-01-14 03:10:24813 LayerAnimationElement::AnimatableProperties animated =
814 LayerAnimationElement::UNKNOWN;
[email protected]b4db9372011-10-24 14:44:19815 for (RunningAnimations::const_iterator iter = running_animations_.begin();
816 iter != running_animations_.end(); ++iter) {
[email protected]a48f30d2012-10-30 00:35:41817 if (!(*iter).is_sequence_alive())
818 continue;
[email protected]e03193d2014-01-14 03:10:24819
820 animated |= (*iter).sequence()->properties();
[email protected]b4db9372011-10-24 14:44:19821 }
822
823 // Try to find an animation that doesn't conflict with an animated
[email protected]f5cd9e52011-11-03 21:38:08824 // property or a property that will be animated before it. Note: starting
825 // the animation may indirectly cause more animations to be started, so we
826 // need to operate on a copy.
[email protected]a48f30d2012-10-30 00:35:41827 std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
[email protected]b4db9372011-10-24 14:44:19828 for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
[email protected]f5cd9e52011-11-03 21:38:08829 queue_iter != animation_queue_.end(); ++queue_iter)
[email protected]a48f30d2012-10-30 00:35:41830 sequences.push_back((*queue_iter)->AsWeakPtr());
[email protected]f5cd9e52011-11-03 21:38:08831
832 for (size_t i = 0; i < sequences.size(); ++i) {
[email protected]7ffde472013-06-04 06:42:19833 if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
[email protected]a48f30d2012-10-30 00:35:41834 continue;
835
[email protected]712f4b642013-03-14 07:09:15836 if (!sequences[i]->HasConflictingProperty(animated)) {
[email protected]a48f30d2012-10-30 00:35:41837 StartSequenceImmediately(sequences[i].get());
[email protected]b4db9372011-10-24 14:44:19838 started_sequence = true;
839 break;
840 }
841
842 // Animation couldn't be started. Add its properties to the collection so
843 // that we don't start a conflicting animation. For example, if our queue
844 // has the elements { {T,B}, {B} } (that is, an element that animates both
845 // the transform and the bounds followed by an element that animates the
846 // bounds), and we're currently animating the transform, we can't start
847 // the first element because it animates the transform, too. We cannot
848 // start the second element, either, because the first element animates
849 // bounds too, and needs to go first.
[email protected]e03193d2014-01-14 03:10:24850 animated |= sequences[i]->properties();
[email protected]b4db9372011-10-24 14:44:19851 }
852
853 // If we started a sequence, try again. We may be able to start several.
854 } while (started_sequence);
855}
856
857bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
[email protected]a48f30d2012-10-30 00:35:41858 PurgeDeletedAnimations();
859
[email protected]b4db9372011-10-24 14:44:19860 // Ensure that no one is animating one of the sequence's properties already.
861 for (RunningAnimations::const_iterator iter = running_animations_.begin();
862 iter != running_animations_.end(); ++iter) {
[email protected]712f4b642013-03-14 07:09:15863 if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
[email protected]b4db9372011-10-24 14:44:19864 return false;
865 }
866
charliea3be839702015-01-26 17:35:41867 // All clear, actually start the sequence.
[email protected]9034a282014-06-05 03:11:47868 // All LayerAnimators share the same LayerAnimatorCollection. Use the
[email protected]1778cbc2012-09-06 04:31:19869 // last_tick_time() from there to ensure animations started during the same
870 // event complete at the same time.
871 base::TimeTicks start_time;
[email protected]9034a282014-06-05 03:11:47872 LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
[email protected]d064ef82012-11-13 10:26:59873 if (is_animating() || adding_animations_)
[email protected]1778cbc2012-09-06 04:31:19874 start_time = last_step_time_;
[email protected]9034a282014-06-05 03:11:47875 else if (collection && collection->HasActiveAnimators())
876 start_time = collection->last_tick_time();
[email protected]1778cbc2012-09-06 04:31:19877 else
abhishek.ka7215854d2015-05-26 06:13:17878 start_time = base::TimeTicks::Now();
[email protected]b4db9372011-10-24 14:44:19879
[email protected]bf912272013-02-23 01:54:16880 if (!sequence->animation_group_id())
881 sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
882 if (!sequence->waiting_for_group_start() ||
883 sequence->IsFirstElementThreaded()) {
884 sequence->set_start_time(start_time);
885 sequence->Start(delegate());
886 }
[email protected]a48f30d2012-10-30 00:35:41887 running_animations_.push_back(
[email protected]3d75fed2012-12-15 18:47:38888 RunningAnimation(sequence->AsWeakPtr()));
[email protected]b4db9372011-10-24 14:44:19889
890 // Need to keep a reference to the animation.
891 AddToQueueIfNotPresent(sequence);
892
893 // Ensure that animations get stepped at their start time.
894 Step(start_time);
895
896 return true;
[email protected]710a98d2011-06-23 20:13:29897}
898
[email protected]fe7074c62011-10-28 15:22:54899void LayerAnimator::GetTargetValue(
900 LayerAnimationElement::TargetValue* target) const {
[email protected]b1c37fc2012-03-22 03:36:13901 for (AnimationQueue::const_iterator iter = animation_queue_.begin();
902 iter != animation_queue_.end(); ++iter) {
903 (*iter)->GetTargetValue(target);
[email protected]fe7074c62011-10-28 15:22:54904 }
905}
906
[email protected]e876c2712011-11-02 16:42:45907void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
908 if (observers_.might_have_observers()) {
brettw5a1613dc2015-06-02 05:34:43909 base::ObserverListBase<LayerAnimationObserver>::Iterator it(&observers_);
[email protected]e876c2712011-11-02 16:42:45910 LayerAnimationObserver* obs;
911 while ((obs = it.GetNext()) != NULL) {
912 sequence->AddObserver(obs);
913 }
914 }
915 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() {
956 return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
957}
958
loyso79c0bfc2016-04-18 23:46:42959void LayerAnimator::NotifyAnimationStarted(
960 base::TimeTicks monotonic_time,
961 cc::TargetProperty::Type target_property,
962 int group) {
963 OnThreadedAnimationStarted(monotonic_time, target_property, group);
loyso1fbd9f92015-12-17 07:43:13964}
965
[email protected]a48f30d2012-10-30 00:35:41966LayerAnimator::RunningAnimation::RunningAnimation(
[email protected]3d75fed2012-12-15 18:47:38967 const base::WeakPtr<LayerAnimationSequence>& sequence)
968 : sequence_(sequence) {
[email protected]a48f30d2012-10-30 00:35:41969}
970
vmpstr0ae825e72016-02-25 20:31:31971LayerAnimator::RunningAnimation::RunningAnimation(
972 const RunningAnimation& other) = default;
973
[email protected]a48f30d2012-10-30 00:35:41974LayerAnimator::RunningAnimation::~RunningAnimation() { }
975
[email protected]710a98d2011-06-23 20:13:29976} // namespace ui