summaryrefslogtreecommitdiff
path: root/chromium/cc/animation
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/cc/animation
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/animation')
-rw-r--r--chromium/cc/animation/animation.cc23
-rw-r--r--chromium/cc/animation/animation.h13
-rw-r--r--chromium/cc/animation/animation_delegate.h6
-rw-r--r--chromium/cc/animation/animation_host.cc45
-rw-r--r--chromium/cc/animation/animation_host.h1
-rw-r--r--chromium/cc/animation/animation_host_unittest.cc7
-rw-r--r--chromium/cc/animation/element_animations_unittest.cc20
-rw-r--r--chromium/cc/animation/keyframe_effect.cc34
-rw-r--r--chromium/cc/animation/keyframe_effect.h5
-rw-r--r--chromium/cc/animation/keyframe_model.cc5
-rw-r--r--chromium/cc/animation/transform_operations.h2
-rw-r--r--chromium/cc/animation/worklet_animation.cc9
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc14
13 files changed, 56 insertions, 128 deletions
diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc
index 5c40eed8453..df27dc32d11 100644
--- a/chromium/cc/animation/animation.cc
+++ b/chromium/cc/animation/animation.cc
@@ -127,20 +127,15 @@ void Animation::Tick(base::TimeTicks tick_time) {
// time and then ticks it which side-steps the start time altogether. See
// crbug.com/1076012 for alternative design choices considered for future
// improvement.
- TickWithLocalTime(tick_time - base::TimeTicks());
+ keyframe_effect_->Pause(tick_time - base::TimeTicks(),
+ PauseCondition::kAfterStart);
+ keyframe_effect_->Tick(base::TimeTicks());
} else {
DCHECK(!tick_time.is_null());
keyframe_effect_->Tick(tick_time);
}
}
-void Animation::TickWithLocalTime(base::TimeDelta local_time) {
- // TODO(yigu): KeyframeEffect should support ticking KeyframeModel
- // directly without using Pause(). https://crbug.com/1076012.
- keyframe_effect_->Pause(local_time);
- keyframe_effect_->Tick(base::TimeTicks());
-}
-
bool Animation::IsScrollLinkedAnimation() const {
return animation_timeline_ && animation_timeline_->IsScrollTimeline();
}
@@ -211,10 +206,6 @@ void Animation::DelegateAnimationEvent(const AnimationEvent& event) {
}
}
-size_t Animation::TickingKeyframeModelsCount() const {
- return keyframe_effect_->TickingKeyframeModelsCount();
-}
-
bool Animation::AffectsCustomProperty() const {
return keyframe_effect_->AffectsCustomProperty();
}
@@ -287,12 +278,4 @@ void Animation::NotifyKeyframeModelFinishedForTesting(
DispatchAndDelegateAnimationEvent(event);
}
-void Animation::UpdateScrollTimeline(base::Optional<ElementId> scroller_id,
- base::Optional<double> start_scroll_offset,
- base::Optional<double> end_scroll_offset) {
- ToScrollTimeline(animation_timeline_)
- ->UpdateScrollerIdAndScrollOffsets(scroller_id, start_scroll_offset,
- end_scroll_offset);
-}
-
} // namespace cc
diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h
index 7fa4136d591..6cc50117d1f 100644
--- a/chromium/cc/animation/animation.h
+++ b/chromium/cc/animation/animation.h
@@ -65,17 +65,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
}
void SetAnimationTimeline(AnimationTimeline* timeline);
- // TODO(yigu): There is a reverse dependency between AnimationTimeline and
- // Animation. ScrollTimeline update should be handled by AnimationHost instead
- // of Animation. This could be fixed once the snapshotting in blink is
- // implemented. https://crbug.com/1023508.
-
- // Should be called when the ScrollTimeline attached to this animation has a
- // change, such as when the scroll source changes ElementId.
- void UpdateScrollTimeline(base::Optional<ElementId> scroller_id,
- base::Optional<double> start_scroll_offset,
- base::Optional<double> end_scroll_offset);
-
scoped_refptr<ElementAnimations> element_animations() const;
void set_animation_delegate(AnimationDelegate* delegate) {
@@ -118,7 +107,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
// to be dispatched.
void DispatchAndDelegateAnimationEvent(const AnimationEvent& event);
- size_t TickingKeyframeModelsCount() const;
bool AffectsCustomProperty() const;
void SetNeedsPushProperties();
@@ -151,7 +139,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
explicit Animation(int id);
Animation(int id, std::unique_ptr<KeyframeEffect>);
virtual ~Animation();
- void TickWithLocalTime(base::TimeDelta local_time);
AnimationHost* animation_host_;
AnimationTimeline* animation_timeline_;
diff --git a/chromium/cc/animation/animation_delegate.h b/chromium/cc/animation/animation_delegate.h
index 0adbb115c59..6931c8b0d18 100644
--- a/chromium/cc/animation/animation_delegate.h
+++ b/chromium/cc/animation/animation_delegate.h
@@ -13,12 +13,6 @@ namespace cc {
class CC_ANIMATION_EXPORT AnimationDelegate {
public:
- // TODO(yigu): The Notify* methods will be called multiple times per
- // animation (once for effect/property pairing).
- // Ideally, we would only notify start once (e.g., wait on all effects to
- // start before notifying delegate) this way effect becomes an internal
- // details of the animation. Perhaps we can do that at some point maybe as
- // part of https://bugs.chromium.org/p/chromium/issues/detail?id=810003
virtual void NotifyAnimationStarted(base::TimeTicks monotonic_time,
int target_property,
int group) = 0;
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index 1dfe39e66c9..d2154f19594 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -219,6 +219,8 @@ void AnimationHost::SetNeedsCommit() {
}
void AnimationHost::SetNeedsPushProperties() {
+ if (needs_push_properties_)
+ return;
needs_push_properties_ = true;
if (mutator_host_client_)
mutator_host_client_->SetMutatorsNeedCommit();
@@ -227,6 +229,14 @@ void AnimationHost::SetNeedsPushProperties() {
void AnimationHost::PushPropertiesTo(MutatorHost* mutator_host_impl) {
auto* host_impl = static_cast<AnimationHost*>(mutator_host_impl);
+ // Update animation counts and whether raf was requested. These explicitly
+ // do not request push properties and are pushed as part of the next commit
+ // when it happens as requesting a commit leads to performance issues:
+ // https://crbug.com/1083244
+ host_impl->main_thread_animations_count_ = main_thread_animations_count_;
+ host_impl->current_frame_had_raf_ = current_frame_had_raf_;
+ host_impl->next_frame_has_pending_raf_ = next_frame_has_pending_raf_;
+
if (needs_push_properties_) {
needs_push_properties_ = false;
PushTimelinesToImplThread(host_impl);
@@ -289,9 +299,6 @@ void AnimationHost::PushPropertiesToImplThread(AnimationHost* host_impl) {
// Update the impl-only scroll offset animations.
scroll_offset_animations_->PushPropertiesTo(
host_impl->scroll_offset_animations_impl_.get());
- host_impl->main_thread_animations_count_ = main_thread_animations_count_;
- host_impl->current_frame_had_raf_ = current_frame_had_raf_;
- host_impl->next_frame_has_pending_raf_ = next_frame_has_pending_raf_;
// The pending info list is cleared in LayerTreeHostImpl::CommitComplete
// and should be empty when pushing properties.
@@ -752,37 +759,25 @@ void AnimationHost::SetMutationUpdate(
}
}
-size_t AnimationHost::CompositedAnimationsCount() const {
- size_t composited_animations_count = 0;
- for (const auto& it : ticking_animations_)
- composited_animations_count += it->TickingKeyframeModelsCount();
- return composited_animations_count;
-}
-
void AnimationHost::SetAnimationCounts(
size_t total_animations_count,
bool current_frame_had_raf,
bool next_frame_has_pending_raf) {
+ // Though these changes are pushed as part of AnimationHost::PushPropertiesTo
+ // we don't SetNeedsPushProperties as pushing the values requires a commit.
+ // Instead we allow them to be pushed whenever the next required commit
+ // happens to avoid unnecessary work. See https://crbug.com/1083244.
+
// If an animation is being run on the compositor, it will have a ticking
// Animation (which will have a corresponding impl-thread version). Therefore
// to find the count of main-only animations, we can simply subtract the
// number of ticking animations from the total count.
size_t ticking_animations_count = ticking_animations_.size();
- if (main_thread_animations_count_ !=
- total_animations_count - ticking_animations_count) {
- main_thread_animations_count_ =
- total_animations_count - ticking_animations_count;
- DCHECK_GE(main_thread_animations_count_, 0u);
- SetNeedsPushProperties();
- }
- if (current_frame_had_raf != current_frame_had_raf_) {
- current_frame_had_raf_ = current_frame_had_raf;
- SetNeedsPushProperties();
- }
- if (next_frame_has_pending_raf != next_frame_has_pending_raf_) {
- next_frame_has_pending_raf_ = next_frame_has_pending_raf;
- SetNeedsPushProperties();
- }
+ main_thread_animations_count_ =
+ total_animations_count - ticking_animations_count;
+ DCHECK_GE(main_thread_animations_count_, 0u);
+ current_frame_had_raf_ = current_frame_had_raf;
+ next_frame_has_pending_raf_ = next_frame_has_pending_raf;
}
size_t AnimationHost::MainThreadAnimationsCount() const {
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
index de1ae6f8811..534f8c0c642 100644
--- a/chromium/cc/animation/animation_host.h
+++ b/chromium/cc/animation/animation_host.h
@@ -207,7 +207,6 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
void SetMutationUpdate(
std::unique_ptr<MutatorOutputState> output_state) override;
- size_t CompositedAnimationsCount() const override;
size_t MainThreadAnimationsCount() const override;
bool HasCustomPropertyAnimations() const override;
bool CurrentFrameHadRAF() const override;
diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc
index c2659983070..4dc4f9905d5 100644
--- a/chromium/cc/animation/animation_host_unittest.cc
+++ b/chromium/cc/animation/animation_host_unittest.cc
@@ -363,6 +363,9 @@ TEST_F(AnimationHostTest, LayerTreeMutatorUpdateReflectsScrollAnimations) {
}
TEST_F(AnimationHostTest, TickScrollLinkedAnimation) {
+ client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
+ client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
+ client_impl_.RegisterElementId(element_id_, ElementListType::ACTIVE);
PropertyTrees property_trees;
property_trees.is_main_thread = false;
property_trees.is_active = true;
@@ -378,7 +381,7 @@ TEST_F(AnimationHostTest, TickScrollLinkedAnimation) {
scoped_refptr<Animation> animation = Animation::Create(animation_id);
host_impl_->AddAnimationTimeline(scroll_timeline);
scroll_timeline->AttachAnimation(animation);
- animation->AddToTicking();
+
ASSERT_TRUE(animation->IsScrollLinkedAnimation());
animation->AttachElement(element_id_);
@@ -393,7 +396,7 @@ TEST_F(AnimationHostTest, TickScrollLinkedAnimation) {
EXPECT_TRUE(host_impl_->TickAnimations(base::TimeTicks(),
property_trees.scroll_tree, false));
- EXPECT_EQ(keyframe_model->run_state(), KeyframeModel::PAUSED);
+ EXPECT_EQ(keyframe_model->run_state(), KeyframeModel::STARTING);
double tick_time = (scroll_timeline->CurrentTime(scroll_tree, false).value() -
base::TimeTicks())
.InSecondsF();
diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc
index 34debd1808a..9e1fa8337f3 100644
--- a/chromium/cc/animation/element_animations_unittest.cc
+++ b/chromium/cc/animation/element_animations_unittest.cc
@@ -3874,26 +3874,6 @@ TEST_F(ElementAnimationsTest, RemoveAndReAddAnimationToTicking) {
EXPECT_EQ(1u, host_->ticking_animations_for_testing().size());
}
-TEST_F(ElementAnimationsTest, TickingKeyframeModelsCount) {
- CreateTestLayer(false, false);
- AttachTimelineAnimationLayer();
-
- // Add an animation and ensure the animation is in the host's ticking
- // animations.
- animation_->AddKeyframeModel(CreateKeyframeModel(
- std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 1.f, 0.5f)),
- 2, TargetProperty::OPACITY));
- EXPECT_EQ(1u, animation_->TickingKeyframeModelsCount());
- EXPECT_EQ(1u, host_->CompositedAnimationsCount());
- animation_->AddKeyframeModel(CreateKeyframeModel(
- std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1,
- TargetProperty::TRANSFORM));
- EXPECT_EQ(2u, animation_->TickingKeyframeModelsCount());
- EXPECT_EQ(2u, host_->CompositedAnimationsCount());
- animation_->keyframe_effect()->RemoveFromTicking();
- EXPECT_EQ(0u, host_->CompositedAnimationsCount());
-}
-
// This test verifies that finished keyframe models don't get copied over to
// impl thread.
TEST_F(ElementAnimationsTest, FinishedKeyframeModelsNotCopiedToImpl) {
diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc
index 5af52eb211b..710d4f51c13 100644
--- a/chromium/cc/animation/keyframe_effect.cc
+++ b/chromium/cc/animation/keyframe_effect.cc
@@ -214,14 +214,28 @@ void KeyframeEffect::UpdateTickingState() {
}
}
-void KeyframeEffect::Pause(base::TimeDelta pause_offset) {
- for (auto& keyframe_model : keyframe_models_)
+void KeyframeEffect::Pause(base::TimeDelta pause_offset,
+ PauseCondition pause_condition) {
+ bool did_pause = false;
+ for (auto& keyframe_model : keyframe_models_) {
+ // TODO(crbug.com/1076012): KeyframeEffect is paused with local time for
+ // scroll-linked animations. To make sure the start event of a keyframe
+ // model is sent to blink, we should not set its run state to PAUSED until
+ // such event is sent. This should be revisited once KeyframeEffect is able
+ // to tick scroll-linked keyframe models directly.
+ if (pause_condition == PauseCondition::kAfterStart &&
+ (keyframe_model->run_state() ==
+ KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY ||
+ keyframe_model->run_state() == KeyframeModel::STARTING))
+ continue;
keyframe_model->Pause(pause_offset);
-
- if (has_bound_element_animations()) {
- animation_->SetNeedsCommit();
- SetNeedsPushProperties();
+ did_pause = true;
}
+
+ if (!did_pause || !has_bound_element_animations())
+ return;
+ animation_->SetNeedsCommit();
+ SetNeedsPushProperties();
}
void KeyframeEffect::AddKeyframeModel(
@@ -458,14 +472,6 @@ bool KeyframeEffect::HasTickingKeyframeModel() const {
return false;
}
-size_t KeyframeEffect::TickingKeyframeModelsCount() const {
- size_t ticking_keyframe_models_count = 0;
- for (const auto& it : keyframe_models_)
- if (!it->is_finished())
- ticking_keyframe_models_count++;
- return ticking_keyframe_models_count;
-}
-
bool KeyframeEffect::AffectsCustomProperty() const {
for (const auto& it : keyframe_models_)
if (it->target_property_id() == TargetProperty::CSS_CUSTOM_PROPERTY)
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index e7806e4cc1d..0e1280f82e1 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -22,6 +22,7 @@
namespace cc {
class Animation;
+enum class PauseCondition { kUnconditional, kAfterStart };
struct PropertyAnimationState;
// A KeyframeEffect owns a group of KeyframeModels for a single target
@@ -86,7 +87,8 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
void UpdateTickingState();
- void Pause(base::TimeDelta pause_offset);
+ void Pause(base::TimeDelta pause_offset,
+ PauseCondition = PauseCondition::kUnconditional);
void AddKeyframeModel(std::unique_ptr<KeyframeModel> keyframe_model);
void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
@@ -106,7 +108,6 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
// Returns true if there are any KeyframeModels that have neither finished
// nor aborted.
bool HasTickingKeyframeModel() const;
- size_t TickingKeyframeModelsCount() const;
bool AffectsCustomProperty() const;
diff --git a/chromium/cc/animation/keyframe_model.cc b/chromium/cc/animation/keyframe_model.cc
index 25e2c6d232b..bb779226080 100644
--- a/chromium/cc/animation/keyframe_model.cc
+++ b/chromium/cc/animation/keyframe_model.cc
@@ -156,7 +156,7 @@ void KeyframeModel::SetRunState(RunState run_state,
void KeyframeModel::Pause(base::TimeDelta pause_offset) {
// Convert pause offset which is in local time to monotonic time.
- // TODO(yigu): This should be scaled by playbackrate. http://crbug.com/912407
+ // TODO(crbug.com/912407): This should be scaled by playbackrate.
base::TimeTicks monotonic_time =
pause_offset + start_time_ + total_paused_duration_;
SetRunState(PAUSED, monotonic_time);
@@ -246,8 +246,7 @@ bool KeyframeModel::InEffect(base::TimeTicks monotonic_time) const {
return CalculateActiveTime(monotonic_time).has_value();
}
-// TODO(yigu): Local time should be scaled by playback rate by spec.
-// https://crbug.com/912407.
+// TODO(crbug.com/912407): Local time should be scaled by playback rate by spec.
base::TimeDelta KeyframeModel::ConvertMonotonicTimeToLocalTime(
base::TimeTicks monotonic_time) const {
// When waiting on receiving a start time, then our global clock is 'stuck' at
diff --git a/chromium/cc/animation/transform_operations.h b/chromium/cc/animation/transform_operations.h
index 2fecd424325..f0c669cf3e7 100644
--- a/chromium/cc/animation/transform_operations.h
+++ b/chromium/cc/animation/transform_operations.h
@@ -9,8 +9,8 @@
#include <unordered_map>
#include <vector>
+#include "base/check_op.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "cc/animation/animation_export.h"
#include "cc/animation/transform_operation.h"
#include "ui/gfx/transform.h"
diff --git a/chromium/cc/animation/worklet_animation.cc b/chromium/cc/animation/worklet_animation.cc
index 17ed083efcc..fd9a9c700ea 100644
--- a/chromium/cc/animation/worklet_animation.cc
+++ b/chromium/cc/animation/worklet_animation.cc
@@ -92,7 +92,8 @@ void WorkletAnimation::Tick(base::TimeTicks monotonic_time) {
// animations lifecycle. To avoid this we pause the underlying keyframe effect
// at the local time obtained from the user script - essentially turning each
// call to |WorkletAnimation::Tick| into a seek in the effect.
- TickWithLocalTime(local_time_.value());
+ keyframe_effect_->Pause(local_time_.value());
+ keyframe_effect_->Tick(base::TimeTicks());
}
void WorkletAnimation::UpdateState(bool start_ready_animations,
@@ -162,10 +163,6 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
switch (state_) {
case State::PENDING:
- // TODO(yigu): cc side WorkletAnimation is only capable of handling single
- // keyframe effect at the moment. We should pass in the number of effects
- // once Worklet Group Effect is fully implemented in cc.
- // https://crbug.com/767043.
input_state->Add({worklet_animation_id(), name(),
current_time->InMillisecondsF(), CloneOptions(),
CloneEffectTimings()});
@@ -186,8 +183,6 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
void WorkletAnimation::SetOutputState(
const MutatorOutputState::AnimationState& state) {
- // TODO(yigu): cc side WorkletAnimation is only capable of handling single
- // keyframe effect at the moment. https://crbug.com/767043.
DCHECK_EQ(state.local_times.size(), 1u);
local_time_ = state.local_times[0];
}
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index e827c3740e3..ed610a56c19 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -555,20 +555,6 @@ TEST_F(WorkletAnimationTest, SkipLockedAnimations) {
EXPECT_EQ(input->updated_animations.size(), 1u);
}
-TEST_F(WorkletAnimationTest, UpdateScrollTimelineScrollerId) {
- auto scroll_timeline = base::WrapRefCounted(new MockScrollTimeline());
- EXPECT_EQ(scroll_timeline->GetPendingIdForTest(), ElementId());
-
- scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
- worklet_animation_id_, "test_name", 1, nullptr, nullptr);
- host_->AddAnimationTimeline(scroll_timeline);
- scroll_timeline->AttachAnimation(worklet_animation);
- ElementId scroller_id = ElementId(1);
- worklet_animation->UpdateScrollTimeline(scroller_id, base::nullopt,
- base::nullopt);
- EXPECT_EQ(scroll_timeline->GetPendingIdForTest(), scroller_id);
-}
-
} // namespace
} // namespace cc