New issue
Advanced search Search tips

Issue 847710 link

Starred by 1 user

Issue metadata

Status: Duplicate
Merged: issue 267710
Owner: ----
Closed: Nov 20
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug



Sign in to add a comment

TextElider is too slow for unicode text

Reported by jongkwon...@navercorp.com, May 30 2018

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3410.0 Safari/537.36

Steps to reproduce the problem:
1. Run the following test on mac.

TEST(TextEliderTest, ElideUnicode) {
  const FontList font_list;
  const std::string input = "가나다라마바사아자차카타파하가나다라마바사아자차카타파하";
  base::string16 output =
      ElideText(UTF8ToUTF16(input), font_list, 200, ELIDE_TAIL);
  LOG(INFO) << "output: " << output;
}

TEST(TextEliderTest, ElideUnicode2) {
  const FontList font_list;
  const std::string input = "가나다라마바사아자차카타파하가나다라마바사아자차카타파하";
  base::string16 output =
      ElideText(UTF8ToUTF16(input), font_list, 200, ELIDE_TAIL, Typesetter::NATIVE);
  LOG(INFO) << "output: " << output;
}

$ out/Cocoa/gfx_unittests --gtest_filter=TextEliderTest.ElideUnicode*

2. Result is as follows:
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from TextEliderTest
[ RUN      ] TextEliderTest.ElideUnicode
[57944:775:0530/111727.135832:159167693828996:INFO:text_elider_unittest.cc(66)] output: 가나다라마바사아자차카타파하가나…
[       OK ] TextEliderTest.ElideUnicode (25 ms)
[ RUN      ] TextEliderTest.ElideUnicode2
[57944:775:0530/111727.136499:159167694486037:INFO:text_elider_unittest.cc(74)] output: 가나다라마바사아자차카타파하가나…
[       OK ] TextEliderTest.ElideUnicode2 (1 ms)
[----------] 2 tests from TextEliderTest (26 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (26 ms total)
[  PASSED  ] 2 tests.
[1/2] TextEliderTest.ElideUnicode (25 ms)
[2/2] TextEliderTest.ElideUnicode2 (1 ms)
SUCCESS: all tests passed.

What is the expected behavior?

What went wrong?
1. ElideText() is too slow with default typesetter on mac compared to Typesetter::NATIVE.
2. 25ms is greater than 16ms, which makes jank when run on UI thread.

Did this work before? N/A 

Chrome version: 68.0.3410.0  Channel: n/a
OS Version: OS X 10.13.4
Flash Version:
 

Comment 1 by sdy@chromium.org, May 30 2018

Cc: tapted@chromium.org
Components: UI
+tapted@: Do you know if anyone owns this code? (Sorry, it looks like you touched it recently :-).)

Comment 2 by tapted@chromium.org, May 31 2018

Cc: pkasting@chromium.org msw@chromium.org
Components: -UI UI>GFX Internals>Views
Owner: tapted@chromium.org
Status: Assigned (was: Unconfirmed)
I think this is something of a known issue. Most specifically, Issue 267710. There's also  Issue 797215 , Issue 740717, http://crbug.com/424082#c69 and http://crbug.com/641726#c29 .

To insert an ellipsis without breaking, there's a fair amount of backtracking. FADE_TAIL tends to perform better.

There might be something particularly screwy here that we can improve upon, or something mac-specific. I'll poke around a bit.

Is there a specific place where this is happening a lot that you're most concerned about? We try to cache elide results in a RenderText object. And, E.g., the bookmarks model does eliding on a background thread (which might be a bug.. I'm not sure all our codepaths are threadsafe).

Comment 3 by tapted@chromium.org, May 31 2018

Labels: -Pri-2 Pri-3
Owner: ----
Status: Available (was: Assigned)
I don't see the same performance impact you're seeing versus the native typesetter.

you can see the test I'm using here - https://chromium-review.googlesource.com/#/c/chromium/src/+/1080477

Typesetter::NATIVE comes about about 2x faster (~0.5ms per run rather than 1ms per run).

*RESULT LabelPerfTest: ElideUnicode= 1134.8316650390625 runs/s
*RESULT LabelPerfTest: ElideUnicodeNative= 2130.805908203125 runs/s

I expect the bulk of the 25ms you're seeing is a font glyph lookup which gets cached after the first time it's used.

There aren't really any surprises. 80% of the time is spent inside hb_shape(). On mac this calls _hb_coretext_shape which mostly falls back to CoreText to do the heavy lifting anyway.

