Issue metadata
Sign in to add a comment
|
[Mac]Views: Improve window resize performance e.g. Task Manager, gfx::Canvas::DrawStringRectWithFlags (and, e.g., RenderTextMac vs RenderTextHarfbuzz plus shared parts) |
||||||||||||||||||||||||
Issue descriptionChrome Version : 56.0.2914.3 OS Version: OS X 10.12.1 What steps will reproduce the problem? 1. With MacViews, open the Task Manager, resize it a bunch What is the expected result? Smooth resize What happens instead of that? Even on a high performance machine, ui::WindowResizeHelperMac sometimes fails to receive a frame within 50ms and redraws the window frame without an updated window contents, resulting in black gumf around the window edge. (we put up with this on Windows and Linux, but we're fussier on Mac). Both RenderTextMac and RenderTextHarfbuzz seem to have similar CPU usage, but I think there's some low-hanging fruit in RenderTextHarfbuzz that could put it on top. (e.g. calls to gfx::Font::Derive that could be cached) At a glance, I think there's some low-hanging fruit in the shared parts too. E.g. there are multiple calls to EnsureLayout under DrawStringRectWithFlags -- one for drawing, one for eliding. There might be a way to layout only once and effectively double performance. Attaching symbolized two traces: one with --enable-harfbuzz-rendertext and one without, for the "resize task manager a bunch" test case, over 3000ms. Note there's some noise in the delay between me hitting "sample" and starting to resizing the window. Noteworthy bits: - gfx::Canvas::DrawStringRectWithFlags: 158ms harfbuzz, 184ms mac - DrawStringRectWithFlags calling EnsureLayout multipe times: once for elide, once for draw - Also a layout called via gfx::Canvas::GetStringWidth - which is also called via views::CalculateTableColumnSizes - A surprising (to me) sample taken inside FontListImpl::GetFonts(): It has a CHECK(FontList::ParseDescription(..)) which might be expensive in release code. - noticable std::vector<gfx::BreakList> memory management in gfx::internal::StyleIterator::StyleIterator - ui::FormatBytes isn't cheap (4% of drawing time) Latency - base::WaitableEvent::Wait in content::BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurface - IPC::SyncChannel::WaitForReply in gpu::GpuChannelHost::ValidateFlushIDReachedServer The Window resize - ScreenMac::GetDisplayNearestWindow is slow (called by WidgetDelegate::SaveWindowPlacement, AND by BridgedNativeWidget::UpdateLayerProperties(), when under BridgedNativeWidget::OnSizeChanged()) (the slow bit is mostly under -[NSWindow _bestScreenBySpaceAssignmentOrGeometry]). Also called internally by AppKit under -[_NSViewLayerSurface update] (under [NSThemeFrame setFrameSize:], and under -[NSView _invalidateFocus] of BridgedContentView). - and under -[NSWindow showsFullScreenButton]!! ** - AND called under gfx::ApplyNSWindowSizeConstraints(..) - this is triggered by views::View::BoundsChanged(..) calling views::BridgedNativeWidget::OnSizeConstraintsChanged() -- maybe that can be avoided entirely. For a 100ms saving. - wow - I have an easy fix for this already - https://codereview.chromium.org/2502813003/ Other stuff - -[AppMenuButtonViewController containerSuperviewFrameChanged:] gets a notification posted when the window resizes -- why? (probably not filtering its subscription properly). Everything, ranked. -[NSWindow _bestScreenBySpaceAssignmentOrGeometry] 27 -[NSCGSWindow(NSCGSSpace) bestSpaceContainingWindow] (in AppKit) + 39 [0x7fff81cf72f4] 27 -[NSWindow _bestScreenByGeometryOfFrame:respectingSpaceAssignment:] (in AppKit) + 654 [0x7fff81727934] 27 -[NSWindow _bestScreenBySpaceAssignmentOrGeometry] (in AppKit) + 71 [0x7fff8172769d] 24 NSCGSWindowBestManagedDisplayMatchesByGeometry (in AppKit) + 231 [0x7fff8189f737] 23 -[NSCGSWindow(NSCGSSpace) bestSpaceContainingWindow] (in AppKit) + 63 [0x7fff81cf730c] 23 SLSCopyBestManagedDisplayForRect (in SkyLight) + 327 [0x7fff94f2ec45] 22 SLSCopySpacesForWindows (in SkyLight) + 199 [0x7fff94f2bfe5] 22 _NSCGSWindowGetSpaceIDs (in AppKit) + 115 [0x7fff81cf72a6] 21 NSCGSWindowBestManagedDisplayMatchesByGeometry (in AppKit) + 261 [0x7fff8189f755] 21 __SLSCopySpacesForWindows_block_invoke (in SkyLight) + 175 [0x7fff94f2c0bc] 19 SLSCopyManagedDisplayForWindow (in SkyLight) + 170 [0x7fff94f2ed63] -[NSWindow showsFullScreenButton] 14 -[NSWindow _implicitlyAllowsFullScreenPrimary] (in AppKit) + 233 [0x7fff81733242] 7 -[NSWindow _effectiveCollectionBehavior] (in AppKit) + 50 [0x7fff81732dbe] 7 -[NSWindow _implicitlyAllowsFullScreenPrimary] (in AppKit) + 322 [0x7fff8173329b] gfx::Font::Derive 17 -[NSFontManager traitsOfFont:] (in AppKit) + 37 [0x7fff818b3183] 16 -[NSCTFontDescriptor objectForKey:] (in UIFoundation) + 21 [0x7fff961656cb] 16 -[NSFontDescriptor symbolicTraits] (in UIFoundation) + 33 [0x7fff96164e7a] 16 CTFontDescriptorCopyAttribute (in CoreText) + 98 [0x7fff8500e8bb] 11 TDescriptor::CopyAttribute(__CFString const*) const (in CoreText) + 204 [0x7fff8500e9c4] 9 -[NSFontManager convertFont:toHaveTrait:] (in AppKit) + 92 [0x7fff819ac89b] 9 -[NSFontManager convertFont:toNotHaveTrait:] (in AppKit) + 36 [0x7fff819ac763] 9 gfx::Font::Derive(int, int, gfx::Font::Weight) const (in Google Chrome Framework) load address 0x103188000 + 0x1dcd3d1 [font.cc:45] 9 gfx::internal::CreateSkiaTypeface(gfx::Font const&, bool, gfx::Font::Weight) (in Google Chrome Framework) load address 0x103188000 + 0x1dea414 [render_text_mac.mm:76] 9 TComponentFont::CopyAttribute(unsigned long) const (in CoreText) + 88 [0x7fff8500f890] 9 TTenuousComponentFont::CopyAttribute(unsigned long) const (in CoreText) + 61 [0x7fff850ec161] 8 -[NSFontManager convertFont:toHaveTrait:] (in AppKit) + 121 [0x7fff819ac8b8] 7 gfx::PlatformFontMac::PlatformFontMac(NSFont*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, int, gfx::Font::Weight) (in Google Chrome Framework) load address 0x103188000 + 0x1dd7ba6 [platform_font_mac.mm:192] 7 gfx::PlatformFontMac::DeriveFont(int, int, gfx::Font::Weight) const (in Google Chrome Framework) load address 0x103188000 + 0x1dd7cda [platform_font_mac.mm:190] 7 TBaseFont::CopyAttribute(unsigned long) const (in CoreText) + 336 [0x7fff8500fa02] 7 TDescriptor::CopyAttribute(__CFString const*) const (in CoreText) + 30 [0x7fff8500e916] 6 gfx::PlatformFontMac::DeriveFont(int, int, gfx::Font::Weight) const (in Google Chrome Framework) load address 0x103188000 + 0x1dd7c71 [platform_font_mac.mm:112] 6 TBaseFont::CopyTraits(bool) const (in CoreText) + 35 [0x7fff850e5c0b] 6 TBaseFont::CopyTraitsInternal() const (in CoreText) + 43 [0x7fff85029733] 5 gfx::PlatformFontMac::DeriveFont(int, int, gfx::Font::Weight) const (in Google Chrome Framework) load address 0x103188000 + 0x1dd7c92 [platform_font_mac.mm:114] 5 gfx::PlatformFontMac::DeriveFont(int, int, gfx::Font::Weight) const (in Google Chrome Framework) load address 0x103188000 + 0x1dd7cac [platform_font_mac.mm:117] RenderText layout (HarfBuzz) 10 gfx::RenderTextHarfBuzz::EnsureLayoutRunList() (in Google Chrome Framework) load address 0x103188000 + 0x1de421e [iterator:1311] 10 gfx::RenderTextHarfBuzz::ShapeRunWithFont(std::__1::basic_string<unsigned short, base::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::Font const&, gfx::FontRenderParams const&, gfx::internal::TextRunHarfBuzz*) (in Google Chrome Framework) load address 0x103188000 + 0x1de77c6 [SkRefCnt.h:308] 10 gfx::RenderTextHarfBuzz::ShapeRun(std::__1::basic_string<unsigned short, base::string16_char_traits, std::__1::allocator<unsigned short> > const&, gfx::internal::TextRunHarfBuzz*) (in Google Chrome Framework) load address 0x103188000 + 0x1de7d64 [render_text_harfbuzz.cc:1350] 9 gfx::RenderTextHarfBuzz::EnsureLayoutRunList() (in Google Chrome Framework) load address 0x103188000 + 0x1de41bd [render_text_harfbuzz.cc:1569] toolkit-views framework stuff [actually this is calling NSWindow schedulePaintInRect, which takes up more of the time] 9 views::View::SchedulePaintInRect(gfx::Rect const&) (in Google Chrome Framework) load address 0x103188000 + 0x30f0084 [view.cc:760] The rest are probably hard to improve on: moved into more_things_ranked.txt
,
Nov 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/37ff93058a11ab26e575152d207b849c009a4a00 commit 37ff93058a11ab26e575152d207b849c009a4a00 Author: tapted <tapted@chromium.org> Date: Sun Nov 20 23:47:03 2016 Remove Widget::OnRootViewLayout(). It was added early on in the development for Linux Aura (r222386) to propagate min/max window size properties to the window server. However, it never really worked right because mapping the x11 window is asynchronous: there's no guarantee a layout would occur after the window was mapped. This was fixed in r325538 (and moved around in r388040 and r389572). Furthermore, calls to SetBounds() will also update the min and max size properties. This is since r283945 (and a fix for that in r350338), so the associated OnRootViewLayout() call is redundant. Mac was also using OnRootViewLayout() but r368141 added OnWidgetInitDone() which is a better place to trigger this. Mac stopped using OnRootViewLayout() in r432821. BUG= 665280 TEST=Should be covered by WidgetTest.MinimumSizeConstraints added in r325538 Review-Url: https://codereview.chromium.org/2507403002 Cr-Commit-Position: refs/heads/master@{#433462} [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/mus/desktop_window_tree_host_mus.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/mus/desktop_window_tree_host_mus.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/mus/native_widget_mus.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/mus/native_widget_mus.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_native_widget_aura.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_window_tree_host.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/native_widget_aura.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/native_widget_aura.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/native_widget_mac.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/native_widget_mac.mm [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/native_widget_private.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/root_view.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/root_view.h [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/widget.cc [modify] https://crrev.com/37ff93058a11ab26e575152d207b849c009a4a00/ui/views/widget/widget.h
,
Nov 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/7330ed4e42141778cb25604dd4949471f034a38f commit 7330ed4e42141778cb25604dd4949471f034a38f Author: tapted <tapted@chromium.org> Date: Sun Nov 20 23:48:55 2016 Mac: Use a cache for ScreenMac::GetDisplayForScreen(). Performance traces on the associated bugs turn up a lot of time spent in display::screen_mac::GetDisplayForScreen(). It does a lot of work, and calls some expensive AppKit and CoreGraphics methods. It's currently invoked multiple times during a window resize. GetDisplayNearestWindow would also invoke -[NSWindow _bestScreenBySpaceAssignmentOrGeometry] which does some synchronous messaging with the window server process, adding significant latency. ScreenMac already maintains a std::vector<Display>, but GetDisplayForScreen() does not use it. Use it. Optimize GetDisplayNearestWindow for the case of a single display. BUG= 666556 , 665280 Review-Url: https://codereview.chromium.org/2514703002 Cr-Commit-Position: refs/heads/master@{#433463} [modify] https://crrev.com/7330ed4e42141778cb25604dd4949471f034a38f/ui/display/mac/screen_mac.mm
,
Apr 12 2017
tapted: how is this looking now?
,
Apr 13 2017
Performance is good, but there's more to do. I want to get rid of calls to Font::Derive in RenderText (the fonts are usually already cached in ResourceBundle already and Derive is slow). Caching text runs is also a possibility. See http://crbug.com/641726#c27 and http://crbug.com/641726#c29 For Mac to get these benefits, we should deploy harfbuzz more widely there first ( Issue 454835 ). That has its own set of problems.
,
May 8 2017
,
Oct 4 2017
This bug affects resizeable MacViews windows, of which there's only one that I know of (the bookmark editor). Also, I don't see any noticeable problems with that window. I'm going to say we can defer fixing this until after launch if we need to, so M-X and MacViews-Browser.
,
Dec 4 2017
,
Mar 23 2018
MacViews triage: assigning this to sdy@ because they own related work; let's target a fix for this (if there is further work we want to do) at M-69.
,
Mar 23 2018
Maybe related to issue 682825 , too.
,
Mar 26 2018
The switch from RenderTextMac to RenderTextHarfbuzz for views (Issue 791391) may have had an impact on this too. There's also Issue 740717, which I just remembered is assigned to me.. Basically a big refactor of TableView to cache RenderText objects. I think this will fix the lion's share of remaining performance concerns here.
,
Mar 27 2018
,
Jun 28 2018
,
Jul 12
|
|||||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||||
Comment 1 by bugdroid1@chromium.org
, Nov 17 2016