1db7594047c88cab0ddafe0037a3be6cac386886
[WebKit-https.git] / Source / WebCore / page / scrolling / chromium / ScrollingCoordinatorChromium.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include "ScrollingCoordinator.h"
29
30 #include "Frame.h"
31 #include "FrameView.h"
32 #include "Region.h"
33 #include "RenderLayerCompositor.h"
34 #include "RenderView.h"
35 #include "ScrollbarThemeComposite.h"
36 #include "WebScrollbarThemeGeometryNative.h"
37 #include <public/WebScrollableLayer.h>
38 #include <public/WebScrollbar.h>
39 #include <public/WebScrollbarLayer.h>
40 #include <public/WebScrollbarThemeGeometry.h>
41 #include <public/WebScrollbarThemePainter.h>
42
43 using WebKit::WebLayer;
44 using WebKit::WebRect;
45 using WebKit::WebScrollableLayer;
46 using WebKit::WebScrollbarLayer;
47 using WebKit::WebVector;
48
49 namespace WebCore {
50
51 class ScrollingCoordinatorPrivate {
52 WTF_MAKE_NONCOPYABLE(ScrollingCoordinatorPrivate);
53 public:
54     ScrollingCoordinatorPrivate() { }
55     ~ScrollingCoordinatorPrivate() { }
56
57     void setScrollLayer(WebScrollableLayer layer)
58     {
59         m_scrollLayer = layer;
60
61         if (!m_horizontalScrollbarLayer.isNull())
62             m_horizontalScrollbarLayer.setScrollLayer(layer);
63         if (!m_verticalScrollbarLayer.isNull())
64             m_verticalScrollbarLayer.setScrollLayer(layer);
65     }
66
67     void setHorizontalScrollbarLayer(WebScrollbarLayer layer)
68     {
69         m_horizontalScrollbarLayer = layer;
70     }
71
72     void setVerticalScrollbarLayer(WebScrollbarLayer layer)
73     {
74         m_verticalScrollbarLayer = layer;
75     }
76
77     bool hasScrollLayer() const { return !m_scrollLayer.isNull(); }
78     WebScrollableLayer scrollLayer() const { return m_scrollLayer; }
79
80 private:
81     WebScrollableLayer m_scrollLayer;
82     WebScrollbarLayer m_horizontalScrollbarLayer;
83     WebScrollbarLayer m_verticalScrollbarLayer;
84 };
85
86 PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
87 {
88     RefPtr<ScrollingCoordinator> coordinator(adoptRef(new ScrollingCoordinator(page)));
89     coordinator->m_private = new ScrollingCoordinatorPrivate;
90     return coordinator.release();
91 }
92
93 ScrollingCoordinator::~ScrollingCoordinator()
94 {
95     ASSERT(!m_page);
96     delete m_private;
97 }
98
99 static GraphicsLayer* scrollLayerForFrameView(FrameView* frameView)
100 {
101 #if USE(ACCELERATED_COMPOSITING)
102     Frame* frame = frameView->frame();
103     if (!frame)
104         return 0;
105
106     RenderView* renderView = frame->contentRenderer();
107     if (!renderView)
108         return 0;
109     return renderView->compositor()->scrollLayer();
110 #else
111     return 0;
112 #endif
113 }
114
115 static WebScrollbarLayer createScrollbarLayer(Scrollbar* scrollbar, WebScrollableLayer scrollLayer, GraphicsLayer* scrollbarGraphicsLayer, FrameView* frameView)
116 {
117     ASSERT(scrollbar);
118     ASSERT(scrollbarGraphicsLayer);
119
120     if (scrollLayer.isNull()) {
121         // FIXME: sometimes we get called before setScrollLayer, workaround by finding the scroll layout ourselves.
122         scrollLayer = scrollLayerForFrameView(frameView)->platformLayer()->to<WebScrollableLayer>();
123         ASSERT(!scrollLayer.isNull());
124     }
125
126     // Root layer non-overlay scrollbars should be marked opaque to disable
127     // blending.
128     bool isOpaqueRootScrollbar = !frameView->parent() && !scrollbar->isOverlayScrollbar();
129     if (!scrollbarGraphicsLayer->contentsOpaque())
130         scrollbarGraphicsLayer->setContentsOpaque(isOpaqueRootScrollbar);
131
132     // FIXME: Mac scrollbar themes are not thread-safe to paint.
133     bool platformSupported = true;
134 #if OS(DARWIN)
135     platformSupported = false;
136 #endif
137
138     if (!platformSupported || scrollbar->isCustomScrollbar()) {
139         scrollbarGraphicsLayer->setContentsToMedia(0);
140         scrollbarGraphicsLayer->setDrawsContent(true);
141         return WebScrollbarLayer();
142     }
143
144     // All Chromium scrollbar themes derive from ScrollbarThemeComposite.
145     ScrollbarThemeComposite* themeComposite = static_cast<ScrollbarThemeComposite*>(scrollbar->theme());
146     WebKit::WebScrollbarThemePainter painter(themeComposite, scrollbar);
147     OwnPtr<WebKit::WebScrollbarThemeGeometry> geometry(WebKit::WebScrollbarThemeGeometryNative::create(themeComposite));
148
149     WebScrollbarLayer scrollbarLayer = WebScrollbarLayer::create(scrollbar, painter, geometry.release());
150     scrollbarLayer.setScrollLayer(scrollLayer);
151
152     scrollbarGraphicsLayer->setContentsToMedia(&scrollbarLayer);
153     scrollbarGraphicsLayer->setDrawsContent(false);
154     scrollbarLayer.setOpaque(scrollbarGraphicsLayer->contentsOpaque());
155
156     return scrollbarLayer;
157 }
158
159 void ScrollingCoordinator::frameViewHorizontalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer* horizontalScrollbarLayer)
160 {
161     if (!horizontalScrollbarLayer || !coordinatesScrollingForFrameView(frameView))
162         return;
163
164     m_private->setHorizontalScrollbarLayer(createScrollbarLayer(frameView->horizontalScrollbar(), m_private->scrollLayer(), horizontalScrollbarLayer, frameView));
165 }
166
167 void ScrollingCoordinator::frameViewVerticalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer* verticalScrollbarLayer)
168 {
169     if (!verticalScrollbarLayer || !coordinatesScrollingForFrameView(frameView))
170         return;
171
172     m_private->setVerticalScrollbarLayer(createScrollbarLayer(frameView->verticalScrollbar(), m_private->scrollLayer(), verticalScrollbarLayer, frameView));
173 }
174
175 void ScrollingCoordinator::setScrollLayer(GraphicsLayer* scrollLayer)
176 {
177     WebScrollableLayer layer;
178     if (scrollLayer)
179         layer = scrollLayer->platformLayer()->to<WebScrollableLayer>();
180     m_private->setScrollLayer(layer);
181 }
182
183 void ScrollingCoordinator::setNonFastScrollableRegion(const Region& region)
184 {
185     if (m_private->hasScrollLayer()) {
186         Vector<IntRect> rects = region.rects();
187         WebVector<WebRect> webRects(rects.size());
188         for (size_t i = 0; i < rects.size(); ++i)
189             webRects[i] = rects[i];
190         m_private->scrollLayer().setNonFastScrollableRegion(webRects);
191     }
192 }
193
194 void ScrollingCoordinator::setScrollParameters(const ScrollParameters&)
195 {
196     // FIXME: Implement!
197 }
198
199 void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
200 {
201     if (m_private->hasScrollLayer())
202         m_private->scrollLayer().setHaveWheelEventHandlers(wheelEventHandlerCount > 0);
203 }
204
205 void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool should)
206 {
207     if (m_private->hasScrollLayer())
208         m_private->scrollLayer().setShouldScrollOnMainThread(should);
209 }
210
211 bool ScrollingCoordinator::supportsFixedPositionLayers() const
212 {
213     return true;
214 }
215
216 void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable)
217 {
218     if (WebLayer* platformLayer = layer->platformLayer())
219         platformLayer->to<WebScrollableLayer>().setIsContainerForFixedPositionLayers(enable);
220 }
221
222 void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer* layer, bool enable)
223 {
224     if (WebLayer* platformLayer = layer->platformLayer())
225         platformLayer->to<WebScrollableLayer>().setFixedToContainerLayer(enable);
226 }
227
228 }