One possible avenue to explore: There are *two* calls to RenderTextHarfBuzz::ShapeRun(). Once before eliding and once after. The first is used just to determine whether we need to elide at all. Maybe one can be skipped.. This seems to be the fastpath that FADE_TAIL can already take -- since an ellipsis doesn't need to be inserted, text runs are not broken, so only one pass is needed. 

4.65 s   97.7%  1.00 ms              gfx::ElideText(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::FontList const&, float, gfx::ElideBehavior, gfx::Typesetter)

3.35 s   70.2%  1.00 ms                 gfx::RenderText::UpdateDisplayText(float)
3.09 s   64.9%  2.00 ms                      gfx::RenderTextHarfBuzz::ShapeRun(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::internal::TextRunHarfBuzz*)
2.62 s   54.9%  0 s                        hb_shape


1.25 s   26.1%  2.00 ms                 gfx::RenderTextHarfBuzz::ShapeRun(std::__1::basic_string<unsigned short, base::string16_internals::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::internal::TextRunHarfBuzz*)
1.03 s   21.6%  0 s                   hb_shape


Based on the above, I'm moving this to available. I don't think there's any low-hanging fruit here or new concern specific to unicode or to mac that isn't already covered by other bugs.
I got the same result in LabelPerfTest above, where ElideText() with RenderTextHarfBuzz didn't show much difference. (The font glyph lookup cache might be the reason?)

I am experiencing janks when I open bookmark bar and move mouse around the bookmark bar menus (with MacViewsBrowser). MenuItemView::PaintButton() takes more than 20ms every time I open the bookmark bar menus. I logged the elapsed times in MenuItemView::PaintButton() and Canvas::DrawStringRectWithFlags():

[94155:775:0529/165952.166760:INFO:menu_item_view.cc(844)] PaintButton with title: 중국 알리페이, 국내 편의점 2만곳에 모바일결제 인프라 깐다 - 대한민국 IT포털의 중심! 이티뉴스
[94155:775:0529/165952.166776:INFO:menu_item_view.cc(845)] title length: 55
[94155:775:0529/165952.166799:INFO:canvas_skia.cc(176)] Harfbuzz created: 0ms
[94155:775:0529/165952.185057:INFO:canvas_skia.cc(240)] ElideTextAndAdjustRange finished: 18ms
[94155:775:0529/165952.185085:INFO:canvas_skia.cc(248)] UpdateRenderText finished: 18ms
[94155:775:0529/165952.188449:INFO:canvas_skia.cc(257)] render_text->Draw() finished: 21ms
[94155:775:0529/165952.188505:INFO:menu_item_view.cc(973)] end: 21ms

I could remove the jank by using gfx::Typesetter::NATIVE in ElideTextAndAdjustRange() of canvas_skia.cc and BookmarkBarView::CreateToolTipForURLAndTitle().
Ahh, likely the real bug here is similar to Issue 740717

MenuItemView::PaintMinorIconAndText() creates a new gfx::RenderText object each time it needs to repaint (e.g. background change on hover).

I think MenuItemView should retain the RenderText object created so it doesn't need to do repeated typesetting.
There was no minor text when I tested this, but gfx::ElideText() also creates a new gfx::RenderText object each time.
oop - yeah all the calls to DrawStringRectWithFlags will be creating fresh gfx::RenderText objects too, which can be cached instead. DrawStringRectWithFlags being slow is a common theme in the other bugs as well.

I think we can attempt to deprecate DrawStringRectWithFlags. The Cocoa approach would be to use -[NSAttributedString drawInRect:] (and gfx::RenderText is basically an NSAttributedString). That is, Cocoa sorta forces you to into a pattern of keeping the typeset text around.

https://developer.apple.com/documentation/foundation/nsattributedstring/1531631-drawinrect?changes=_2&language=objc

Comment 8 by tapted@chromium.org, Jun 25 2018

Cc: rsesek@chromium.org
Robert did some tracing in  Issue 826265 , which is pointing to elide calls coming from BookmarkBarView::CreateToolTipForURLAndTitle() whilst populating a11y properties.
Cc: ccameron@chromium.org
Labels: Hotlist-DesktopUIChecked
Status: Archived (was: Available)
**UI mass Triage**
We were unable to find repro steps for this bug. If you have more data to
reproduce this bug or have clear repro steps, please reopen or file a new issue.
Thanks!

Status: Available (was: Archived)
Not sure what was "checked" here.
I think this issue can be closed now. It shows no latency on Chrome/70.0.3538.102.
Mergedinto: 267710
Status: Duplicate (was: Available)
Trent mentioned a few open issues about eliding performance above, it's probably safe to dup this to one of those.
I'll dup to Issue 267710 for now, feel free to change as needed.

Sign in to add a comment