Commit 254181fa authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

Introduce scroll_timeline_util namespace for utility functions

Various functions in WorkletAnimation had gotten far too big to be anonymous
namespace methods. Pull them out into proper utility functions - which means
they can also now be tested!

Bug: 910777
Change-Id: I50a65f0e613ff71e7fddc042ee80448f0c3fbcba
Reviewed-on: https://chromium-review.googlesource.com/c/1355984Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarMajid Valipour <majidvp@chromium.org>
Reviewed-by: default avatarYi Gu <yigu@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#613221}
parent 5d10a30b
...@@ -53,6 +53,17 @@ class CC_ANIMATION_EXPORT ScrollTimeline { ...@@ -53,6 +53,17 @@ class CC_ANIMATION_EXPORT ScrollTimeline {
void PromoteScrollTimelinePendingToActive(); void PromoteScrollTimelinePendingToActive();
base::Optional<ElementId> GetActiveIdForTest() const { return active_id_; }
base::Optional<ElementId> GetPendingIdForTest() const { return pending_id_; }
ScrollDirection GetDirectionForTest() const { return direction_; }
base::Optional<double> GetStartScrollOffsetForTest() const {
return start_scroll_offset_;
}
base::Optional<double> GetEndScrollOffsetForTest() const {
return end_scroll_offset_;
}
double GetTimeRangeForTest() const { return time_range_; }
private: private:
// The scroller which this ScrollTimeline is based on. The same underlying // The scroller which this ScrollTimeline is based on. The same underlying
// scroll source may have different ids in the pending and active tree (see // scroll source may have different ids in the pending and active tree (see
......
...@@ -1720,6 +1720,7 @@ jumbo_source_set("unit_tests") { ...@@ -1720,6 +1720,7 @@ jumbo_source_set("unit_tests") {
"animation/list_interpolation_functions_test.cc", "animation/list_interpolation_functions_test.cc",
"animation/property_handle_test.cc", "animation/property_handle_test.cc",
"animation/scroll_timeline_test.cc", "animation/scroll_timeline_test.cc",
"animation/scroll_timeline_util_test.cc",
"animation/timing_calculations_test.cc", "animation/timing_calculations_test.cc",
"animation/timing_input_test.cc", "animation/timing_input_test.cc",
"clipboard/data_object_test.cc", "clipboard/data_object_test.cc",
......
...@@ -182,6 +182,8 @@ blink_core_sources("animation") { ...@@ -182,6 +182,8 @@ blink_core_sources("animation") {
"sampled_effect.h", "sampled_effect.h",
"scroll_timeline.cc", "scroll_timeline.cc",
"scroll_timeline.h", "scroll_timeline.h",
"scroll_timeline_util.cc",
"scroll_timeline_util.h",
"shadow_interpolation_functions.cc", "shadow_interpolation_functions.cc",
"shadow_interpolation_functions.h", "shadow_interpolation_functions.h",
"side_index.h", "side_index.h",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
namespace blink {
namespace scroll_timeline_util {
std::unique_ptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
AnimationTimeline* timeline) {
if (!timeline || timeline->IsDocumentTimeline())
return nullptr;
ScrollTimeline* scroll_timeline = ToScrollTimeline(timeline);
Node* scroll_source = scroll_timeline->ResolvedScrollSource();
base::Optional<CompositorElementId> element_id =
GetCompositorScrollElementId(scroll_source);
DoubleOrScrollTimelineAutoKeyword time_range;
scroll_timeline->timeRange(time_range);
// TODO(smcgruer): Handle 'auto' time range value.
DCHECK(time_range.IsDouble());
LayoutBox* box = scroll_source ? scroll_source->GetLayoutBox() : nullptr;
CompositorScrollTimeline::ScrollDirection orientation = ConvertOrientation(
scroll_timeline->GetOrientation(), box ? box->Style() : nullptr);
base::Optional<double> start_scroll_offset;
base::Optional<double> end_scroll_offset;
if (box) {
double current_offset;
double max_offset;
scroll_timeline->GetCurrentAndMaxOffset(box, current_offset, max_offset);
double resolved_start_scroll_offset = 0;
double resolved_end_scroll_offset = max_offset;
scroll_timeline->ResolveScrollStartAndEnd(box, max_offset,
resolved_start_scroll_offset,
resolved_end_scroll_offset);
start_scroll_offset = resolved_start_scroll_offset;
end_scroll_offset = resolved_end_scroll_offset;
}
return std::make_unique<CompositorScrollTimeline>(
element_id, orientation, start_scroll_offset, end_scroll_offset,
time_range.GetAsDouble());
}
base::Optional<CompositorElementId> GetCompositorScrollElementId(
const Node* node) {
if (!node || !node->GetLayoutObject() || !node->GetLayoutObject()->UniqueId())
return base::nullopt;
return CompositorElementIdFromUniqueObjectId(
node->GetLayoutObject()->UniqueId(),
CompositorElementIdNamespace::kScroll);
}
// The compositor does not know about writing modes, so we have to convert the
// web concepts of 'block' and 'inline' direction into absolute vertical or
// horizontal directions.
CompositorScrollTimeline::ScrollDirection ConvertOrientation(
ScrollTimeline::ScrollDirection orientation,
const ComputedStyle* style) {
// Easy cases; physical is always physical.
if (orientation == ScrollTimeline::Horizontal)
return CompositorScrollTimeline::ScrollRight;
if (orientation == ScrollTimeline::Vertical)
return CompositorScrollTimeline::ScrollDown;
// Harder cases; first work out which axis is which, and then for each check
// which edge we start at.
// writing-mode: horizontal-tb
bool is_horizontal_writing_mode =
style ? style->IsHorizontalWritingMode() : true;
// writing-mode: vertical-lr
bool is_flipped_lines_writing_mode =
style ? style->IsFlippedLinesWritingMode() : false;
// direction: ltr;
bool is_ltr_direction = style ? style->IsLeftToRightDirection() : true;
if (orientation == ScrollTimeline::Block) {
if (is_horizontal_writing_mode) {
// For horizontal writing mode, block is vertical. The starting edge is
// always the top.
return CompositorScrollTimeline::ScrollDown;
}
// For vertical writing mode, the block axis is horizontal. The starting
// edge depends on if we are lr or rl.
return is_flipped_lines_writing_mode ? CompositorScrollTimeline::ScrollRight
: CompositorScrollTimeline::ScrollLeft;
}
DCHECK_EQ(orientation, ScrollTimeline::Inline);
if (is_horizontal_writing_mode) {
// For horizontal writing mode, inline is horizontal. The starting edge
// depends on the directionality.
return is_ltr_direction ? CompositorScrollTimeline::ScrollRight
: CompositorScrollTimeline::ScrollLeft;
}
// For vertical writing mode, inline is vertical. The starting edge still
// depends on the directionality; whether it is vertical-lr or vertical-rl
// does not matter.
return is_ltr_direction ? CompositorScrollTimeline::ScrollDown
: CompositorScrollTimeline::ScrollUp;
}
} // namespace scroll_timeline_util
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_UTIL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_UTIL_H_
#include <memory>
#include "base/optional.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
namespace blink {
class AnimationTimeline;
class ComputedStyle;
class Node;
namespace scroll_timeline_util {
// Converts the input timeline to the compositor representation of a
// ScrollTimeline. Returns nullptr if the input is not a ScrollTimeline.
std::unique_ptr<CompositorScrollTimeline> CORE_EXPORT
ToCompositorScrollTimeline(AnimationTimeline*);
// Retrieves the 'scroll' compositor element id for the input node, or
// base::nullopt if it does not exist.
base::Optional<CompositorElementId> CORE_EXPORT
GetCompositorScrollElementId(const Node*);
// Convert the blink concept of a ScrollTimeline orientation into the cc one.
//
// This implements a subset of the conversions documented in
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
CompositorScrollTimeline::ScrollDirection CORE_EXPORT
ConvertOrientation(ScrollTimeline::ScrollDirection, const ComputedStyle*);
} // namespace scroll_timeline_util
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_UTIL_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
namespace blink {
namespace scroll_timeline_util {
using ScrollTimelineUtilTest = PageTestBase;
// This test covers only the basic conversions for element id, time range,
// orientation, and start and end scroll offset. Complex orientation conversions
// are tested in the GetOrientation* tests, and complex start/end scroll offset
// resolutions are tested in blink::ScrollTimelineTest.
TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimeline) {
SetBodyInnerHTML(R"HTML(
<style>
#scroller {
overflow: auto;
width: 100px;
height: 100px;
}
#contents {
height: 1000px;
}
</style>
<div id='scroller'><div id='contents'></div></div>
)HTML");
Element* scroller = GetElementById("scroller");
base::Optional<CompositorElementId> element_id =
GetCompositorScrollElementId(scroller);
ASSERT_TRUE(element_id.has_value());
ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
options->setScrollSource(scroller);
const double time_range = 100;
options->setTimeRange(
DoubleOrScrollTimelineAutoKeyword::FromDouble(time_range));
options->setOrientation("block");
options->setStartScrollOffset("50px");
options->setEndScrollOffset("auto");
ScrollTimeline* timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
EXPECT_EQ(compositor_timeline->GetActiveIdForTest(), base::nullopt);
EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), element_id);
EXPECT_EQ(compositor_timeline->GetTimeRangeForTest(), time_range);
EXPECT_EQ(compositor_timeline->GetDirectionForTest(),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(compositor_timeline->GetStartScrollOffsetForTest(), 50);
// 900 is contents-size - scroller-viewport == 1000 - 100
EXPECT_EQ(compositor_timeline->GetEndScrollOffsetForTest(), 900);
}
TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullParameter) {
EXPECT_EQ(ToCompositorScrollTimeline(nullptr), nullptr);
}
TEST_F(ScrollTimelineUtilTest,
ToCompositorScrollTimelineDocumentTimelineParameter) {
DocumentTimeline* timeline =
DocumentTimeline::Create(Document::CreateForTest());
EXPECT_EQ(ToCompositorScrollTimeline(timeline), nullptr);
}
TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullScrollSource) {
// Directly call the constructor to make it easier to pass a null
// scrollSource. The alternative approach would require us to remove the
// documentElement from the document.
Element* scroll_source = nullptr;
CSSPrimitiveValue* start_scroll_offset = nullptr;
CSSPrimitiveValue* end_scroll_offset = nullptr;
ScrollTimeline* timeline =
new ScrollTimeline(scroll_source, ScrollTimeline::Block,
start_scroll_offset, end_scroll_offset, 100);
std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
ASSERT_TRUE(compositor_timeline.get());
EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), base::nullopt);
}
TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullLayoutBox) {
Element* div = HTMLDivElement::Create(GetDocument());
ASSERT_FALSE(div->GetLayoutBox());
ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
DoubleOrScrollTimelineAutoKeyword time_range =
DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
options->setTimeRange(time_range);
options->setScrollSource(div);
ScrollTimeline* timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
EXPECT_TRUE(compositor_timeline.get());
// Here we just want to test the start/end scroll offset.
// ToCompositorScrollTimelineNullScrollSource covers the expected pending id
// and ConvertOrientationNullStyle covers the orientation conversion.
EXPECT_EQ(compositor_timeline->GetStartScrollOffsetForTest(), base::nullopt);
EXPECT_EQ(compositor_timeline->GetEndScrollOffsetForTest(), base::nullopt);
}
TEST_F(ScrollTimelineUtilTest, ConvertOrientationPhysicalCases) {
// For physical the writing-mode and directionality shouldn't matter, so make
// sure it doesn't.
Vector<WritingMode> writing_modes = {WritingMode::kHorizontalTb,
WritingMode::kVerticalLr,
WritingMode::kVerticalRl};
Vector<TextDirection> directions = {TextDirection::kLtr, TextDirection::kRtl};
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
for (const WritingMode& writing_mode : writing_modes) {
for (const TextDirection& direction : directions) {
style->SetWritingMode(writing_mode);
style->SetDirection(direction);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Vertical, style.get()),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Horizontal, style.get()),
CompositorScrollTimeline::ScrollRight);
}
}
}
TEST_F(ScrollTimelineUtilTest, ConvertOrientationLogical) {
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
// horizontal-tb, ltr
style->SetWritingMode(WritingMode::kHorizontalTb);
style->SetDirection(TextDirection::kLtr);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollRight);
// vertical-lr, ltr
style->SetWritingMode(WritingMode::kVerticalLr);
style->SetDirection(TextDirection::kLtr);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollRight);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollDown);
// vertical-rl, ltr
style->SetWritingMode(WritingMode::kVerticalRl);
style->SetDirection(TextDirection::kLtr);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollLeft);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollDown);
// horizontal-tb, rtl
style->SetWritingMode(WritingMode::kHorizontalTb);
style->SetDirection(TextDirection::kRtl);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollLeft);
// vertical-lr, rtl
style->SetWritingMode(WritingMode::kVerticalLr);
style->SetDirection(TextDirection::kRtl);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollRight);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollUp);
// vertical-rl, rtl
style->SetWritingMode(WritingMode::kVerticalRl);
style->SetDirection(TextDirection::kRtl);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, style.get()),
CompositorScrollTimeline::ScrollLeft);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, style.get()),
CompositorScrollTimeline::ScrollUp);
}
TEST_F(ScrollTimelineUtilTest, ConvertOrientationNullStyle) {
// When the style is nullptr we assume horizontal-tb and ltr direction. This
// means that block is ScrollDown and inline is ScrollRight
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Vertical, nullptr),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Horizontal, nullptr),
CompositorScrollTimeline::ScrollRight);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Block, nullptr),
CompositorScrollTimeline::ScrollDown);
EXPECT_EQ(ConvertOrientation(ScrollTimeline::Inline, nullptr),
CompositorScrollTimeline::ScrollRight);
}
TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNullNode) {
EXPECT_EQ(GetCompositorScrollElementId(nullptr), base::nullopt);
}
TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNullLayoutObject) {
Element* div = HTMLDivElement::Create(GetDocument());
ASSERT_FALSE(div->GetLayoutObject());
EXPECT_EQ(GetCompositorScrollElementId(nullptr), base::nullopt);
}
TEST_F(ScrollTimelineUtilTest, GetCompositorScrollElementIdNoUniqueId) {
SetBodyInnerHTML("<div id='test'></div>");
Element* test = GetElementById("test");
ASSERT_TRUE(test->GetLayoutObject());
ASSERT_FALSE(test->GetLayoutObject()->UniqueId());
EXPECT_EQ(GetCompositorScrollElementId(test), base::nullopt);
}
} // namespace scroll_timeline_util
} // namespace blink
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h" #include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#include "third_party/blink/renderer/core/animation/timing.h" #include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_controller.h" #include "third_party/blink/renderer/core/animation/worklet_animation_controller.h"
#include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/node.h"
...@@ -121,120 +122,6 @@ bool CheckElementComposited(const Node& target) { ...@@ -121,120 +122,6 @@ bool CheckElementComposited(const Node& target) {
kPaintsIntoOwnBacking; kPaintsIntoOwnBacking;
} }
base::Optional<CompositorElementId> GetCompositorScrollElementId(
const Node* node) {
if (!node || !node->GetLayoutObject() || !node->GetLayoutObject()->UniqueId())
return base::nullopt;
return CompositorElementIdFromUniqueObjectId(
node->GetLayoutObject()->UniqueId(),
CompositorElementIdNamespace::kScroll);
}
// Convert the blink concept of a ScrollTimeline orientation into the cc one.
//
// The compositor does not know about writing modes, so we have to convert the
// web concepts of 'block' and 'inline' direction into absolute vertical or
// horizontal directions.
//
// This implements a subset of the conversions documented in
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
//
// TODO(smcgruer): If the writing mode of a scroller changes, we have to update
// any related cc::ScrollTimeline somehow.
CompositorScrollTimeline::ScrollDirection ConvertOrientation(
ScrollTimeline::ScrollDirection orientation,
const ComputedStyle* style) {
// Easy cases; physical is always physical.
if (orientation == ScrollTimeline::Horizontal)
return CompositorScrollTimeline::ScrollRight;
if (orientation == ScrollTimeline::Vertical)
return CompositorScrollTimeline::ScrollDown;
// Harder cases; first work out which axis is which, and then for each check
// which edge we start at.
// writing-mode: horizontal-tb
bool is_horizontal_writing_mode =
style ? style->IsHorizontalWritingMode() : true;
// writing-mode: vertical-lr
bool is_flipped_lines_writing_mode =
style ? style->IsFlippedLinesWritingMode() : false;
// direction: ltr;
bool is_ltr_direction = style ? style->IsLeftToRightDirection() : true;
if (orientation == ScrollTimeline::Block) {
if (is_horizontal_writing_mode) {
// For horizontal writing mode, block is vertical. The starting edge is
// always the top.
return CompositorScrollTimeline::ScrollDown;
}
// For vertical writing mode, the block axis is horizontal. The starting
// edge depends on if we are lr or rl.
return is_flipped_lines_writing_mode ? CompositorScrollTimeline::ScrollRight
: CompositorScrollTimeline::ScrollLeft;
}
DCHECK_EQ(orientation, ScrollTimeline::Inline);
if (is_horizontal_writing_mode) {
// For horizontal writing mode, inline is horizontal. The starting edge
// depends on the directionality.
return is_ltr_direction ? CompositorScrollTimeline::ScrollRight
: CompositorScrollTimeline::ScrollLeft;
}
// For vertical writing mode, inline is vertical. The starting edge still
// depends on the directionality; whether it is vertical-lr or vertical-rl
// does not matter.
return is_ltr_direction ? CompositorScrollTimeline::ScrollDown
: CompositorScrollTimeline::ScrollUp;
}
// Converts a blink::ScrollTimeline into a cc::ScrollTimeline.
//
// If the timeline cannot be converted, returns nullptr.
std::unique_ptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
AnimationTimeline* timeline) {
if (!timeline || timeline->IsDocumentTimeline())
return nullptr;
ScrollTimeline* scroll_timeline = ToScrollTimeline(timeline);
Node* scroll_source = scroll_timeline->ResolvedScrollSource();
base::Optional<CompositorElementId> element_id =
GetCompositorScrollElementId(scroll_source);
DoubleOrScrollTimelineAutoKeyword time_range;
scroll_timeline->timeRange(time_range);
// TODO(smcgruer): Handle 'auto' time range value.
DCHECK(time_range.IsDouble());
// TODO(smcgruer): If the scroll source later gets a LayoutBox (e.g. was
// display:none and now isn't), we need to update the compositor to have the
// correct orientation and start/end offset information.
LayoutBox* box = scroll_source ? scroll_source->GetLayoutBox() : nullptr;
CompositorScrollTimeline::ScrollDirection orientation = ConvertOrientation(
scroll_timeline->GetOrientation(), box ? box->Style() : nullptr);
base::Optional<double> start_scroll_offset;
base::Optional<double> end_scroll_offset;
if (box) {
double current_offset;
double max_offset;
scroll_timeline->GetCurrentAndMaxOffset(box, current_offset, max_offset);
double resolved_start_scroll_offset = 0;
double resolved_end_scroll_offset = max_offset;
scroll_timeline->ResolveScrollStartAndEnd(box, max_offset,
resolved_start_scroll_offset,
resolved_end_scroll_offset);
start_scroll_offset = resolved_start_scroll_offset;
end_scroll_offset = resolved_end_scroll_offset;
}
return std::make_unique<CompositorScrollTimeline>(
element_id, orientation, start_scroll_offset, end_scroll_offset,
time_range.GetAsDouble());
}
void StartEffectOnCompositor(CompositorAnimation* animation, void StartEffectOnCompositor(CompositorAnimation* animation,
KeyframeEffect* effect) { KeyframeEffect* effect) {
DCHECK(effect); DCHECK(effect);
...@@ -533,8 +420,13 @@ bool WorkletAnimation::StartOnCompositor() { ...@@ -533,8 +420,13 @@ bool WorkletAnimation::StartOnCompositor() {
return false; return false;
if (!compositor_animation_) { if (!compositor_animation_) {
// TODO(smcgruer): If the scroll source later gets a LayoutBox (e.g. was
// display:none and now isn't) or the writing mode changes, we need to
// update the compositor to have the correct orientation and start/end
// offset information.
compositor_animation_ = CompositorAnimation::CreateWorkletAnimation( compositor_animation_ = CompositorAnimation::CreateWorkletAnimation(
id_, animator_name_, ToCompositorScrollTimeline(timeline_), id_, animator_name_,
scroll_timeline_util::ToCompositorScrollTimeline(timeline_),
std::move(options_)); std::move(options_));
compositor_animation_->SetAnimationDelegate(this); compositor_animation_->SetAnimationDelegate(this);
} }
...@@ -591,8 +483,8 @@ void WorkletAnimation::UpdateOnCompositor() { ...@@ -591,8 +483,8 @@ void WorkletAnimation::UpdateOnCompositor() {
end_scroll_offset = resolved_end_scroll_offset; end_scroll_offset = resolved_end_scroll_offset;
} }
compositor_animation_->UpdateScrollTimeline( compositor_animation_->UpdateScrollTimeline(
GetCompositorScrollElementId(scroll_source), start_scroll_offset, scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
end_scroll_offset); start_scroll_offset, end_scroll_offset);
} }
} }
......
...@@ -248,6 +248,7 @@ _CONFIG = [ ...@@ -248,6 +248,7 @@ _CONFIG = [
'root_scroller_util::.+', 'root_scroller_util::.+',
'scheduler::.+', 'scheduler::.+',
'scroll_customization::.+', 'scroll_customization::.+',
'scroll_timeline_util::.+',
'style_change_extra_data::.+', 'style_change_extra_data::.+',
'style_change_reason::.+', 'style_change_reason::.+',
'svg_path_parser::.+', 'svg_path_parser::.+',
......
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