OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/page/scrolling/RootScrollerController.h" | 5 #include "core/page/scrolling/RootScrollerController.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/dom/Element.h" | 8 #include "core/dom/Element.h" |
9 #include "core/frame/FrameHost.h" | 9 #include "core/frame/FrameHost.h" |
10 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
11 #include "core/frame/TopControls.h" | 11 #include "core/frame/TopControls.h" |
| 12 #include "core/frame/VisualViewport.h" |
12 #include "core/layout/LayoutBox.h" | 13 #include "core/layout/LayoutBox.h" |
| 14 #include "core/page/ChromeClient.h" |
13 #include "core/page/Page.h" | 15 #include "core/page/Page.h" |
14 #include "core/page/scrolling/OverscrollController.h" | 16 #include "core/page/scrolling/OverscrollController.h" |
15 #include "core/page/scrolling/ViewportScrollCallback.h" | 17 #include "core/page/scrolling/ViewportScrollCallback.h" |
16 #include "core/paint/PaintLayerScrollableArea.h" | 18 #include "core/paint/PaintLayerScrollableArea.h" |
| 19 #include "platform/graphics/GraphicsLayer.h" |
17 #include "platform/scroll/ScrollableArea.h" | 20 #include "platform/scroll/ScrollableArea.h" |
18 | 21 |
19 namespace blink { | 22 namespace blink { |
20 | 23 |
21 namespace { | 24 namespace { |
22 | 25 |
23 ScrollableArea* scrollableAreaFor(const Element& element) | 26 ScrollableArea* scrollableAreaFor(const Element& element) |
24 { | 27 { |
25 if (!element.layoutObject() || !element.layoutObject()->isBox()) | 28 if (!element.layoutObject() || !element.layoutObject()->isBox()) |
26 return nullptr; | 29 return nullptr; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 78 |
76 ViewportScrollCallback* RootScrollerController::createViewportApplyScroll( | 79 ViewportScrollCallback* RootScrollerController::createViewportApplyScroll( |
77 TopControls* topControls, OverscrollController* overscrollController) | 80 TopControls* topControls, OverscrollController* overscrollController) |
78 { | 81 { |
79 return new ViewportScrollCallback(topControls, overscrollController); | 82 return new ViewportScrollCallback(topControls, overscrollController); |
80 } | 83 } |
81 | 84 |
82 RootScrollerController::RootScrollerController(Document& document, ViewportScrol
lCallback* applyScrollCallback) | 85 RootScrollerController::RootScrollerController(Document& document, ViewportScrol
lCallback* applyScrollCallback) |
83 : m_document(&document) | 86 : m_document(&document) |
84 , m_viewportApplyScroll(applyScrollCallback) | 87 , m_viewportApplyScroll(applyScrollCallback) |
| 88 , m_changedSinceLastCompositingUpdate(false) |
85 { | 89 { |
86 } | 90 } |
87 | 91 |
88 DEFINE_TRACE(RootScrollerController) | 92 DEFINE_TRACE(RootScrollerController) |
89 { | 93 { |
90 visitor->trace(m_document); | 94 visitor->trace(m_document); |
91 visitor->trace(m_viewportApplyScroll); | 95 visitor->trace(m_viewportApplyScroll); |
92 visitor->trace(m_rootScroller); | 96 visitor->trace(m_rootScroller); |
93 visitor->trace(m_effectiveRootScroller); | 97 visitor->trace(m_effectiveRootScroller); |
94 } | 98 } |
(...skipping 26 matching lines...) Expand all Loading... |
121 | 125 |
122 Element* newEffectiveRootScroller = rootScrollerValid | 126 Element* newEffectiveRootScroller = rootScrollerValid |
123 ? m_rootScroller.get() | 127 ? m_rootScroller.get() |
124 : defaultEffectiveRootScroller(); | 128 : defaultEffectiveRootScroller(); |
125 | 129 |
126 if (m_effectiveRootScroller == newEffectiveRootScroller) | 130 if (m_effectiveRootScroller == newEffectiveRootScroller) |
127 return; | 131 return; |
128 | 132 |
129 moveViewportApplyScroll(newEffectiveRootScroller); | 133 moveViewportApplyScroll(newEffectiveRootScroller); |
130 m_effectiveRootScroller = newEffectiveRootScroller; | 134 m_effectiveRootScroller = newEffectiveRootScroller; |
| 135 |
| 136 m_changedSinceLastCompositingUpdate = true; |
131 } | 137 } |
132 | 138 |
133 void RootScrollerController::moveViewportApplyScroll(Element* target) | 139 void RootScrollerController::moveViewportApplyScroll(Element* target) |
134 { | 140 { |
135 if (!m_viewportApplyScroll) | 141 if (!m_viewportApplyScroll) |
136 return; | 142 return; |
137 | 143 |
138 if (m_effectiveRootScroller) | 144 if (m_effectiveRootScroller) |
139 m_effectiveRootScroller->removeApplyScroll(); | 145 m_effectiveRootScroller->removeApplyScroll(); |
140 | 146 |
141 ScrollableArea* targetScroller = | 147 ScrollableArea* targetScroller = |
142 target ? scrollableAreaFor(*target) : nullptr; | 148 target ? scrollableAreaFor(*target) : nullptr; |
143 | 149 |
144 if (targetScroller) { | 150 if (targetScroller) { |
145 // Use disable-native-scroll since the ViewportScrollCallback needs to | 151 // Use disable-native-scroll since the ViewportScrollCallback needs to |
146 // apply scroll actions both before (TopControls) and after (overscroll) | 152 // apply scroll actions both before (TopControls) and after (overscroll) |
147 // scrolling the element so it will apply scroll to the element itself. | 153 // scrolling the element so it will apply scroll to the element itself. |
148 target->setApplyScroll( | 154 target->setApplyScroll( |
149 m_viewportApplyScroll, | 155 m_viewportApplyScroll, |
150 "disable-native-scroll"); | 156 "disable-native-scroll"); |
151 } | 157 } |
152 | 158 |
153 // Ideally, scroll customization would pass the current element to scroll to | 159 // Ideally, scroll customization would pass the current element to scroll to |
154 // the apply scroll callback but this doesn't happen today so we set it | 160 // the apply scroll callback but this doesn't happen today so we set it |
155 // through a back door here. | 161 // through a back door here. |
156 m_viewportApplyScroll->setScroller(targetScroller); | 162 m_viewportApplyScroll->setScroller(targetScroller); |
157 } | 163 } |
158 | 164 |
| 165 void RootScrollerController::didUpdateCompositing() |
| 166 { |
| 167 if (!m_changedSinceLastCompositingUpdate |
| 168 || !m_document |
| 169 || !m_document->frameHost() |
| 170 || !m_effectiveRootScroller) |
| 171 return; |
| 172 |
| 173 FrameHost& frameHost = *m_document->frameHost(); |
| 174 |
| 175 WebLayer* newRootScrollerLayer = nullptr; |
| 176 |
| 177 if (m_effectiveRootScroller->layoutObject() |
| 178 && m_effectiveRootScroller->layoutObject()->isBox()) { |
| 179 |
| 180 LayoutBox* box = toLayoutBox(m_effectiveRootScroller->layoutObject()); |
| 181 GraphicsLayer* graphicsLayer = nullptr; |
| 182 |
| 183 if (box->isDocumentElement()) |
| 184 graphicsLayer = frameHost.visualViewport().layerForScrolling(); |
| 185 else |
| 186 graphicsLayer = box->getScrollableArea()->layerForScrolling(); |
| 187 |
| 188 // TODO(bokan): We should assert graphicsLayer here and |
| 189 // RootScrollerController should do whatever needs to happen to ensure |
| 190 // the root scroller gets composited. |
| 191 |
| 192 if (graphicsLayer) |
| 193 newRootScrollerLayer = graphicsLayer->platformLayer(); |
| 194 } |
| 195 |
| 196 m_changedSinceLastCompositingUpdate = false; |
| 197 |
| 198 // Let the compositor-side counterpart know about this change. |
| 199 if (m_document->isInMainFrame()) |
| 200 frameHost.chromeClient().didUpdateRootScrollerLayer(newRootScrollerLayer
); |
| 201 } |
| 202 |
159 Element* RootScrollerController::defaultEffectiveRootScroller() | 203 Element* RootScrollerController::defaultEffectiveRootScroller() |
160 { | 204 { |
161 DCHECK(m_document); | 205 DCHECK(m_document); |
162 return m_document->documentElement(); | 206 return m_document->documentElement(); |
163 } | 207 } |
164 | 208 |
165 } // namespace blink | 209 } // namespace blink |
OLD | NEW |