Commit f1c58810 authored by Emil A Eklund's avatar Emil A Eklund Committed by Commit Bot

Pre-compute start/end index for ShapeResult

The methods for computing start and end index for a shape result compute
the values on demand, while not too expensive these methods are called a
lot during both layout and paint. By pre-computing the values text paint
performance is improved by about 10% for LayoutNG & about 2% for legacy.

Bug: 714962
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng
Change-Id: Ib652b947d6cc670e657d72d753e96ecb4e2aa85d
Reviewed-on: https://chromium-review.googlesource.com/1176202
Commit-Queue: Emil A Eklund <eae@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584335}
parent 2ced14c3
...@@ -381,6 +381,7 @@ ShapeResult::ShapeResult(const ShapeResult& other) ...@@ -381,6 +381,7 @@ ShapeResult::ShapeResult(const ShapeResult& other)
: width_(other.width_), : width_(other.width_),
glyph_bounding_box_(other.glyph_bounding_box_), glyph_bounding_box_(other.glyph_bounding_box_),
primary_font_(other.primary_font_), primary_font_(other.primary_font_),
start_index_(other.start_index_),
num_characters_(other.num_characters_), num_characters_(other.num_characters_),
num_glyphs_(other.num_glyphs_), num_glyphs_(other.num_glyphs_),
direction_(other.direction_), direction_(other.direction_),
...@@ -408,26 +409,6 @@ CharacterRange ShapeResult::GetCharacterRange(const StringView& text, ...@@ -408,26 +409,6 @@ CharacterRange ShapeResult::GetCharacterRange(const StringView& text,
from, to); from, to);
} }
unsigned ShapeResult::StartIndexForResult() const {
if (UNLIKELY(runs_.IsEmpty()))
return 0;
const RunInfo& first_run = *runs_.front();
if (!Rtl())
return first_run.start_index_;
unsigned end = first_run.start_index_ + first_run.num_characters_;
DCHECK_GE(end, NumCharacters());
return end - NumCharacters();
}
unsigned ShapeResult::EndIndexForResult() const {
if (UNLIKELY(runs_.IsEmpty()))
return NumCharacters();
const RunInfo& first_run = *runs_.front();
if (!Rtl())
return first_run.start_index_ + NumCharacters();
return first_run.start_index_ + first_run.num_characters_;
}
scoped_refptr<ShapeResult> ShapeResult::MutableUnique() const { scoped_refptr<ShapeResult> ShapeResult::MutableUnique() const {
if (HasOneRef()) if (HasOneRef())
return const_cast<ShapeResult*>(this); return const_cast<ShapeResult*>(this);
...@@ -1071,6 +1052,10 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) { ...@@ -1071,6 +1052,10 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run) {
// If we didn't find an existing slot to place it, append. // If we didn't find an existing slot to place it, append.
if (run) if (run)
runs_.push_back(std::move(run)); runs_.push_back(std::move(run));
// TODO(layout-dev): We could skip this unless the inserted run is the first
// one but determiening that is likely as expensive as the computation.
UpdateStartIndex();
} }
// Insert a |RunInfo| without glyphs. |StartIndexForResult()| needs a run to // Insert a |RunInfo| without glyphs. |StartIndexForResult()| needs a run to
...@@ -1082,6 +1067,7 @@ void ShapeResult::InsertRunForIndex(unsigned start_character_index) { ...@@ -1082,6 +1067,7 @@ void ShapeResult::InsertRunForIndex(unsigned start_character_index) {
primary_font_.get(), !Rtl() ? HB_DIRECTION_LTR : HB_DIRECTION_RTL, primary_font_.get(), !Rtl() ? HB_DIRECTION_LTR : HB_DIRECTION_RTL,
CanvasRotationInVertical::kRegular, HB_SCRIPT_UNKNOWN, CanvasRotationInVertical::kRegular, HB_SCRIPT_UNKNOWN,
start_character_index, 0, num_characters_)); start_character_index, 0, num_characters_));
UpdateStartIndex();
} }
ShapeResult::RunInfo* ShapeResult::InsertRunForTesting( ShapeResult::RunInfo* ShapeResult::InsertRunForTesting(
...@@ -1136,6 +1122,21 @@ void ShapeResult::ReorderRtlRuns(unsigned run_size_before) { ...@@ -1136,6 +1122,21 @@ void ShapeResult::ReorderRtlRuns(unsigned run_size_before) {
runs_.swap(new_runs); runs_.swap(new_runs);
} }
unsigned ShapeResult::ComputeStartIndex() const {
if (UNLIKELY(runs_.IsEmpty()))
return 0;
const RunInfo& first_run = *runs_.front();
if (!Rtl()) // Left-to-right.
return first_run.start_index_;
// Right-to-left.
unsigned end_index = first_run.start_index_ + first_run.num_characters_;
return end_index - num_characters_;
}
void ShapeResult::UpdateStartIndex() {
start_index_ = ComputeStartIndex();
}
// Returns the left of the glyph bounding box of the left most character. // Returns the left of the glyph bounding box of the left most character.
float ShapeResult::LineLeftBounds() const { float ShapeResult::LineLeftBounds() const {
DCHECK(!runs_.IsEmpty()); DCHECK(!runs_.IsEmpty());
...@@ -1218,8 +1219,10 @@ void ShapeResult::CopyRange(unsigned start_offset, ...@@ -1218,8 +1219,10 @@ void ShapeResult::CopyRange(unsigned start_offset,
} }
} }
if (!target->num_glyphs_) if (!target->num_glyphs_) {
target->UpdateStartIndex();
return; return;
}
// Runs in RTL result are in visual order, and that new runs should be // Runs in RTL result are in visual order, and that new runs should be
// prepended. Reorder appended runs. // prepended. Reorder appended runs.
...@@ -1249,6 +1252,7 @@ void ShapeResult::CopyRange(unsigned start_offset, ...@@ -1249,6 +1252,7 @@ void ShapeResult::CopyRange(unsigned start_offset,
target->glyph_bounding_box_.UniteIfNonZero(adjusted_box); target->glyph_bounding_box_.UniteIfNonZero(adjusted_box);
target->has_vertical_offsets_ |= has_vertical_offsets_; target->has_vertical_offsets_ |= has_vertical_offsets_;
target->UpdateStartIndex();
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
DCHECK_EQ(target->num_characters_ - target_num_characters_before, DCHECK_EQ(target->num_characters_ - target_num_characters_before,
...@@ -1283,6 +1287,7 @@ scoped_refptr<ShapeResult> ShapeResult::CopyAdjustedOffset( ...@@ -1283,6 +1287,7 @@ scoped_refptr<ShapeResult> ShapeResult::CopyAdjustedOffset(
} }
} }
result->UpdateStartIndex();
return result; return result;
} }
...@@ -1294,6 +1299,7 @@ void ShapeResult::CheckConsistency() const { ...@@ -1294,6 +1299,7 @@ void ShapeResult::CheckConsistency() const {
return; return;
} }
DCHECK_EQ(start_index_, ComputeStartIndex());
const unsigned start_index = StartIndexForResult(); const unsigned start_index = StartIndexForResult();
unsigned index = start_index; unsigned index = start_index;
unsigned num_glyphs = 0; unsigned num_glyphs = 0;
...@@ -1351,6 +1357,7 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters( ...@@ -1351,6 +1357,7 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters(
result->has_vertical_offsets_ = result->has_vertical_offsets_ =
font_data->PlatformData().IsVerticalAnyUpright(); font_data->PlatformData().IsVerticalAnyUpright();
result->runs_.push_back(std::move(run)); result->runs_.push_back(std::move(run));
result->UpdateStartIndex();
return result; return result;
} }
......
...@@ -118,8 +118,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { ...@@ -118,8 +118,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned from, unsigned from,
unsigned to) const; unsigned to) const;
// The character start/end index of a range shape result. // The character start/end index of a range shape result.
unsigned StartIndexForResult() const; unsigned StartIndexForResult() const { return start_index_; }
unsigned EndIndexForResult() const; unsigned EndIndexForResult() const { return start_index_ + num_characters_; }
void FallbackFonts(HashSet<const SimpleFontData*>*) const; void FallbackFonts(HashSet<const SimpleFontData*>*) const;
TextDirection Direction() const { TextDirection Direction() const {
return static_cast<TextDirection>(direction_); return static_cast<TextDirection>(direction_);
...@@ -332,6 +332,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { ...@@ -332,6 +332,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
void InsertRun(std::unique_ptr<ShapeResult::RunInfo>); void InsertRun(std::unique_ptr<ShapeResult::RunInfo>);
void InsertRunForIndex(unsigned start_character_index); void InsertRunForIndex(unsigned start_character_index);
void ReorderRtlRuns(unsigned run_size_before); void ReorderRtlRuns(unsigned run_size_before);
unsigned ComputeStartIndex() const;
void UpdateStartIndex();
float LineLeftBounds() const; float LineLeftBounds() const;
float LineRightBounds() const; float LineRightBounds() const;
...@@ -342,6 +344,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { ...@@ -342,6 +344,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
scoped_refptr<const SimpleFontData> primary_font_; scoped_refptr<const SimpleFontData> primary_font_;
mutable std::unique_ptr<CharacterPositionData> character_position_; mutable std::unique_ptr<CharacterPositionData> character_position_;
unsigned start_index_;
unsigned num_characters_; unsigned num_characters_;
unsigned num_glyphs_ : 30; unsigned num_glyphs_ : 30;
......
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