Chromium Code Reviews| Index: third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp |
| diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp |
| index 6fde443334dd11e05976d3406fb927cb3e945a76..02cd8a75fee2a5c031052d5c619e239c5bf94d55 100644 |
| --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp |
| +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp |
| @@ -190,7 +190,12 @@ void ScrollingCoordinator::updateAfterCompositingChangeIfNeeded() { |
| if (m_shouldScrollOnMainThreadDirty || |
| m_wasFrameScrollable != frameIsScrollable) { |
| setShouldUpdateScrollLayerPositionOnMainThread( |
| - mainThreadScrollingReasons()); |
| + mainThreadScrollingReasons(m_page->deprecatedLocalMainFrame())); |
| + |
| + // Need to update scroll on main thread reasons for subframe because |
| + // subframe (e.g. iframe with background-attachment:fixed) should |
| + // scroll on main thread while the main frame scrolls on impl. |
| + updateSubFrameScrollOnMainReason(); |
| m_shouldScrollOnMainThreadDirty = false; |
| } |
| m_wasFrameScrollable = frameIsScrollable; |
| @@ -832,6 +837,26 @@ void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread( |
| } |
| } |
| +void ScrollingCoordinator::updateSubFrameScrollOnMainReason() { |
| + MainThreadScrollingReasons reasons = |
| + static_cast<MainThreadScrollingReasons>(0); |
| + for (Frame* frame = m_page->mainFrame(); frame; |
| + frame = frame->tree().traverseNext()) { |
| + if (!frame->isLocalFrame()) |
| + continue; |
| + if (toLocalFrame(frame)->localFrameRoot() != m_page->mainFrame()) |
| + continue; |
| + |
| + reasons = mainThreadScrollingReasons(toLocalFrame(frame)); |
| + if (reasons) { |
| + if (WebLayer* scrollLayer = |
| + toWebLayer(toLocalFrame(frame)->view()->layerForScrolling())) { |
| + scrollLayer->addMainThreadScrollingReasons(reasons); |
| + } |
| + } |
|
flackr
2016/12/07 21:53:11
Do the reasons need to be cleared if we no longer
yigu
2016/12/08 18:52:29
Done.
|
| + } |
| +} |
| + |
| void ScrollingCoordinator::layerTreeViewInitialized( |
| WebLayerTreeView& layerTreeView) { |
| if (Platform::current()->isThreadedAnimationEnabled()) { |
| @@ -1138,8 +1163,8 @@ bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects( |
| return false; |
| } |
| -MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() |
| - const { |
| +MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons( |
| + LocalFrame* targetFrame) const { |
| MainThreadScrollingReasons reasons = |
| static_cast<MainThreadScrollingReasons>(0); |
| @@ -1149,22 +1174,22 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() |
| if (!m_page->mainFrame()->isLocalFrame()) |
| return reasons; |
| - // TODO(flackr) Currently we combine reasons for main thread scrolling from |
| - // all frames but we should only look at the targetted frame (and its |
| - // ancestors if the scroll bubbles up). http://crbug.com/568901 |
| - for (Frame* frame = m_page->mainFrame(); frame; |
| - frame = frame->tree().traverseNext()) { |
| - if (!frame->isLocalFrame()) |
| + // Walk through the subtree from the target frame to root. Use the gathered |
| + // reasons to determine whether the target frame should be scrolled on main |
| + // thread regardless other subframes on the same page. |
| + for (Frame* checkFrame = targetFrame; checkFrame; |
|
flackr
2016/12/07 21:53:11
nit: This can continue to just be called frame.
yigu
2016/12/08 18:52:29
Done.
|
| + checkFrame = checkFrame->tree().parent()) { |
| + if (!checkFrame->isLocalFrame()) |
| continue; |
| // TODO(alexmos,kenrb): For OOPIF, local roots that are different from |
| // the main frame can't be used in the calculation, since they use |
| // different compositors with unrelated state, which breaks some of the |
| // calculations below. |
| - if (toLocalFrame(frame)->localFrameRoot() != m_page->mainFrame()) |
| + if (toLocalFrame(checkFrame)->localFrameRoot() != m_page->mainFrame()) |
| continue; |
| - FrameView* frameView = toLocalFrame(frame)->view(); |
| + FrameView* frameView = toLocalFrame(checkFrame)->view(); |
| if (!frameView || frameView->shouldThrottleRendering()) |
| continue; |
| @@ -1193,11 +1218,19 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() |
| return reasons; |
| } |
| -String ScrollingCoordinator::mainThreadScrollingReasonsAsText() const { |
| - DCHECK(m_page->deprecatedLocalMainFrame()->document()->lifecycle().state() >= |
| +String ScrollingCoordinator::mainThreadScrollingReasonsAsText( |
| + Frame* frame) const { |
| + DCHECK(toLocalFrame(frame)->document()->lifecycle().state() >= |
| DocumentLifecycle::CompositingClean); |
| - if (WebLayer* scrollLayer = toWebLayer( |
| - m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) { |
| + |
| + // If an iframe has attributes like background-attachment: fixed |
| + // it should scroll on main thread. The reasons is added in |
| + // mainThreadScrollingReasons. Need to call this function |
| + // before access such reason. |
| + mainThreadScrollingReasons(toLocalFrame(frame)); |
|
flackr
2016/12/07 21:53:11
This shouldn't be necessary anymore right?
yigu
2016/12/08 18:52:29
Done.
|
| + |
| + if (WebLayer* scrollLayer = |
| + toWebLayer(toLocalFrame(frame)->view()->layerForScrolling())) { |
| String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText( |
| scrollLayer->mainThreadScrollingReasons()) |
| .c_str()); |