Commit db757646 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

Mac RenderTextHarfBuzz: Use hb_coretext_font_create().

The HarfBuzz roll in r513541 improved Mac UI font support in the
renderer by detecting UI fonts and invoking CTFontCreateUIFontForLanguage().

However, in chrome UI, there is already a CTFont wrapped in a gfx::
PlatformFont for UI fonts. So creating a new CTFont for every hb_shape
call becomes unnecessary and expensive.

hb_coretext_font_create() (after a hb_coretext_face_create()) allows
the steps requiring the call to CTFontCreateUIFontForLanguage() to
be skipped by associating the CTFont with the hb_font_t directly.

Adds a new views_perftest target and LabelPerfTest.GetPreferredSize
to track. On a Late 2013 Mac Pro perf improves from 1390 runs/second
to 3300 runs/second.

+250 runs/second of that comes from a related hotspot in gfx::internal::
CreateSkiaTypeface() which was deriving a new CTFont unnecessarily
before sending it to gfx::CreateHarfBuzzFont().

Bug: 785522
Change-Id: Iccf57fe3fc9a93cd4b9de1e79e81fb84d2ad88bb
Reviewed-on: https://chromium-review.googlesource.com/823743
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#526920}
parent 1f43131d
......@@ -42,6 +42,9 @@ Font::~Font() {
}
Font Font::Derive(int size_delta, int style, Font::Weight weight) const {
if (size_delta == 0 && style == GetStyle() && weight == GetWeight())
return *this;
return platform_font_->DeriveFont(size_delta, style, weight);
}
......
......@@ -292,7 +292,17 @@ hb_font_t* CreateHarfBuzzFont(sk_sp<SkTypeface> skia_face,
if (face_cache->first.get() == NULL)
face_cache->first.Init(skia_face.get());
hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get());
hb_font_t* harfbuzz_font = nullptr;
#if defined(OS_MACOSX)
// Since we have a CTFontRef available at the right size, associate it with
// the hb_font_t. This avoids Harfbuzz doing its own lookup by typeface name,
// which requires talking to the font server again.
if (CTFontRef ct_font = SkTypeface_GetCTFontRef(skia_face.get()))
harfbuzz_font = hb_coretext_font_create(ct_font);
#endif
if (!harfbuzz_font)
harfbuzz_font = hb_font_create(face_cache->first.get());
const int scale = SkiaScalarToHarfBuzzUnits(text_size);
hb_font_set_scale(harfbuzz_font, scale, scale);
FontData* hb_font_data = new FontData(&face_cache->second);
......
......@@ -1177,3 +1177,18 @@ source_set("views_interactive_ui_tests") {
sources -= [ "corewm/desktop_capture_controller_unittest.cc" ]
}
}
test("views_perftests") {
sources = [
"controls/label_perftest.cc",
"views_perftests.cc",
]
deps = [
":test_support",
"//base/test:test_support",
"//cc/base:base",
"//testing/perf",
"//ui/resources:ui_test_pak",
]
}
......@@ -31,13 +31,16 @@ specific_include_rules = {
"run_all_unittests_main\.cc": [
"+mojo/edk/embedder",
],
"views_perftests\.cc": [
"+mojo/edk/embedder",
],
"view_unittest\.cc": [
"+cc/playback"
],
"views_test_suite\.cc": [
"+gpu/ipc/service",
],
"paint_info_unittest\.cc": [
".*test\.cc": [
"+cc/base",
]
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/label.h"
#include "base/strings/utf_string_conversions.h"
#include "cc/base/lap_timer.h"
#include "testing/perf/perf_test.h"
#include "ui/views/test/views_test_base.h"
namespace views {
using LabelPerfTest = ViewsTestBase;
// Test the number of text size measurements that can be made made per second.
// This should surface any performance regressions in underlying text layout
// system, e.g., failure to cache font structures.
TEST_F(LabelPerfTest, GetPreferredSize) {
Label label;
// Alternate between two strings to ensure caches are cleared.
base::string16 string1 = base::ASCIIToUTF16("boring ascii string");
base::string16 string2 = base::ASCIIToUTF16("another uninteresting sequence");
constexpr int kLaps = 5000; // Aim to run in under 3 seconds.
constexpr int kWarmupLaps = 5;
// The time limit is unused. Use kLaps for the check interval so the time is
// only measured once.
cc::LapTimer timer(kWarmupLaps, base::TimeDelta(), kLaps);
for (int i = 0; i < kLaps + kWarmupLaps; ++i) {
label.SetText(i % 2 == 0 ? string1 : string2);
label.GetPreferredSize();
timer.NextLap();
}
perf_test::PrintResult("LabelPerfTest", std::string(), "GetPreferredSize",
timer.LapsPerSecond(), "runs/s", true);
}
} // namespace views
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/launcher/unit_test_launcher.h"
#include "ui/views/views_test_suite.h"
int main(int argc, char** argv) {
views::ViewsTestSuite test_suite(argc, argv);
return base::LaunchUnitTestsSerially(
argc, argv,
base::Bind(&views::ViewsTestSuite::Run, base::Unretained(&test_suite)));
}
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