Implements RLZTrackerDelegate on iOS.
[chromium-blink-merge.git] / cc / animation / animation_host.cc
blob8bab8abad44738bdec29391cbc0813abd28194bd
1 // Copyright 2015 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.
5 #include "cc/animation/animation_host.h"
7 #include <algorithm>
9 #include "cc/animation/animation_delegate.h"
10 #include "cc/animation/animation_id_provider.h"
11 #include "cc/animation/animation_player.h"
12 #include "cc/animation/animation_registrar.h"
13 #include "cc/animation/animation_timeline.h"
14 #include "cc/animation/element_animations.h"
15 #include "cc/animation/scroll_offset_animation_curve.h"
16 #include "cc/animation/timing_function.h"
17 #include "ui/gfx/geometry/box_f.h"
18 #include "ui/gfx/geometry/scroll_offset.h"
20 namespace cc {
22 class AnimationHost::ScrollOffsetAnimations : public AnimationDelegate {
23 public:
24 explicit ScrollOffsetAnimations(AnimationHost* animation_host)
25 : animation_host_(animation_host),
26 scroll_offset_timeline_(
27 AnimationTimeline::Create(AnimationIdProvider::NextTimelineId())),
28 scroll_offset_animation_player_(
29 AnimationPlayer::Create(AnimationIdProvider::NextPlayerId())) {
30 scroll_offset_timeline_->set_is_impl_only(true);
31 scroll_offset_animation_player_->set_layer_animation_delegate(this);
33 animation_host_->AddAnimationTimeline(scroll_offset_timeline_.get());
34 scroll_offset_timeline_->AttachPlayer(
35 scroll_offset_animation_player_.get());
38 ~ScrollOffsetAnimations() override {
39 scroll_offset_timeline_->DetachPlayer(
40 scroll_offset_animation_player_.get());
41 animation_host_->RemoveAnimationTimeline(scroll_offset_timeline_.get());
44 void ScrollAnimationCreate(int layer_id,
45 const gfx::ScrollOffset& target_offset,
46 const gfx::ScrollOffset& current_offset) {
47 scoped_ptr<ScrollOffsetAnimationCurve> curve =
48 ScrollOffsetAnimationCurve::Create(target_offset,
49 EaseInOutTimingFunction::Create());
50 curve->SetInitialValue(current_offset);
52 scoped_ptr<Animation> animation = Animation::Create(
53 curve.Pass(), AnimationIdProvider::NextAnimationId(),
54 AnimationIdProvider::NextGroupId(), Animation::SCROLL_OFFSET);
55 animation->set_is_impl_only(true);
57 DCHECK(scroll_offset_animation_player_);
58 DCHECK(scroll_offset_animation_player_->animation_timeline());
60 if (scroll_offset_animation_player_->layer_id() != layer_id) {
61 if (scroll_offset_animation_player_->layer_id())
62 scroll_offset_animation_player_->DetachLayer();
63 scroll_offset_animation_player_->AttachLayer(layer_id);
66 scroll_offset_animation_player_->AddAnimation(animation.Pass());
69 bool ScrollAnimationUpdateTarget(int layer_id,
70 const gfx::Vector2dF& scroll_delta,
71 const gfx::ScrollOffset& max_scroll_offset,
72 base::TimeTicks frame_monotonic_time) {
73 DCHECK(scroll_offset_animation_player_);
74 DCHECK_EQ(layer_id, scroll_offset_animation_player_->layer_id());
76 Animation* animation = scroll_offset_animation_player_->element_animations()
77 ->layer_animation_controller()
78 ->GetAnimation(Animation::SCROLL_OFFSET);
79 if (!animation) {
80 scroll_offset_animation_player_->DetachLayer();
81 return false;
84 ScrollOffsetAnimationCurve* curve =
85 animation->curve()->ToScrollOffsetAnimationCurve();
87 gfx::ScrollOffset new_target =
88 gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta);
89 new_target.SetToMax(gfx::ScrollOffset());
90 new_target.SetToMin(max_scroll_offset);
92 curve->UpdateTarget(animation->TrimTimeToCurrentIteration(
93 frame_monotonic_time).InSecondsF(),
94 new_target);
96 return true;
99 // AnimationDelegate implementation.
100 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
101 Animation::TargetProperty target_property,
102 int group) override {}
103 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
104 Animation::TargetProperty target_property,
105 int group) override {
106 DCHECK_EQ(target_property, Animation::SCROLL_OFFSET);
107 DCHECK(animation_host_->mutator_host_client());
108 animation_host_->mutator_host_client()->ScrollOffsetAnimationFinished();
111 private:
112 AnimationHost* animation_host_;
113 scoped_refptr<AnimationTimeline> scroll_offset_timeline_;
115 // We have just one player for impl-only scroll offset animations.
116 // I.e. only one layer can have an impl-only scroll offset animation at
117 // any given time.
118 scoped_refptr<AnimationPlayer> scroll_offset_animation_player_;
120 DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimations);
123 scoped_ptr<AnimationHost> AnimationHost::Create(
124 ThreadInstance thread_instance) {
125 return make_scoped_ptr(new AnimationHost(thread_instance));
128 AnimationHost::AnimationHost(ThreadInstance thread_instance)
129 : animation_registrar_(AnimationRegistrar::Create()),
130 mutator_host_client_(nullptr),
131 thread_instance_(thread_instance) {
132 if (thread_instance_ == ThreadInstance::IMPL)
133 scroll_offset_animations_ =
134 make_scoped_ptr(new ScrollOffsetAnimations(this));
137 AnimationHost::~AnimationHost() {
138 scroll_offset_animations_ = nullptr;
140 ClearTimelines();
141 DCHECK(!mutator_host_client());
142 DCHECK(layer_to_element_animations_map_.empty());
145 AnimationTimeline* AnimationHost::GetTimelineById(int timeline_id) const {
146 for (auto& timeline : timelines_)
147 if (timeline->id() == timeline_id)
148 return timeline.get();
149 return nullptr;
152 void AnimationHost::ClearTimelines() {
153 EraseTimelines(timelines_.begin(), timelines_.end());
156 void AnimationHost::EraseTimelines(AnimationTimelineList::iterator begin,
157 AnimationTimelineList::iterator end) {
158 for (auto i = begin; i != end; ++i) {
159 auto& timeline = *i;
160 timeline->ClearPlayers();
161 timeline->SetAnimationHost(nullptr);
164 timelines_.erase(begin, end);
167 void AnimationHost::AddAnimationTimeline(
168 scoped_refptr<AnimationTimeline> timeline) {
169 timeline->SetAnimationHost(this);
170 timelines_.push_back(timeline);
173 void AnimationHost::RemoveAnimationTimeline(
174 scoped_refptr<AnimationTimeline> timeline) {
175 for (auto iter = timelines_.begin(); iter != timelines_.end(); ++iter) {
176 if (iter->get() != timeline)
177 continue;
179 EraseTimelines(iter, iter + 1);
180 break;
184 void AnimationHost::RegisterLayer(int layer_id, LayerTreeType tree_type) {
185 ElementAnimations* element_animations =
186 GetElementAnimationsForLayerId(layer_id);
187 if (element_animations)
188 element_animations->LayerRegistered(layer_id, tree_type);
191 void AnimationHost::UnregisterLayer(int layer_id, LayerTreeType tree_type) {
192 ElementAnimations* element_animations =
193 GetElementAnimationsForLayerId(layer_id);
194 if (element_animations)
195 element_animations->LayerUnregistered(layer_id, tree_type);
198 void AnimationHost::RegisterPlayerForLayer(int layer_id,
199 AnimationPlayer* player) {
200 DCHECK(layer_id);
201 DCHECK(player);
203 ElementAnimations* element_animations =
204 GetElementAnimationsForLayerId(layer_id);
205 if (!element_animations) {
206 auto new_element_animations = ElementAnimations::Create(this);
207 element_animations = new_element_animations.get();
209 layer_to_element_animations_map_.add(layer_id,
210 new_element_animations.Pass());
211 element_animations->CreateLayerAnimationController(layer_id);
214 DCHECK(element_animations);
215 element_animations->AddPlayer(player);
218 void AnimationHost::UnregisterPlayerForLayer(int layer_id,
219 AnimationPlayer* player) {
220 DCHECK(layer_id);
221 DCHECK(player);
223 ElementAnimations* element_animations =
224 GetElementAnimationsForLayerId(layer_id);
225 DCHECK(element_animations);
226 element_animations->RemovePlayer(player);
228 if (element_animations->IsEmpty()) {
229 element_animations->DestroyLayerAnimationController();
230 layer_to_element_animations_map_.erase(layer_id);
231 element_animations = nullptr;
235 void AnimationHost::SetMutatorHostClient(MutatorHostClient* client) {
236 if (mutator_host_client_ == client)
237 return;
239 mutator_host_client_ = client;
242 void AnimationHost::SetNeedsCommit() {
243 DCHECK(mutator_host_client_);
244 mutator_host_client_->SetMutatorsNeedCommit();
247 void AnimationHost::PushPropertiesTo(AnimationHost* host_impl) {
248 PushTimelinesToImplThread(host_impl);
249 RemoveTimelinesFromImplThread(host_impl);
250 PushPropertiesToImplThread(host_impl);
253 void AnimationHost::PushTimelinesToImplThread(AnimationHost* host_impl) const {
254 for (auto& timeline : timelines_) {
255 AnimationTimeline* timeline_impl =
256 host_impl->GetTimelineById(timeline->id());
257 if (timeline_impl)
258 continue;
260 scoped_refptr<AnimationTimeline> to_add = timeline->CreateImplInstance();
261 host_impl->AddAnimationTimeline(to_add.get());
265 void AnimationHost::RemoveTimelinesFromImplThread(
266 AnimationHost* host_impl) const {
267 AnimationTimelineList& timelines_impl = host_impl->timelines_;
269 auto to_erase =
270 std::partition(timelines_impl.begin(), timelines_impl.end(),
271 [this](AnimationTimelineList::value_type timeline_impl) {
272 return timeline_impl->is_impl_only() ||
273 GetTimelineById(timeline_impl->id());
276 host_impl->EraseTimelines(to_erase, timelines_impl.end());
279 void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_impl) {
280 // Firstly, sync all players with impl thread to create ElementAnimations and
281 // layer animation controllers.
282 for (auto& timeline : timelines_) {
283 AnimationTimeline* timeline_impl =
284 host_impl->GetTimelineById(timeline->id());
285 if (timeline_impl)
286 timeline->PushPropertiesTo(timeline_impl);
289 // Secondly, sync properties for created layer animation controllers.
290 for (auto& kv : layer_to_element_animations_map_) {
291 ElementAnimations* element_animations = kv.second;
292 ElementAnimations* element_animations_impl =
293 host_impl->GetElementAnimationsForLayerId(kv.first);
294 if (element_animations_impl)
295 element_animations->PushPropertiesTo(element_animations_impl);
299 LayerAnimationController* AnimationHost::GetControllerForLayerId(
300 int layer_id) const {
301 const ElementAnimations* element_animations =
302 GetElementAnimationsForLayerId(layer_id);
303 if (!element_animations)
304 return nullptr;
306 return element_animations->layer_animation_controller();
309 ElementAnimations* AnimationHost::GetElementAnimationsForLayerId(
310 int layer_id) const {
311 DCHECK(layer_id);
312 auto iter = layer_to_element_animations_map_.find(layer_id);
313 return iter == layer_to_element_animations_map_.end() ? nullptr
314 : iter->second;
317 void AnimationHost::SetSupportsScrollAnimations(
318 bool supports_scroll_animations) {
319 animation_registrar_->set_supports_scroll_animations(
320 supports_scroll_animations);
323 bool AnimationHost::SupportsScrollAnimations() const {
324 return animation_registrar_->supports_scroll_animations();
327 bool AnimationHost::NeedsAnimateLayers() const {
328 return animation_registrar_->needs_animate_layers();
331 bool AnimationHost::ActivateAnimations() {
332 return animation_registrar_->ActivateAnimations();
335 bool AnimationHost::AnimateLayers(base::TimeTicks monotonic_time) {
336 return animation_registrar_->AnimateLayers(monotonic_time);
339 bool AnimationHost::UpdateAnimationState(bool start_ready_animations,
340 AnimationEventsVector* events) {
341 return animation_registrar_->UpdateAnimationState(start_ready_animations,
342 events);
345 scoped_ptr<AnimationEventsVector> AnimationHost::CreateEvents() {
346 return animation_registrar_->CreateEvents();
349 void AnimationHost::SetAnimationEvents(
350 scoped_ptr<AnimationEventsVector> events) {
351 return animation_registrar_->SetAnimationEvents(events.Pass());
354 bool AnimationHost::ScrollOffsetAnimationWasInterrupted(int layer_id) const {
355 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
356 return controller ? controller->scroll_offset_animation_was_interrupted()
357 : false;
360 bool AnimationHost::IsAnimatingFilterProperty(int layer_id) const {
361 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
362 return controller ? controller->IsAnimatingProperty(Animation::FILTER)
363 : false;
366 bool AnimationHost::IsAnimatingOpacityProperty(int layer_id) const {
367 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
368 return controller ? controller->IsAnimatingProperty(Animation::OPACITY)
369 : false;
372 bool AnimationHost::IsAnimatingTransformProperty(int layer_id) const {
373 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
374 return controller ? controller->IsAnimatingProperty(Animation::TRANSFORM)
375 : false;
378 bool AnimationHost::HasPotentiallyRunningOpacityAnimation(int layer_id) const {
379 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
380 if (!controller)
381 return false;
383 Animation* animation = controller->GetAnimation(Animation::OPACITY);
384 return animation && !animation->is_finished();
387 bool AnimationHost::HasPotentiallyRunningTransformAnimation(
388 int layer_id) const {
389 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
390 if (!controller)
391 return false;
393 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
394 return animation && !animation->is_finished();
397 bool AnimationHost::HasAnyAnimationTargetingProperty(
398 int layer_id,
399 Animation::TargetProperty property) const {
400 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
401 if (!controller)
402 return false;
404 return !!controller->GetAnimation(property);
407 bool AnimationHost::FilterIsAnimatingOnImplOnly(int layer_id) const {
408 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
409 if (!controller)
410 return false;
412 Animation* animation = controller->GetAnimation(Animation::FILTER);
413 return animation && animation->is_impl_only();
416 bool AnimationHost::OpacityIsAnimatingOnImplOnly(int layer_id) const {
417 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
418 if (!controller)
419 return false;
421 Animation* animation = controller->GetAnimation(Animation::OPACITY);
422 return animation && animation->is_impl_only();
425 bool AnimationHost::TransformIsAnimatingOnImplOnly(int layer_id) const {
426 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
427 if (!controller)
428 return false;
430 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
431 return animation && animation->is_impl_only();
434 bool AnimationHost::HasFilterAnimationThatInflatesBounds(int layer_id) const {
435 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
436 return controller ? controller->HasFilterAnimationThatInflatesBounds()
437 : false;
440 bool AnimationHost::HasTransformAnimationThatInflatesBounds(
441 int layer_id) const {
442 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
443 return controller ? controller->HasTransformAnimationThatInflatesBounds()
444 : false;
447 bool AnimationHost::HasAnimationThatInflatesBounds(int layer_id) const {
448 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
449 return controller ? controller->HasAnimationThatInflatesBounds() : false;
452 bool AnimationHost::FilterAnimationBoundsForBox(int layer_id,
453 const gfx::BoxF& box,
454 gfx::BoxF* bounds) const {
455 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
456 return controller ? controller->FilterAnimationBoundsForBox(box, bounds)
457 : false;
460 bool AnimationHost::TransformAnimationBoundsForBox(int layer_id,
461 const gfx::BoxF& box,
462 gfx::BoxF* bounds) const {
463 *bounds = gfx::BoxF();
464 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
465 return controller ? controller->TransformAnimationBoundsForBox(box, bounds)
466 : true;
469 bool AnimationHost::HasOnlyTranslationTransforms(int layer_id) const {
470 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
471 return controller ? controller->HasOnlyTranslationTransforms() : true;
474 bool AnimationHost::AnimationsPreserveAxisAlignment(int layer_id) const {
475 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
476 return controller ? controller->AnimationsPreserveAxisAlignment() : true;
479 bool AnimationHost::MaximumTargetScale(int layer_id, float* max_scale) const {
480 *max_scale = 0.f;
481 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
482 return controller ? controller->MaximumTargetScale(max_scale) : true;
485 bool AnimationHost::AnimationStartScale(int layer_id,
486 float* start_scale) const {
487 *start_scale = 0.f;
488 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
489 return controller ? controller->AnimationStartScale(start_scale) : true;
492 bool AnimationHost::HasAnyAnimation(int layer_id) const {
493 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
494 return controller ? controller->has_any_animation() : false;
497 bool AnimationHost::HasActiveAnimation(int layer_id) const {
498 LayerAnimationController* controller = GetControllerForLayerId(layer_id);
499 return controller ? controller->HasActiveAnimation() : false;
502 void AnimationHost::ImplOnlyScrollAnimationCreate(
503 int layer_id,
504 const gfx::ScrollOffset& target_offset,
505 const gfx::ScrollOffset& current_offset) {
506 DCHECK(scroll_offset_animations_);
507 scroll_offset_animations_->ScrollAnimationCreate(layer_id, target_offset,
508 current_offset);
511 bool AnimationHost::ImplOnlyScrollAnimationUpdateTarget(
512 int layer_id,
513 const gfx::Vector2dF& scroll_delta,
514 const gfx::ScrollOffset& max_scroll_offset,
515 base::TimeTicks frame_monotonic_time) {
516 DCHECK(scroll_offset_animations_);
517 return scroll_offset_animations_->ScrollAnimationUpdateTarget(
518 layer_id, scroll_delta, max_scroll_offset, frame_monotonic_time);
521 } // namespace cc