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 fe04c5a66b7f62cd407af5223674f1da69f07753..1421f22a809547064d6726fa49570346607d5be2 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())); |
pdr.
2016/12/13 05:51:17
Nit: lets refactor this to not use deprecated func
yigu
2016/12/14 21:07:27
Done.
|
+ |
+ // 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; |
@@ -835,6 +840,35 @@ void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread( |
} |
} |
+void ScrollingCoordinator::updateSubFrameScrollOnMainReason() { |
pdr.
2016/12/13 05:51:16
Ah, I misread this code. You are correct that this
yigu
2016/12/14 21:07:27
Done.
|
+ MainThreadScrollingReasons reasons = |
+ static_cast<MainThreadScrollingReasons>(0); |
+ MainThreadScrollingReasons mainFrameReasons = |
+ static_cast<MainThreadScrollingReasons>(0); |
+ |
+ if (!m_page->settings().threadedScrollingEnabled()) |
+ mainFrameReasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; |
+ |
+ for (Frame* frame = m_page->mainFrame(); frame; |
pdr.
2016/12/13 05:51:16
This loop doesn't quite look right, or I may misun
pdr.
2016/12/13 23:07:10
I was wrong in how this works. For A-B-C, if B has
|
+ frame = frame->tree().traverseNext()) { |
+ if (!frame->isLocalFrame()) |
+ continue; |
+ |
+ reasons = mainFrameReasons | |
+ mainThreadScrollingReasonsPerFrame(toLocalFrame(frame)); |
+ if (WebLayer* scrollLayer = |
+ toWebLayer(toLocalFrame(frame)->view()->layerForScrolling())) { |
+ if (reasons) { |
+ scrollLayer->addMainThreadScrollingReasons(reasons); |
+ } else { |
+ reasons = ~reasons; |
+ reasons &= ~MainThreadScrollingReason::kHandlingScrollFromMainThread; |
+ scrollLayer->clearMainThreadScrollingReasons(reasons); |
+ } |
+ } |
+ } |
+} |
+ |
void ScrollingCoordinator::layerTreeViewInitialized( |
WebLayerTreeView& layerTreeView) { |
if (Platform::current()->isThreadedAnimationEnabled()) { |
@@ -952,9 +986,12 @@ static void accumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects, |
if (!targets) |
return; |
- // If there's a handler on the window, document, html or body element (fairly |
- // common in practice), then we can quickly mark the entire document and skip |
- // looking at any other handlers. Note that technically a handler on the body |
+ // If there's a handler on the window, document, html or body element |
pdr.
2016/12/13 05:51:16
Nit: please re-flow this multi-line comment so it'
yigu
2016/12/14 21:07:27
Done.
|
+ // (fairly |
+ // common in practice), then we can quickly mark the entire document and |
+ // skip |
+ // looking at any other handlers. Note that technically a handler on the |
+ // body |
// doesn't cover the whole document, but it's reasonable to be conservative |
// and report the whole document anyway. |
// |
@@ -1141,8 +1178,39 @@ bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects( |
return false; |
} |
-MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() |
- const { |
+MainThreadScrollingReasons |
+ScrollingCoordinator::mainThreadScrollingReasonsPerFrame( |
pdr.
2016/12/13 05:51:16
Does this need to be on ScrollingCoordinator? I wo
|
+ LocalFrame* frame) const { |
+ MainThreadScrollingReasons reasons = |
+ static_cast<MainThreadScrollingReasons>(0); |
+ |
+ FrameView* frameView = frame->view(); |
+ if (!frameView || frameView->shouldThrottleRendering()) |
+ return reasons; |
+ |
+ if (frameView->hasBackgroundAttachmentFixedObjects()) |
+ reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
+ FrameView::ScrollingReasons scrollingReasons = |
+ frameView->getScrollingReasons(); |
+ const bool mayBeScrolledByInput = (scrollingReasons == FrameView::Scrollable); |
+ const bool mayBeScrolledByScript = |
+ mayBeScrolledByInput || |
+ (scrollingReasons == FrameView::NotScrollableExplicitlyDisabled); |
+ |
+ // TODO(awoloszyn) Currently crbug.com/304810 will let certain |
+ // overflow:hidden elements scroll on the compositor thread, so we should |
+ // not let this move there path as an optimization, when we have |
+ // slow-repaint elements. |
+ if (mayBeScrolledByScript && |
+ hasVisibleSlowRepaintViewportConstrainedObjects(frameView)) { |
+ reasons |= |
+ MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects; |
+ } |
+ return reasons; |
+} |
+ |
+MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons( |
+ LocalFrame* targetFrame) const { |
MainThreadScrollingReasons reasons = |
static_cast<MainThreadScrollingReasons>(0); |
@@ -1152,55 +1220,27 @@ 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()) |
- 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()) |
- continue; |
+ if (targetFrame->localFrameRoot() != m_page->mainFrame()) |
pdr.
2016/12/13 05:51:16
Please add the comment back about OOPIF:
// TODO(a
|
+ return reasons; |
- FrameView* frameView = toLocalFrame(frame)->view(); |
- if (!frameView || frameView->shouldThrottleRendering()) |
+ // 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* frame = targetFrame; frame; frame = frame->tree().parent()) { |
+ if (!frame->isLocalFrame()) |
continue; |
- |
- if (frameView->hasBackgroundAttachmentFixedObjects()) |
- reasons |= |
- MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
- FrameView::ScrollingReasons scrollingReasons = |
- frameView->getScrollingReasons(); |
- const bool mayBeScrolledByInput = |
- (scrollingReasons == FrameView::Scrollable); |
- const bool mayBeScrolledByScript = |
- mayBeScrolledByInput || |
- (scrollingReasons == FrameView::NotScrollableExplicitlyDisabled); |
- |
- // TODO(awoloszyn) Currently crbug.com/304810 will let certain |
- // overflow:hidden elements scroll on the compositor thread, so we should |
- // not let this move there path as an optimization, when we have |
- // slow-repaint elements. |
- if (mayBeScrolledByScript && |
- hasVisibleSlowRepaintViewportConstrainedObjects(frameView)) { |
- reasons |= |
- MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects; |
- } |
+ reasons |= mainThreadScrollingReasonsPerFrame(toLocalFrame(frame)); |
} |
return reasons; |
} |
-String ScrollingCoordinator::mainThreadScrollingReasonsAsText() const { |
- DCHECK(m_page->deprecatedLocalMainFrame()->document()->lifecycle().state() >= |
+String ScrollingCoordinator::mainThreadScrollingReasonsAsText( |
+ const Frame* frame) const { |
+ DCHECK(toLocalFrame(frame)->document()->lifecycle().state() >= |
DocumentLifecycle::CompositingClean); |
- if (WebLayer* scrollLayer = toWebLayer( |
- m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) { |
+ if (WebLayer* scrollLayer = |
+ toWebLayer(toLocalFrame(frame)->view()->layerForScrolling())) { |
String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText( |
scrollLayer->mainThreadScrollingReasons()) |
.c_str()); |