Commit 7472d7c2 authored by Michael Lippautz's avatar Michael Lippautz Committed by Chromium LUCI CQ

animation: Avoid dynamic HeapVector when creating ScrollTimeline

Avoids Member<HeapVector<...>> and saves the allocation when
creating ScrollTimeline.

Bug: 1154667
Change-Id: Id8a61f4ca6607a21e23d8ad1d9ac54340bf0d452
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2570369
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833285}
parent c4e6369a
...@@ -434,11 +434,11 @@ AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect, ...@@ -434,11 +434,11 @@ AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect,
CSSScrollTimeline* CreateCSSScrollTimeline( CSSScrollTimeline* CreateCSSScrollTimeline(
Element* element, Element* element,
const CSSScrollTimeline::Options& options) { CSSScrollTimeline::Options&& options) {
if (!options.IsValid()) if (!options.IsValid())
return nullptr; return nullptr;
auto* scroll_timeline = auto* scroll_timeline = MakeGarbageCollected<CSSScrollTimeline>(
MakeGarbageCollected<CSSScrollTimeline>(&element->GetDocument(), options); &element->GetDocument(), std::move(options));
// It's is not allowed for a style resolve to create timelines that // It's is not allowed for a style resolve to create timelines that
// needs timing updates (i.e. AnimationTimeline::NeedsAnimationTimingUpdate() // needs timing updates (i.e. AnimationTimeline::NeedsAnimationTimingUpdate()
// must return false). Servicing animations after creation preserves this // must return false). Servicing animations after creation preserves this
...@@ -486,7 +486,7 @@ AnimationTimeline* ComputeTimeline(Element* element, ...@@ -486,7 +486,7 @@ AnimationTimeline* ComputeTimeline(Element* element,
if (timeline->Matches(options)) if (timeline->Matches(options))
return existing_timeline; return existing_timeline;
} }
if (auto* timeline = CreateCSSScrollTimeline(element, options)) if (auto* timeline = CreateCSSScrollTimeline(element, std::move(options)))
return timeline; return timeline;
} }
return nullptr; return nullptr;
......
...@@ -123,23 +123,22 @@ ScrollTimelineOffset* ComputeScrollOffset(Document& document, ...@@ -123,23 +123,22 @@ ScrollTimelineOffset* ComputeScrollOffset(Document& document,
return MakeGarbageCollected<ScrollTimelineOffset>(); return MakeGarbageCollected<ScrollTimelineOffset>();
} }
HeapVector<Member<ScrollTimelineOffset>>* ComputeScrollOffsets( HeapVector<Member<ScrollTimelineOffset>> ComputeScrollOffsets(
Document& document, Document& document,
const CSSValue* start, const CSSValue* start,
const CSSValue* end) { const CSSValue* end) {
auto* offsets = HeapVector<Member<ScrollTimelineOffset>> offsets;
MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>();
bool start_is_auto = IsAuto(start) || !start; const bool start_is_auto = !start || IsAuto(start);
bool end_is_auto = IsAuto(end) || !end; const bool end_is_auto = !end || IsAuto(end);
// TODO(crbug.com/1094014): scroll_offsets will replace start and end // TODO(crbug.com/1094014): scroll_offsets will replace start and end
// offsets once spec decision on multiple scroll offsets is finalized. // offsets once spec decision on multiple scroll offsets is finalized.
// https://github.com/w3c/csswg-drafts/issues/4912 // https://github.com/w3c/csswg-drafts/issues/4912
if (!start_is_auto) if (!start_is_auto)
offsets->push_back(ComputeScrollOffset(document, start)); offsets.push_back(ComputeScrollOffset(document, start));
if (!end_is_auto || !start_is_auto) if (!end_is_auto || !start_is_auto)
offsets->push_back(ComputeScrollOffset(document, end)); offsets.push_back(ComputeScrollOffset(document, end));
return offsets; return offsets;
} }
...@@ -214,11 +213,11 @@ CSSScrollTimeline::Options::Options(Element* element, ...@@ -214,11 +213,11 @@ CSSScrollTimeline::Options::Options(Element* element,
time_range_(ComputeTimeRange(rule.GetTimeRange())), time_range_(ComputeTimeRange(rule.GetTimeRange())),
rule_(&rule) {} rule_(&rule) {}
CSSScrollTimeline::CSSScrollTimeline(Document* document, const Options& options) CSSScrollTimeline::CSSScrollTimeline(Document* document, Options&& options)
: ScrollTimeline(document, : ScrollTimeline(document,
options.source_, options.source_,
options.direction_, options.direction_,
options.offsets_, std::move(options.offsets_),
*options.time_range_), *options.time_range_),
rule_(options.rule_) { rule_(options.rule_) {
DCHECK(options.IsValid()); DCHECK(options.IsValid());
...@@ -231,10 +230,9 @@ const AtomicString& CSSScrollTimeline::Name() const { ...@@ -231,10 +230,9 @@ const AtomicString& CSSScrollTimeline::Name() const {
} }
bool CSSScrollTimeline::Matches(const Options& options) const { bool CSSScrollTimeline::Matches(const Options& options) const {
DCHECK(options.offsets_);
return (scrollSource() == options.source_) && return (scrollSource() == options.source_) &&
(GetOrientation() == options.direction_) && (GetOrientation() == options.direction_) &&
(ScrollOffsetsEqual(*options.offsets_)) && (ScrollOffsetsEqual(options.offsets_)) &&
(GetTimeRange() == options.time_range_) && (rule_ == options.rule_); (GetTimeRange() == options.time_range_) && (rule_ == options.rule_);
} }
......
...@@ -33,12 +33,12 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline { ...@@ -33,12 +33,12 @@ class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline {
Element* source_; Element* source_;
ScrollTimeline::ScrollDirection direction_; ScrollTimeline::ScrollDirection direction_;
HeapVector<Member<ScrollTimelineOffset>>* offsets_; HeapVector<Member<ScrollTimelineOffset>> offsets_;
base::Optional<double> time_range_; base::Optional<double> time_range_;
StyleRuleScrollTimeline* rule_; StyleRuleScrollTimeline* rule_;
}; };
CSSScrollTimeline(Document*, const Options&); CSSScrollTimeline(Document*, Options&&);
const AtomicString& Name() const; const AtomicString& Name() const;
......
...@@ -138,17 +138,16 @@ ScrollTimeline* ScrollTimeline::Create(Document& document, ...@@ -138,17 +138,16 @@ ScrollTimeline* ScrollTimeline::Create(Document& document,
return nullptr; return nullptr;
} }
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets = HeapVector<Member<ScrollTimelineOffset>> scroll_offsets;
MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>();
if (options->scrollOffsets().IsEmpty()) { if (options->scrollOffsets().IsEmpty()) {
// TODO(crbug.com/1094014): scroll_offsets will replace start and end // TODO(crbug.com/1094014): scroll_offsets will replace start and end
// offsets once spec decision on multiple scroll offsets is finalized. // offsets once spec decision on multiple scroll offsets is finalized.
// https://github.com/w3c/csswg-drafts/issues/4912 // https://github.com/w3c/csswg-drafts/issues/4912
if (!start_scroll_offset->IsDefaultValue()) if (!start_scroll_offset->IsDefaultValue())
scroll_offsets->push_back(start_scroll_offset); scroll_offsets.push_back(start_scroll_offset);
if (!end_scroll_offset->IsDefaultValue() || if (!end_scroll_offset->IsDefaultValue() ||
!start_scroll_offset->IsDefaultValue()) !start_scroll_offset->IsDefaultValue())
scroll_offsets->push_back(end_scroll_offset); scroll_offsets.push_back(end_scroll_offset);
} else { } else {
for (auto& offset : options->scrollOffsets()) { for (auto& offset : options->scrollOffsets()) {
ScrollTimelineOffset* scroll_offset = ScrollTimelineOffset* scroll_offset =
...@@ -159,13 +158,13 @@ ScrollTimeline* ScrollTimeline::Create(Document& document, ...@@ -159,13 +158,13 @@ ScrollTimeline* ScrollTimeline::Create(Document& document,
} }
if (scroll_offset->IsDefaultValue() && if (scroll_offset->IsDefaultValue() &&
(options->scrollOffsets().size() == 1 || (options->scrollOffsets().size() == 1 ||
(scroll_offsets->size() + 1) < options->scrollOffsets().size())) { (scroll_offsets.size() + 1) < options->scrollOffsets().size())) {
exception_state.ThrowTypeError( exception_state.ThrowTypeError(
"Invalid scrollOffsets: 'auto' can only be set as an end " "Invalid scrollOffsets: 'auto' can only be set as an end "
"offset when start offset presents."); "offset when start offset presents.");
return nullptr; return nullptr;
} }
scroll_offsets->push_back(scroll_offset); scroll_offsets.push_back(scroll_offset);
} }
} }
...@@ -182,15 +181,14 @@ ScrollTimeline::ScrollTimeline( ...@@ -182,15 +181,14 @@ ScrollTimeline::ScrollTimeline(
Document* document, Document* document,
Element* scroll_source, Element* scroll_source,
ScrollDirection orientation, ScrollDirection orientation,
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets, HeapVector<Member<ScrollTimelineOffset>> scroll_offsets,
base::Optional<double> time_range) base::Optional<double> time_range)
: AnimationTimeline(document), : AnimationTimeline(document),
scroll_source_(scroll_source), scroll_source_(scroll_source),
resolved_scroll_source_(ResolveScrollSource(scroll_source_)), resolved_scroll_source_(ResolveScrollSource(scroll_source_)),
orientation_(orientation), orientation_(orientation),
scroll_offsets_(scroll_offsets), scroll_offsets_(std::move(scroll_offsets)),
time_range_(time_range) { time_range_(time_range) {
DCHECK(scroll_offsets_);
if (resolved_scroll_source_) { if (resolved_scroll_source_) {
ScrollTimelineSet& set = GetScrollTimelineSet(); ScrollTimelineSet& set = GetScrollTimelineSet();
if (!set.Contains(resolved_scroll_source_)) { if (!set.Contains(resolved_scroll_source_)) {
...@@ -222,14 +220,12 @@ bool ScrollTimeline::ComputeIsActive() const { ...@@ -222,14 +220,12 @@ bool ScrollTimeline::ComputeIsActive() const {
ScrollTimelineOffset* ScrollTimeline::StartScrollOffset() const { ScrollTimelineOffset* ScrollTimeline::StartScrollOffset() const {
// Single entry offset in scrollOffsets is considered as 'end'. Thus, // Single entry offset in scrollOffsets is considered as 'end'. Thus,
// resolving start offset only if there is at least 2 offsets. // resolving start offset only if there is at least 2 offsets.
return scroll_offsets_ && scroll_offsets_->size() >= 2 return scroll_offsets_.size() >= 2 ? scroll_offsets_.at(0) : nullptr;
? scroll_offsets_->at(0)
: nullptr;
} }
ScrollTimelineOffset* ScrollTimeline::EndScrollOffset() const { ScrollTimelineOffset* ScrollTimeline::EndScrollOffset() const {
// End offset is always the last offset in scrollOffsets if exists. // End offset is always the last offset in scrollOffsets if exists.
return scroll_offsets_ && scroll_offsets_->size() >= 1 return scroll_offsets_.size() >= 1
? scroll_offsets_->at(scroll_offsets_->size() - 1) ? scroll_offsets_.at(scroll_offsets_.size() - 1)
: nullptr; : nullptr;
} }
...@@ -255,16 +251,16 @@ bool ScrollTimeline::ResolveScrollOffsets( ...@@ -255,16 +251,16 @@ bool ScrollTimeline::ResolveScrollOffsets(
auto orientation = ToPhysicalScrollOrientation(orientation_, *layout_box); auto orientation = ToPhysicalScrollOrientation(orientation_, *layout_box);
if (scroll_offsets_->size() == 0) { if (scroll_offsets_.size() == 0) {
// Start and end offsets resolve to 'auto'. // Start and end offsets resolve to 'auto'.
resolved_offsets.push_back(0); resolved_offsets.push_back(0);
resolved_offsets.push_back(max_offset); resolved_offsets.push_back(max_offset);
return true; return true;
} }
// Single entry offset in scrollOffsets is considered as 'end'. // Single entry offset in scrollOffsets is considered as 'end'.
if (scroll_offsets_->size() == 1) if (scroll_offsets_.size() == 1)
resolved_offsets.push_back(0); resolved_offsets.push_back(0);
for (auto& offset : *scroll_offsets_) { for (auto& offset : scroll_offsets_) {
auto resolved_offset = offset->ResolveOffset( auto resolved_offset = offset->ResolveOffset(
resolved_scroll_source_, orientation, max_offset, max_offset); resolved_scroll_source_, orientation, max_offset, max_offset);
if (!resolved_offset) { if (!resolved_offset) {
...@@ -286,12 +282,11 @@ AnimationTimeline::PhaseAndTime ScrollTimeline::CurrentPhaseAndTime() { ...@@ -286,12 +282,11 @@ AnimationTimeline::PhaseAndTime ScrollTimeline::CurrentPhaseAndTime() {
bool ScrollTimeline::ScrollOffsetsEqual( bool ScrollTimeline::ScrollOffsetsEqual(
const HeapVector<Member<ScrollTimelineOffset>>& other) const { const HeapVector<Member<ScrollTimelineOffset>>& other) const {
DCHECK(scroll_offsets_); if (scroll_offsets_.size() != other.size())
if (scroll_offsets_->size() != other.size())
return false; return false;
size_t size = scroll_offsets_->size(); size_t size = scroll_offsets_.size();
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
if (!DataEquivalent(scroll_offsets_->at(i), other.at(i))) if (!DataEquivalent(scroll_offsets_.at(i), other.at(i)))
return false; return false;
} }
return true; return true;
...@@ -477,11 +472,7 @@ void ScrollTimeline::endScrollOffset(ScrollTimelineOffsetValue& out) const { ...@@ -477,11 +472,7 @@ void ScrollTimeline::endScrollOffset(ScrollTimelineOffsetValue& out) const {
const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets() const HeapVector<ScrollTimelineOffsetValue> ScrollTimeline::scrollOffsets()
const { const {
HeapVector<ScrollTimelineOffsetValue> scroll_offsets; HeapVector<ScrollTimelineOffsetValue> scroll_offsets;
for (auto& offset : scroll_offsets_) {
if (!scroll_offsets_)
return scroll_offsets;
for (auto& offset : *scroll_offsets_) {
scroll_offsets.push_back(offset->ToScrollTimelineOffsetValue()); scroll_offsets.push_back(offset->ToScrollTimelineOffsetValue());
// 'auto' can only be the end offset. // 'auto' can only be the end offset.
DCHECK(!offset->IsDefaultValue() || scroll_offsets.size() == 2); DCHECK(!offset->IsDefaultValue() || scroll_offsets.size() == 2);
......
...@@ -44,7 +44,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ...@@ -44,7 +44,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
ScrollTimeline(Document*, ScrollTimeline(Document*,
Element*, Element*,
ScrollDirection, ScrollDirection,
HeapVector<Member<ScrollTimelineOffset>>*, HeapVector<Member<ScrollTimelineOffset>>,
base::Optional<double>); base::Optional<double>);
bool IsScrollTimeline() const override { return true; } bool IsScrollTimeline() const override { return true; }
...@@ -169,7 +169,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline { ...@@ -169,7 +169,7 @@ class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
Member<Element> scroll_source_; Member<Element> scroll_source_;
Member<Node> resolved_scroll_source_; Member<Node> resolved_scroll_source_;
ScrollDirection orientation_; ScrollDirection orientation_;
Member<HeapVector<Member<ScrollTimelineOffset>>> scroll_offsets_; HeapVector<Member<ScrollTimelineOffset>> scroll_offsets_;
base::Optional<double> time_range_; base::Optional<double> time_range_;
......
...@@ -30,7 +30,7 @@ static constexpr double time_error_ms = 0.001 + 1e-13; ...@@ -30,7 +30,7 @@ static constexpr double time_error_ms = 0.001 + 1e-13;
#define EXPECT_TIME_NEAR(expected, value) \ #define EXPECT_TIME_NEAR(expected, value) \
EXPECT_NEAR(expected, value, time_error_ms) EXPECT_NEAR(expected, value, time_error_ms)
HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets( HeapVector<Member<ScrollTimelineOffset>> CreateScrollOffsets(
ScrollTimelineOffset* start_scroll_offset = ScrollTimelineOffset* start_scroll_offset =
MakeGarbageCollected<ScrollTimelineOffset>( MakeGarbageCollected<ScrollTimelineOffset>(
CSSNumericLiteralValue::Create( CSSNumericLiteralValue::Create(
...@@ -41,10 +41,9 @@ HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets( ...@@ -41,10 +41,9 @@ HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets(
CSSNumericLiteralValue::Create( CSSNumericLiteralValue::Create(
90.0, 90.0,
CSSPrimitiveValue::UnitType::kPixels))) { CSSPrimitiveValue::UnitType::kPixels))) {
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets = HeapVector<Member<ScrollTimelineOffset>> scroll_offsets;
MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>(); scroll_offsets.push_back(start_scroll_offset);
scroll_offsets->push_back(start_scroll_offset); scroll_offsets.push_back(end_scroll_offset);
scroll_offsets->push_back(end_scroll_offset);
return scroll_offsets; return scroll_offsets;
} }
...@@ -82,12 +81,12 @@ class TestScrollTimeline : public ScrollTimeline { ...@@ -82,12 +81,12 @@ class TestScrollTimeline : public ScrollTimeline {
public: public:
TestScrollTimeline(Document* document, TestScrollTimeline(Document* document,
Element* scroll_source, Element* scroll_source,
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets = HeapVector<Member<ScrollTimelineOffset>> scroll_offsets =
CreateScrollOffsets()) CreateScrollOffsets())
: ScrollTimeline(document, : ScrollTimeline(document,
scroll_source, scroll_source,
ScrollTimeline::Vertical, ScrollTimeline::Vertical,
scroll_offsets, std::move(scroll_offsets),
100.0), 100.0),
next_service_scheduled_(false) {} next_service_scheduled_(false) {}
......
...@@ -16,13 +16,12 @@ namespace blink { ...@@ -16,13 +16,12 @@ namespace blink {
namespace { namespace {
HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets( HeapVector<Member<ScrollTimelineOffset>> CreateScrollOffsets(
ScrollTimelineOffset* start_scroll_offset, ScrollTimelineOffset* start_scroll_offset,
ScrollTimelineOffset* end_scroll_offset) { ScrollTimelineOffset* end_scroll_offset) {
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets = HeapVector<Member<ScrollTimelineOffset>> scroll_offsets;
MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>(); scroll_offsets.push_back(start_scroll_offset);
scroll_offsets->push_back(start_scroll_offset); scroll_offsets.push_back(end_scroll_offset);
scroll_offsets->push_back(end_scroll_offset);
return scroll_offsets; return scroll_offsets;
} }
......
...@@ -34,7 +34,7 @@ class ScrollableAreaMockChromeClient : public RenderingTestChromeClient { ...@@ -34,7 +34,7 @@ class ScrollableAreaMockChromeClient : public RenderingTestChromeClient {
} }
}; };
HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets( HeapVector<Member<ScrollTimelineOffset>> CreateScrollOffsets(
ScrollTimelineOffset* start_scroll_offset = ScrollTimelineOffset* start_scroll_offset =
MakeGarbageCollected<ScrollTimelineOffset>( MakeGarbageCollected<ScrollTimelineOffset>(
CSSNumericLiteralValue::Create( CSSNumericLiteralValue::Create(
...@@ -45,10 +45,9 @@ HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets( ...@@ -45,10 +45,9 @@ HeapVector<Member<ScrollTimelineOffset>>* CreateScrollOffsets(
CSSNumericLiteralValue::Create( CSSNumericLiteralValue::Create(
90.0, 90.0,
CSSPrimitiveValue::UnitType::kPixels))) { CSSPrimitiveValue::UnitType::kPixels))) {
HeapVector<Member<ScrollTimelineOffset>>* scroll_offsets = HeapVector<Member<ScrollTimelineOffset>> scroll_offsets;
MakeGarbageCollected<HeapVector<Member<ScrollTimelineOffset>>>(); scroll_offsets.push_back(start_scroll_offset);
scroll_offsets->push_back(start_scroll_offset); scroll_offsets.push_back(end_scroll_offset);
scroll_offsets->push_back(end_scroll_offset);
return scroll_offsets; return scroll_offsets;
} }
...@@ -1590,12 +1589,12 @@ class ScrollTimelineForTest : public ScrollTimeline { ...@@ -1590,12 +1589,12 @@ class ScrollTimelineForTest : public ScrollTimeline {
public: public:
ScrollTimelineForTest(Document* document, ScrollTimelineForTest(Document* document,
Element* scroll_source, Element* scroll_source,
HeapVector<Member<ScrollTimelineOffset>>* HeapVector<Member<ScrollTimelineOffset>>
scroll_offsets = CreateScrollOffsets()) scroll_offsets = CreateScrollOffsets())
: ScrollTimeline(document, : ScrollTimeline(document,
scroll_source, scroll_source,
ScrollTimeline::Vertical, ScrollTimeline::Vertical,
scroll_offsets, std::move(scroll_offsets),
100.0), 100.0),
invalidated_(false) {} invalidated_(false) {}
void Invalidate() override { void Invalidate() override {
......
...@@ -517,6 +517,26 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> { ...@@ -517,6 +517,26 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
CheckType(); CheckType();
} }
HeapVector(const HeapVector& other)
: Vector<T, inlineCapacity, HeapAllocator>(other) {
CheckType();
}
HeapVector& operator=(const HeapVector& other) {
Vector<T, inlineCapacity, HeapAllocator>::operator=(other);
return *this;
}
HeapVector(HeapVector&& other)
: Vector<T, inlineCapacity, HeapAllocator>(std::move(other)) {
CheckType();
}
HeapVector& operator=(HeapVector&& other) {
Vector<T, inlineCapacity, HeapAllocator>::operator=(std::move(other));
return *this;
}
HeapVector(std::initializer_list<T> elements) HeapVector(std::initializer_list<T> elements)
: Vector<T, inlineCapacity, HeapAllocator>(elements) { : Vector<T, inlineCapacity, HeapAllocator>(elements) {
CheckType(); CheckType();
......
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