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

Unified Diff: cc/animation/element_animations.cc

Issue 1957533002: cc : Track opacity animation changes on effect tree (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: cc/animation/element_animations.cc
diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc
index be4b9687d99075a6e8b8aa7cc5c3bdb9e74e164b..ddcdd3489b0d25f987f47ee122c1fa22a32f690d 100644
--- a/cc/animation/element_animations.cc
+++ b/cc/animation/element_animations.cc
@@ -35,7 +35,11 @@ ElementAnimations::ElementAnimations()
needs_to_start_animations_(false),
scroll_offset_animation_was_interrupted_(false),
potentially_animating_transform_for_active_elements_(false),
- potentially_animating_transform_for_pending_elements_(false) {}
+ potentially_animating_transform_for_pending_elements_(false),
+ currently_running_opacity_animation_for_active_elements_(false),
+ currently_running_opacity_animation_for_pending_elements_(false),
+ potentially_animating_opacity_for_active_elements_(false),
+ potentially_animating_opacity_for_pending_elements_(false) {}
ElementAnimations::~ElementAnimations() {}
@@ -67,12 +71,18 @@ void ElementAnimations::InitAffectedElementTypes() {
void ElementAnimations::ClearAffectedElementTypes() {
DCHECK(animation_host_);
- if (has_element_in_active_list())
+ if (has_element_in_active_list()) {
OnTransformIsPotentiallyAnimatingChanged(ElementListType::ACTIVE, false);
+ OnOpacityIsAnimatingChanged(ElementListType::ACTIVE,
+ AnimationChangeType::BOTH, false);
+ }
set_has_element_in_active_list(false);
- if (has_element_in_pending_list())
+ if (has_element_in_pending_list()) {
OnTransformIsPotentiallyAnimatingChanged(ElementListType::PENDING, false);
+ OnOpacityIsAnimatingChanged(ElementListType::PENDING,
+ AnimationChangeType::BOTH, false);
+ }
set_has_element_in_pending_list(false);
animation_host_->DidDeactivateElementAnimations(this);
@@ -138,11 +148,15 @@ void ElementAnimations::PushPropertiesTo(
void ElementAnimations::AddAnimation(std::unique_ptr<Animation> animation) {
bool added_transform_animation =
animation->target_property() == TargetProperty::TRANSFORM;
+ bool added_opacity_animation =
+ animation->target_property() == TargetProperty::OPACITY;
animations_.push_back(std::move(animation));
needs_to_start_animations_ = true;
UpdateActivation(NORMAL_ACTIVATION);
if (added_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (added_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::Animate(base::TimeTicks monotonic_time) {
@@ -154,6 +168,7 @@ void ElementAnimations::Animate(base::TimeTicks monotonic_time) {
StartAnimations(monotonic_time);
TickAnimations(monotonic_time);
last_tick_time_ = monotonic_time;
+ UpdateAnimatingOpacity();
}
void ElementAnimations::AccumulatePropertyUpdates(
@@ -251,11 +266,15 @@ void ElementAnimations::UpdateState(bool start_ready_animations,
void ElementAnimations::ActivateAnimations() {
bool changed_transform_animation = false;
+ bool changed_opacity_animation = false;
for (size_t i = 0; i < animations_.size(); ++i) {
if (animations_[i]->affects_active_elements() !=
- animations_[i]->affects_pending_elements() &&
- animations_[i]->target_property() == TargetProperty::TRANSFORM)
- changed_transform_animation = true;
+ animations_[i]->affects_pending_elements()) {
+ if (animations_[i]->target_property() == TargetProperty::TRANSFORM)
+ changed_transform_animation = true;
+ else if (animations_[i]->target_property() == TargetProperty::OPACITY)
+ changed_opacity_animation = true;
+ }
animations_[i]->set_affects_active_elements(
animations_[i]->affects_pending_elements());
}
@@ -270,6 +289,8 @@ void ElementAnimations::ActivateAnimations() {
UpdateActivation(NORMAL_ACTIVATION);
if (changed_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (changed_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) {
@@ -326,6 +347,7 @@ void ElementAnimations::NotifyAnimationTakeover(const AnimationEvent& event) {
void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) {
bool aborted_transform_animation = false;
+ bool aborted_opacity_animation = false;
for (size_t i = 0; i < animations_.size(); ++i) {
if (animations_[i]->group() == event.group_id &&
animations_[i]->target_property() == event.target_property) {
@@ -335,11 +357,15 @@ void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) {
event.group_id);
if (event.target_property == TargetProperty::TRANSFORM)
aborted_transform_animation = true;
+ else if (event.target_property == TargetProperty::OPACITY)
+ aborted_opacity_animation = true;
break;
}
}
if (aborted_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (aborted_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::NotifyAnimationPropertyUpdate(
@@ -597,6 +623,7 @@ static bool IsCompleted(
void ElementAnimations::RemoveAnimationsCompletedOnMainThread(
ElementAnimations* element_animations_impl) const {
bool removed_transform_animation = false;
+ bool removed_opacity_animation = false;
// Animations removed on the main thread should no longer affect pending
// elements, and should stop affecting active elements after the next call
// to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
@@ -607,6 +634,8 @@ void ElementAnimations::RemoveAnimationsCompletedOnMainThread(
animation->set_affects_pending_elements(false);
if (animation->target_property() == TargetProperty::TRANSFORM)
removed_transform_animation = true;
+ else if (animation->target_property() == TargetProperty::OPACITY)
+ removed_opacity_animation = true;
}
}
auto affects_active_only_and_is_waiting_for_deletion =
@@ -621,6 +650,8 @@ void ElementAnimations::RemoveAnimationsCompletedOnMainThread(
if (removed_transform_animation)
element_animations_impl->UpdatePotentiallyAnimatingTransform();
+ if (removed_opacity_animation)
+ element_animations_impl->UpdateAnimatingOpacity();
}
void ElementAnimations::PushPropertiesToImplThread(
@@ -763,17 +794,21 @@ void ElementAnimations::PromoteStartedAnimations(base::TimeTicks monotonic_time,
void ElementAnimations::MarkFinishedAnimations(base::TimeTicks monotonic_time) {
bool finished_transform_animation = false;
+ bool finished_opacity_animation = false;
for (size_t i = 0; i < animations_.size(); ++i) {
if (!animations_[i]->is_finished() &&
animations_[i]->IsFinishedAt(monotonic_time)) {
animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
- if (animations_[i]->target_property() == TargetProperty::TRANSFORM) {
+ if (animations_[i]->target_property() == TargetProperty::TRANSFORM)
finished_transform_animation = true;
- }
+ else if (animations_[i]->target_property() == TargetProperty::OPACITY)
+ finished_opacity_animation = true;
}
}
if (finished_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (finished_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::MarkAnimationsForDeletion(
@@ -905,6 +940,7 @@ void ElementAnimations::MarkAnimationsForDeletion(
void ElementAnimations::MarkAbortedAnimationsForDeletion(
ElementAnimations* element_animations_impl) const {
bool aborted_transform_animation = false;
+ bool aborted_opacity_animation = false;
auto& animations_impl = element_animations_impl->animations_;
for (const auto& animation_impl : animations_impl) {
// If the animation has been aborted on the main thread, mark it for
@@ -915,15 +951,18 @@ void ElementAnimations::MarkAbortedAnimationsForDeletion(
element_animations_impl->last_tick_time_);
animation->SetRunState(Animation::WAITING_FOR_DELETION,
last_tick_time_);
- if (animation_impl->target_property() == TargetProperty::TRANSFORM) {
+ if (animation_impl->target_property() == TargetProperty::TRANSFORM)
aborted_transform_animation = true;
- }
+ else if (animation_impl->target_property() == TargetProperty::OPACITY)
+ aborted_opacity_animation = true;
}
}
}
if (aborted_transform_animation)
element_animations_impl->UpdatePotentiallyAnimatingTransform();
+ if (aborted_opacity_animation)
+ element_animations_impl->UpdateAnimatingOpacity();
}
void ElementAnimations::PurgeAnimationsMarkedForDeletion() {
@@ -1077,6 +1116,53 @@ void ElementAnimations::NotifyClientTransformIsPotentiallyAnimatingChanged(
potentially_animating_transform_for_pending_elements_);
}
+void ElementAnimations::NotifyClientOpacityAnimationChanged(
+ bool notify_active_elements_about_potential_animation,
+ bool notify_pending_elements_about_potential_animation,
+ bool notify_active_elements_about_running_animation,
+ bool notify_pending_elements_about_running_animation) {
+ bool notify_active_elements_about_potential_and_running_animation =
+ notify_active_elements_about_potential_animation &&
+ notify_active_elements_about_running_animation;
+ bool notify_pending_elements_about_potential_and_running_animation =
+ notify_pending_elements_about_potential_animation &&
+ notify_pending_elements_about_running_animation;
+ if (has_element_in_active_list()) {
+ if (notify_active_elements_about_potential_and_running_animation) {
+ DCHECK_EQ(potentially_animating_opacity_for_active_elements_,
+ currently_running_opacity_animation_for_active_elements_);
+ OnOpacityIsAnimatingChanged(
+ ElementListType::ACTIVE, AnimationChangeType::BOTH,
+ potentially_animating_opacity_for_active_elements_);
+ } else if (notify_active_elements_about_potential_animation) {
+ OnOpacityIsAnimatingChanged(
+ ElementListType::ACTIVE, AnimationChangeType::POTENTIAL,
+ potentially_animating_opacity_for_active_elements_);
+ } else if (notify_active_elements_about_running_animation) {
+ OnOpacityIsAnimatingChanged(
+ ElementListType::ACTIVE, AnimationChangeType::RUNNING,
+ currently_running_opacity_animation_for_active_elements_);
+ }
+ }
+ if (has_element_in_pending_list()) {
+ if (notify_pending_elements_about_potential_and_running_animation) {
+ DCHECK_EQ(potentially_animating_opacity_for_pending_elements_,
+ currently_running_opacity_animation_for_pending_elements_);
+ OnOpacityIsAnimatingChanged(
+ ElementListType::PENDING, AnimationChangeType::BOTH,
+ potentially_animating_opacity_for_pending_elements_);
+ } else if (notify_pending_elements_about_potential_animation) {
+ OnOpacityIsAnimatingChanged(
+ ElementListType::PENDING, AnimationChangeType::POTENTIAL,
+ potentially_animating_opacity_for_pending_elements_);
+ } else if (notify_pending_elements_about_running_animation) {
+ OnOpacityIsAnimatingChanged(
+ ElementListType::PENDING, AnimationChangeType::RUNNING,
+ currently_running_opacity_animation_for_pending_elements_);
+ }
+ }
+}
+
void ElementAnimations::UpdatePotentiallyAnimatingTransform() {
bool was_potentially_animating_transform_for_active_elements =
potentially_animating_transform_for_active_elements_;
@@ -1110,6 +1196,65 @@ void ElementAnimations::UpdatePotentiallyAnimatingTransform() {
changed_for_active_elements, changed_for_pending_elements);
}
+void ElementAnimations::UpdateAnimatingOpacity() {
+ bool was_currently_running_opacity_animation_for_active_elements =
+ currently_running_opacity_animation_for_active_elements_;
+ bool was_currently_running_opacity_animation_for_pending_elements =
+ currently_running_opacity_animation_for_pending_elements_;
+ bool was_potentially_animating_opacity_for_active_elements =
+ potentially_animating_opacity_for_active_elements_;
+ bool was_potentially_animating_opacity_for_pending_elements =
+ potentially_animating_opacity_for_pending_elements_;
+
+ DCHECK(was_potentially_animating_opacity_for_active_elements ||
+ !was_currently_running_opacity_animation_for_active_elements);
+ DCHECK(was_potentially_animating_opacity_for_pending_elements ||
+ !was_currently_running_opacity_animation_for_pending_elements);
+ currently_running_opacity_animation_for_active_elements_ = false;
+ currently_running_opacity_animation_for_pending_elements_ = false;
+ potentially_animating_opacity_for_active_elements_ = false;
+ potentially_animating_opacity_for_pending_elements_ = false;
+
+ for (const auto& animation : animations_) {
+ if (!animation->is_finished() &&
+ animation->target_property() == TargetProperty::OPACITY) {
+ potentially_animating_opacity_for_active_elements_ |=
+ animation->affects_active_elements();
+ potentially_animating_opacity_for_pending_elements_ |=
+ animation->affects_pending_elements();
+ currently_running_opacity_animation_for_active_elements_ =
+ potentially_animating_opacity_for_active_elements_ &&
+ animation->InEffect(last_tick_time_);
+ currently_running_opacity_animation_for_pending_elements_ =
+ potentially_animating_opacity_for_pending_elements_ &&
+ animation->InEffect(last_tick_time_);
+ }
+ }
+
+ bool potentially_animating_changed_for_active_elements =
+ was_potentially_animating_opacity_for_active_elements !=
+ potentially_animating_opacity_for_active_elements_;
+ bool potentially_animating_changed_for_pending_elements =
+ was_potentially_animating_opacity_for_pending_elements !=
+ potentially_animating_opacity_for_pending_elements_;
+ bool currently_running_animation_changed_for_active_elements =
+ was_currently_running_opacity_animation_for_active_elements !=
+ currently_running_opacity_animation_for_active_elements_;
+ bool currently_running_animation_changed_for_pending_elements =
+ was_currently_running_opacity_animation_for_pending_elements !=
+ currently_running_opacity_animation_for_pending_elements_;
+ if (!potentially_animating_changed_for_active_elements &&
+ !potentially_animating_changed_for_pending_elements &&
+ !currently_running_animation_changed_for_active_elements &&
+ !currently_running_animation_changed_for_pending_elements)
+ return;
+ NotifyClientOpacityAnimationChanged(
+ potentially_animating_changed_for_active_elements,
+ potentially_animating_changed_for_pending_elements,
+ currently_running_animation_changed_for_active_elements,
+ currently_running_animation_changed_for_pending_elements);
+}
+
bool ElementAnimations::HasActiveAnimation() const {
for (size_t i = 0; i < animations_.size(); ++i) {
if (!animations_[i]->is_finished())
@@ -1164,6 +1309,7 @@ void ElementAnimations::PauseAnimation(int animation_id,
void ElementAnimations::RemoveAnimation(int animation_id) {
bool removed_transform_animation = false;
+ bool removed_opacity_animation = false;
// Since we want to use the animations that we're going to remove, we need to
// use a stable_parition here instead of remove_if. Remove_if leaves the
// removed items in an unspecified state.
@@ -1178,6 +1324,9 @@ void ElementAnimations::RemoveAnimation(int animation_id) {
} else if ((*it)->target_property() == TargetProperty::TRANSFORM &&
!(*it)->is_finished()) {
removed_transform_animation = true;
+ } else if ((*it)->target_property() == TargetProperty::OPACITY &&
+ !(*it)->is_finished()) {
+ removed_opacity_animation = true;
}
}
@@ -1185,19 +1334,26 @@ void ElementAnimations::RemoveAnimation(int animation_id) {
UpdateActivation(NORMAL_ACTIVATION);
if (removed_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (removed_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::AbortAnimation(int animation_id) {
bool aborted_transform_animation = false;
+ bool aborted_opacity_animation = false;
if (Animation* animation = GetAnimationById(animation_id)) {
if (!animation->is_finished()) {
animation->SetRunState(Animation::ABORTED, last_tick_time_);
if (animation->target_property() == TargetProperty::TRANSFORM)
aborted_transform_animation = true;
+ else if (animation->target_property() == TargetProperty::OPACITY)
+ aborted_opacity_animation = true;
}
}
if (aborted_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (aborted_opacity_animation)
+ UpdateAnimatingOpacity();
}
void ElementAnimations::AbortAnimations(TargetProperty::Type target_property,
@@ -1206,6 +1362,7 @@ void ElementAnimations::AbortAnimations(TargetProperty::Type target_property,
DCHECK(target_property == TargetProperty::SCROLL_OFFSET);
bool aborted_transform_animation = false;
+ bool aborted_opacity_animation = false;
for (size_t i = 0; i < animations_.size(); ++i) {
if (animations_[i]->target_property() == target_property &&
!animations_[i]->is_finished()) {
@@ -1219,10 +1376,14 @@ void ElementAnimations::AbortAnimations(TargetProperty::Type target_property,
}
if (target_property == TargetProperty::TRANSFORM)
aborted_transform_animation = true;
+ else if (target_property == TargetProperty::OPACITY)
+ aborted_opacity_animation = true;
}
}
if (aborted_transform_animation)
UpdatePotentiallyAnimatingTransform();
+ if (aborted_opacity_animation)
+ UpdateAnimatingOpacity();
}
Animation* ElementAnimations::GetAnimation(
@@ -1298,6 +1459,18 @@ void ElementAnimations::OnTransformIsPotentiallyAnimatingChanged(
is_animating);
}
+void ElementAnimations::OnOpacityIsAnimatingChanged(
+ ElementListType list_type,
+ AnimationChangeType change_type,
+ bool is_animating) {
+ if (!element_id())
+ return;
+ DCHECK(animation_host());
+ if (animation_host()->mutator_host_client())
+ animation_host()->mutator_host_client()->ElementOpacityIsAnimatingChanged(
+ element_id(), list_type, change_type, is_animating);
+}
+
void ElementAnimations::NotifyPlayersAnimationStarted(
base::TimeTicks monotonic_time,
TargetProperty::Type target_property,

Powered by Google App Engine
This is Rietveld 408576698