Commit e27dda01 authored by Yi Gu's avatar Yi Gu Committed by Commit Bot

[cc] Avoid checking WorkletAnimation::NeedsUpdate() twice

Currently we check whether ticking mutator is needed and if so we
collect mutator input state. There are duplicated logic in the two
operations above. This patch is to skip the first check and collect
input state directly. Then mutate if the input state is not empty.

Bug: 791279
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ib4c7b92ca0b545b42d75b91bc3fd7f9296034d74
Reviewed-on: https://chromium-review.googlesource.com/1103013
Commit-Queue: Yi Gu <yigu@chromium.org>
Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567830}
parent b0278053
...@@ -275,22 +275,20 @@ bool AnimationHost::NeedsTickAnimations() const { ...@@ -275,22 +275,20 @@ bool AnimationHost::NeedsTickAnimations() const {
return !ticking_animations_.empty(); return !ticking_animations_.empty();
} }
bool AnimationHost::NeedsTickMutator(base::TimeTicks monotonic_time, bool AnimationHost::TickMutator(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree, const ScrollTree& scroll_tree,
bool is_active_tree) const { bool is_active_tree) {
if (!mutator_ || !mutator_->HasAnimators()) if (!mutator_ || !mutator_->HasAnimators())
return false; return false;
for (auto& animation : ticking_animations_) { std::unique_ptr<MutatorInputState> state = CollectWorkletAnimationsState(
if (!animation->IsWorkletAnimation()) monotonic_time, scroll_tree, is_active_tree);
continue; if (state->IsEmpty())
return false;
if (ToWorkletAnimation(animation.get()) mutator_->Mutate(std::move(state));
->NeedsUpdate(monotonic_time, scroll_tree, is_active_tree))
return true;
}
return false; return true;
} }
bool AnimationHost::ActivateAnimations() { bool AnimationHost::ActivateAnimations() {
...@@ -319,15 +317,12 @@ bool AnimationHost::TickAnimations(base::TimeTicks monotonic_time, ...@@ -319,15 +317,12 @@ bool AnimationHost::TickAnimations(base::TimeTicks monotonic_time,
did_animate = true; did_animate = true;
} }
if (NeedsTickMutator(monotonic_time, scroll_tree, is_active_tree)) {
// TODO(majidvp): At the moment we call this for both active and pending // TODO(majidvp): At the moment we call this for both active and pending
// trees similar to other animations. However our final goal is to only call // trees similar to other animations. However our final goal is to only call
// it once, ideally after activation, and only when the input // it once, ideally after activation, and only when the input
// to an active timeline has changed. http://crbug.com/767210 // to an active timeline has changed. http://crbug.com/767210
mutator_->Mutate(CollectWorkletAnimationsState(monotonic_time, scroll_tree, did_animate |= TickMutator(monotonic_time, scroll_tree, is_active_tree);
is_active_tree));
did_animate = true;
}
return did_animate; return did_animate;
} }
...@@ -339,15 +334,10 @@ void AnimationHost::TickScrollAnimations(base::TimeTicks monotonic_time, ...@@ -339,15 +334,10 @@ void AnimationHost::TickScrollAnimations(base::TimeTicks monotonic_time,
// fine-grained approach based on invalidating individual ScrollTimelines and // fine-grained approach based on invalidating individual ScrollTimelines and
// then ticking the animations attached to those timelines. To make // then ticking the animations attached to those timelines. To make
// this happen we probably need to move "ticking" animations to timeline. // this happen we probably need to move "ticking" animations to timeline.
const bool is_active_tree = true;
if (!NeedsTickMutator(monotonic_time, scroll_tree, is_active_tree))
return;
DCHECK(mutator_);
// TODO(majidvp): We need to return a boolean here so that LTHI knows // TODO(majidvp): We need to return a boolean here so that LTHI knows
// whether it needs to schedule another frame. // whether it needs to schedule another frame.
mutator_->Mutate(CollectWorkletAnimationsState(monotonic_time, scroll_tree, TickMutator(monotonic_time, scroll_tree, true /* is_active_tree */);
is_active_tree));
} }
std::unique_ptr<MutatorInputState> AnimationHost::CollectWorkletAnimationsState( std::unique_ptr<MutatorInputState> AnimationHost::CollectWorkletAnimationsState(
......
...@@ -200,9 +200,10 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost, ...@@ -200,9 +200,10 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
void EraseTimeline(scoped_refptr<AnimationTimeline> timeline); void EraseTimeline(scoped_refptr<AnimationTimeline> timeline);
bool NeedsTickMutator(base::TimeTicks monotonic_time, // Return true if there are any animations that get mutated.
const ScrollTree& scroll_tree, bool TickMutator(base::TimeTicks monotonic_time,
bool is_active_tree) const; const ScrollTree& scroll_tree,
bool is_active_tree);
// Return the state representing all ticking worklet animations. // Return the state representing all ticking worklet animations.
std::unique_ptr<MutatorInputState> CollectWorkletAnimationsState( std::unique_ptr<MutatorInputState> CollectWorkletAnimationsState(
......
...@@ -53,12 +53,6 @@ class CC_ANIMATION_EXPORT WorkletAnimation final ...@@ -53,12 +53,6 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
void PushPropertiesTo(Animation* animation_impl) override; void PushPropertiesTo(Animation* animation_impl) override;
// Returns true if the worklet animation needs to be updated which happens iff
// its current time is going to be different from last time given these input.
bool NeedsUpdate(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree);
// Should be called when the scroll source of the ScrollTimeline attached to // Should be called when the scroll source of the ScrollTimeline attached to
// this animation has a change in ElementId. Such a change happens when the // this animation has a change in ElementId. Such a change happens when the
// scroll source changes compositing state. // scroll source changes compositing state.
...@@ -79,6 +73,12 @@ class CC_ANIMATION_EXPORT WorkletAnimation final ...@@ -79,6 +73,12 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
const ScrollTree& scroll_tree, const ScrollTree& scroll_tree,
bool is_active_tree); bool is_active_tree);
// Returns true if the worklet animation needs to be updated which happens iff
// its current time is going to be different from last time given these input.
bool NeedsUpdate(base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
bool is_active_tree);
std::unique_ptr<AnimationOptions> CloneOptions() const { std::unique_ptr<AnimationOptions> CloneOptions() const {
return options_ ? options_->Clone() : nullptr; return options_ ? options_->Clone() : nullptr;
} }
......
...@@ -192,30 +192,6 @@ TEST_F(WorkletAnimationTest, ...@@ -192,30 +192,6 @@ TEST_F(WorkletAnimationTest,
EXPECT_EQ(246.8, third_state->updated_animations[0].current_time); EXPECT_EQ(246.8, third_state->updated_animations[0].current_time);
} }
TEST_F(WorkletAnimationTest, NeedsUpdateCorrectlyReflectsInputTimeChange) {
scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
worklet_animation_id_, "test_name", nullptr, nullptr);
base::TimeTicks first_ticks =
base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111);
base::TimeTicks second_ticks =
base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111 + 123.4);
ScrollTree scroll_tree;
std::unique_ptr<MutatorInputState> state =
std::make_unique<MutatorInputState>();
// First time should always be true.
EXPECT_TRUE(worklet_animation->NeedsUpdate(first_ticks, scroll_tree, true));
worklet_animation->UpdateInputState(state.get(), first_ticks, scroll_tree,
true);
// Should be false if time is not different from last GetState.
EXPECT_FALSE(worklet_animation->NeedsUpdate(first_ticks, scroll_tree, true));
// Should be true when input time is different.
EXPECT_TRUE(worklet_animation->NeedsUpdate(second_ticks, scroll_tree, true));
// Should be side-effect free.
EXPECT_TRUE(worklet_animation->NeedsUpdate(second_ticks, scroll_tree, true));
}
// This test verifies that worklet animation state is properly updated. // This test verifies that worklet animation state is properly updated.
TEST_F(WorkletAnimationTest, WorkletAnimationStateTestWithSingleKeyframeModel) { TEST_F(WorkletAnimationTest, WorkletAnimationStateTestWithSingleKeyframeModel) {
AttachWorkletAnimation(); AttachWorkletAnimation();
......
...@@ -41,9 +41,14 @@ struct CC_EXPORT MutatorInputState { ...@@ -41,9 +41,14 @@ struct CC_EXPORT MutatorInputState {
MutatorInputState(); MutatorInputState();
~MutatorInputState(); ~MutatorInputState();
std::vector<int> removed_animations; bool IsEmpty() {
return added_and_updated_animations.empty() && updated_animations.empty() &&
removed_animations.empty();
}
std::vector<AddAndUpdateState> added_and_updated_animations; std::vector<AddAndUpdateState> added_and_updated_animations;
std::vector<UpdateState> updated_animations; std::vector<UpdateState> updated_animations;
std::vector<int> removed_animations;
DISALLOW_COPY_AND_ASSIGN(MutatorInputState); DISALLOW_COPY_AND_ASSIGN(MutatorInputState);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment