Commit 58605429 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Reduces the size of NGPhysical{Box|Text}Fragment

This patch reduces the size of:
* NGPhysicalBoxFragment by a pointer, by removing |style_|
  from NGPhysicalFragment. This field is used only for line
  box and for ellipsis, and thus it is moved to each
  subclasses.
* NGPhysicalTextFragment by 16 bytes, by moving
  |self_ink_overflow_| and |style_| to RareData. Quick
  investigation shows that |self_ink_overflow_| is different
  from |LocalRect()| in 10-20% of the time (on Linux,
  google.com and a few other sites.)

Change-Id: I225edd42d6d9488611ffe2fa7ef9b11b7e9da4a1
Bug: 635619, 636993
Reviewed-on: https://chromium-review.googlesource.com/c/1331102Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607444}
parent 0197d393
...@@ -15,6 +15,11 @@ bool NGPhysicalOffsetRect::operator==(const NGPhysicalOffsetRect& other) const { ...@@ -15,6 +15,11 @@ bool NGPhysicalOffsetRect::operator==(const NGPhysicalOffsetRect& other) const {
return other.offset == offset && other.size == size; return other.offset == offset && other.size == size;
} }
bool NGPhysicalOffsetRect::Contains(const NGPhysicalOffsetRect& other) const {
return offset.left <= other.offset.left && offset.top <= other.offset.top &&
Right() >= other.Right() && Bottom() >= other.Bottom();
}
NGPhysicalOffsetRect NGPhysicalOffsetRect::operator+( NGPhysicalOffsetRect NGPhysicalOffsetRect::operator+(
const NGPhysicalOffset& offset) const { const NGPhysicalOffset& offset) const {
return {this->offset + offset, size}; return {this->offset + offset, size};
......
...@@ -34,6 +34,8 @@ struct CORE_EXPORT NGPhysicalOffsetRect { ...@@ -34,6 +34,8 @@ struct CORE_EXPORT NGPhysicalOffsetRect {
bool operator==(const NGPhysicalOffsetRect& other) const; bool operator==(const NGPhysicalOffsetRect& other) const;
bool Contains(const NGPhysicalOffsetRect& other) const;
NGPhysicalOffsetRect operator+(const NGPhysicalOffset&) const; NGPhysicalOffsetRect operator+(const NGPhysicalOffset&) const;
void Unite(const NGPhysicalOffsetRect&); void Unite(const NGPhysicalOffsetRect&);
......
...@@ -14,6 +14,7 @@ namespace blink { ...@@ -14,6 +14,7 @@ namespace blink {
namespace { namespace {
struct SameSizeAsNGPhysicalLineBoxFragment : NGPhysicalContainerFragment { struct SameSizeAsNGPhysicalLineBoxFragment : NGPhysicalContainerFragment {
void* pointer;
NGLineHeightMetrics metrics; NGLineHeightMetrics metrics;
}; };
...@@ -46,6 +47,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment( ...@@ -46,6 +47,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
kFragmentLineBox, kFragmentLineBox,
0), 0),
metrics_(builder->metrics_) { metrics_(builder->metrics_) {
style_ = std::move(builder->style_);
base_direction_ = static_cast<unsigned>(builder->base_direction_); base_direction_ = static_cast<unsigned>(builder->base_direction_);
} }
......
...@@ -29,6 +29,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final ...@@ -29,6 +29,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
return ChildLinkList(num_children_, &children_[0]); return ChildLinkList(num_children_, &children_[0]);
} }
const ComputedStyle& Style() const { return *style_; }
const NGLineHeightMetrics& Metrics() const { return metrics_; } const NGLineHeightMetrics& Metrics() const { return metrics_; }
// The base direction of this line. Also known as the paragraph direction. // The base direction of this line. Also known as the paragraph direction.
...@@ -66,6 +67,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final ...@@ -66,6 +67,7 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
private: private:
NGPhysicalLineBoxFragment(NGLineBoxFragmentBuilder* builder); NGPhysicalLineBoxFragment(NGLineBoxFragmentBuilder* builder);
scoped_refptr<const ComputedStyle> style_;
NGLineHeightMetrics metrics_; NGLineHeightMetrics metrics_;
NGLinkStorage children_[]; NGLinkStorage children_[];
}; };
......
...@@ -19,8 +19,7 @@ namespace blink { ...@@ -19,8 +19,7 @@ namespace blink {
namespace { namespace {
struct SameSizeAsNGPhysicalTextFragment : NGPhysicalFragment { struct SameSizeAsNGPhysicalTextFragment : NGPhysicalFragment {
void* pointers[2]; void* pointers[3];
NGPhysicalOffsetRect rect;
unsigned offsets[2]; unsigned offsets[2];
}; };
...@@ -56,31 +55,31 @@ NGLineOrientation ToLineOrientation(WritingMode writing_mode) { ...@@ -56,31 +55,31 @@ NGLineOrientation ToLineOrientation(WritingMode writing_mode) {
} // anonymous namespace } // anonymous namespace
NGPhysicalTextFragment::NGPhysicalTextFragment( NGPhysicalTextFragment::NGPhysicalTextFragment(
LayoutObject* layout_object, const NGPhysicalTextFragment& source,
const ComputedStyle& style,
NGStyleVariant style_variant,
NGTextType text_type,
const String& text,
unsigned start_offset, unsigned start_offset,
unsigned end_offset, unsigned end_offset,
NGPhysicalSize size,
NGLineOrientation line_orientation,
scoped_refptr<const ShapeResultView> shape_result) scoped_refptr<const ShapeResultView> shape_result)
: NGPhysicalFragment(layout_object, : NGPhysicalFragment(source.GetLayoutObject(),
style, source.StyleVariant(),
style_variant, source.IsHorizontal()
size, ? NGPhysicalSize{shape_result->SnappedWidth(),
source.Size().height}
: NGPhysicalSize{source.Size().width,
shape_result->SnappedWidth()},
kFragmentText, kFragmentText,
text_type), source.TextType()),
text_(text), text_(source.text_),
start_offset_(start_offset), start_offset_(start_offset),
end_offset_(end_offset), end_offset_(end_offset),
shape_result_(shape_result) { shape_result_(shape_result) {
DCHECK_GE(start_offset_, source.StartOffset());
DCHECK_LE(end_offset_, source.EndOffset());
DCHECK(shape_result_ || IsFlowControl()) << ToString(); DCHECK(shape_result_ || IsFlowControl()) << ToString();
line_orientation_ = static_cast<unsigned>(line_orientation); DCHECK(!source.rare_data_ || !source.rare_data_->style_);
is_anonymous_text_ = IsPhysicalTextFragmentAnonymousText(layout_object); line_orientation_ = source.line_orientation_;
is_anonymous_text_ = source.is_anonymous_text_;
self_ink_overflow_ = ComputeSelfInkOverflow(); UpdateSelfInkOverflow();
} }
NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder) NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
...@@ -95,7 +94,29 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder) ...@@ -95,7 +94,29 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
is_anonymous_text_ = is_anonymous_text_ =
IsPhysicalTextFragmentAnonymousText(builder->layout_object_); IsPhysicalTextFragmentAnonymousText(builder->layout_object_);
self_ink_overflow_ = ComputeSelfInkOverflow(); if (UNLIKELY(StyleVariant() == NGStyleVariant::kEllipsis))
EnsureRareData()->style_ = std::move(builder->style_);
UpdateSelfInkOverflow();
}
NGPhysicalTextFragment::RareData* NGPhysicalTextFragment::EnsureRareData() {
if (!rare_data_)
rare_data_ = std::make_unique<RareData>();
return rare_data_.get();
}
const ComputedStyle& NGPhysicalTextFragment::Style() const {
switch (StyleVariant()) {
case NGStyleVariant::kStandard:
case NGStyleVariant::kFirstLine:
return NGPhysicalFragment::Style();
case NGStyleVariant::kEllipsis:
DCHECK(rare_data_ && rare_data_->style_);
return *rare_data_->style_;
}
NOTREACHED();
return NGPhysicalFragment::Style();
} }
// Convert logical cooridnate to local physical coordinate. // Convert logical cooridnate to local physical coordinate.
...@@ -185,9 +206,20 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::LocalRect( ...@@ -185,9 +206,20 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::LocalRect(
return {}; return {};
} }
NGPhysicalOffsetRect NGPhysicalTextFragment::ComputeSelfInkOverflow() const { NGPhysicalOffsetRect NGPhysicalTextFragment::SelfInkOverflow() const {
if (UNLIKELY(!shape_result_)) return UNLIKELY(rare_data_) ? rare_data_->self_ink_overflow_ : LocalRect();
return LocalRect(); }
void NGPhysicalTextFragment::ClearSelfInkOverflow() {
if (UNLIKELY(rare_data_))
rare_data_->self_ink_overflow_ = LocalRect();
}
void NGPhysicalTextFragment::UpdateSelfInkOverflow() {
if (UNLIKELY(!shape_result_)) {
ClearSelfInkOverflow();
return;
}
// Glyph bounds is in logical coordinate, origin at the alphabetic baseline. // Glyph bounds is in logical coordinate, origin at the alphabetic baseline.
LayoutRect ink_overflow = EnclosingLayoutRect(shape_result_->Bounds()); LayoutRect ink_overflow = EnclosingLayoutRect(shape_result_->Bounds());
...@@ -234,8 +266,13 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::ComputeSelfInkOverflow() const { ...@@ -234,8 +266,13 @@ NGPhysicalOffsetRect NGPhysicalTextFragment::ComputeSelfInkOverflow() const {
// Uniting the frame rect ensures that non-ink spaces such side bearings, or // Uniting the frame rect ensures that non-ink spaces such side bearings, or
// even space characters, are included in the visual rect for decorations. // even space characters, are included in the visual rect for decorations.
NGPhysicalOffsetRect local_ink_overflow = ConvertToLocal(ink_overflow); NGPhysicalOffsetRect local_ink_overflow = ConvertToLocal(ink_overflow);
local_ink_overflow.Unite(LocalRect()); NGPhysicalOffsetRect local_rect = LocalRect();
return local_ink_overflow; if (local_rect.Contains(local_ink_overflow)) {
ClearSelfInkOverflow();
return;
}
local_ink_overflow.Unite(local_rect);
EnsureRareData()->self_ink_overflow_ = local_ink_overflow;
} }
scoped_refptr<const NGPhysicalFragment> NGPhysicalTextFragment::TrimText( scoped_refptr<const NGPhysicalFragment> NGPhysicalTextFragment::TrimText(
...@@ -250,13 +287,9 @@ scoped_refptr<const NGPhysicalFragment> NGPhysicalTextFragment::TrimText( ...@@ -250,13 +287,9 @@ scoped_refptr<const NGPhysicalFragment> NGPhysicalTextFragment::TrimText(
scoped_refptr<ShapeResult> new_shape_result = scoped_refptr<ShapeResult> new_shape_result =
shape_result_->CreateShapeResult()->SubRange(new_start_offset, shape_result_->CreateShapeResult()->SubRange(new_start_offset,
new_end_offset); new_end_offset);
LayoutUnit new_inline_size = new_shape_result->SnappedWidth();
return base::AdoptRef(new NGPhysicalTextFragment( return base::AdoptRef(new NGPhysicalTextFragment(
layout_object_, Style(), static_cast<NGStyleVariant>(style_variant_), *this, new_start_offset, new_end_offset,
TextType(), text_, new_start_offset, new_end_offset, ShapeResultView::Create(new_shape_result.get())));
IsHorizontal() ? NGPhysicalSize{new_inline_size, size_.height}
: NGPhysicalSize{size_.width, new_inline_size},
LineOrientation(), ShapeResultView::Create(new_shape_result.get())));
} }
unsigned NGPhysicalTextFragment::TextOffsetForPoint( unsigned NGPhysicalTextFragment::TextOffsetForPoint(
......
...@@ -72,6 +72,8 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { ...@@ -72,6 +72,8 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
return IsLineBreak() || TextType() == kFlowControl; return IsLineBreak() || TextType() == kFlowControl;
} }
const ComputedStyle& Style() const;
unsigned Length() const { return end_offset_ - start_offset_; } unsigned Length() const { return end_offset_ - start_offset_; }
StringView Text() const { return StringView(text_, start_offset_, Length()); } StringView Text() const { return StringView(text_, start_offset_, Length()); }
const String& TextContent() const { return text_; } const String& TextContent() const { return text_; }
...@@ -102,7 +104,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { ...@@ -102,7 +104,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
// The visual bounding box that includes glpyh bounding box and CSS // The visual bounding box that includes glpyh bounding box and CSS
// properties, in local coordinates. // properties, in local coordinates.
NGPhysicalOffsetRect SelfInkOverflow() const { return self_ink_overflow_; } NGPhysicalOffsetRect SelfInkOverflow() const;
// Create a new fragment that has part of the text of this fragment. // Create a new fragment that has part of the text of this fragment.
// All other properties are the same as this fragment. // All other properties are the same as this fragment.
...@@ -135,24 +137,25 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { ...@@ -135,24 +137,25 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
private: private:
// For use by TrimText only // For use by TrimText only
NGPhysicalTextFragment(LayoutObject* layout_object, NGPhysicalTextFragment(const NGPhysicalTextFragment& source,
const ComputedStyle& style,
NGStyleVariant style_variant,
NGTextType text_type,
const String& text,
unsigned start_offset, unsigned start_offset,
unsigned end_offset, unsigned end_offset,
NGPhysicalSize size,
NGLineOrientation line_orientation,
scoped_refptr<const ShapeResultView> shape_result); scoped_refptr<const ShapeResultView> shape_result);
struct RareData {
NGPhysicalOffsetRect self_ink_overflow_;
scoped_refptr<const ComputedStyle> style_; // Used only for ellipsis.
};
RareData* EnsureRareData();
LayoutUnit InlinePositionForOffset(unsigned offset, LayoutUnit InlinePositionForOffset(unsigned offset,
LayoutUnit (*round)(float), LayoutUnit (*round)(float),
AdjustMidCluster) const; AdjustMidCluster) const;
NGPhysicalOffsetRect ConvertToLocal(const LayoutRect&) const; NGPhysicalOffsetRect ConvertToLocal(const LayoutRect&) const;
NGPhysicalOffsetRect ComputeSelfInkOverflow() const; void UpdateSelfInkOverflow();
void ClearSelfInkOverflow();
// The text of NGInlineNode; i.e., of a parent block. The text for this // The text of NGInlineNode; i.e., of a parent block. The text for this
// fragment is a substring(start_offset_, end_offset_) of this string. // fragment is a substring(start_offset_, end_offset_) of this string.
...@@ -161,8 +164,9 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { ...@@ -161,8 +164,9 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
// Start and end offset of the parent block text. // Start and end offset of the parent block text.
const unsigned start_offset_; const unsigned start_offset_;
const unsigned end_offset_; const unsigned end_offset_;
NGPhysicalOffsetRect self_ink_overflow_;
const scoped_refptr<const ShapeResultView> shape_result_; const scoped_refptr<const ShapeResultView> shape_result_;
std::unique_ptr<RareData> rare_data_;
}; };
DEFINE_TYPE_CASTS(NGPhysicalTextFragment, DEFINE_TYPE_CASTS(NGPhysicalTextFragment,
......
...@@ -23,7 +23,7 @@ namespace { ...@@ -23,7 +23,7 @@ namespace {
struct SameSizeAsNGPhysicalFragment struct SameSizeAsNGPhysicalFragment
: RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> { : RefCounted<const NGPhysicalFragment, NGPhysicalFragmentTraits> {
void* pointers[3]; void* pointers[2];
NGPhysicalSize size; NGPhysicalSize size;
unsigned flags; unsigned flags;
}; };
...@@ -249,7 +249,6 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder, ...@@ -249,7 +249,6 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
NGFragmentType type, NGFragmentType type,
unsigned sub_type) unsigned sub_type)
: layout_object_(builder->layout_object_), : layout_object_(builder->layout_object_),
style_(std::move(builder->style_)),
size_(ToNGPhysicalSize(builder->size_, builder->GetWritingMode())), size_(ToNGPhysicalSize(builder->size_, builder->GetWritingMode())),
break_token_(std::move(builder->break_token_)), break_token_(std::move(builder->break_token_)),
type_(type), type_(type),
...@@ -259,14 +258,12 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder, ...@@ -259,14 +258,12 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
style_variant_((unsigned)builder->style_variant_) {} style_variant_((unsigned)builder->style_variant_) {}
NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
const ComputedStyle& style,
NGStyleVariant style_variant, NGStyleVariant style_variant,
NGPhysicalSize size, NGPhysicalSize size,
NGFragmentType type, NGFragmentType type,
unsigned sub_type, unsigned sub_type,
scoped_refptr<NGBreakToken> break_token) scoped_refptr<NGBreakToken> break_token)
: layout_object_(layout_object), : layout_object_(layout_object),
style_(&style),
size_(size), size_(size),
break_token_(std::move(break_token)), break_token_(std::move(break_token)),
type_(type), type_(type),
...@@ -298,21 +295,20 @@ void NGPhysicalFragment::Destroy() const { ...@@ -298,21 +295,20 @@ void NGPhysicalFragment::Destroy() const {
} }
const ComputedStyle& NGPhysicalFragment::Style() const { const ComputedStyle& NGPhysicalFragment::Style() const {
DCHECK(style_); if (Type() == kFragmentLineBox)
// TODO(kojii): Returning |style_| locks the style at the layout time, and return ToNGPhysicalLineBoxFragment(this)->Style();
// will not be updated when its base style is updated later. Line styles and
// ellipsis styles have this problem.
if (!GetLayoutObject())
return *style_;
switch (StyleVariant()) { switch (StyleVariant()) {
case NGStyleVariant::kStandard: case NGStyleVariant::kStandard:
DCHECK(GetLayoutObject());
return *GetLayoutObject()->Style(); return *GetLayoutObject()->Style();
case NGStyleVariant::kFirstLine: case NGStyleVariant::kFirstLine:
DCHECK(GetLayoutObject());
return *GetLayoutObject()->FirstLineStyle(); return *GetLayoutObject()->FirstLineStyle();
case NGStyleVariant::kEllipsis: case NGStyleVariant::kEllipsis:
return *style_; return ToNGPhysicalTextFragment(this)->Style();
} }
return *style_; NOTREACHED();
return *GetLayoutObject()->Style();
} }
Node* NGPhysicalFragment::GetNode() const { Node* NGPhysicalFragment::GetNode() const {
......
...@@ -236,7 +236,6 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -236,7 +236,6 @@ class CORE_EXPORT NGPhysicalFragment
unsigned sub_type); unsigned sub_type);
NGPhysicalFragment(LayoutObject* layout_object, NGPhysicalFragment(LayoutObject* layout_object,
const ComputedStyle& style,
NGStyleVariant, NGStyleVariant,
NGPhysicalSize size, NGPhysicalSize size,
NGFragmentType type, NGFragmentType type,
...@@ -246,7 +245,6 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -246,7 +245,6 @@ class CORE_EXPORT NGPhysicalFragment
const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const; const Vector<NGInlineItem>& InlineItemsOfContainingBlock() const;
LayoutObject* const layout_object_; LayoutObject* const layout_object_;
scoped_refptr<const ComputedStyle> style_;
const NGPhysicalSize size_; const NGPhysicalSize size_;
scoped_refptr<NGBreakToken> break_token_; scoped_refptr<NGBreakToken> break_token_;
......
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