153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)/*
253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2011 Apple Inc. All rights reserved.
353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * modification, are permitted provided that the following conditions
653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * are met:
753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
1053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
1153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
1253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) *
1353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE.
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) */
2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/scrolling/ScrollingCoordinator.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
319e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/dom/Fullscreen.h"
327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/Node.h"
33323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/frame/EventHandlerRegistry.h"
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h"
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/frame/Settings.h"
37323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/html/HTMLElement.h"
3843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/page/Page.h"
3943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/plugins/PluginView.h"
4043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/rendering/RenderGeometryMap.h"
41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/rendering/RenderPart.h"
4243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/rendering/RenderView.h"
4343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/rendering/compositing/CompositedLayerMapping.h"
4443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "core/rendering/compositing/RenderLayerCompositor.h"
455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "platform/RuntimeEnabledFeatures.h"
461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/TraceEvent.h"
47a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/exported/WebScrollbarImpl.h"
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/exported/WebScrollbarThemeGeometryNative.h"
491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/geometry/Region.h"
50bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "platform/geometry/TransformState.h"
51a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsLayer.h"
528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
53a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/mac/ScrollAnimatorMac.h"
54f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#endif
55a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollAnimator.h"
56a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollbarTheme.h"
575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/Platform.h"
585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebCompositorSupport.h"
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebLayerPositionConstraint.h"
605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebScrollbarLayer.h"
615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebScrollbarThemeGeometry.h"
625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebScrollbarThemePainter.h"
630019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch#include "wtf/text/StringBuilder.h"
6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebLayer;
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebLayerPositionConstraint;
6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebRect;
6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebScrollbarLayer;
6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)using blink::WebVector;
7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)namespace {
7253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)WebLayer* toWebLayer(blink::GraphicsLayer* layer)
7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return layer ? layer->platformLayer() : 0;
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
7753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} // namespace
7953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassOwnPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return adoptPtr(new ScrollingCoordinator(page));
8553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
8653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ScrollingCoordinator::ScrollingCoordinator(Page* page)
8853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    : m_page(page)
8919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    , m_scrollGestureRegionIsDirty(false)
9019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    , m_touchEventTargetRectsAreDirty(false)
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_shouldScrollOnMainThreadDirty(false)
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    , m_wasFrameScrollable(false)
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    , m_lastMainThreadScrollingReasons(0)
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
9653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)ScrollingCoordinator::~ScrollingCoordinator()
9853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
10053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
10181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)void ScrollingCoordinator::setShouldHandleScrollGestureOnMainThreadRegion(const Region& region)
10253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
1035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame())
1045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return;
1055d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
10653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        Vector<IntRect> rects = region.rects();
10753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        WebVector<WebRect> webRects(rects.size());
10853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (size_t i = 0; i < rects.size(); ++i)
10953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            webRects[i] = rects[i];
11053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        scrollLayer->setNonFastScrollableRegion(webRects);
11153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
11253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
11353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
11419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)void ScrollingCoordinator::notifyLayoutUpdated()
11553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
11619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    m_scrollGestureRegionIsDirty = true;
11719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    m_touchEventTargetRectsAreDirty = true;
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_shouldScrollOnMainThreadDirty = true;
11919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
12053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void ScrollingCoordinator::updateAfterCompositingChangeIfNeeded()
12219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
1235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame())
1245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return;
1255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!shouldUpdateAfterCompositingChange())
1275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return;
1285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    TRACE_EVENT0("input", "ScrollingCoordinator::updateAfterCompositingChangeIfNeeded");
13083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
13119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (m_scrollGestureRegionIsDirty) {
13219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // Compute the region of the page where we can't handle scroll gestures and mousewheel events
13319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // on the impl thread. This currently includes:
13419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // 1. All scrollable areas, such as subframes, overflow divs and list boxes, whose composited
13519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // scrolling are not enabled. We need to do this even if the frame view whose layout was updated
13619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // is not the main frame.
13719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // 2. Resize control areas, e.g. the small rect at the right bottom of div/textarea/iframe when
13819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // CSS property "resize" is enabled.
13919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        // 3. Plugin areas.
1405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        Region shouldHandleScrollGestureOnMainThreadRegion = computeShouldHandleScrollGestureOnMainThreadRegion(m_page->deprecatedLocalMainFrame(), IntPoint());
14119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        setShouldHandleScrollGestureOnMainThreadRegion(shouldHandleScrollGestureOnMainThreadRegion);
14219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        m_scrollGestureRegionIsDirty = false;
14383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch    }
14483750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch
14519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (m_touchEventTargetRectsAreDirty) {
14619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        updateTouchEventTargetRectsIfNeeded();
14719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        m_touchEventTargetRectsAreDirty = false;
14819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
14919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
1505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
15151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool frameIsScrollable = frameView && frameView->isScrollable();
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_shouldScrollOnMainThreadDirty || m_wasFrameScrollable != frameIsScrollable) {
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setShouldUpdateScrollLayerPositionOnMainThread(mainThreadScrollingReasons());
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_shouldScrollOnMainThreadDirty = false;
15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
15651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_wasFrameScrollable = frameIsScrollable;
15751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The mainFrame view doesn't get included in the FrameTree below, so we
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // update its size separately.
16043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (WebLayer* scrollingWebLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0) {
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // If there is a fullscreen element, set the scroll bounds to empty so the main frame won't scroll.
1625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        Document* mainFrameDocument = m_page->deprecatedLocalMainFrame()->document();
1639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        Element* fullscreenElement = Fullscreen::fullscreenElementFrom(*mainFrameDocument);
164f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (fullscreenElement && fullscreenElement != mainFrameDocument->documentElement())
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            scrollingWebLayer->setBounds(IntSize());
16643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        else
1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            scrollingWebLayer->setBounds(frameView->contentsSize());
16843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    }
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
17019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    const FrameTree& tree = m_page->mainFrame()->tree();
171f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
172f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!child->isLocalFrame())
173f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            continue;
174f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (WebLayer* scrollLayer = toWebLayer(toLocalFrame(child)->view()->layerForScrolling()))
175f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            scrollLayer->setBounds(toLocalFrame(child)->view()->contentsSize());
17619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    }
17753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
17853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable)
18053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (WebLayer* scrollableLayer = toWebLayer(layer))
18253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        scrollableLayer->setIsContainerForFixedPositionLayers(enable);
18353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
18453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
18553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static void clearPositionConstraintExceptForLayer(GraphicsLayer* layer, GraphicsLayer* except)
18653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (layer && layer != except && toWebLayer(layer))
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        toWebLayer(layer)->setPositionConstraint(WebLayerPositionConstraint());
18953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
19053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
19153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static WebLayerPositionConstraint computePositionConstraint(const RenderLayer* layer)
19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
19351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(layer->hasCompositedLayerMapping());
19453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    do {
19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (layer->renderer()->style()->position() == FixedPosition) {
19653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            const RenderObject* fixedPositionObject = layer->renderer();
19753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            bool fixedToRight = !fixedPositionObject->style()->right().isAuto();
19853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            bool fixedToBottom = !fixedPositionObject->style()->bottom().isAuto();
19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return WebLayerPositionConstraint::fixedPosition(fixedToRight, fixedToBottom);
20053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
20253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        layer = layer->parent();
203bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
204bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // Composited layers that inherit a fixed position state will be positioned with respect to the nearest compositedLayerMapping's GraphicsLayer.
205bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        // So, once we find a layer that has its own compositedLayerMapping, we can stop searching for a fixed position RenderObject.
20651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } while (layer && !layer->hasCompositedLayerMapping());
20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return WebLayerPositionConstraint();
20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::updateLayerPositionConstraint(RenderLayer* layer)
21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(layer->hasCompositedLayerMapping());
213e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMapping();
214e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    GraphicsLayer* mainLayer = compositedLayerMapping->childForSuperlayers();
21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Avoid unnecessary commits
217e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    clearPositionConstraintExceptForLayer(compositedLayerMapping->squashingContainmentLayer(), mainLayer);
2181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    clearPositionConstraintExceptForLayer(compositedLayerMapping->ancestorClippingLayer(), mainLayer);
2191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    clearPositionConstraintExceptForLayer(compositedLayerMapping->mainGraphicsLayer(), mainLayer);
22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (WebLayer* scrollableLayer = toWebLayer(mainLayer))
22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        scrollableLayer->setPositionConstraint(computePositionConstraint(layer));
22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::willDestroyScrollableArea(ScrollableArea* scrollableArea)
22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    removeWebScrollbarLayer(scrollableArea, HorizontalScrollbar);
22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    removeWebScrollbarLayer(scrollableArea, VerticalScrollbar);
22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::removeWebScrollbarLayer(ScrollableArea* scrollableArea, ScrollbarOrientation orientation)
23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScrollbarMap& scrollbars = orientation == HorizontalScrollbar ? m_horizontalScrollbars : m_verticalScrollbars;
23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (OwnPtr<WebScrollbarLayer> scrollbarLayer = scrollbars.take(scrollableArea))
2355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        GraphicsLayer::unregisterContentsLayer(scrollbarLayer->layer());
23653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
23753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
23853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar)
23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
2403c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ScrollbarTheme* theme = scrollbar->theme();
24151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::WebScrollbarThemePainter painter(theme, scrollbar);
24251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<blink::WebScrollbarThemeGeometry> geometry(blink::WebScrollbarThemeGeometryNative::create(theme));
24353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
24451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(blink::Platform::current()->compositorSupport()->createScrollbarLayer(new blink::WebScrollbarImpl(scrollbar), painter, geometry.leakPtr()));
2455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    GraphicsLayer::registerContentsLayer(scrollbarLayer->layer());
24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return scrollbarLayer.release();
24753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
24853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
2496f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochPassOwnPtr<WebScrollbarLayer> ScrollingCoordinator::createSolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumbThickness, int trackStart, bool isLeftSideVerticalScrollbar)
2508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
25151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    blink::WebScrollbar::Orientation webOrientation = (orientation == HorizontalScrollbar) ? blink::WebScrollbar::Horizontal : blink::WebScrollbar::Vertical;
2526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(blink::Platform::current()->compositorSupport()->createSolidColorScrollbarLayer(webOrientation, thumbThickness, trackStart, isLeftSideVerticalScrollbar));
2538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    GraphicsLayer::registerContentsLayer(scrollbarLayer->layer());
2548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return scrollbarLayer.release();
2558abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
2568abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
25753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)static void detachScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer)
25853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
25953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(scrollbarGraphicsLayer);
26053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
26153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    scrollbarGraphicsLayer->setContentsToPlatformLayer(0);
26253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    scrollbarGraphicsLayer->setDrawsContent(true);
26353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
26453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScrollbarLayer* scrollbarLayer, WebLayer* scrollLayer, WebLayer* containerLayer)
26653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
26753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(scrollbarGraphicsLayer);
26853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(scrollbarLayer);
26953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
27053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!scrollLayer) {
27153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        detachScrollbarLayer(scrollbarGraphicsLayer);
27253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
27353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
27453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    scrollbarLayer->setScrollLayer(scrollLayer);
27509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    scrollbarLayer->setClipLayer(containerLayer);
27653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    scrollbarGraphicsLayer->setContentsToPlatformLayer(scrollbarLayer->layer());
27753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    scrollbarGraphicsLayer->setDrawsContent(false);
27853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
27953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)WebScrollbarLayer* ScrollingCoordinator::addWebScrollbarLayer(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, PassOwnPtr<blink::WebScrollbarLayer> scrollbarLayer)
28153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
28253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScrollbarMap& scrollbars = orientation == HorizontalScrollbar ? m_horizontalScrollbars : m_verticalScrollbars;
28309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return scrollbars.add(scrollableArea, scrollbarLayer).storedValue->value.get();
28453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
28553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
28653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)WebScrollbarLayer* ScrollingCoordinator::getWebScrollbarLayer(ScrollableArea* scrollableArea, ScrollbarOrientation orientation)
28753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
28853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ScrollbarMap& scrollbars = orientation == HorizontalScrollbar ? m_horizontalScrollbars : m_verticalScrollbars;
28953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return scrollbars.get(scrollableArea);
29053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
29253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea* scrollableArea, ScrollbarOrientation orientation)
29353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
29453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// FIXME: Instead of hardcode here, we should make a setting flag.
2958abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
296f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    static const bool platformSupportsCoordinatedScrollbar = ScrollAnimatorMac::canUseCoordinatedScrollbar();
29753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const bool platformSupportsMainFrameOnly = false; // Don't care.
29853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#elif OS(ANDROID)
29953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const bool platformSupportsCoordinatedScrollbar = true;
30053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const bool platformSupportsMainFrameOnly = false;
30153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#else
30253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const bool platformSupportsCoordinatedScrollbar = true;
30353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    static const bool platformSupportsMainFrameOnly = true;
30453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
30553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!platformSupportsCoordinatedScrollbar)
30653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
30753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
308e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    bool isMainFrame = isForMainFrame(scrollableArea);
30953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!isMainFrame && platformSupportsMainFrameOnly)
31053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
31153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    GraphicsLayer* scrollbarGraphicsLayer = orientation == HorizontalScrollbar
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ? scrollableArea->layerForHorizontalScrollbar()
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        : scrollableArea->layerForVerticalScrollbar();
315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
31653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (scrollbarGraphicsLayer) {
31753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        Scrollbar* scrollbar = orientation == HorizontalScrollbar ? scrollableArea->horizontalScrollbar() : scrollableArea->verticalScrollbar();
31853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (scrollbar->isCustomScrollbar()) {
31953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            detachScrollbarLayer(scrollbarGraphicsLayer);
32053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return;
32153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
32253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
32353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, orientation);
3248abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (!scrollbarLayer) {
3255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            Settings* settings = m_page->mainFrame()->settings();
3268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
3278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            OwnPtr<WebScrollbarLayer> webScrollbarLayer;
3288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (settings->useSolidColorScrollbars()) {
3298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                ASSERT(RuntimeEnabledFeatures::overlayScrollbarsEnabled());
3306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch                webScrollbarLayer = createSolidColorScrollbarLayer(orientation, scrollbar->theme()->thumbThickness(scrollbar), scrollbar->theme()->trackPosition(scrollbar), scrollableArea->shouldPlaceVerticalScrollbarOnLeft());
3318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            } else {
3328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                webScrollbarLayer = createScrollbarLayer(scrollbar);
3338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            }
3348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            scrollbarLayer = addWebScrollbarLayer(scrollableArea, orientation, webScrollbarLayer.release());
3358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
33653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
33753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // Root layer non-overlay scrollbars should be marked opaque to disable
33853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        // blending.
33953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        bool isOpaqueScrollbar = !scrollbar->isOverlayScrollbar();
340197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        scrollbarGraphicsLayer->setContentsOpaque(isMainFrame && isOpaqueScrollbar);
34153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        WebLayer* scrollLayer = toWebLayer(scrollableArea->layerForScrolling());
343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
34409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollLayer, containerLayer);
34553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    } else
34653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        removeWebScrollbarLayer(scrollableArea, orientation);
34753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
34853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
349e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea* scrollableArea)
35053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    GraphicsLayer* scrollLayer = scrollableArea->layerForScrolling();
352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
353e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (scrollLayer) {
354323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        ASSERT(m_page);
35507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        // With pinch virtual viewport we no longer need to special case the main frame.
356323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        bool pinchVirtualViewportEnabled = m_page->settings().pinchVirtualViewportEnabled();
35707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        bool layerScrollShouldFireGraphicsLayerDidScroll = isForMainFrame(scrollableArea) && !pinchVirtualViewportEnabled;
35807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        scrollLayer->setScrollableArea(scrollableArea, layerScrollShouldFireGraphicsLayerDidScroll);
359e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
36053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    WebLayer* webLayer = toWebLayer(scrollableArea->layerForScrolling());
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
36353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (webLayer) {
36409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        webLayer->setScrollClipLayer(containerLayer);
36553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        webLayer->setScrollPosition(IntPoint(scrollableArea->scrollPosition() - scrollableArea->minimumScrollPosition()));
36609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        webLayer->setBounds(scrollableArea->contentsSize());
367f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        bool canScrollX = scrollableArea->userInputScrollable(HorizontalScrollbar);
368f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        bool canScrollY = scrollableArea->userInputScrollable(VerticalScrollbar);
369f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        webLayer->setUserScrollable(canScrollX, canScrollY);
37053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
371e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, HorizontalScrollbar)) {
372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        GraphicsLayer* horizontalScrollbarLayer = scrollableArea->layerForHorizontalScrollbar();
373e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (horizontalScrollbarLayer)
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
375e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
376e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, VerticalScrollbar)) {
377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        GraphicsLayer* verticalScrollbarLayer = scrollableArea->layerForVerticalScrollbar();
378e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (verticalScrollbarLayer)
37909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
380e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
381e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
382e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return !!webLayer;
38353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
38453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
385a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochtypedef WTF::HashMap<const GraphicsLayer*, Vector<LayoutRect> > GraphicsLayerHitTestRects;
386a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
387e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// In order to do a DFS cross-frame walk of the RenderLayer tree, we need to know which
388e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// RenderLayers have child frames inside of them. This computes a mapping for the
389e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// current frame which we can consult while walking the layers of that frame.
390e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)// Whenever we descend into a new frame, a new map will be created.
391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)typedef HashMap<const RenderLayer*, Vector<const LocalFrame*> > LayerFrameMap;
392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static void makeLayerChildFrameMap(const LocalFrame* currentFrame, LayerFrameMap* map)
393e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
394e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    map->clear();
395f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    const FrameTree& tree = currentFrame->tree();
396f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
397f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!child->isLocalFrame())
398f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            continue;
399f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        const RenderObject* ownerRenderer = toLocalFrame(child)->ownerRenderer();
40007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (!ownerRenderer)
40107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            continue;
40207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        const RenderLayer* containingLayer = ownerRenderer->enclosingLayer();
403e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        LayerFrameMap::iterator iter = map->find(containingLayer);
404e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (iter == map->end())
405f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            map->add(containingLayer, Vector<const LocalFrame*>()).storedValue->value.append(toLocalFrame(child));
40609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        else
407f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            iter->value.append(toLocalFrame(child));
408e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
409e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
410f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
411a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochstatic void projectRectsToGraphicsLayerSpaceRecursive(
412e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const RenderLayer* curLayer,
413e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    const LayerHitTestRects& layerRects,
414a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    GraphicsLayerHitTestRects& graphicsRects,
415e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    RenderGeometryMap& geometryMap,
416e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    HashSet<const RenderLayer*>& layersWithRects,
417e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    LayerFrameMap& layerChildFrameMap)
418e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
419e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Project any rects for the current layer
420e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    LayerHitTestRects::const_iterator layerIter = layerRects.find(curLayer);
421e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (layerIter != layerRects.end()) {
4227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        // Find the enclosing composited layer when it's in another document (for non-composited iframes).
423197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        const RenderLayer* compositedLayer = layerIter->key->enclosingLayerForPaintInvalidationCrossingFrameBoundaries();
424197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        ASSERT(compositedLayer);
425a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
426a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // Find the appropriate GraphicsLayer for the composited RenderLayer.
427197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        GraphicsLayer* graphicsLayer = compositedLayer->graphicsLayerBackingForScrolling();
4287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
429a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        GraphicsLayerHitTestRects::iterator glIter = graphicsRects.find(graphicsLayer);
430a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        Vector<LayoutRect>* glRects;
431a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (glIter == graphicsRects.end())
432a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            glRects = &graphicsRects.add(graphicsLayer, Vector<LayoutRect>()).storedValue->value;
43309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        else
434a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            glRects = &glIter->value;
435197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
436a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        // Transform each rect to the co-ordinate space of the graphicsLayer.
4377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        for (size_t i = 0; i < layerIter->value.size(); ++i) {
438e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            LayoutRect rect = layerIter->value[i];
439e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (compositedLayer != curLayer) {
440e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                FloatQuad compositorQuad = geometryMap.mapToContainer(rect, compositedLayer->renderer());
441e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                rect = LayoutRect(compositorQuad.boundingBox());
44206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // If the enclosing composited layer itself is scrolled, we have to undo the subtraction
44306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // of its scroll offset since we want the offset relative to the scrolling content, not
44406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // the element itself.
445bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                if (compositedLayer->renderer()->hasOverflowClip())
446bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)                    rect.move(compositedLayer->renderBox()->scrolledContentOffset());
447e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            }
448197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            RenderLayer::mapRectToPaintBackingCoordinates(compositedLayer->renderer(), rect);
449a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            glRects->append(rect);
450e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
451e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
452e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
453e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Walk child layers of interest
454e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for (const RenderLayer* childLayer = curLayer->firstChild(); childLayer; childLayer = childLayer->nextSibling()) {
455e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (layersWithRects.contains(childLayer)) {
456e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            geometryMap.pushMappingsToAncestor(childLayer, curLayer);
457a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            projectRectsToGraphicsLayerSpaceRecursive(childLayer, layerRects, graphicsRects, geometryMap, layersWithRects, layerChildFrameMap);
458e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            geometryMap.popMappingsToAncestor(curLayer);
459e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
460e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
461e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
462e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // If this layer has any frames of interest as a child of it, walk those (with an updated frame map).
463e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    LayerFrameMap::iterator mapIter = layerChildFrameMap.find(curLayer);
464e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (mapIter != layerChildFrameMap.end()) {
465e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        for (size_t i = 0; i < mapIter->value.size(); i++) {
466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            const LocalFrame* childFrame = mapIter->value[i];
467e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            const RenderLayer* childLayer = childFrame->view()->renderView()->layer();
468e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (layersWithRects.contains(childLayer)) {
469e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                LayerFrameMap newLayerChildFrameMap;
470e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                makeLayerChildFrameMap(childFrame, &newLayerChildFrameMap);
471e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                geometryMap.pushMappingsToAncestor(childLayer, curLayer);
472a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                projectRectsToGraphicsLayerSpaceRecursive(childLayer, layerRects, graphicsRects, geometryMap, layersWithRects, newLayerChildFrameMap);
473e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                geometryMap.popMappingsToAncestor(curLayer);
474e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            }
4757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        }
4767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
4777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch}
4787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
479a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochstatic void projectRectsToGraphicsLayerSpace(LocalFrame* mainFrame, const LayerHitTestRects& layerRects, GraphicsLayerHitTestRects& graphicsRects)
480e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
481a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    TRACE_EVENT0("input", "ScrollingCoordinator::projectRectsToGraphicsLayerSpace");
482e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    bool touchHandlerInChildFrame = false;
483e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
484e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // We have a set of rects per RenderLayer, we need to map them to their bounding boxes in their
485e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // enclosing composited layer. To do this most efficiently we'll walk the RenderLayer tree using
486e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // RenderGeometryMap. First record all the branches we should traverse in the tree (including
487e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // all documents on the page).
488e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    HashSet<const RenderLayer*> layersWithRects;
489e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for (LayerHitTestRects::const_iterator layerIter = layerRects.begin(); layerIter != layerRects.end(); ++layerIter) {
490e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        const RenderLayer* layer = layerIter->key;
491e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        do {
492e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (!layersWithRects.add(layer).isNewEntry)
493e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                break;
494e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
495e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (layer->parent()) {
496e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                layer = layer->parent();
497e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            } else if (RenderObject* parentDocRenderer = layer->renderer()->frame()->ownerRenderer()) {
498e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                layer = parentDocRenderer->enclosingLayer();
499e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                touchHandlerInChildFrame = true;
500e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            }
501e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        } while (layer);
502e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
503e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
504e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Now walk the layer projecting rects while maintaining a RenderGeometryMap
505e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    MapCoordinatesFlags flags = UseTransforms;
506e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (touchHandlerInChildFrame)
507e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        flags |= TraverseDocumentBoundaries;
50809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RenderLayer* rootLayer = mainFrame->contentRenderer()->layer();
509e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    RenderGeometryMap geometryMap(flags);
51009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    geometryMap.pushMappingsToAncestor(rootLayer, 0);
511e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    LayerFrameMap layerChildFrameMap;
512e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    makeLayerChildFrameMap(mainFrame, &layerChildFrameMap);
513a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    projectRectsToGraphicsLayerSpaceRecursive(rootLayer, layerRects, graphicsRects, geometryMap, layersWithRects, layerChildFrameMap);
514e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
515e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
51619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)void ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded()
51719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
51819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    TRACE_EVENT0("input", "ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded");
51919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
520c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!RuntimeEnabledFeatures::touchEnabled())
52119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return;
52219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
52319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    LayerHitTestRects touchEventTargetRects;
52419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    computeTouchEventTargetRects(touchEventTargetRects);
52519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    setTouchEventTargetRects(touchEventTargetRects);
52619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
52719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
52851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void ScrollingCoordinator::reset()
52951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
530a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    for (ScrollbarMap::iterator it = m_horizontalScrollbars.begin(); it != m_horizontalScrollbars.end(); ++it)
531a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        GraphicsLayer::unregisterContentsLayer(it->value->layer());
532a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    for (ScrollbarMap::iterator it = m_verticalScrollbars.begin(); it != m_verticalScrollbars.end(); ++it)
533a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        GraphicsLayer::unregisterContentsLayer(it->value->layer());
534a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
53551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_horizontalScrollbars.clear();
53651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_verticalScrollbars.clear();
53751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_layersWithTouchRects.clear();
53851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_wasFrameScrollable = false;
53951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
54051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // This is retained for testing.
54151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_lastMainThreadScrollingReasons = 0;
54251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setShouldUpdateScrollLayerPositionOnMainThread(m_lastMainThreadScrollingReasons);
54351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
54451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5453c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch// Note that in principle this could be called more often than computeTouchEventTargetRects, for
5463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch// example during a non-composited scroll (although that's not yet implemented - crbug.com/261307).
547a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid ScrollingCoordinator::setTouchEventTargetRects(LayerHitTestRects& layerRects)
5487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{
5497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    TRACE_EVENT0("input", "ScrollingCoordinator::setTouchEventTargetRects");
5507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
551a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // Update the list of layers with touch hit rects.
552e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    HashSet<const RenderLayer*> oldLayersWithTouchRects;
553e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    m_layersWithTouchRects.swap(oldLayersWithTouchRects);
554a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    for (LayerHitTestRects::iterator it = layerRects.begin(); it != layerRects.end(); ++it) {
555a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (!it->value.isEmpty()) {
556197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            const RenderLayer* compositedLayer = it->key->enclosingLayerForPaintInvalidationCrossingFrameBoundaries();
557197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            ASSERT(compositedLayer);
558197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            m_layersWithTouchRects.add(compositedLayer);
559a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        }
560a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
5617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
562a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // Ensure we have an entry for each composited layer that previously had rects (so that old
563a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // ones will get cleared out). Note that ideally we'd track this on GraphicsLayer instead of
564a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // RenderLayer, but we have no good hook into the lifetime of a GraphicsLayer.
565a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    for (HashSet<const RenderLayer*>::iterator it = oldLayersWithTouchRects.begin(); it != oldLayersWithTouchRects.end(); ++it) {
566a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (!layerRects.contains(*it))
567a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            layerRects.add(*it, Vector<LayoutRect>());
568a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    }
569a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
570a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    GraphicsLayerHitTestRects graphicsLayerRects;
5715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    projectRectsToGraphicsLayerSpace(m_page->deprecatedLocalMainFrame(), layerRects, graphicsLayerRects);
572a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
573a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    for (GraphicsLayerHitTestRects::const_iterator iter = graphicsLayerRects.begin(); iter != graphicsLayerRects.end(); ++iter) {
574a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        const GraphicsLayer* graphicsLayer = iter->key;
5757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        WebVector<WebRect> webRects(iter->value.size());
5767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        for (size_t i = 0; i < iter->value.size(); ++i)
5777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            webRects[i] = enclosingIntRect(iter->value[i]);
5787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        graphicsLayer->platformLayer()->setTouchEventHandlerRegion(webRects);
57953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
58053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
58153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
58209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void ScrollingCoordinator::touchEventTargetRectsDidChange()
58353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
584c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!RuntimeEnabledFeatures::touchEnabled())
5857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        return;
58653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
58753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // Wait until after layout to update.
5885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->deprecatedLocalMainFrame()->view() || m_page->deprecatedLocalMainFrame()->view()->needsLayout())
58953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
59053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
59119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    // FIXME: scheduleAnimation() is just a method of forcing the compositor to realize that it
59219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    // needs to commit here. We should expose a cleaner API for this.
5935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
59410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (renderView && renderView->compositor() && renderView->compositor()->staleInCompositingMode())
5955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        m_page->deprecatedLocalMainFrame()->view()->scheduleAnimation();
5967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
59719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    m_touchEventTargetRectsAreDirty = true;
59853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
59953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
60006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void ScrollingCoordinator::updateScrollParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent)
6019bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
6029bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    WebLayer* scrollParentWebLayer = 0;
60351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (parent && parent->hasCompositedLayerMapping())
6045d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        scrollParentWebLayer = toWebLayer(parent->compositedLayerMapping()->scrollingContentsLayer());
6059bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
60606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    child->setScrollParent(scrollParentWebLayer);
6079bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
6089bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
60906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void ScrollingCoordinator::updateClipParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent)
6109bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
6119bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    WebLayer* clipParentWebLayer = 0;
61251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (parent && parent->hasCompositedLayerMapping())
613d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        clipParentWebLayer = toWebLayer(parent->compositedLayerMapping()->parentForSublayers());
6149bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
61506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    child->setClipParent(clipParentWebLayer);
6169bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
6179bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
618e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void ScrollingCoordinator::willDestroyRenderLayer(RenderLayer* layer)
619e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
620e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    m_layersWithTouchRects.remove(layer);
621e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
622e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
6236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScrollingCoordinator::updateHaveWheelEventHandlers()
62453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6256f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ASSERT(isMainThread());
6266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ASSERT(m_page);
6275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame() || !m_page->deprecatedLocalMainFrame()->view())
628d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return;
6296f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
6305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
631f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        bool haveHandlers = m_page->frameHost().eventHandlerRegistry().hasEventHandlers(EventHandlerRegistry::WheelEvent);
632f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        scrollLayer->setHaveWheelEventHandlers(haveHandlers);
6336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
63453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
63553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScrollingCoordinator::updateHaveScrollEventHandlers()
63753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ASSERT(isMainThread());
6396f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    ASSERT(m_page);
6405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame() || !m_page->deprecatedLocalMainFrame()->view())
641d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return;
6426f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
6436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // Currently the compositor only cares whether there are scroll handlers anywhere on the page
6446f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // instead on a per-layer basis. We therefore only update this information for the root
6456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    // scrolling layer.
6465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
647323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        bool haveHandlers = m_page->frameHost().eventHandlerRegistry().hasEventHandlers(EventHandlerRegistry::ScrollEvent);
6486f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        scrollLayer->setHaveScrollEventHandlers(haveHandlers);
6496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    }
65053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
65153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
65253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
65353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
6545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame())
6555d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return;
6565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
65751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_lastMainThreadScrollingReasons = reasons;
65853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        scrollLayer->setShouldScrollOnMainThread(reasons);
65951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
66053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
66153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochvoid ScrollingCoordinator::willBeDestroyed()
66353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
66453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_page);
66553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_page = 0;
6666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    for (ScrollbarMap::iterator it = m_horizontalScrollbars.begin(); it != m_horizontalScrollbars.end(); ++it)
6676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        GraphicsLayer::unregisterContentsLayer(it->value->layer());
6686f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    for (ScrollbarMap::iterator it = m_verticalScrollbars.begin(); it != m_verticalScrollbars.end(); ++it)
6696f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        GraphicsLayer::unregisterContentsLayer(it->value->layer());
67053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
67153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
67253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView) const
67353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
67453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(isMainThread());
67553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_page);
67653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
67753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // We currently only handle the main frame.
6788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (&frameView->frame() != m_page->mainFrame())
67953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
68053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
6815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame())
6825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return false;
6835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
68453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    // We currently only support composited mode.
6855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
68653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!renderView)
68753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
68853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return renderView->usesCompositing();
68953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
69053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
691d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame* frame, const IntPoint& frameLocation) const
69253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
69381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    Region shouldHandleScrollGestureOnMainThreadRegion;
69453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    FrameView* frameView = frame->view();
69553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!frameView)
69681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        return shouldHandleScrollGestureOnMainThreadRegion;
69753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
69853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    IntPoint offset = frameLocation;
69953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    offset.moveBy(frameView->frameRect().location());
70053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
70153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) {
70253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
70353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            ScrollableArea* scrollableArea = *it;
70453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            // Composited scrollable areas can be scrolled off the main thread.
70553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (scrollableArea->usesCompositedScrolling())
70653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                continue;
70753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            IntRect box = scrollableArea->scrollableAreaBoundingBox();
70853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            box.moveBy(offset);
70981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)            shouldHandleScrollGestureOnMainThreadRegion.unite(box);
71081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        }
71181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    }
71281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
71381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // We use GestureScrollBegin/Update/End for moving the resizer handle. So we mark these
71481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // small resizer areas as non-fast-scrollable to allow the scroll gestures to be passed to
71581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // main thread if they are targeting the resizer area. (Resizing is done in EventHandler.cpp
71681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    // on main thread).
71781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    if (const FrameView::ResizerAreaSet* resizerAreas = frameView->resizerAreas()) {
71881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)        for (FrameView::ResizerAreaSet::const_iterator it = resizerAreas->begin(), end = resizerAreas->end(); it != end; ++it) {
7191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            RenderBox* box = *it;
7201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            IntRect bounds = box->absoluteBoundingBoxRect();
7211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            IntRect corner = box->layer()->scrollableArea()->touchResizerCornerRect(bounds);
72281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)            corner.moveBy(offset);
72381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)            shouldHandleScrollGestureOnMainThreadRegion.unite(corner);
72453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
72553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
72653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
72753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (const HashSet<RefPtr<Widget> >* children = frameView->children()) {
72853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(), end = children->end(); it != end; ++it) {
72953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (!(*it)->isPluginView())
73053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                continue;
73153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
732d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            PluginView* pluginView = toPluginView(it->get());
73353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            if (pluginView->wantsWheelEvents())
73481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)                shouldHandleScrollGestureOnMainThreadRegion.unite(pluginView->frameRect());
73553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
73653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
73753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
738f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    const FrameTree& tree = frame->tree();
739f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (Frame* subFrame = tree.firstChild(); subFrame; subFrame = subFrame->tree().nextSibling()) {
740f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (subFrame->isLocalFrame())
741f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            shouldHandleScrollGestureOnMainThreadRegion.unite(computeShouldHandleScrollGestureOnMainThreadRegion(toLocalFrame(subFrame), offset));
742f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
74353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
74481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)    return shouldHandleScrollGestureOnMainThreadRegion;
74553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
74653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static void accumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects, const Document* document)
74853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
74953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(document);
750e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    const EventTargetSet* targets = document->frameHost()->eventHandlerRegistry().eventHandlerTargets(EventHandlerRegistry::TouchEvent);
751e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (!targets)
75253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
75353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
754e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // If there's a handler on the window, document, html or body element (fairly common in practice),
7557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    // then we can quickly mark the entire document and skip looking at any other handlers.
7567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    // Note that technically a handler on the body doesn't cover the whole document, but it's
7577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    // reasonable to be conservative and report the whole document anyway.
7585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    //
7595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // Fullscreen HTML5 video when OverlayFullscreenVideo is enabled is implemented by replacing the
7605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // root cc::layer with the video layer so doing this optimization causes the compositor to think
7615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // that there are no handlers, therefore skip it.
7625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!document->renderView()->compositor()->inOverlayFullscreenVideo()) {
763e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
764e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            EventTarget* target = iter->key;
765e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            Node* node = target->toNode();
766e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            if (target->toDOMWindow() || node == document || node == document->documentElement() || node == document->body()) {
7675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                if (RenderView* rendererView = document->renderView()) {
7685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                    rendererView->computeLayerHitTestRects(rects);
7695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                }
7705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                return;
77153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            }
77253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        }
7737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    }
77453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
775e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
776e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        EventTarget* target = iter->key;
777e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        Node* node = target->toNode();
778e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (!node || !node->inDocument())
77953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            continue;
78053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
7817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // If the document belongs to an invisible subframe it does not have a composited layer
7827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // and should be skipped.
7837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (node->document().isInInvisibleSubframe())
7847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            continue;
7857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
786e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (node->isDocumentNode() && node != document) {
787e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            accumulateDocumentTouchEventTargetRects(rects, toDocument(node));
788e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        } else if (RenderObject* renderer = node->renderer()) {
7893c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            // If the set also contains one of our ancestor nodes then processing
7903c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            // this node would be redundant.
7913c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            bool hasTouchEventTargetAncestor = false;
792e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            for (Node* ancestor = node->parentNode(); ancestor && !hasTouchEventTargetAncestor; ancestor = ancestor->parentNode()) {
7933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                if (targets->contains(ancestor))
7943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                    hasTouchEventTargetAncestor = true;
7953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            }
79609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!hasTouchEventTargetAncestor) {
79709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // Walk up the tree to the outermost non-composited scrollable layer.
79809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                RenderLayer* enclosingNonCompositedScrollLayer = 0;
79909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                for (RenderLayer* parent = renderer->enclosingLayer(); parent && parent->compositingState() == NotComposited; parent = parent->parent()) {
80009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    if (parent->scrollsOverflow())
80109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        enclosingNonCompositedScrollLayer = parent;
80209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                }
80309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
80409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // Report the whole non-composited scroll layer as a touch hit rect because any
80509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // rects inside of it may move around relative to their enclosing composited layer
80609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // without causing the rects to be recomputed. Non-composited scrolling occurs on
80709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // the main thread, so we're not getting much benefit from compositor touch hit
80809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                // testing in this case anyway.
80909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (enclosingNonCompositedScrollLayer)
81009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    enclosingNonCompositedScrollLayer->computeSelfHitTestRects(rects);
81109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8123c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                renderer->computeLayerHitTestRects(rects);
81309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
8147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        }
81553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
81653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
81753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochvoid ScrollingCoordinator::computeTouchEventTargetRects(LayerHitTestRects& rects)
81953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
8207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    TRACE_EVENT0("input", "ScrollingCoordinator::computeTouchEventTargetRects");
821c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    ASSERT(RuntimeEnabledFeatures::touchEnabled());
8227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
8235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Document* document = m_page->deprecatedLocalMainFrame()->document();
8247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if (!document || !document->view())
82553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
82653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    accumulateDocumentTouchEventTargetRects(rects, document);
82853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
82953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
83053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* frameView)
83153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
83253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(isMainThread());
83353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_page);
83453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
83553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!coordinatesScrollingForFrameView(frameView))
83653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
83753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
83809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_shouldScrollOnMainThreadDirty = true;
83953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
84053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
84153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView)
84253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
84353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(isMainThread());
84453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_page);
84553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
84653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!coordinatesScrollingForFrameView(frameView))
84753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
84853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
84909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_shouldScrollOnMainThreadDirty = true;
85053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
85153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
852e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool ScrollingCoordinator::isForMainFrame(ScrollableArea* scrollableArea) const
853e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
8545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return m_page->mainFrame()->isLocalFrame() ? scrollableArea == m_page->deprecatedLocalMainFrame()->view() : false;
855e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
856e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
85753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView* frameView)
85853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
85953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(isMainThread());
86053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(m_page);
86153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
86253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!coordinatesScrollingForFrameView(frameView))
86353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
86453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
86519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    notifyLayoutUpdated();
8666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    updateHaveWheelEventHandlers();
8676f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    updateHaveScrollEventHandlers();
86853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
86953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(MACOSX)
87153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void ScrollingCoordinator::handleWheelEventPhase(PlatformWheelEventPhase phase)
87253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
87353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    ASSERT(isMainThread());
87453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
87553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!m_page)
87653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
87753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
87953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!frameView)
88053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
88153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
88253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    frameView->scrollAnimator()->handleWheelEventPhase(phase);
88353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
88453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#endif
88553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
88653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(FrameView* frameView) const
88753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
88853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects();
88953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!viewportConstrainedObjects)
89053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
89153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
89253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) {
893e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        RenderObject* renderer = *it;
894e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ASSERT(renderer->isBoxModelObject() && renderer->hasLayer());
895e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        ASSERT(renderer->style()->position() == FixedPosition);
896e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
897e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
898e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // Whether the RenderLayer scrolls with the viewport is a tree-depenent
899e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // property and our viewportConstrainedObjects collection is maintained
900e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // with only RenderObject-level information.
901e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (!layer->scrollsWithViewport())
902e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            continue;
9039bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
9049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // If the whole subtree is invisible, there's no reason to scroll on
9059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // the main thread because we don't need to generate invalidations
9069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // for invisible content.
9079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (layer->subtreeIsInvisible())
9089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            continue;
9099e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
910e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // We're only smart enough to scroll viewport-constrainted objects
911e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // in the compositor if they have their own backing or they paint
912e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // into a grouped back (which necessarily all have the same viewport
913e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        // constraints).
914e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        CompositingState compositingState = layer->compositingState();
915e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if (compositingState != PaintsIntoOwnBacking && compositingState != PaintsIntoGroupedBacking)
9169bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            return true;
91753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
91853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return false;
91953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
92053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
92153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() const
92253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9239e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    MainThreadScrollingReasons reasons = static_cast<MainThreadScrollingReasons>(0);
9249e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
9257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_page->settings().threadedScrollingEnabled())
9267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        reasons |= ThreadedScrollingDisabled;
9277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
9285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!m_page->mainFrame()->isLocalFrame())
9299e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return reasons;
9305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
93109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!frameView)
9329e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return reasons;
93353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
93453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (frameView->hasSlowRepaintObjects())
9359e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        reasons |= HasSlowRepaintObjects;
936a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    FrameView::ScrollingReasons scrollingReasons = frameView->scrollingReasons();
937a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    const bool mayBeScrolledByInput = (scrollingReasons == FrameView::Scrollable);
938a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    const bool mayBeScrolledByScript = mayBeScrolledByInput || (scrollingReasons ==
939a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch        FrameView::NotScrollableExplicitlyDisabled);
940a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch
941a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    // TODO(awoloszyn) Currently crbug.com/304810 will let certain
942a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    // overflow:hidden elements scroll on the compositor thread, so we should
943a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    // not let this move there path as an optimization, when we have slow-repaint
944a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    // elements.
945a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    if (mayBeScrolledByScript && hasVisibleSlowRepaintViewportConstrainedObjects(frameView)) {
9469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        reasons |= HasNonLayerViewportConstrainedObjects;
947a372c30a9dc26aa32e51fa7b85e0c47b55479f89Ben Murdoch    }
94853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
9499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return reasons;
95053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
95153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
95253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)String ScrollingCoordinator::mainThreadScrollingReasonsAsText(MainThreadScrollingReasons reasons)
95353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
95453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    StringBuilder stringBuilder;
95553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
95653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (reasons & ScrollingCoordinator::HasSlowRepaintObjects)
9579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        stringBuilder.appendLiteral("Has slow repaint objects, ");
95853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (reasons & ScrollingCoordinator::HasViewportConstrainedObjectsWithoutSupportingFixedLayers)
9599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        stringBuilder.appendLiteral("Has viewport constrained objects without supporting fixed layers, ");
96053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (reasons & ScrollingCoordinator::HasNonLayerViewportConstrainedObjects)
9619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        stringBuilder.appendLiteral("Has non-layer viewport-constrained objects, ");
9627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (reasons & ScrollingCoordinator::ThreadedScrollingDisabled)
9637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        stringBuilder.appendLiteral("Threaded scrolling is disabled, ");
96453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
96553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (stringBuilder.length())
96653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        stringBuilder.resize(stringBuilder.length() - 2);
96753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return stringBuilder.toString();
96853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
96953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
97053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)String ScrollingCoordinator::mainThreadScrollingReasonsAsText() const
97153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
9725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(m_page->deprecatedLocalMainFrame()->document()->lifecycle().state() >= DocumentLifecycle::CompositingClean);
97351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return mainThreadScrollingReasonsAsText(m_lastMainThreadScrollingReasons);
97451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
97551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
97609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool ScrollingCoordinator::frameViewIsDirty() const
97751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
9785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    FrameView* frameView = m_page->mainFrame()->isLocalFrame() ? m_page->deprecatedLocalMainFrame()->view() : 0;
97951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool frameIsScrollable = frameView && frameView->isScrollable();
98009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (frameIsScrollable != m_wasFrameScrollable)
98109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return true;
98209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
983d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (WebLayer* scrollLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0)
98409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return blink::WebSize(frameView->contentsSize()) != scrollLayer->bounds();
98509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return false;
98653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
98753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
988c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
989