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