Commit 9801165f authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

HarfBuzz: Identify runs with common font parameters

Optimization part 2.5 of ~3

In ShapeRunsWithFont, identify runs that the same initial CommonParams
and insert them into a RunVector. Change the rest of the shaping
pipeline to operate on these RunVectors, and move most of the
processing of CommonParams to be done once per RunVector instead of
once per run.

This change was intended to be part of the change to allow coalescing
of similar calls into HarfBuzz (which may or may not land), but it was
found to improve the performance in the cache hit case by a factor of
almost 2.

Bug: 862773
Change-Id: I8df02c2a8622eb9be74a65191fad79613ff1da2d
Reviewed-on: https://chromium-review.googlesource.com/1145904
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarLeonard Grey <lgrey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577330}
parent daa348fa
This diff is collapsed.
...@@ -72,21 +72,27 @@ struct GFX_EXPORT TextRunHarfBuzz { ...@@ -72,21 +72,27 @@ struct GFX_EXPORT TextRunHarfBuzz {
// Parameters that may be common to multiple text runs within a text run // Parameters that may be common to multiple text runs within a text run
// list. // list.
struct GFX_EXPORT CommonParams { struct GFX_EXPORT CommonParams {
CommonParams(); // The default constructor for Font is expensive, so always require that a
// Font be provided.
explicit CommonParams(const Font& template_font); explicit CommonParams(const Font& template_font);
~CommonParams(); ~CommonParams();
CommonParams(const CommonParams& other); CommonParams(const CommonParams& other);
CommonParams& operator=(const CommonParams& other); CommonParams& operator=(const CommonParams& other);
bool operator==(const CommonParams& other) const;
// Populate |font_size| and |baseline_offset| based on |primary_font|. Note // Populate |render_params|, |font_size| and |baseline_offset| based on
// that this will not populate |font|. // |font|.
void ComputeFontSizeAndBaselineOffset(const Font& primary_font); void ComputeRenderParamsFontSizeAndBaselineOffset();
// Populate |font|, |skia_face|, and |render_params|. Return false if // Populate |font|, |skia_face|, and |render_params|. Return false if
// |skia_face| is nullptr. // |skia_face| is nullptr.
bool SetFontAndRenderParams(const Font& font, bool SetFontAndRenderParams(const Font& font,
const FontRenderParams& render_params); const FontRenderParams& render_params);
struct Hash {
size_t operator()(const CommonParams& key) const;
};
Font font; Font font;
sk_sp<SkTypeface> skia_face; sk_sp<SkTypeface> skia_face;
FontRenderParams render_params; FontRenderParams render_params;
...@@ -124,6 +130,11 @@ struct GFX_EXPORT TextRunHarfBuzz { ...@@ -124,6 +130,11 @@ struct GFX_EXPORT TextRunHarfBuzz {
size_t missing_glyph_count = std::numeric_limits<size_t>::max(); size_t missing_glyph_count = std::numeric_limits<size_t>::max();
}; };
// If |new_shape.missing_glyph_count| is less than that of |shape|, set
// |common| and |shape| to the specified values.
void UpdateCommonParamsAndShape(const CommonParams& new_common_params,
const ShapeOutput& new_shape);
Range range; Range range;
CommonParams common; CommonParams common;
ShapeOutput shape; ShapeOutput shape;
...@@ -242,31 +253,42 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText { ...@@ -242,31 +253,42 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
SelectionModel LastSelectionModelInsideRun( SelectionModel LastSelectionModelInsideRun(
const internal::TextRunHarfBuzz* run); const internal::TextRunHarfBuzz* run);
// Break the text into logical runs and populate the visual <-> logical maps using CommonizedRunsMap =
// into |run_list_out|. std::unordered_map<internal::TextRunHarfBuzz::CommonParams,
std::vector<internal::TextRunHarfBuzz*>,
internal::TextRunHarfBuzz::CommonParams::Hash>;
// Break the text into logical runs in |out_run_list|. Populate
// |out_commonized_run_map| such that each run is present in the vector
// corresponding to its CommonParams.
void ItemizeTextToRuns(const base::string16& string, void ItemizeTextToRuns(const base::string16& string,
internal::TextRunList* run_list_out); internal::TextRunList* out_run_list,
CommonizedRunsMap* out_commonized_run_map);
// Shape the glyphs of all runs in |run_list| using |text|.
void ShapeRunList(const base::string16& text, // Shape the glyphs needed for each run in |runs| within |text|. This method
internal::TextRunList* run_list); // will apply a number of fonts to |base_common_params| and assign to each
// run's CommonParams and ShapeOutput the parameters and resulting shape that
// Shape the glyphs needed for the |run| within the |text|. This method will // had the smallest number of missing glyphs.
// apply a number of fonts to |common_params| and assign to |run->common| and void ShapeRuns(
// |run->shape| the common font parameters and resulting shape output with the
// smallest number of missing glyphs.
void ShapeRun(const base::string16& text,
const internal::TextRunHarfBuzz::CommonParams& common_params,
internal::TextRunHarfBuzz* run);
// Shape the glyphs for |run| within |text| using the font specified by
// |common_params|. If the resulting shaping has fewer missing glyphs than
// |run->shape.missing_glyph_count|, then write |common_params| to
// |run->common| and write the shaping output to |run->shape|.
void ShapeRunWithFont(
const base::string16& text, const base::string16& text,
const internal::TextRunHarfBuzz::CommonParams& common_params, const internal::TextRunHarfBuzz::CommonParams& base_common_params,
internal::TextRunHarfBuzz* run); std::vector<internal::TextRunHarfBuzz*> runs);
// Shape the glyphs for |in_out_runs| within |text| using the parameters
// specified by |common_params|. If, for any run in |*in_out_runs|, the
// resulting shaping has fewer missing glyphs than the existing shape, then
// write |common_params| and the resulting ShapeOutput to that run. Remove all
// runs with no missing glyphs from |in_out_runs| (the caller, ShapeRuns, will
// terminate when no runs with missing glyphs remain).
void ShapeRunsWithFont(
const base::string16& text,
const internal::TextRunHarfBuzz::CommonParams& base_common_params,
std::vector<internal::TextRunHarfBuzz*>* in_out_runs);
// Itemize |text| into runs in |out_run_list|, shape the runs, and populate
// |out_run_list|'s visual <-> logical maps.
void ItemizeAndShapeText(const base::string16& text,
internal::TextRunList* out_run_list);
// Makes sure that text runs for layout text are shaped. // Makes sure that text runs for layout text are shaped.
void EnsureLayoutRunList(); void EnsureLayoutRunList();
......
...@@ -553,14 +553,13 @@ class RenderTextHarfBuzzTest : public RenderTextTest { ...@@ -553,14 +553,13 @@ class RenderTextHarfBuzzTest : public RenderTextTest {
const Font& font, const Font& font,
const FontRenderParams& render_params, const FontRenderParams& render_params,
internal::TextRunHarfBuzz* run) { internal::TextRunHarfBuzz* run) {
const Font& primary_font = internal::TextRunHarfBuzz::CommonParams common_params = run->common;
GetRenderTextHarfBuzz()->font_list().GetPrimaryFont(); common_params.ComputeRenderParamsFontSizeAndBaselineOffset();
run->common.ComputeFontSizeAndBaselineOffset(primary_font); common_params.SetFontAndRenderParams(font, render_params);
if (!run->common.SetFontAndRenderParams(font, render_params))
return false;
run->shape.missing_glyph_count = static_cast<size_t>(-1); run->shape.missing_glyph_count = static_cast<size_t>(-1);
GetRenderTextHarfBuzz()->ShapeRunWithFont(text, run->common, run); std::vector<internal::TextRunHarfBuzz*> runs = {run};
return true; GetRenderTextHarfBuzz()->ShapeRunsWithFont(text, common_params, &runs);
return runs.empty();
} }
int GetCursorYForTesting(int line_num = 0) { int GetCursorYForTesting(int line_num = 0) {
......
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