Commit 750bcab0 authored by Yi Gu's avatar Yi Gu Committed by Commit Bot

[ScrollTimeline] Update compositor timeline from blink timeline

Previously CompositorTimeline was updated on Animation level which
introduced a reverse dependency. This patch moves the update logic up
to AnimationTimeline level to fix this issue.

Bug: 921031
Change-Id: Iaaa92686003c741cad424eb9867a0993193c05c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2225853Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Commit-Queue: Yi Gu <yigu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774351}
parent d63e98f5
...@@ -282,12 +282,4 @@ void Animation::NotifyKeyframeModelFinishedForTesting( ...@@ -282,12 +282,4 @@ void Animation::NotifyKeyframeModelFinishedForTesting(
DispatchAndDelegateAnimationEvent(event); 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 } // namespace cc
...@@ -65,17 +65,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> { ...@@ -65,17 +65,6 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
} }
void SetAnimationTimeline(AnimationTimeline* timeline); 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; scoped_refptr<ElementAnimations> element_animations() const;
void set_animation_delegate(AnimationDelegate* delegate) { void set_animation_delegate(AnimationDelegate* delegate) {
......
...@@ -555,20 +555,6 @@ TEST_F(WorkletAnimationTest, SkipLockedAnimations) { ...@@ -555,20 +555,6 @@ TEST_F(WorkletAnimationTest, SkipLockedAnimations) {
EXPECT_EQ(input->updated_animations.size(), 1u); 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
} // namespace cc } // namespace cc
...@@ -2027,19 +2027,6 @@ void Animation::DetachCompositorTimeline() { ...@@ -2027,19 +2027,6 @@ void Animation::DetachCompositorTimeline() {
compositor_timeline->AnimationDestroyed(*this); compositor_timeline->AnimationDestroyed(*this);
} }
void Animation::UpdateCompositorScrollTimeline() {
if (!compositor_animation_ || !timeline_)
return;
auto& timeline = To<ScrollTimeline>(*timeline_);
Node* scroll_source = timeline.ResolvedScrollSource();
auto start_scroll_offset = timeline.GetResolvedStartScrollOffset();
auto end_scroll_offset = timeline.GetResolvedEndScrollOffset();
compositor_animation_->GetAnimation()->UpdateScrollTimeline(
scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
start_scroll_offset, end_scroll_offset);
}
void Animation::AttachCompositedLayers() { void Animation::AttachCompositedLayers() {
if (!compositor_animation_) if (!compositor_animation_)
return; return;
......
...@@ -286,11 +286,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData, ...@@ -286,11 +286,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
// depends on computed values. // depends on computed values.
virtual void FlushPendingUpdates() const {} virtual void FlushPendingUpdates() const {}
// TODO(yigu): This is a reverse dependency between AnimationTimeline and
// Animation. We should move the update logic once snapshotting is
// implemented. https://crbug.com/1060578.
void UpdateCompositorScrollTimeline();
protected: protected:
DispatchEventResult DispatchEventInternal(Event&) override; DispatchEventResult DispatchEventInternal(Event&) override;
void AddedEventListener(const AtomicString& event_type, void AddedEventListener(const AtomicString& event_type,
......
...@@ -85,11 +85,10 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) { ...@@ -85,11 +85,10 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) {
TRACE_EVENT0("blink", "AnimationTimeline::serviceAnimations"); TRACE_EVENT0("blink", "AnimationTimeline::serviceAnimations");
auto current_phase_and_time = CurrentPhaseAndTime(); auto current_phase_and_time = CurrentPhaseAndTime();
bool maybe_update_compositor_scroll_timeline = false;
if (IsScrollTimeline() && if (IsScrollTimeline() &&
last_current_phase_and_time_ != current_phase_and_time) { last_current_phase_and_time_ != current_phase_and_time) {
maybe_update_compositor_scroll_timeline = true; UpdateCompositorTimeline();
} }
last_current_phase_and_time_ = current_phase_and_time; last_current_phase_and_time_ = current_phase_and_time;
...@@ -102,12 +101,8 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) { ...@@ -102,12 +101,8 @@ void AnimationTimeline::ServiceAnimations(TimingUpdateReason reason) {
std::sort(animations.begin(), animations.end(), CompareAnimations); std::sort(animations.begin(), animations.end(), CompareAnimations);
for (Animation* animation : animations) { for (Animation* animation : animations) {
if (!animation->Update(reason)) { if (!animation->Update(reason))
animations_needing_update_.erase(animation); animations_needing_update_.erase(animation);
continue;
}
if (maybe_update_compositor_scroll_timeline)
animation->UpdateCompositorScrollTimeline();
} }
DCHECK_EQ(outdated_animation_count_, 0U); DCHECK_EQ(outdated_animation_count_, 0U);
......
...@@ -89,6 +89,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable { ...@@ -89,6 +89,7 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
return compositor_timeline_.get(); return compositor_timeline_.get();
} }
virtual CompositorAnimationTimeline* EnsureCompositorTimeline() = 0; virtual CompositorAnimationTimeline* EnsureCompositorTimeline() = 0;
virtual void UpdateCompositorTimeline() {}
void MarkAnimationsCompositorPending(bool source_changed = false); void MarkAnimationsCompositorPending(bool source_changed = false);
......
...@@ -440,4 +440,13 @@ CompositorAnimationTimeline* ScrollTimeline::EnsureCompositorTimeline() { ...@@ -440,4 +440,13 @@ CompositorAnimationTimeline* ScrollTimeline::EnsureCompositorTimeline() {
return compositor_timeline_.get(); return compositor_timeline_.get();
} }
void ScrollTimeline::UpdateCompositorTimeline() {
if (!compositor_timeline_)
return;
compositor_timeline_->UpdateCompositorTimeline(
scroll_timeline_util::GetCompositorScrollElementId(
resolved_scroll_source_),
GetResolvedStartScrollOffset(), GetResolvedEndScrollOffset());
}
} // namespace blink } // namespace blink
...@@ -97,6 +97,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ...@@ -97,6 +97,8 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
virtual void Invalidate(); virtual void Invalidate();
CompositorAnimationTimeline* EnsureCompositorTimeline() override; CompositorAnimationTimeline* EnsureCompositorTimeline() override;
void UpdateCompositorTimeline() override;
// TODO(crbug.com/896249): These methods are temporary and currently required // TODO(crbug.com/896249): These methods are temporary and currently required
// to support worklet animations. Once worklet animations become animations // to support worklet animations. Once worklet animations become animations
// these methods will not be longer needed. They are used to keep track of // these methods will not be longer needed. They are used to keep track of
......
...@@ -668,16 +668,9 @@ bool WorkletAnimation::UpdateOnCompositor() { ...@@ -668,16 +668,9 @@ bool WorkletAnimation::UpdateOnCompositor() {
StartEffectOnCompositor(compositor_animation_.get(), GetEffect()); StartEffectOnCompositor(compositor_animation_.get(), GetEffect());
} }
if (timeline_->IsScrollTimeline()) { if (timeline_->IsScrollTimeline())
auto& timeline = To<ScrollTimeline>(*timeline_); timeline_->UpdateCompositorTimeline();
Node* scroll_source = timeline.ResolvedScrollSource();
auto start_scroll_offset = timeline.GetResolvedStartScrollOffset();
auto end_scroll_offset = timeline.GetResolvedEndScrollOffset();
compositor_animation_->UpdateScrollTimeline(
scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
start_scroll_offset, end_scroll_offset);
}
compositor_animation_->UpdatePlaybackRate(playback_rate_); compositor_animation_->UpdatePlaybackRate(playback_rate_);
return true; return true;
} }
......
...@@ -80,14 +80,6 @@ void CompositorAnimation::AbortKeyframeModel(int keyframe_model_id) { ...@@ -80,14 +80,6 @@ void CompositorAnimation::AbortKeyframeModel(int keyframe_model_id) {
animation_->AbortKeyframeModel(keyframe_model_id); animation_->AbortKeyframeModel(keyframe_model_id);
} }
void CompositorAnimation::UpdateScrollTimeline(
base::Optional<cc::ElementId> element_id,
base::Optional<double> start_scroll_offset,
base::Optional<double> end_scroll_offset) {
animation_->UpdateScrollTimeline(element_id, start_scroll_offset,
end_scroll_offset);
}
void CompositorAnimation::UpdatePlaybackRate(double playback_rate) { void CompositorAnimation::UpdatePlaybackRate(double playback_rate) {
cc::ToWorkletAnimation(animation_.get())->UpdatePlaybackRate(playback_rate); cc::ToWorkletAnimation(animation_.get())->UpdatePlaybackRate(playback_rate);
} }
......
...@@ -57,9 +57,6 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate { ...@@ -57,9 +57,6 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset); void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
void AbortKeyframeModel(int keyframe_model_id); void AbortKeyframeModel(int keyframe_model_id);
void UpdateScrollTimeline(base::Optional<cc::ElementId>,
base::Optional<double> start_scroll_offset,
base::Optional<double> end_scroll_offset);
void UpdatePlaybackRate(double playback_rate); void UpdatePlaybackRate(double playback_rate);
private: private:
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "cc/animation/animation_host.h" #include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h" #include "cc/animation/animation_id_provider.h"
#include "cc/animation/scroll_timeline.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h" #include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
...@@ -32,6 +33,15 @@ cc::AnimationTimeline* CompositorAnimationTimeline::GetAnimationTimeline() ...@@ -32,6 +33,15 @@ cc::AnimationTimeline* CompositorAnimationTimeline::GetAnimationTimeline()
return animation_timeline_.get(); return animation_timeline_.get();
} }
void CompositorAnimationTimeline::UpdateCompositorTimeline(
base::Optional<CompositorElementId> pending_id,
base::Optional<double> start_scroll_offset,
base::Optional<double> end_scroll_offset) {
ToScrollTimeline(animation_timeline_.get())
->UpdateScrollerIdAndScrollOffsets(pending_id, start_scroll_offset,
end_scroll_offset);
}
void CompositorAnimationTimeline::AnimationAttached( void CompositorAnimationTimeline::AnimationAttached(
const blink::CompositorAnimationClient& client) { const blink::CompositorAnimationClient& client) {
if (client.GetCompositorAnimation()) { if (client.GetCompositorAnimation()) {
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "cc/animation/animation_timeline.h" #include "cc/animation/animation_timeline.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
...@@ -28,6 +30,9 @@ class PLATFORM_EXPORT CompositorAnimationTimeline { ...@@ -28,6 +30,9 @@ class PLATFORM_EXPORT CompositorAnimationTimeline {
~CompositorAnimationTimeline(); ~CompositorAnimationTimeline();
cc::AnimationTimeline* GetAnimationTimeline() const; cc::AnimationTimeline* GetAnimationTimeline() const;
void UpdateCompositorTimeline(base::Optional<CompositorElementId> pending_id,
base::Optional<double> start_scroll_offset,
base::Optional<double> end_scroll_offset);
void AnimationAttached(const CompositorAnimationClient&); void AnimationAttached(const CompositorAnimationClient&);
void AnimationDestroyed(const CompositorAnimationClient&); void AnimationDestroyed(const CompositorAnimationClient&);
......
...@@ -34,7 +34,7 @@ layout changes on percentage-based scroll offset"> ...@@ -34,7 +34,7 @@ layout changes on percentage-based scroll offset">
} }
#spacer { #spacer {
height: 400px; height: 80px;
} }
.invisible { .invisible {
...@@ -70,15 +70,18 @@ layout changes on percentage-based scroll offset"> ...@@ -70,15 +70,18 @@ layout changes on percentage-based scroll offset">
const animation = new Animation(effect, timeline); const animation = new Animation(effect, timeline);
animation.play(); animation.play();
// Moves the scroller to the end point (400px). // Moves the scroller to the end point (240px).
const maxScroll = scroller.scrollHeight - scroller.clientHeight; const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = maxScroll; scroller.scrollTop = maxScroll * 0.6;
// Adds 400px to scroll height which pushes scroll progress back to 50%.
const spacer = document.getElementById('spacer');
spacer.classList.remove('invisible');
// Makes sure that the animation runs on compositor with current scroll offset
waitForAnimationFrames(2).then(_ => { waitForAnimationFrames(2).then(_ => {
takeScreenshot(); // Adds 80px to scroll height which pushes scroll progress back to 50%.
const spacer = document.getElementById('spacer');
spacer.classList.remove('invisible');
// Makes sure that the change is propagated to the compositor.
waitForAnimationFrames(2).then(_ => {
takeScreenshot();
});
}); });
</script> </script>
\ No newline at end of file
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