| 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 |