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)
: width_(other.width_),
glyph_bounding_box_(other.glyph_bounding_box_),
primary_font_(other.primary_font_),
start_index_(other.start_index_),
num_characters_(other.num_characters_),
num_glyphs_(other.num_glyphs_),
direction_(other.direction_),
......@@ -408,26 +409,6 @@ CharacterRange ShapeResult::GetCharacterRange(const StringView& text,
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 {
if (HasOneRef())
return const_cast<ShapeResult*>(this);
......@@ -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 (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
......@@ -1082,6 +1067,7 @@ void ShapeResult::InsertRunForIndex(unsigned start_character_index) {
primary_font_.get(), !Rtl() ? HB_DIRECTION_LTR : HB_DIRECTION_RTL,
CanvasRotationInVertical::kRegular, HB_SCRIPT_UNKNOWN,
start_character_index, 0, num_characters_));
UpdateStartIndex();
}
ShapeResult::RunInfo* ShapeResult::InsertRunForTesting(
......@@ -1136,6 +1122,21 @@ void ShapeResult::ReorderRtlRuns(unsigned run_size_before) {
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.
float ShapeResult::LineLeftBounds() const {
DCHECK(!runs_.IsEmpty());
......@@ -1218,8 +1219,10 @@ void ShapeResult::CopyRange(unsigned start_offset,
}
}
if (!target->num_glyphs_)
if (!target->num_glyphs_) {
target->UpdateStartIndex();
return;
}
// Runs in RTL result are in visual order, and that new runs should be
// prepended. Reorder appended runs.
......@@ -1249,6 +1252,7 @@ void ShapeResult::CopyRange(unsigned start_offset,
target->glyph_bounding_box_.UniteIfNonZero(adjusted_box);
target->has_vertical_offsets_ |= has_vertical_offsets_;
target->UpdateStartIndex();
#if DCHECK_IS_ON()
DCHECK_EQ(target->num_characters_ - target_num_characters_before,
......@@ -1283,6 +1287,7 @@ scoped_refptr<ShapeResult> ShapeResult::CopyAdjustedOffset(
}
}
result->UpdateStartIndex();
return result;
}
......@@ -1294,6 +1299,7 @@ void ShapeResult::CheckConsistency() const {
return;
}
DCHECK_EQ(start_index_, ComputeStartIndex());
const unsigned start_index = StartIndexForResult();
unsigned index = start_index;
unsigned num_glyphs = 0;
......@@ -1351,6 +1357,7 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters(
result->has_vertical_offsets_ =
font_data->PlatformData().IsVerticalAnyUpright();
result->runs_.push_back(std::move(run));
result->UpdateStartIndex();
return result;
}
......
......@@ -118,8 +118,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned from,
unsigned to) const;
// The character start/end index of a range shape result.
unsigned StartIndexForResult() const;
unsigned EndIndexForResult() const;
unsigned StartIndexForResult() const { return start_index_; }
unsigned EndIndexForResult() const { return start_index_ + num_characters_; }
void FallbackFonts(HashSet<const SimpleFontData*>*) const;
TextDirection Direction() const {
return static_cast<TextDirection>(direction_);
......@@ -332,6 +332,8 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
void InsertRun(std::unique_ptr<ShapeResult::RunInfo>);
void InsertRunForIndex(unsigned start_character_index);
void ReorderRtlRuns(unsigned run_size_before);
unsigned ComputeStartIndex() const;
void UpdateStartIndex();
float LineLeftBounds() const;
float LineRightBounds() const;
......@@ -342,6 +344,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
scoped_refptr<const SimpleFontData> primary_font_;
mutable std::unique_ptr<CharacterPositionData> character_position_;
unsigned start_index_;
unsigned num_characters_;
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