Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: cc/animation/layer_animation_controller.cc

Issue 1904653002: CC Animation: Merge LayerAnimationController into ElementAnimations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor optimization: Don't init value observations if same host. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/animation/layer_animation_controller.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <vector>
11
12 #include "cc/animation/animation.h"
13 #include "cc/animation/animation_curve.h"
14 #include "cc/animation/animation_delegate.h"
15 #include "cc/animation/animation_events.h"
16 #include "cc/animation/animation_host.h"
17 #include "cc/animation/keyframed_animation_curve.h"
18 #include "cc/animation/layer_animation_value_observer.h"
19 #include "cc/animation/layer_animation_value_provider.h"
20 #include "cc/animation/scroll_offset_animation_curve.h"
21 #include "cc/output/filter_operations.h"
22 #include "ui/gfx/geometry/box_f.h"
23 #include "ui/gfx/transform.h"
24
25 namespace cc {
26
27 LayerAnimationController::LayerAnimationController(int id)
28 : host_(0),
29 id_(id),
30 is_active_(false),
31 value_observer_(nullptr),
32 value_provider_(nullptr),
33 layer_animation_delegate_(nullptr),
34 needs_active_value_observations_(false),
35 needs_pending_value_observations_(false),
36 needs_to_start_animations_(false),
37 scroll_offset_animation_was_interrupted_(false),
38 potentially_animating_transform_for_active_observers_(false),
39 potentially_animating_transform_for_pending_observers_(false) {}
40
41 LayerAnimationController::~LayerAnimationController() {
42 if (host_)
43 host_->UnregisterAnimationController(this);
44 }
45
46 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
47 int id) {
48 return make_scoped_refptr(new LayerAnimationController(id));
49 }
50
51 void LayerAnimationController::PauseAnimation(int animation_id,
52 base::TimeDelta time_offset) {
53 for (size_t i = 0; i < animations_.size(); ++i) {
54 if (animations_[i]->id() == animation_id) {
55 animations_[i]->SetRunState(Animation::PAUSED,
56 time_offset + animations_[i]->start_time() +
57 animations_[i]->time_offset());
58 }
59 }
60 }
61
62 void LayerAnimationController::UpdatePotentiallyAnimatingTransform() {
63 bool was_potentially_animating_transform_for_active_observers =
64 potentially_animating_transform_for_active_observers_;
65 bool was_potentially_animating_transform_for_pending_observers =
66 potentially_animating_transform_for_pending_observers_;
67
68 potentially_animating_transform_for_active_observers_ = false;
69 potentially_animating_transform_for_pending_observers_ = false;
70
71 for (const auto& animation : animations_) {
72 if (!animation->is_finished() &&
73 animation->target_property() == TargetProperty::TRANSFORM) {
74 potentially_animating_transform_for_active_observers_ |=
75 animation->affects_active_observers();
76 potentially_animating_transform_for_pending_observers_ |=
77 animation->affects_pending_observers();
78 }
79 }
80
81 bool changed_for_active_observers =
82 was_potentially_animating_transform_for_active_observers !=
83 potentially_animating_transform_for_active_observers_;
84 bool changed_for_pending_observers =
85 was_potentially_animating_transform_for_pending_observers !=
86 potentially_animating_transform_for_pending_observers_;
87
88 if (!changed_for_active_observers && !changed_for_pending_observers)
89 return;
90
91 NotifyObserversTransformIsPotentiallyAnimatingChanged(
92 changed_for_active_observers, changed_for_pending_observers);
93 }
94
95 void LayerAnimationController::RemoveAnimation(int animation_id) {
96 bool removed_transform_animation = false;
97 // Since we want to use the animations that we're going to remove, we need to
98 // use a stable_parition here instead of remove_if. Remove_if leaves the
99 // removed items in an unspecified state.
100 auto animations_to_remove = std::stable_partition(
101 animations_.begin(), animations_.end(),
102 [animation_id](const std::unique_ptr<Animation>& animation) {
103 return animation->id() != animation_id;
104 });
105 for (auto it = animations_to_remove; it != animations_.end(); ++it) {
106 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) {
107 scroll_offset_animation_was_interrupted_ = true;
108 } else if ((*it)->target_property() == TargetProperty::TRANSFORM &&
109 !(*it)->is_finished()) {
110 removed_transform_animation = true;
111 }
112 }
113
114 animations_.erase(animations_to_remove, animations_.end());
115 UpdateActivation(NORMAL_ACTIVATION);
116 if (removed_transform_animation)
117 UpdatePotentiallyAnimatingTransform();
118 }
119
120 void LayerAnimationController::AbortAnimation(int animation_id) {
121 bool aborted_transform_animation = false;
122 if (Animation* animation = GetAnimationById(animation_id)) {
123 if (!animation->is_finished()) {
124 animation->SetRunState(Animation::ABORTED, last_tick_time_);
125 if (animation->target_property() == TargetProperty::TRANSFORM)
126 aborted_transform_animation = true;
127 }
128 }
129 if (aborted_transform_animation)
130 UpdatePotentiallyAnimatingTransform();
131 }
132
133 void LayerAnimationController::AbortAnimations(
134 TargetProperty::Type target_property,
135 bool needs_completion) {
136 if (needs_completion)
137 DCHECK(target_property == TargetProperty::SCROLL_OFFSET);
138
139 bool aborted_transform_animation = false;
140 for (size_t i = 0; i < animations_.size(); ++i) {
141 if (animations_[i]->target_property() == target_property &&
142 !animations_[i]->is_finished()) {
143 // Currently only impl-only scroll offset animations can be completed on
144 // the main thread.
145 if (needs_completion && animations_[i]->is_impl_only()) {
146 animations_[i]->SetRunState(Animation::ABORTED_BUT_NEEDS_COMPLETION,
147 last_tick_time_);
148 } else {
149 animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_);
150 }
151 if (target_property == TargetProperty::TRANSFORM)
152 aborted_transform_animation = true;
153 }
154 }
155 if (aborted_transform_animation)
156 UpdatePotentiallyAnimatingTransform();
157 }
158
159 // Ensures that the list of active animations on the main thread and the impl
160 // thread are kept in sync.
161 void LayerAnimationController::PushAnimationUpdatesTo(
162 LayerAnimationController* controller_impl) {
163 DCHECK(this != controller_impl);
164 if (!has_any_animation() && !controller_impl->has_any_animation())
165 return;
166 MarkAbortedAnimationsForDeletion(controller_impl);
167 PurgeAnimationsMarkedForDeletion();
168 PushNewAnimationsToImplThread(controller_impl);
169
170 // Remove finished impl side animations only after pushing,
171 // and only after the animations are deleted on the main thread
172 // this insures we will never push an animation twice.
173 RemoveAnimationsCompletedOnMainThread(controller_impl);
174
175 PushPropertiesToImplThread(controller_impl);
176 controller_impl->UpdateActivation(NORMAL_ACTIVATION);
177 UpdateActivation(NORMAL_ACTIVATION);
178 }
179
180 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
181 DCHECK(!monotonic_time.is_null());
182 if (!HasValueObserver())
183 return;
184
185 if (needs_to_start_animations_)
186 StartAnimations(monotonic_time);
187 TickAnimations(monotonic_time);
188 last_tick_time_ = monotonic_time;
189 }
190
191 void LayerAnimationController::AccumulatePropertyUpdates(
192 base::TimeTicks monotonic_time,
193 AnimationEvents* events) {
194 if (!events)
195 return;
196
197 for (size_t i = 0; i < animations_.size(); ++i) {
198 Animation* animation = animations_[i].get();
199 if (!animation->is_impl_only())
200 continue;
201
202 if (!animation->InEffect(monotonic_time))
203 continue;
204
205 base::TimeDelta trimmed =
206 animation->TrimTimeToCurrentIteration(monotonic_time);
207 switch (animation->target_property()) {
208 case TargetProperty::OPACITY: {
209 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
210 animation->group(), TargetProperty::OPACITY,
211 monotonic_time);
212 const FloatAnimationCurve* float_animation_curve =
213 animation->curve()->ToFloatAnimationCurve();
214 event.opacity = float_animation_curve->GetValue(trimmed);
215 event.is_impl_only = true;
216 events->events_.push_back(event);
217 break;
218 }
219
220 case TargetProperty::TRANSFORM: {
221 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
222 animation->group(), TargetProperty::TRANSFORM,
223 monotonic_time);
224 const TransformAnimationCurve* transform_animation_curve =
225 animation->curve()->ToTransformAnimationCurve();
226 event.transform = transform_animation_curve->GetValue(trimmed);
227 event.is_impl_only = true;
228 events->events_.push_back(event);
229 break;
230 }
231
232 case TargetProperty::FILTER: {
233 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
234 animation->group(), TargetProperty::FILTER,
235 monotonic_time);
236 const FilterAnimationCurve* filter_animation_curve =
237 animation->curve()->ToFilterAnimationCurve();
238 event.filters = filter_animation_curve->GetValue(trimmed);
239 event.is_impl_only = true;
240 events->events_.push_back(event);
241 break;
242 }
243
244 case TargetProperty::BACKGROUND_COLOR: {
245 break;
246 }
247
248 case TargetProperty::SCROLL_OFFSET: {
249 // Impl-side changes to scroll offset are already sent back to the
250 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE
251 // isn't needed.
252 break;
253 }
254 }
255 }
256 }
257
258 void LayerAnimationController::UpdateState(bool start_ready_animations,
259 AnimationEvents* events) {
260 if (!HasActiveValueObserver())
261 return;
262
263 // Animate hasn't been called, this happens if an observer has been added
264 // between the Commit and Draw phases.
265 if (last_tick_time_ == base::TimeTicks())
266 return;
267
268 if (start_ready_animations)
269 PromoteStartedAnimations(last_tick_time_, events);
270
271 MarkFinishedAnimations(last_tick_time_);
272 MarkAnimationsForDeletion(last_tick_time_, events);
273
274 if (needs_to_start_animations_ && start_ready_animations) {
275 StartAnimations(last_tick_time_);
276 PromoteStartedAnimations(last_tick_time_, events);
277 }
278
279 AccumulatePropertyUpdates(last_tick_time_, events);
280
281 UpdateActivation(NORMAL_ACTIVATION);
282 }
283
284 void LayerAnimationController::ActivateAnimations() {
285 bool changed_transform_animation = false;
286 for (size_t i = 0; i < animations_.size(); ++i) {
287 if (animations_[i]->affects_active_observers() !=
288 animations_[i]->affects_pending_observers() &&
289 animations_[i]->target_property() == TargetProperty::TRANSFORM)
290 changed_transform_animation = true;
291 animations_[i]->set_affects_active_observers(
292 animations_[i]->affects_pending_observers());
293 }
294 auto affects_no_observers = [](const std::unique_ptr<Animation>& animation) {
295 return !animation->affects_active_observers() &&
296 !animation->affects_pending_observers();
297 };
298 animations_.erase(std::remove_if(animations_.begin(), animations_.end(),
299 affects_no_observers),
300 animations_.end());
301 scroll_offset_animation_was_interrupted_ = false;
302 UpdateActivation(NORMAL_ACTIVATION);
303 if (changed_transform_animation)
304 UpdatePotentiallyAnimatingTransform();
305 }
306
307 void LayerAnimationController::AddAnimation(
308 std::unique_ptr<Animation> animation) {
309 bool added_transform_animation =
310 animation->target_property() == TargetProperty::TRANSFORM;
311 animations_.push_back(std::move(animation));
312 needs_to_start_animations_ = true;
313 UpdateActivation(NORMAL_ACTIVATION);
314 if (added_transform_animation)
315 UpdatePotentiallyAnimatingTransform();
316 }
317
318 Animation* LayerAnimationController::GetAnimation(
319 TargetProperty::Type target_property) const {
320 for (size_t i = 0; i < animations_.size(); ++i) {
321 size_t index = animations_.size() - i - 1;
322 if (animations_[index]->target_property() == target_property)
323 return animations_[index].get();
324 }
325 return nullptr;
326 }
327
328 Animation* LayerAnimationController::GetAnimationById(int animation_id) const {
329 for (size_t i = 0; i < animations_.size(); ++i)
330 if (animations_[i]->id() == animation_id)
331 return animations_[i].get();
332 return nullptr;
333 }
334
335 bool LayerAnimationController::HasActiveAnimation() const {
336 for (size_t i = 0; i < animations_.size(); ++i) {
337 if (!animations_[i]->is_finished())
338 return true;
339 }
340 return false;
341 }
342
343 bool LayerAnimationController::IsPotentiallyAnimatingProperty(
344 TargetProperty::Type target_property,
345 ObserverType observer_type) const {
346 for (size_t i = 0; i < animations_.size(); ++i) {
347 if (!animations_[i]->is_finished() &&
348 animations_[i]->target_property() == target_property) {
349 if ((observer_type == ObserverType::ACTIVE &&
350 animations_[i]->affects_active_observers()) ||
351 (observer_type == ObserverType::PENDING &&
352 animations_[i]->affects_pending_observers()))
353 return true;
354 }
355 }
356 return false;
357 }
358
359 bool LayerAnimationController::IsCurrentlyAnimatingProperty(
360 TargetProperty::Type target_property,
361 ObserverType observer_type) const {
362 for (size_t i = 0; i < animations_.size(); ++i) {
363 if (!animations_[i]->is_finished() &&
364 animations_[i]->InEffect(last_tick_time_) &&
365 animations_[i]->target_property() == target_property) {
366 if ((observer_type == ObserverType::ACTIVE &&
367 animations_[i]->affects_active_observers()) ||
368 (observer_type == ObserverType::PENDING &&
369 animations_[i]->affects_pending_observers()))
370 return true;
371 }
372 }
373 return false;
374 }
375
376 void LayerAnimationController::SetAnimationHost(AnimationHost* host) {
377 if (host_ == host)
378 return;
379
380 if (host_)
381 host_->UnregisterAnimationController(this);
382
383 host_ = host;
384 if (host_)
385 host_->RegisterAnimationController(this);
386
387 UpdateActivation(FORCE_ACTIVATION);
388 }
389
390 void LayerAnimationController::NotifyAnimationStarted(
391 const AnimationEvent& event) {
392 if (event.is_impl_only) {
393 if (layer_animation_delegate_)
394 layer_animation_delegate_->NotifyAnimationStarted(
395 event.monotonic_time, event.target_property, event.group_id);
396 return;
397 }
398
399 for (size_t i = 0; i < animations_.size(); ++i) {
400 if (animations_[i]->group() == event.group_id &&
401 animations_[i]->target_property() == event.target_property &&
402 animations_[i]->needs_synchronized_start_time()) {
403 animations_[i]->set_needs_synchronized_start_time(false);
404 if (!animations_[i]->has_set_start_time())
405 animations_[i]->set_start_time(event.monotonic_time);
406
407 if (layer_animation_delegate_)
408 layer_animation_delegate_->NotifyAnimationStarted(
409 event.monotonic_time, event.target_property, event.group_id);
410
411 return;
412 }
413 }
414 }
415
416 void LayerAnimationController::NotifyAnimationFinished(
417 const AnimationEvent& event) {
418 if (event.is_impl_only) {
419 if (layer_animation_delegate_)
420 layer_animation_delegate_->NotifyAnimationFinished(
421 event.monotonic_time, event.target_property, event.group_id);
422 return;
423 }
424
425 for (size_t i = 0; i < animations_.size(); ++i) {
426 if (animations_[i]->group() == event.group_id &&
427 animations_[i]->target_property() == event.target_property) {
428 animations_[i]->set_received_finished_event(true);
429 if (layer_animation_delegate_)
430 layer_animation_delegate_->NotifyAnimationFinished(
431 event.monotonic_time, event.target_property, event.group_id);
432
433 return;
434 }
435 }
436 }
437
438 void LayerAnimationController::NotifyAnimationTakeover(
439 const AnimationEvent& event) {
440 DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET);
441 if (layer_animation_delegate_) {
442 std::unique_ptr<AnimationCurve> animation_curve = event.curve->Clone();
443 layer_animation_delegate_->NotifyAnimationTakeover(
444 event.monotonic_time, event.target_property, event.animation_start_time,
445 std::move(animation_curve));
446 }
447 }
448
449 void LayerAnimationController::NotifyAnimationAborted(
450 const AnimationEvent& event) {
451 bool aborted_transform_animation = false;
452 for (size_t i = 0; i < animations_.size(); ++i) {
453 if (animations_[i]->group() == event.group_id &&
454 animations_[i]->target_property() == event.target_property) {
455 animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time);
456 animations_[i]->set_received_finished_event(true);
457 if (layer_animation_delegate_)
458 layer_animation_delegate_->NotifyAnimationAborted(
459 event.monotonic_time, event.target_property, event.group_id);
460 if (event.target_property == TargetProperty::TRANSFORM)
461 aborted_transform_animation = true;
462 break;
463 }
464 }
465 if (aborted_transform_animation)
466 UpdatePotentiallyAnimatingTransform();
467 }
468
469 void LayerAnimationController::NotifyAnimationPropertyUpdate(
470 const AnimationEvent& event) {
471 bool notify_active_observers = true;
472 bool notify_pending_observers = true;
473 switch (event.target_property) {
474 case TargetProperty::OPACITY:
475 NotifyObserversOpacityAnimated(
476 event.opacity, notify_active_observers, notify_pending_observers);
477 break;
478 case TargetProperty::TRANSFORM:
479 NotifyObserversTransformAnimated(
480 event.transform, notify_active_observers, notify_pending_observers);
481 break;
482 default:
483 NOTREACHED();
484 }
485 }
486
487 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
488 for (size_t i = 0; i < animations_.size(); ++i) {
489 if (!animations_[i]->is_finished() &&
490 animations_[i]->target_property() == TargetProperty::FILTER &&
491 animations_[i]
492 ->curve()
493 ->ToFilterAnimationCurve()
494 ->HasFilterThatMovesPixels())
495 return true;
496 }
497
498 return false;
499 }
500
501 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
502 return IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM,
503 ObserverType::ACTIVE) ||
504 IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM,
505 ObserverType::PENDING);
506 }
507
508 bool LayerAnimationController::FilterAnimationBoundsForBox(
509 const gfx::BoxF& box, gfx::BoxF* bounds) const {
510 // TODO(avallee): Implement.
511 return false;
512 }
513
514 bool LayerAnimationController::TransformAnimationBoundsForBox(
515 const gfx::BoxF& box,
516 gfx::BoxF* bounds) const {
517 DCHECK(HasTransformAnimationThatInflatesBounds())
518 << "TransformAnimationBoundsForBox will give incorrect results if there "
519 << "are no transform animations affecting bounds, non-animated transform "
520 << "is not known";
521
522 // Compute bounds based on animations for which is_finished() is false.
523 // Do nothing if there are no such animations; in this case, it is assumed
524 // that callers will take care of computing bounds based on the owning layer's
525 // actual transform.
526 *bounds = gfx::BoxF();
527 for (size_t i = 0; i < animations_.size(); ++i) {
528 if (animations_[i]->is_finished() ||
529 animations_[i]->target_property() != TargetProperty::TRANSFORM)
530 continue;
531
532 const TransformAnimationCurve* transform_animation_curve =
533 animations_[i]->curve()->ToTransformAnimationCurve();
534 gfx::BoxF animation_bounds;
535 bool success =
536 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
537 if (!success)
538 return false;
539 bounds->Union(animation_bounds);
540 }
541
542 return true;
543 }
544
545 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
546 for (size_t i = 0; i < animations_.size(); ++i) {
547 if (animations_[i]->is_finished() ||
548 animations_[i]->target_property() != TargetProperty::TRANSFORM)
549 continue;
550
551 const TransformAnimationCurve* transform_animation_curve =
552 animations_[i]->curve()->ToTransformAnimationCurve();
553 if (transform_animation_curve->AffectsScale())
554 return true;
555 }
556
557 return false;
558 }
559
560 bool LayerAnimationController::HasOnlyTranslationTransforms(
561 ObserverType observer_type) const {
562 for (size_t i = 0; i < animations_.size(); ++i) {
563 if (animations_[i]->is_finished() ||
564 animations_[i]->target_property() != TargetProperty::TRANSFORM)
565 continue;
566
567 if ((observer_type == ObserverType::ACTIVE &&
568 !animations_[i]->affects_active_observers()) ||
569 (observer_type == ObserverType::PENDING &&
570 !animations_[i]->affects_pending_observers()))
571 continue;
572
573 const TransformAnimationCurve* transform_animation_curve =
574 animations_[i]->curve()->ToTransformAnimationCurve();
575 if (!transform_animation_curve->IsTranslation())
576 return false;
577 }
578
579 return true;
580 }
581
582 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
583 for (size_t i = 0; i < animations_.size(); ++i) {
584 if (animations_[i]->is_finished() ||
585 animations_[i]->target_property() != TargetProperty::TRANSFORM)
586 continue;
587
588 const TransformAnimationCurve* transform_animation_curve =
589 animations_[i]->curve()->ToTransformAnimationCurve();
590 if (!transform_animation_curve->PreservesAxisAlignment())
591 return false;
592 }
593
594 return true;
595 }
596
597 bool LayerAnimationController::AnimationStartScale(ObserverType observer_type,
598 float* start_scale) const {
599 *start_scale = 0.f;
600 for (size_t i = 0; i < animations_.size(); ++i) {
601 if (animations_[i]->is_finished() ||
602 animations_[i]->target_property() != TargetProperty::TRANSFORM)
603 continue;
604
605 if ((observer_type == ObserverType::ACTIVE &&
606 !animations_[i]->affects_active_observers()) ||
607 (observer_type == ObserverType::PENDING &&
608 !animations_[i]->affects_pending_observers()))
609 continue;
610
611 bool forward_direction = true;
612 switch (animations_[i]->direction()) {
613 case Animation::DIRECTION_NORMAL:
614 case Animation::DIRECTION_ALTERNATE:
615 forward_direction = animations_[i]->playback_rate() >= 0.0;
616 break;
617 case Animation::DIRECTION_REVERSE:
618 case Animation::DIRECTION_ALTERNATE_REVERSE:
619 forward_direction = animations_[i]->playback_rate() < 0.0;
620 break;
621 }
622
623 const TransformAnimationCurve* transform_animation_curve =
624 animations_[i]->curve()->ToTransformAnimationCurve();
625 float animation_start_scale = 0.f;
626 if (!transform_animation_curve->AnimationStartScale(forward_direction,
627 &animation_start_scale))
628 return false;
629 *start_scale = std::max(*start_scale, animation_start_scale);
630 }
631 return true;
632 }
633
634 bool LayerAnimationController::MaximumTargetScale(ObserverType observer_type,
635 float* max_scale) const {
636 *max_scale = 0.f;
637 for (size_t i = 0; i < animations_.size(); ++i) {
638 if (animations_[i]->is_finished() ||
639 animations_[i]->target_property() != TargetProperty::TRANSFORM)
640 continue;
641
642 if ((observer_type == ObserverType::ACTIVE &&
643 !animations_[i]->affects_active_observers()) ||
644 (observer_type == ObserverType::PENDING &&
645 !animations_[i]->affects_pending_observers()))
646 continue;
647
648 bool forward_direction = true;
649 switch (animations_[i]->direction()) {
650 case Animation::DIRECTION_NORMAL:
651 case Animation::DIRECTION_ALTERNATE:
652 forward_direction = animations_[i]->playback_rate() >= 0.0;
653 break;
654 case Animation::DIRECTION_REVERSE:
655 case Animation::DIRECTION_ALTERNATE_REVERSE:
656 forward_direction = animations_[i]->playback_rate() < 0.0;
657 break;
658 }
659
660 const TransformAnimationCurve* transform_animation_curve =
661 animations_[i]->curve()->ToTransformAnimationCurve();
662 float animation_scale = 0.f;
663 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
664 &animation_scale))
665 return false;
666 *max_scale = std::max(*max_scale, animation_scale);
667 }
668
669 return true;
670 }
671
672 void LayerAnimationController::PushNewAnimationsToImplThread(
673 LayerAnimationController* controller_impl) const {
674 // Any new animations owned by the main thread's controller are cloned and
675 // add to the impl thread's controller.
676 for (size_t i = 0; i < animations_.size(); ++i) {
677 // If the animation is already running on the impl thread, there is no
678 // need to copy it over.
679 if (controller_impl->GetAnimationById(animations_[i]->id()))
680 continue;
681
682 if (animations_[i]->target_property() == TargetProperty::SCROLL_OFFSET &&
683 !animations_[i]
684 ->curve()
685 ->ToScrollOffsetAnimationCurve()
686 ->HasSetInitialValue()) {
687 gfx::ScrollOffset current_scroll_offset;
688 if (controller_impl->value_provider_) {
689 current_scroll_offset =
690 controller_impl->value_provider_->ScrollOffsetForAnimation();
691 } else {
692 // The owning layer isn't yet in the active tree, so the main thread
693 // scroll offset will be up-to-date.
694 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
695 }
696 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
697 current_scroll_offset);
698 }
699
700 // The new animation should be set to run as soon as possible.
701 Animation::RunState initial_run_state =
702 Animation::WAITING_FOR_TARGET_AVAILABILITY;
703 std::unique_ptr<Animation> to_add(
704 animations_[i]->CloneAndInitialize(initial_run_state));
705 DCHECK(!to_add->needs_synchronized_start_time());
706 to_add->set_affects_active_observers(false);
707 controller_impl->AddAnimation(std::move(to_add));
708 }
709 }
710
711 static bool IsCompleted(
712 Animation* animation,
713 const LayerAnimationController* main_thread_controller) {
714 if (animation->is_impl_only()) {
715 return (animation->run_state() == Animation::WAITING_FOR_DELETION);
716 } else {
717 return !main_thread_controller->GetAnimationById(animation->id());
718 }
719 }
720
721 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
722 LayerAnimationController* controller_impl) const {
723 bool removed_transform_animation = false;
724 // Animations removed on the main thread should no longer affect pending
725 // observers, and should stop affecting active observers after the next call
726 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
727 // immediately.
728 auto& animations = controller_impl->animations_;
729 for (const auto& animation : animations) {
730 if (IsCompleted(animation.get(), this)) {
731 animation->set_affects_pending_observers(false);
732 if (animation->target_property() == TargetProperty::TRANSFORM)
733 removed_transform_animation = true;
734 }
735 }
736 auto affects_active_only_and_is_waiting_for_deletion = [](
737 const std::unique_ptr<Animation>& animation) {
738 return animation->run_state() == Animation::WAITING_FOR_DELETION &&
739 !animation->affects_pending_observers();
740 };
741 animations.erase(
742 std::remove_if(animations.begin(), animations.end(),
743 affects_active_only_and_is_waiting_for_deletion),
744 animations.end());
745
746 if (removed_transform_animation)
747 controller_impl->UpdatePotentiallyAnimatingTransform();
748 }
749
750 void LayerAnimationController::PushPropertiesToImplThread(
751 LayerAnimationController* controller_impl) {
752 for (size_t i = 0; i < animations_.size(); ++i) {
753 Animation* current_impl =
754 controller_impl->GetAnimationById(animations_[i]->id());
755 if (current_impl)
756 animations_[i]->PushPropertiesTo(current_impl);
757 }
758 controller_impl->scroll_offset_animation_was_interrupted_ =
759 scroll_offset_animation_was_interrupted_;
760 scroll_offset_animation_was_interrupted_ = false;
761 }
762
763 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
764 DCHECK(needs_to_start_animations_);
765 needs_to_start_animations_ = false;
766 // First collect running properties affecting each type of observer.
767 TargetProperties blocked_properties_for_active_observers;
768 TargetProperties blocked_properties_for_pending_observers;
769 std::vector<size_t> animations_waiting_for_target;
770
771 animations_waiting_for_target.reserve(animations_.size());
772 for (size_t i = 0; i < animations_.size(); ++i) {
773 if (animations_[i]->run_state() == Animation::STARTING ||
774 animations_[i]->run_state() == Animation::RUNNING) {
775 if (animations_[i]->affects_active_observers()) {
776 blocked_properties_for_active_observers[animations_[i]
777 ->target_property()] = true;
778 }
779 if (animations_[i]->affects_pending_observers()) {
780 blocked_properties_for_pending_observers[animations_[i]
781 ->target_property()] =
782 true;
783 }
784 } else if (animations_[i]->run_state() ==
785 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
786 animations_waiting_for_target.push_back(i);
787 }
788 }
789
790 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
791 // Collect all properties for animations with the same group id (they
792 // should all also be in the list of animations).
793 size_t animation_index = animations_waiting_for_target[i];
794 Animation* animation_waiting_for_target =
795 animations_[animation_index].get();
796 // Check for the run state again even though the animation was waiting
797 // for target because it might have changed the run state while handling
798 // previous animation in this loop (if they belong to same group).
799 if (animation_waiting_for_target->run_state() ==
800 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
801 TargetProperties enqueued_properties;
802 bool affects_active_observers =
803 animation_waiting_for_target->affects_active_observers();
804 bool affects_pending_observers =
805 animation_waiting_for_target->affects_pending_observers();
806 enqueued_properties[animation_waiting_for_target->target_property()] =
807 true;
808 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
809 if (animation_waiting_for_target->group() == animations_[j]->group()) {
810 enqueued_properties[animations_[j]->target_property()] = true;
811 affects_active_observers |=
812 animations_[j]->affects_active_observers();
813 affects_pending_observers |=
814 animations_[j]->affects_pending_observers();
815 }
816 }
817
818 // Check to see if intersection of the list of properties affected by
819 // the group and the list of currently blocked properties is null, taking
820 // into account the type(s) of observers affected by the group. In any
821 // case, the group's target properties need to be added to the lists of
822 // blocked properties.
823 bool null_intersection = true;
824 static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0,
825 "TargetProperty must be 0-based enum");
826 for (int property = TargetProperty::FIRST_TARGET_PROPERTY;
827 property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) {
828 if (enqueued_properties[property]) {
829 if (affects_active_observers) {
830 if (blocked_properties_for_active_observers[property])
831 null_intersection = false;
832 else
833 blocked_properties_for_active_observers[property] = true;
834 }
835 if (affects_pending_observers) {
836 if (blocked_properties_for_pending_observers[property])
837 null_intersection = false;
838 else
839 blocked_properties_for_pending_observers[property] = true;
840 }
841 }
842 }
843
844 // If the intersection is null, then we are free to start the animations
845 // in the group.
846 if (null_intersection) {
847 animation_waiting_for_target->SetRunState(Animation::STARTING,
848 monotonic_time);
849 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
850 if (animation_waiting_for_target->group() ==
851 animations_[j]->group()) {
852 animations_[j]->SetRunState(Animation::STARTING, monotonic_time);
853 }
854 }
855 } else {
856 needs_to_start_animations_ = true;
857 }
858 }
859 }
860 }
861
862 void LayerAnimationController::PromoteStartedAnimations(
863 base::TimeTicks monotonic_time,
864 AnimationEvents* events) {
865 for (size_t i = 0; i < animations_.size(); ++i) {
866 if (animations_[i]->run_state() == Animation::STARTING &&
867 animations_[i]->affects_active_observers()) {
868 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time);
869 if (!animations_[i]->has_set_start_time() &&
870 !animations_[i]->needs_synchronized_start_time())
871 animations_[i]->set_start_time(monotonic_time);
872 if (events) {
873 base::TimeTicks start_time;
874 if (animations_[i]->has_set_start_time())
875 start_time = animations_[i]->start_time();
876 else
877 start_time = monotonic_time;
878 AnimationEvent started_event(
879 AnimationEvent::STARTED, id_, animations_[i]->group(),
880 animations_[i]->target_property(), start_time);
881 started_event.is_impl_only = animations_[i]->is_impl_only();
882 if (started_event.is_impl_only)
883 NotifyAnimationStarted(started_event);
884 else
885 events->events_.push_back(started_event);
886 }
887 }
888 }
889 }
890
891 void LayerAnimationController::MarkFinishedAnimations(
892 base::TimeTicks monotonic_time) {
893 bool finished_transform_animation = false;
894 for (size_t i = 0; i < animations_.size(); ++i) {
895 if (!animations_[i]->is_finished() &&
896 animations_[i]->IsFinishedAt(monotonic_time)) {
897 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
898 if (animations_[i]->target_property() == TargetProperty::TRANSFORM) {
899 finished_transform_animation = true;
900 }
901 }
902 }
903 if (finished_transform_animation)
904 UpdatePotentiallyAnimatingTransform();
905 }
906
907 void LayerAnimationController::MarkAnimationsForDeletion(
908 base::TimeTicks monotonic_time,
909 AnimationEvents* events) {
910 bool marked_animations_for_deletions = false;
911 std::vector<size_t> animations_with_same_group_id;
912
913 animations_with_same_group_id.reserve(animations_.size());
914 // Non-aborted animations are marked for deletion after a corresponding
915 // AnimationEvent::FINISHED event is sent or received. This means that if
916 // we don't have an events vector, we must ensure that non-aborted animations
917 // have received a finished event before marking them for deletion.
918 for (size_t i = 0; i < animations_.size(); i++) {
919 int group_id = animations_[i]->group();
920 if (animations_[i]->run_state() == Animation::ABORTED) {
921 if (events && !animations_[i]->is_impl_only()) {
922 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id,
923 animations_[i]->target_property(),
924 monotonic_time);
925 events->events_.push_back(aborted_event);
926 }
927 // If on the compositor or on the main thread and received finish event,
928 // animation can be marked for deletion.
929 if (events || animations_[i]->received_finished_event()) {
930 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
931 monotonic_time);
932 marked_animations_for_deletions = true;
933 }
934 continue;
935 }
936
937 // If running on the compositor and need to complete an aborted animation
938 // on the main thread.
939 if (events &&
940 animations_[i]->run_state() ==
941 Animation::ABORTED_BUT_NEEDS_COMPLETION) {
942 AnimationEvent aborted_event(AnimationEvent::TAKEOVER, id_, group_id,
943 animations_[i]->target_property(),
944 monotonic_time);
945 aborted_event.animation_start_time =
946 (animations_[i]->start_time() - base::TimeTicks()).InSecondsF();
947 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
948 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
949 aborted_event.curve = scroll_offset_animation_curve->Clone();
950 // Notify the compositor that the animation is finished.
951 if (layer_animation_delegate_) {
952 layer_animation_delegate_->NotifyAnimationFinished(
953 aborted_event.monotonic_time, aborted_event.target_property,
954 aborted_event.group_id);
955 }
956 // Notify main thread.
957 events->events_.push_back(aborted_event);
958
959 // Remove the animation from the compositor.
960 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
961 monotonic_time);
962 marked_animations_for_deletions = true;
963 continue;
964 }
965
966 bool all_anims_with_same_id_are_finished = false;
967
968 // Since deleting an animation on the main thread leads to its deletion
969 // on the impl thread, we only mark a FINISHED main thread animation for
970 // deletion once it has received a FINISHED event from the impl thread.
971 bool animation_i_will_send_or_has_received_finish_event =
972 animations_[i]->is_controlling_instance() ||
973 animations_[i]->is_impl_only() ||
974 animations_[i]->received_finished_event();
975 // If an animation is finished, and not already marked for deletion,
976 // find out if all other animations in the same group are also finished.
977 if (animations_[i]->run_state() == Animation::FINISHED &&
978 animation_i_will_send_or_has_received_finish_event) {
979 // Clear the animations_with_same_group_id if it was added for
980 // the previous animation's iteration.
981 if (animations_with_same_group_id.size() > 0)
982 animations_with_same_group_id.clear();
983 all_anims_with_same_id_are_finished = true;
984 for (size_t j = 0; j < animations_.size(); ++j) {
985 bool animation_j_will_send_or_has_received_finish_event =
986 animations_[j]->is_controlling_instance() ||
987 animations_[j]->is_impl_only() ||
988 animations_[j]->received_finished_event();
989 if (group_id == animations_[j]->group()) {
990 if (!animations_[j]->is_finished() ||
991 (animations_[j]->run_state() == Animation::FINISHED &&
992 !animation_j_will_send_or_has_received_finish_event)) {
993 all_anims_with_same_id_are_finished = false;
994 break;
995 } else if (j >= i &&
996 animations_[j]->run_state() != Animation::ABORTED) {
997 // Mark down the animations which belong to the same group
998 // and is not yet aborted. If this current iteration finds that all
999 // animations with same ID are finished, then the marked
1000 // animations below will be set to WAITING_FOR_DELETION in next
1001 // iteration.
1002 animations_with_same_group_id.push_back(j);
1003 }
1004 }
1005 }
1006 }
1007 if (all_anims_with_same_id_are_finished) {
1008 // We now need to remove all animations with the same group id as
1009 // group_id (and send along animation finished notifications, if
1010 // necessary).
1011 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
1012 size_t animation_index = animations_with_same_group_id[j];
1013 if (events) {
1014 AnimationEvent finished_event(
1015 AnimationEvent::FINISHED, id_,
1016 animations_[animation_index]->group(),
1017 animations_[animation_index]->target_property(),
1018 monotonic_time);
1019 finished_event.is_impl_only =
1020 animations_[animation_index]->is_impl_only();
1021 if (finished_event.is_impl_only)
1022 NotifyAnimationFinished(finished_event);
1023 else
1024 events->events_.push_back(finished_event);
1025 }
1026 animations_[animation_index]->SetRunState(
1027 Animation::WAITING_FOR_DELETION, monotonic_time);
1028 }
1029 marked_animations_for_deletions = true;
1030 }
1031 }
1032 if (marked_animations_for_deletions)
1033 NotifyObserversAnimationWaitingForDeletion();
1034 }
1035
1036 void LayerAnimationController::MarkAbortedAnimationsForDeletion(
1037 LayerAnimationController* controller_impl) const {
1038 bool aborted_transform_animation = false;
1039 auto& animations_impl = controller_impl->animations_;
1040 for (const auto& animation_impl : animations_impl) {
1041 // If the animation has been aborted on the main thread, mark it for
1042 // deletion.
1043 if (Animation* animation = GetAnimationById(animation_impl->id())) {
1044 if (animation->run_state() == Animation::ABORTED) {
1045 animation_impl->SetRunState(Animation::WAITING_FOR_DELETION,
1046 controller_impl->last_tick_time_);
1047 animation->SetRunState(Animation::WAITING_FOR_DELETION,
1048 last_tick_time_);
1049 if (animation_impl->target_property() == TargetProperty::TRANSFORM) {
1050 aborted_transform_animation = true;
1051 }
1052 }
1053 }
1054 }
1055
1056 if (aborted_transform_animation)
1057 controller_impl->UpdatePotentiallyAnimatingTransform();
1058 }
1059
1060 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
1061 animations_.erase(
1062 std::remove_if(animations_.begin(), animations_.end(),
1063 [](const std::unique_ptr<Animation>& animation) {
1064 return animation->run_state() ==
1065 Animation::WAITING_FOR_DELETION;
1066 }),
1067 animations_.end());
1068 }
1069
1070 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
1071 for (size_t i = 0; i < animations_.size(); ++i) {
1072 if (animations_[i]->run_state() == Animation::STARTING ||
1073 animations_[i]->run_state() == Animation::RUNNING ||
1074 animations_[i]->run_state() == Animation::PAUSED) {
1075 if (!animations_[i]->InEffect(monotonic_time))
1076 continue;
1077
1078 base::TimeDelta trimmed =
1079 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
1080
1081 switch (animations_[i]->target_property()) {
1082 case TargetProperty::TRANSFORM: {
1083 const TransformAnimationCurve* transform_animation_curve =
1084 animations_[i]->curve()->ToTransformAnimationCurve();
1085 const gfx::Transform transform =
1086 transform_animation_curve->GetValue(trimmed);
1087 NotifyObserversTransformAnimated(
1088 transform,
1089 animations_[i]->affects_active_observers(),
1090 animations_[i]->affects_pending_observers());
1091 break;
1092 }
1093
1094 case TargetProperty::OPACITY: {
1095 const FloatAnimationCurve* float_animation_curve =
1096 animations_[i]->curve()->ToFloatAnimationCurve();
1097 const float opacity = std::max(
1098 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
1099 NotifyObserversOpacityAnimated(
1100 opacity,
1101 animations_[i]->affects_active_observers(),
1102 animations_[i]->affects_pending_observers());
1103 break;
1104 }
1105
1106 case TargetProperty::FILTER: {
1107 const FilterAnimationCurve* filter_animation_curve =
1108 animations_[i]->curve()->ToFilterAnimationCurve();
1109 const FilterOperations filter =
1110 filter_animation_curve->GetValue(trimmed);
1111 NotifyObserversFilterAnimated(
1112 filter,
1113 animations_[i]->affects_active_observers(),
1114 animations_[i]->affects_pending_observers());
1115 break;
1116 }
1117
1118 case TargetProperty::BACKGROUND_COLOR: {
1119 // Not yet implemented.
1120 break;
1121 }
1122
1123 case TargetProperty::SCROLL_OFFSET: {
1124 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
1125 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
1126 const gfx::ScrollOffset scroll_offset =
1127 scroll_offset_animation_curve->GetValue(trimmed);
1128 NotifyObserversScrollOffsetAnimated(
1129 scroll_offset,
1130 animations_[i]->affects_active_observers(),
1131 animations_[i]->affects_pending_observers());
1132 break;
1133 }
1134 }
1135 }
1136 }
1137 }
1138
1139 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
1140 bool force = type == FORCE_ACTIVATION;
1141 if (host_) {
1142 bool was_active = is_active_;
1143 is_active_ = false;
1144 for (size_t i = 0; i < animations_.size(); ++i) {
1145 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) {
1146 is_active_ = true;
1147 break;
1148 }
1149 }
1150
1151 if (is_active_ && (!was_active || force))
1152 host_->DidActivateAnimationController(this);
1153 else if (!is_active_ && (was_active || force))
1154 host_->DidDeactivateAnimationController(this);
1155 }
1156 }
1157
1158 void LayerAnimationController::NotifyObserversOpacityAnimated(
1159 float opacity,
1160 bool notify_active_observers,
1161 bool notify_pending_observers) {
1162 if (!value_observer_)
1163 return;
1164 if (notify_active_observers && needs_active_value_observations())
1165 value_observer_->OnOpacityAnimated(LayerTreeType::ACTIVE, opacity);
1166 if (notify_pending_observers && needs_pending_value_observations())
1167 value_observer_->OnOpacityAnimated(LayerTreeType::PENDING, opacity);
1168 }
1169
1170 void LayerAnimationController::NotifyObserversTransformAnimated(
1171 const gfx::Transform& transform,
1172 bool notify_active_observers,
1173 bool notify_pending_observers) {
1174 if (!value_observer_)
1175 return;
1176 if (notify_active_observers && needs_active_value_observations())
1177 value_observer_->OnTransformAnimated(LayerTreeType::ACTIVE, transform);
1178 if (notify_pending_observers && needs_pending_value_observations())
1179 value_observer_->OnTransformAnimated(LayerTreeType::PENDING, transform);
1180 }
1181
1182 void LayerAnimationController::NotifyObserversFilterAnimated(
1183 const FilterOperations& filters,
1184 bool notify_active_observers,
1185 bool notify_pending_observers) {
1186 if (!value_observer_)
1187 return;
1188 if (notify_active_observers && needs_active_value_observations())
1189 value_observer_->OnFilterAnimated(LayerTreeType::ACTIVE, filters);
1190 if (notify_pending_observers && needs_pending_value_observations())
1191 value_observer_->OnFilterAnimated(LayerTreeType::PENDING, filters);
1192 }
1193
1194 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1195 const gfx::ScrollOffset& scroll_offset,
1196 bool notify_active_observers,
1197 bool notify_pending_observers) {
1198 if (!value_observer_)
1199 return;
1200 if (notify_active_observers && needs_active_value_observations())
1201 value_observer_->OnScrollOffsetAnimated(LayerTreeType::ACTIVE,
1202 scroll_offset);
1203 if (notify_pending_observers && needs_pending_value_observations())
1204 value_observer_->OnScrollOffsetAnimated(LayerTreeType::PENDING,
1205 scroll_offset);
1206 }
1207
1208 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1209 if (value_observer_)
1210 value_observer_->OnAnimationWaitingForDeletion();
1211 }
1212
1213 void LayerAnimationController::
1214 NotifyObserversTransformIsPotentiallyAnimatingChanged(
1215 bool notify_active_observers,
1216 bool notify_pending_observers) {
1217 if (!value_observer_)
1218 return;
1219 if (notify_active_observers && needs_active_value_observations())
1220 value_observer_->OnTransformIsPotentiallyAnimatingChanged(
1221 LayerTreeType::ACTIVE,
1222 potentially_animating_transform_for_active_observers_);
1223 if (notify_pending_observers && needs_pending_value_observations())
1224 value_observer_->OnTransformIsPotentiallyAnimatingChanged(
1225 LayerTreeType::PENDING,
1226 potentially_animating_transform_for_pending_observers_);
1227 }
1228
1229 bool LayerAnimationController::HasValueObserver() {
1230 if (!value_observer_)
1231 return false;
1232 return needs_active_value_observations() ||
1233 needs_pending_value_observations();
1234 }
1235
1236 bool LayerAnimationController::HasActiveValueObserver() {
1237 if (!value_observer_)
1238 return false;
1239 return needs_active_value_observations();
1240 }
1241
1242 } // namespace cc
OLDNEW
« no previous file with comments | « cc/animation/layer_animation_controller.h ('k') | cc/animation/layer_animation_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698