OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/animation/element_animations.h" | 5 #include "cc/animation/element_animations.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 } | 26 } |
27 | 27 |
28 ElementAnimations::ElementAnimations() | 28 ElementAnimations::ElementAnimations() |
29 : players_list_(new PlayersList()), | 29 : players_list_(new PlayersList()), |
30 animation_host_(), | 30 animation_host_(), |
31 element_id_(), | 31 element_id_(), |
32 is_active_(false), | 32 is_active_(false), |
33 has_element_in_active_list_(false), | 33 has_element_in_active_list_(false), |
34 has_element_in_pending_list_(false), | 34 has_element_in_pending_list_(false), |
35 needs_to_start_animations_(false), | 35 needs_to_start_animations_(false), |
36 scroll_offset_animation_was_interrupted_(false) {} | 36 scroll_offset_animation_was_interrupted_(false), |
| 37 needs_push_properties_(false) {} |
37 | 38 |
38 ElementAnimations::~ElementAnimations() {} | 39 ElementAnimations::~ElementAnimations() {} |
39 | 40 |
40 void ElementAnimations::SetAnimationHost(AnimationHost* host) { | 41 void ElementAnimations::SetAnimationHost(AnimationHost* host) { |
41 animation_host_ = host; | 42 animation_host_ = host; |
42 } | 43 } |
43 | 44 |
44 void ElementAnimations::SetElementId(ElementId element_id) { | 45 void ElementAnimations::SetElementId(ElementId element_id) { |
45 element_id_ = element_id; | 46 element_id_ = element_id; |
46 } | 47 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 116 } |
116 | 117 |
117 void ElementAnimations::RemovePlayer(AnimationPlayer* player) { | 118 void ElementAnimations::RemovePlayer(AnimationPlayer* player) { |
118 players_list_->RemoveObserver(player); | 119 players_list_->RemoveObserver(player); |
119 } | 120 } |
120 | 121 |
121 bool ElementAnimations::IsEmpty() const { | 122 bool ElementAnimations::IsEmpty() const { |
122 return !players_list_->might_have_observers(); | 123 return !players_list_->might_have_observers(); |
123 } | 124 } |
124 | 125 |
| 126 void ElementAnimations::SetNeedsPushProperties() { |
| 127 needs_push_properties_ = true; |
| 128 } |
| 129 |
125 void ElementAnimations::PushPropertiesTo( | 130 void ElementAnimations::PushPropertiesTo( |
126 scoped_refptr<ElementAnimations> element_animations_impl) { | 131 scoped_refptr<ElementAnimations> element_animations_impl) { |
127 DCHECK_NE(this, element_animations_impl); | 132 DCHECK_NE(this, element_animations_impl); |
| 133 |
| 134 if (!needs_push_properties_) |
| 135 return; |
| 136 needs_push_properties_ = false; |
| 137 |
128 if (!has_any_animation() && !element_animations_impl->has_any_animation()) | 138 if (!has_any_animation() && !element_animations_impl->has_any_animation()) |
129 return; | 139 return; |
130 MarkAbortedAnimationsForDeletion(element_animations_impl.get()); | 140 MarkAbortedAnimationsForDeletion(element_animations_impl.get()); |
131 PurgeAnimationsMarkedForDeletion(); | 141 PurgeAnimationsMarkedForDeletion(); |
132 PushNewAnimationsToImplThread(element_animations_impl.get()); | 142 PushNewAnimationsToImplThread(element_animations_impl.get()); |
133 | 143 |
134 // Remove finished impl side animations only after pushing, | 144 // Remove finished impl side animations only after pushing, |
135 // and only after the animations are deleted on the main thread | 145 // and only after the animations are deleted on the main thread |
136 // this insures we will never push an animation twice. | 146 // this insures we will never push an animation twice. |
137 RemoveAnimationsCompletedOnMainThread(element_animations_impl.get()); | 147 RemoveAnimationsCompletedOnMainThread(element_animations_impl.get()); |
(...skipping 12 matching lines...) Expand all Loading... |
150 UpdateActivation(NORMAL_ACTIVATION); | 160 UpdateActivation(NORMAL_ACTIVATION); |
151 switch (target_property) { | 161 switch (target_property) { |
152 case TargetProperty::TRANSFORM: | 162 case TargetProperty::TRANSFORM: |
153 case TargetProperty::OPACITY: | 163 case TargetProperty::OPACITY: |
154 case TargetProperty::FILTER: | 164 case TargetProperty::FILTER: |
155 UpdateClientAnimationState(target_property); | 165 UpdateClientAnimationState(target_property); |
156 break; | 166 break; |
157 default: | 167 default: |
158 break; | 168 break; |
159 } | 169 } |
| 170 SetNeedsPushProperties(); |
160 } | 171 } |
161 | 172 |
162 void ElementAnimations::Animate(base::TimeTicks monotonic_time) { | 173 void ElementAnimations::Animate(base::TimeTicks monotonic_time) { |
163 DCHECK(!monotonic_time.is_null()); | 174 DCHECK(!monotonic_time.is_null()); |
164 if (!has_element_in_active_list() && !has_element_in_pending_list()) | 175 if (!has_element_in_active_list() && !has_element_in_pending_list()) |
165 return; | 176 return; |
166 | 177 |
167 if (needs_to_start_animations_) | 178 if (needs_to_start_animations_) |
168 StartAnimations(monotonic_time); | 179 StartAnimations(monotonic_time); |
169 TickAnimations(monotonic_time); | 180 TickAnimations(monotonic_time); |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 else | 890 else |
880 events->events_.push_back(finished_event); | 891 events->events_.push_back(finished_event); |
881 } | 892 } |
882 animations_[animation_index]->SetRunState( | 893 animations_[animation_index]->SetRunState( |
883 Animation::WAITING_FOR_DELETION, monotonic_time); | 894 Animation::WAITING_FOR_DELETION, monotonic_time); |
884 } | 895 } |
885 marked_animations_for_deletions = true; | 896 marked_animations_for_deletions = true; |
886 } | 897 } |
887 } | 898 } |
888 if (marked_animations_for_deletions) | 899 if (marked_animations_for_deletions) |
889 NotifyClientAnimationWaitingForDeletion(); | 900 NotifyPlayersAnimationWaitingForDeletion(); |
890 } | 901 } |
891 | 902 |
892 void ElementAnimations::MarkAbortedAnimationsForDeletion( | 903 void ElementAnimations::MarkAbortedAnimationsForDeletion( |
893 ElementAnimations* element_animations_impl) const { | 904 ElementAnimations* element_animations_impl) const { |
894 bool aborted_transform_animation = false; | 905 bool aborted_transform_animation = false; |
895 bool aborted_opacity_animation = false; | 906 bool aborted_opacity_animation = false; |
896 bool aborted_filter_animation = false; | 907 bool aborted_filter_animation = false; |
897 auto& animations_impl = element_animations_impl->animations_; | 908 auto& animations_impl = element_animations_impl->animations_; |
898 for (const auto& animation_impl : animations_impl) { | 909 for (const auto& animation_impl : animations_impl) { |
899 // If the animation has been aborted on the main thread, mark it for | 910 // If the animation has been aborted on the main thread, mark it for |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 void ElementAnimations::NotifyClientScrollOffsetAnimated( | 1069 void ElementAnimations::NotifyClientScrollOffsetAnimated( |
1059 const gfx::ScrollOffset& scroll_offset, | 1070 const gfx::ScrollOffset& scroll_offset, |
1060 bool notify_active_elements, | 1071 bool notify_active_elements, |
1061 bool notify_pending_elements) { | 1072 bool notify_pending_elements) { |
1062 if (notify_active_elements && has_element_in_active_list()) | 1073 if (notify_active_elements && has_element_in_active_list()) |
1063 OnScrollOffsetAnimated(ElementListType::ACTIVE, scroll_offset); | 1074 OnScrollOffsetAnimated(ElementListType::ACTIVE, scroll_offset); |
1064 if (notify_pending_elements && has_element_in_pending_list()) | 1075 if (notify_pending_elements && has_element_in_pending_list()) |
1065 OnScrollOffsetAnimated(ElementListType::PENDING, scroll_offset); | 1076 OnScrollOffsetAnimated(ElementListType::PENDING, scroll_offset); |
1066 } | 1077 } |
1067 | 1078 |
1068 void ElementAnimations::NotifyClientAnimationWaitingForDeletion() { | |
1069 OnAnimationWaitingForDeletion(); | |
1070 } | |
1071 | |
1072 void ElementAnimations::NotifyClientAnimationChanged( | 1079 void ElementAnimations::NotifyClientAnimationChanged( |
1073 TargetProperty::Type property, | 1080 TargetProperty::Type property, |
1074 ElementListType list_type, | 1081 ElementListType list_type, |
1075 bool notify_elements_about_potential_animation, | 1082 bool notify_elements_about_potential_animation, |
1076 bool notify_elements_about_running_animation) { | 1083 bool notify_elements_about_running_animation) { |
1077 struct PropertyAnimationState* animation_state = nullptr; | 1084 struct PropertyAnimationState* animation_state = nullptr; |
1078 switch (property) { | 1085 switch (property) { |
1079 case TargetProperty::OPACITY: | 1086 case TargetProperty::OPACITY: |
1080 animation_state = &opacity_animation_state_; | 1087 animation_state = &opacity_animation_state_; |
1081 break; | 1088 break; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 | 1245 |
1239 void ElementAnimations::PauseAnimation(int animation_id, | 1246 void ElementAnimations::PauseAnimation(int animation_id, |
1240 base::TimeDelta time_offset) { | 1247 base::TimeDelta time_offset) { |
1241 for (size_t i = 0; i < animations_.size(); ++i) { | 1248 for (size_t i = 0; i < animations_.size(); ++i) { |
1242 if (animations_[i]->id() == animation_id) { | 1249 if (animations_[i]->id() == animation_id) { |
1243 animations_[i]->SetRunState(Animation::PAUSED, | 1250 animations_[i]->SetRunState(Animation::PAUSED, |
1244 time_offset + animations_[i]->start_time() + | 1251 time_offset + animations_[i]->start_time() + |
1245 animations_[i]->time_offset()); | 1252 animations_[i]->time_offset()); |
1246 } | 1253 } |
1247 } | 1254 } |
| 1255 SetNeedsPushProperties(); |
1248 } | 1256 } |
1249 | 1257 |
1250 void ElementAnimations::RemoveAnimation(int animation_id) { | 1258 void ElementAnimations::RemoveAnimation(int animation_id) { |
1251 bool removed_transform_animation = false; | 1259 bool removed_transform_animation = false; |
1252 bool removed_opacity_animation = false; | 1260 bool removed_opacity_animation = false; |
1253 bool removed_filter_animation = false; | 1261 bool removed_filter_animation = false; |
1254 // Since we want to use the animations that we're going to remove, we need to | 1262 // Since we want to use the animations that we're going to remove, we need to |
1255 // use a stable_parition here instead of remove_if. Remove_if leaves the | 1263 // use a stable_parition here instead of remove_if. Remove_if leaves the |
1256 // removed items in an unspecified state. | 1264 // removed items in an unspecified state. |
1257 auto animations_to_remove = std::stable_partition( | 1265 auto animations_to_remove = std::stable_partition( |
(...skipping 17 matching lines...) Expand all Loading... |
1275 } | 1283 } |
1276 | 1284 |
1277 animations_.erase(animations_to_remove, animations_.end()); | 1285 animations_.erase(animations_to_remove, animations_.end()); |
1278 UpdateActivation(NORMAL_ACTIVATION); | 1286 UpdateActivation(NORMAL_ACTIVATION); |
1279 if (removed_transform_animation) | 1287 if (removed_transform_animation) |
1280 UpdateClientAnimationState(TargetProperty::TRANSFORM); | 1288 UpdateClientAnimationState(TargetProperty::TRANSFORM); |
1281 if (removed_opacity_animation) | 1289 if (removed_opacity_animation) |
1282 UpdateClientAnimationState(TargetProperty::OPACITY); | 1290 UpdateClientAnimationState(TargetProperty::OPACITY); |
1283 if (removed_filter_animation) | 1291 if (removed_filter_animation) |
1284 UpdateClientAnimationState(TargetProperty::FILTER); | 1292 UpdateClientAnimationState(TargetProperty::FILTER); |
| 1293 |
| 1294 SetNeedsPushProperties(); |
1285 } | 1295 } |
1286 | 1296 |
1287 void ElementAnimations::AbortAnimation(int animation_id) { | 1297 void ElementAnimations::AbortAnimation(int animation_id) { |
1288 if (Animation* animation = GetAnimationById(animation_id)) { | 1298 if (Animation* animation = GetAnimationById(animation_id)) { |
1289 if (!animation->is_finished()) { | 1299 if (!animation->is_finished()) { |
1290 animation->SetRunState(Animation::ABORTED, last_tick_time_); | 1300 animation->SetRunState(Animation::ABORTED, last_tick_time_); |
1291 switch (animation->target_property()) { | 1301 switch (animation->target_property()) { |
1292 case TargetProperty::TRANSFORM: | 1302 case TargetProperty::TRANSFORM: |
1293 case TargetProperty::OPACITY: | 1303 case TargetProperty::OPACITY: |
1294 case TargetProperty::FILTER: | 1304 case TargetProperty::FILTER: |
1295 UpdateClientAnimationState(animation->target_property()); | 1305 UpdateClientAnimationState(animation->target_property()); |
1296 break; | 1306 break; |
1297 default: | 1307 default: |
1298 break; | 1308 break; |
1299 } | 1309 } |
1300 } | 1310 } |
1301 } | 1311 } |
| 1312 |
| 1313 SetNeedsPushProperties(); |
1302 } | 1314 } |
1303 | 1315 |
1304 void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, | 1316 void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, |
1305 bool needs_completion) { | 1317 bool needs_completion) { |
1306 if (needs_completion) | 1318 if (needs_completion) |
1307 DCHECK(target_property == TargetProperty::SCROLL_OFFSET); | 1319 DCHECK(target_property == TargetProperty::SCROLL_OFFSET); |
1308 | 1320 |
1309 bool aborted_animation = false; | 1321 bool aborted_animation = false; |
1310 for (size_t i = 0; i < animations_.size(); ++i) { | 1322 for (size_t i = 0; i < animations_.size(); ++i) { |
1311 if (animations_[i]->target_property() == target_property && | 1323 if (animations_[i]->target_property() == target_property && |
(...skipping 13 matching lines...) Expand all Loading... |
1325 switch (target_property) { | 1337 switch (target_property) { |
1326 case TargetProperty::TRANSFORM: | 1338 case TargetProperty::TRANSFORM: |
1327 case TargetProperty::OPACITY: | 1339 case TargetProperty::OPACITY: |
1328 case TargetProperty::FILTER: | 1340 case TargetProperty::FILTER: |
1329 UpdateClientAnimationState(target_property); | 1341 UpdateClientAnimationState(target_property); |
1330 break; | 1342 break; |
1331 default: | 1343 default: |
1332 break; | 1344 break; |
1333 } | 1345 } |
1334 } | 1346 } |
| 1347 |
| 1348 SetNeedsPushProperties(); |
1335 } | 1349 } |
1336 | 1350 |
1337 Animation* ElementAnimations::GetAnimation( | 1351 Animation* ElementAnimations::GetAnimation( |
1338 TargetProperty::Type target_property) const { | 1352 TargetProperty::Type target_property) const { |
1339 for (size_t i = 0; i < animations_.size(); ++i) { | 1353 for (size_t i = 0; i < animations_.size(); ++i) { |
1340 size_t index = animations_.size() - i - 1; | 1354 size_t index = animations_.size() - i - 1; |
1341 if (animations_[index]->target_property() == target_property) | 1355 if (animations_[index]->target_property() == target_property) |
1342 return animations_[index].get(); | 1356 return animations_[index].get(); |
1343 } | 1357 } |
1344 return nullptr; | 1358 return nullptr; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 void ElementAnimations::OnScrollOffsetAnimated( | 1395 void ElementAnimations::OnScrollOffsetAnimated( |
1382 ElementListType list_type, | 1396 ElementListType list_type, |
1383 const gfx::ScrollOffset& scroll_offset) { | 1397 const gfx::ScrollOffset& scroll_offset) { |
1384 DCHECK(element_id()); | 1398 DCHECK(element_id()); |
1385 DCHECK(animation_host()); | 1399 DCHECK(animation_host()); |
1386 DCHECK(animation_host()->mutator_host_client()); | 1400 DCHECK(animation_host()->mutator_host_client()); |
1387 animation_host()->mutator_host_client()->SetElementScrollOffsetMutated( | 1401 animation_host()->mutator_host_client()->SetElementScrollOffsetMutated( |
1388 element_id(), list_type, scroll_offset); | 1402 element_id(), list_type, scroll_offset); |
1389 } | 1403 } |
1390 | 1404 |
1391 void ElementAnimations::OnAnimationWaitingForDeletion() { | |
1392 // TODO(loyso): Invalidate AnimationHost::SetNeedsPushProperties here. | |
1393 // But we always do PushProperties in AnimationHost for now. crbug.com/604280 | |
1394 DCHECK(animation_host()); | |
1395 animation_host()->OnAnimationWaitingForDeletion(); | |
1396 } | |
1397 | |
1398 void ElementAnimations::IsAnimatingChanged(ElementListType list_type, | 1405 void ElementAnimations::IsAnimatingChanged(ElementListType list_type, |
1399 TargetProperty::Type property, | 1406 TargetProperty::Type property, |
1400 AnimationChangeType change_type, | 1407 AnimationChangeType change_type, |
1401 bool is_animating) { | 1408 bool is_animating) { |
1402 if (!element_id()) | 1409 if (!element_id()) |
1403 return; | 1410 return; |
1404 DCHECK(animation_host()); | 1411 DCHECK(animation_host()); |
1405 if (animation_host()->mutator_host_client()) { | 1412 if (animation_host()->mutator_host_client()) { |
1406 switch (property) { | 1413 switch (property) { |
1407 case TargetProperty::OPACITY: | 1414 case TargetProperty::OPACITY: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 void ElementAnimations::NotifyPlayersAnimationAborted( | 1461 void ElementAnimations::NotifyPlayersAnimationAborted( |
1455 base::TimeTicks monotonic_time, | 1462 base::TimeTicks monotonic_time, |
1456 TargetProperty::Type target_property, | 1463 TargetProperty::Type target_property, |
1457 int group) { | 1464 int group) { |
1458 ElementAnimations::PlayersList::Iterator it(players_list_.get()); | 1465 ElementAnimations::PlayersList::Iterator it(players_list_.get()); |
1459 AnimationPlayer* player; | 1466 AnimationPlayer* player; |
1460 while ((player = it.GetNext()) != nullptr) | 1467 while ((player = it.GetNext()) != nullptr) |
1461 player->NotifyAnimationAborted(monotonic_time, target_property, group); | 1468 player->NotifyAnimationAborted(monotonic_time, target_property, group); |
1462 } | 1469 } |
1463 | 1470 |
| 1471 void ElementAnimations::NotifyPlayersAnimationWaitingForDeletion() { |
| 1472 ElementAnimations::PlayersList::Iterator it(players_list_.get()); |
| 1473 AnimationPlayer* player; |
| 1474 while ((player = it.GetNext()) != nullptr) |
| 1475 player->NotifyAnimationWaitingForDeletion(); |
| 1476 } |
| 1477 |
1464 void ElementAnimations::NotifyPlayersAnimationTakeover( | 1478 void ElementAnimations::NotifyPlayersAnimationTakeover( |
1465 base::TimeTicks monotonic_time, | 1479 base::TimeTicks monotonic_time, |
1466 TargetProperty::Type target_property, | 1480 TargetProperty::Type target_property, |
1467 double animation_start_time, | 1481 double animation_start_time, |
1468 std::unique_ptr<AnimationCurve> curve) { | 1482 std::unique_ptr<AnimationCurve> curve) { |
1469 DCHECK(curve); | 1483 DCHECK(curve); |
1470 ElementAnimations::PlayersList::Iterator it(players_list_.get()); | 1484 ElementAnimations::PlayersList::Iterator it(players_list_.get()); |
1471 AnimationPlayer* player; | 1485 AnimationPlayer* player; |
1472 while ((player = it.GetNext()) != nullptr) { | 1486 while ((player = it.GetNext()) != nullptr) { |
1473 std::unique_ptr<AnimationCurve> animation_curve = curve->Clone(); | 1487 std::unique_ptr<AnimationCurve> animation_curve = curve->Clone(); |
1474 player->NotifyAnimationTakeover(monotonic_time, target_property, | 1488 player->NotifyAnimationTakeover(monotonic_time, target_property, |
1475 animation_start_time, | 1489 animation_start_time, |
1476 std::move(animation_curve)); | 1490 std::move(animation_curve)); |
1477 } | 1491 } |
1478 } | 1492 } |
1479 | 1493 |
1480 gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const { | 1494 gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const { |
1481 if (animation_host()) { | 1495 if (animation_host()) { |
1482 DCHECK(animation_host()->mutator_host_client()); | 1496 DCHECK(animation_host()->mutator_host_client()); |
1483 return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation( | 1497 return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation( |
1484 element_id()); | 1498 element_id()); |
1485 } | 1499 } |
1486 | 1500 |
1487 return gfx::ScrollOffset(); | 1501 return gfx::ScrollOffset(); |
1488 } | 1502 } |
1489 | 1503 |
1490 } // namespace cc | 1504 } // namespace cc |
OLD | NEW |