Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm

Issue 13665002: Fold ScrollingCoordinatorChromium into ScrollingCoordinator and devirtualize (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #if ENABLE(THREADED_SCROLLING)
29
30 #import "ScrollingCoordinatorMac.h"
31
32 #include "GraphicsLayer.h"
33 #include "Frame.h"
34 #include "FrameView.h"
35 #include "IntRect.h"
36 #include "Page.h"
37 #include "PlatformWheelEvent.h"
38 #include "PluginViewBase.h"
39 #include "Region.h"
40 #include "RenderLayerCompositor.h"
41 #include "RenderView.h"
42 #include "ScrollAnimator.h"
43 #include "ScrollingConstraints.h"
44 #include "ScrollingStateFixedNode.h"
45 #include "ScrollingStateScrollingNode.h"
46 #include "ScrollingStateStickyNode.h"
47 #include "ScrollingStateTree.h"
48 #include "ScrollingThread.h"
49 #include "ScrollingTree.h"
50 #include "TiledBacking.h"
51
52 #include <wtf/Functional.h>
53 #include <wtf/MainThread.h>
54 #include <wtf/PassRefPtr.h>
55
56
57 namespace WebCore {
58
59 class ScrollingCoordinatorPrivate {
60 };
61
62 ScrollingCoordinatorMac::ScrollingCoordinatorMac(Page* page)
63 : ScrollingCoordinator(page)
64 , m_scrollingStateTree(ScrollingStateTree::create())
65 , m_scrollingTree(ScrollingTree::create(this))
66 , m_scrollingStateTreeCommitterTimer(this, &ScrollingCoordinatorMac::scrolli ngStateTreeCommitterTimerFired)
67 {
68 }
69
70 ScrollingCoordinatorMac::~ScrollingCoordinatorMac()
71 {
72 ASSERT(!m_scrollingTree);
73 }
74
75 void ScrollingCoordinatorMac::pageDestroyed()
76 {
77 ScrollingCoordinator::pageDestroyed();
78
79 m_scrollingStateTreeCommitterTimer.stop();
80
81 // Invalidating the scrolling tree will break the reference cycle between th e ScrollingCoordinator and ScrollingTree objects.
82 ScrollingThread::dispatch(bind(&ScrollingTree::invalidate, m_scrollingTree.r elease()));
83 }
84
85 ScrollingTree* ScrollingCoordinatorMac::scrollingTree() const
86 {
87 ASSERT(m_scrollingTree);
88 return m_scrollingTree.get();
89 }
90
91 bool ScrollingCoordinatorMac::isRubberBandInProgress() const
92 {
93 return scrollingTree()->isRubberBandInProgress();
94 }
95
96 bool ScrollingCoordinatorMac::rubberBandsAtBottom() const
97 {
98 return scrollingTree()->rubberBandsAtBottom();
99 }
100
101 void ScrollingCoordinatorMac::setRubberBandsAtBottom(bool rubberBandsAtBottom)
102 {
103 scrollingTree()->setRubberBandsAtBottom(rubberBandsAtBottom);
104 }
105
106 bool ScrollingCoordinatorMac::rubberBandsAtTop() const
107 {
108 return scrollingTree()->rubberBandsAtTop();
109 }
110
111 void ScrollingCoordinatorMac::setRubberBandsAtTop(bool rubberBandsAtTop)
112 {
113 scrollingTree()->setRubberBandsAtTop(rubberBandsAtTop);
114 }
115
116 void ScrollingCoordinatorMac::commitTreeStateIfNeeded()
117 {
118 if (!m_scrollingStateTree->hasChangedProperties())
119 return;
120
121 commitTreeState();
122 m_scrollingStateTreeCommitterTimer.stop();
123 }
124
125 void ScrollingCoordinatorMac::frameViewLayoutUpdated(FrameView* frameView)
126 {
127 ASSERT(isMainThread());
128 ASSERT(m_page);
129
130 // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
131 if (!m_scrollingStateTree->rootStateNode())
132 return;
133
134 // Compute the region of the page that we can't do fast scrolling for. This currently includes
135 // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
136 // frame view whose layout was updated is not the main frame.
137 Region nonFastScrollableRegion = computeNonFastScrollableRegion(m_page->main Frame(), IntPoint());
138
139 // In the future, we may want to have the ability to set non-fast scrolling regions for more than
140 // just the root node. But right now, this concept only applies to the root.
141 setNonFastScrollableRegionForNode(nonFastScrollableRegion, m_scrollingStateT ree->rootStateNode());
142
143 if (!coordinatesScrollingForFrameView(frameView))
144 return;
145
146 ScrollingStateScrollingNode* node = toScrollingStateScrollingNode(m_scrollin gStateTree->stateNodeForID(frameView->scrollLayerID()));
147 if (!node)
148 return;
149
150 ScrollParameters scrollParameters;
151 scrollParameters.horizontalScrollElasticity = frameView->horizontalScrollEla sticity();
152 scrollParameters.verticalScrollElasticity = frameView->verticalScrollElastic ity();
153 scrollParameters.hasEnabledHorizontalScrollbar = frameView->horizontalScroll bar() && frameView->horizontalScrollbar()->enabled();
154 scrollParameters.hasEnabledVerticalScrollbar = frameView->verticalScrollbar( ) && frameView->verticalScrollbar()->enabled();
155 scrollParameters.horizontalScrollbarMode = frameView->horizontalScrollbarMod e();
156 scrollParameters.verticalScrollbarMode = frameView->verticalScrollbarMode();
157
158 scrollParameters.scrollOrigin = frameView->scrollOrigin();
159 scrollParameters.viewportRect = IntRect(IntPoint(), frameView->visibleConten tRect().size());
160 scrollParameters.totalContentsSize = frameView->totalContentsSize();
161 scrollParameters.frameScaleFactor = frameView->frame()->frameScaleFactor();
162 scrollParameters.headerHeight = frameView->headerHeight();
163 scrollParameters.footerHeight = frameView->footerHeight();
164
165 setScrollParametersForNode(scrollParameters, node);
166 }
167
168 void ScrollingCoordinatorMac::recomputeWheelEventHandlerCountForFrameView(FrameV iew* frameView)
169 {
170 ScrollingStateScrollingNode* node = toScrollingStateScrollingNode(m_scrollin gStateTree->stateNodeForID(frameView->scrollLayerID()));
171 if (!node)
172 return;
173 setWheelEventHandlerCountForNode(computeCurrentWheelEventHandlerCount(), nod e);
174 }
175
176 void ScrollingCoordinatorMac::frameViewRootLayerDidChange(FrameView* frameView)
177 {
178 ASSERT(isMainThread());
179 ASSERT(m_page);
180
181 if (!coordinatesScrollingForFrameView(frameView))
182 return;
183
184 // If the root layer does not have a ScrollingStateNode, then we should crea te one.
185 ensureRootStateNodeForFrameView(frameView);
186 ASSERT(m_scrollingStateTree->rootStateNode());
187
188 ScrollingCoordinator::frameViewRootLayerDidChange(frameView);
189
190 ScrollingStateScrollingNode* node = toScrollingStateScrollingNode(m_scrollin gStateTree->stateNodeForID(frameView->scrollLayerID()));
191 setScrollLayerForNode(scrollLayerForFrameView(frameView), node);
192 setCounterScrollingLayerForNode(counterScrollingLayerForFrameView(frameView) , node);
193 }
194
195 void ScrollingCoordinatorMac::scrollableAreaScrollbarLayerDidChange(ScrollableAr ea* scrollableArea, ScrollbarOrientation)
196 {
197 ASSERT(isMainThread());
198 ASSERT(m_page);
199
200 if (scrollableArea != static_cast<ScrollableArea*>(m_page->mainFrame()->view ()))
201 return;
202
203 // FIXME: Implement.
204 }
205
206 bool ScrollingCoordinatorMac::requestScrollPositionUpdate(FrameView* frameView, const IntPoint& scrollPosition)
207 {
208 ASSERT(isMainThread());
209 ASSERT(m_page);
210
211 if (!coordinatesScrollingForFrameView(frameView))
212 return false;
213
214 if (frameView->inProgrammaticScroll() || frameView->frame()->document()->inP ageCache())
215 updateMainFrameScrollPosition(scrollPosition, frameView->inProgrammaticS croll(), SetScrollingLayerPosition);
216
217 // If this frame view's document is being put into the page cache, we don't want to update our
218 // main frame scroll position. Just let the FrameView think that we did.
219 if (frameView->frame()->document()->inPageCache())
220 return true;
221
222 ScrollingStateScrollingNode* stateNode = toScrollingStateScrollingNode(m_scr ollingStateTree->stateNodeForID(frameView->scrollLayerID()));
223 if (!stateNode)
224 return false;
225
226 stateNode->setRequestedScrollPosition(scrollPosition, frameView->inProgramma ticScroll());
227 scheduleTreeStateCommit();
228 return true;
229 }
230
231 bool ScrollingCoordinatorMac::handleWheelEvent(FrameView*, const PlatformWheelEv ent& wheelEvent)
232 {
233 ASSERT(isMainThread());
234 ASSERT(m_page);
235
236 if (m_scrollingTree->willWheelEventStartSwipeGesture(wheelEvent))
237 return false;
238
239 ScrollingThread::dispatch(bind(&ScrollingTree::handleWheelEvent, m_scrolling Tree.get(), wheelEvent));
240
241 return true;
242 }
243
244 ScrollingNodeID ScrollingCoordinatorMac::attachToStateTree(ScrollingNodeType nod eType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
245 {
246 return m_scrollingStateTree->attachNode(nodeType, newNodeID, parentID);
247 }
248
249 void ScrollingCoordinatorMac::detachFromStateTree(ScrollingNodeID nodeID)
250 {
251 m_scrollingStateTree->detachNode(nodeID);
252 }
253
254 void ScrollingCoordinatorMac::clearStateTree()
255 {
256 m_scrollingStateTree->clear();
257 }
258
259 void ScrollingCoordinatorMac::ensureRootStateNodeForFrameView(FrameView* frameVi ew)
260 {
261 ASSERT(frameView->scrollLayerID());
262 attachToStateTree(ScrollingNode, frameView->scrollLayerID(), 0);
263 }
264
265 void ScrollingCoordinatorMac::setScrollLayerForNode(GraphicsLayer* scrollLayer, ScrollingStateNode* node)
266 {
267 node->setScrollLayer(scrollLayer);
268 scheduleTreeStateCommit();
269 }
270
271 void ScrollingCoordinatorMac::setCounterScrollingLayerForNode(GraphicsLayer* lay er, ScrollingStateScrollingNode* node)
272 {
273 node->setCounterScrollingLayer(layer);
274 scheduleTreeStateCommit();
275 }
276
277 void ScrollingCoordinatorMac::setNonFastScrollableRegionForNode(const Region& re gion, ScrollingStateScrollingNode* node)
278 {
279 node->setNonFastScrollableRegion(region);
280 scheduleTreeStateCommit();
281 }
282
283 void ScrollingCoordinatorMac::setScrollParametersForNode(const ScrollParameters& scrollParameters, ScrollingStateScrollingNode* node)
284 {
285 node->setHorizontalScrollElasticity(scrollParameters.horizontalScrollElastic ity);
286 node->setVerticalScrollElasticity(scrollParameters.verticalScrollElasticity) ;
287 node->setHasEnabledHorizontalScrollbar(scrollParameters.hasEnabledHorizontal Scrollbar);
288 node->setHasEnabledVerticalScrollbar(scrollParameters.hasEnabledVerticalScro llbar);
289 node->setHorizontalScrollbarMode(scrollParameters.horizontalScrollbarMode);
290 node->setVerticalScrollbarMode(scrollParameters.verticalScrollbarMode);
291
292 node->setScrollOrigin(scrollParameters.scrollOrigin);
293 node->setViewportRect(scrollParameters.viewportRect);
294 node->setTotalContentsSize(scrollParameters.totalContentsSize);
295 node->setFrameScaleFactor(scrollParameters.frameScaleFactor);
296 node->setHeaderHeight(scrollParameters.headerHeight);
297 node->setFooterHeight(scrollParameters.footerHeight);
298
299 scheduleTreeStateCommit();
300 }
301
302 void ScrollingCoordinatorMac::setWheelEventHandlerCountForNode(unsigned wheelEve ntHandlerCount, ScrollingStateScrollingNode* node)
303 {
304 node->setWheelEventHandlerCount(wheelEventHandlerCount);
305 scheduleTreeStateCommit();
306 }
307
308 void ScrollingCoordinatorMac::setShouldUpdateScrollLayerPositionOnMainThread(Mai nThreadScrollingReasons reasons)
309 {
310 if (!m_scrollingStateTree->rootStateNode())
311 return;
312
313 // The FrameView's GraphicsLayer is likely to be out-of-synch with the Platf ormLayer
314 // at this point. So we'll update it before we switch back to main thread sc rolling
315 // in order to avoid layer positioning bugs.
316 if (reasons)
317 updateMainFrameScrollLayerPosition();
318 m_scrollingStateTree->rootStateNode()->setShouldUpdateScrollLayerPositionOnM ainThread(reasons);
319 scheduleTreeStateCommit();
320 }
321
322 void ScrollingCoordinatorMac::updateMainFrameScrollLayerPosition()
323 {
324 ASSERT(isMainThread());
325
326 if (!m_page)
327 return;
328
329 FrameView* frameView = m_page->mainFrame()->view();
330 if (!frameView)
331 return;
332
333 if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView))
334 scrollLayer->setPosition(-frameView->scrollPosition());
335 }
336
337 void ScrollingCoordinatorMac::syncChildPositions(const LayoutRect& viewportRect)
338 {
339 if (!m_scrollingStateTree->rootStateNode())
340 return;
341
342 Vector<OwnPtr<ScrollingStateNode> >* children = m_scrollingStateTree->rootSt ateNode()->children();
343 if (!children)
344 return;
345
346 // FIXME: We'll have to traverse deeper into the tree at some point.
347 size_t size = children->size();
348 for (size_t i = 0; i < size; ++i) {
349 ScrollingStateNode* child = children->at(i).get();
350 child->syncLayerPositionForViewportRect(viewportRect);
351 }
352 }
353
354 void ScrollingCoordinatorMac::updateScrollingNode(ScrollingNodeID nodeID, Graphi csLayer* scrollLayer, GraphicsLayer* counterScrollingLayer)
355 {
356 ScrollingStateScrollingNode* node = toScrollingStateScrollingNode(m_scrollin gStateTree->stateNodeForID(nodeID));
357 ASSERT(node);
358 if (!node)
359 return;
360
361 node->setScrollLayer(scrollLayer);
362 node->setCounterScrollingLayer(counterScrollingLayer);
363 scheduleTreeStateCommit();
364 }
365
366 void ScrollingCoordinatorMac::updateViewportConstrainedNode(ScrollingNodeID node ID, const ViewportConstraints& constraints, GraphicsLayer* graphicsLayer)
367 {
368 ASSERT(supportsFixedPositionLayers());
369
370 ScrollingStateNode* node = m_scrollingStateTree->stateNodeForID(nodeID);
371 if (!node)
372 return;
373
374 switch (constraints.constraintType()) {
375 case ViewportConstraints::FixedPositionConstaint: {
376 ScrollingStateFixedNode* fixedNode = toScrollingStateFixedNode(node);
377 setScrollLayerForNode(graphicsLayer, fixedNode);
378 fixedNode->updateConstraints((const FixedPositionViewportConstraints&)co nstraints);
379 break;
380 }
381 case ViewportConstraints::StickyPositionConstraint: {
382 ScrollingStateStickyNode* stickyNode = toScrollingStateStickyNode(node);
383 setScrollLayerForNode(graphicsLayer, stickyNode);
384 stickyNode->updateConstraints((const StickyPositionViewportConstraints&) constraints);
385 break;
386 }
387 }
388 scheduleTreeStateCommit();
389 }
390
391 void ScrollingCoordinatorMac::scheduleTreeStateCommit()
392 {
393 if (m_scrollingStateTreeCommitterTimer.isActive())
394 return;
395
396 if (!m_scrollingStateTree->hasChangedProperties())
397 return;
398
399 m_scrollingStateTreeCommitterTimer.startOneShot(0);
400 }
401
402 void ScrollingCoordinatorMac::scrollingStateTreeCommitterTimerFired(Timer<Scroll ingCoordinatorMac>*)
403 {
404 commitTreeState();
405 }
406
407 void ScrollingCoordinatorMac::commitTreeState()
408 {
409 ASSERT(m_scrollingStateTree->hasChangedProperties());
410
411 OwnPtr<ScrollingStateTree> treeState = m_scrollingStateTree->commit();
412 ScrollingThread::dispatch(bind(&ScrollingTree::commitNewTreeState, m_scrolli ngTree.get(), treeState.release()));
413
414 FrameView* frameView = m_page->mainFrame()->view();
415 if (!frameView)
416 return;
417
418 TiledBacking* tiledBacking = frameView->tiledBacking();
419 if (!tiledBacking)
420 return;
421
422 ScrollingModeIndication indicatorMode;
423 if (shouldUpdateScrollLayerPositionOnMainThread())
424 indicatorMode = MainThreadScrollingBecauseOfStyleIndication;
425 else if (scrollingTree() && scrollingTree()->hasWheelEventHandlers())
426 indicatorMode = MainThreadScrollingBecauseOfEventHandlersIndication;
427 else
428 indicatorMode = ThreadedScrollingIndication;
429
430 tiledBacking->setScrollingModeIndication(indicatorMode);
431 }
432
433 String ScrollingCoordinatorMac::scrollingStateTreeAsText() const
434 {
435 if (m_scrollingStateTree->rootStateNode())
436 return m_scrollingStateTree->rootStateNode()->scrollingStateTreeAsText() ;
437
438 return String();
439 }
440
441 } // namespace WebCore
442
443 #endif // ENABLE(THREADED_SCROLLING)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698