[chromium] Change WebLayer from a concrete type to a pure virtual interface
[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 "Page.h"
33 #include "Region.h"
34 #include "RenderLayerCompositor.h"
35 #include "RenderView.h"
36 #include "ScrollbarThemeComposite.h"
37 #include "WebScrollbarThemeGeometryNative.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::WebScrollbarLayer;
46 using WebKit::WebVector;
47
48 namespace WebCore {
49
50 class ScrollingCoordinatorPrivate {
51 WTF_MAKE_NONCOPYABLE(ScrollingCoordinatorPrivate);
52 public:
53     ScrollingCoordinatorPrivate()
54         : m_scrollLayer(0)
55     {
56     }
57
58     ~ScrollingCoordinatorPrivate() { }
59
60     void setScrollLayer(WebLayer* layer)
61     {
62         m_scrollLayer = layer;
63
64         if (m_horizontalScrollbarLayer)
65             m_horizontalScrollbarLayer->setScrollLayer(layer);
66         if (m_verticalScrollbarLayer)
67             m_verticalScrollbarLayer->setScrollLayer(layer);
68     }
69
70     void setHorizontalScrollbarLayer(PassOwnPtr<WebScrollbarLayer> layer)
71     {
72         m_horizontalScrollbarLayer = layer;
73     }
74
75     void setVerticalScrollbarLayer(PassOwnPtr<WebScrollbarLayer> layer)
76     {
77         m_verticalScrollbarLayer = layer;
78     }
79
80     WebLayer* scrollLayer() const { return m_scrollLayer; }
81
82 private:
83     WebLayer* m_scrollLayer;
84     OwnPtr<WebScrollbarLayer> m_horizontalScrollbarLayer;
85     OwnPtr<WebScrollbarLayer> m_verticalScrollbarLayer;
86 };
87
88 PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
89 {
90     RefPtr<ScrollingCoordinator> coordinator(adoptRef(new ScrollingCoordinator(page)));
91     coordinator->m_private = new ScrollingCoordinatorPrivate;
92     return coordinator.release();
93 }
94
95 ScrollingCoordinator::~ScrollingCoordinator()
96 {
97     ASSERT(!m_page);
98     delete m_private;
99 }
100
101 static GraphicsLayer* scrollLayerForFrameView(FrameView* frameView)
102 {
103 #if USE(ACCELERATED_COMPOSITING)
104     Frame* frame = frameView->frame();
105     if (!frame)
106         return 0;
107
108     RenderView* renderView = frame->contentRenderer();
109     if (!renderView)
110         return 0;
111     return renderView->compositor()->scrollLayer();
112 #else
113     return 0;
114 #endif
115 }
116
117 static WebLayer* scrollableLayerForGraphicsLayer(GraphicsLayer* layer)
118 {
119     return layer->platformLayer();
120 }
121
122 static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar, WebLayer* scrollLayer, GraphicsLayer* scrollbarGraphicsLayer, FrameView* frameView)
123 {
124     ASSERT(scrollbar);
125     ASSERT(scrollbarGraphicsLayer);
126
127     if (!scrollLayer) {
128         // FIXME: sometimes we get called before setScrollLayer, workaround by finding the scroll layout ourselves.
129         scrollLayer = scrollableLayerForGraphicsLayer(scrollLayerForFrameView(frameView));
130         ASSERT(scrollLayer);
131     }
132
133     // Root layer non-overlay scrollbars should be marked opaque to disable
134     // blending.
135     bool isOpaqueRootScrollbar = !frameView->parent() && !scrollbar->isOverlayScrollbar();
136     if (!scrollbarGraphicsLayer->contentsOpaque())
137         scrollbarGraphicsLayer->setContentsOpaque(isOpaqueRootScrollbar);
138
139     // FIXME: Mac scrollbar themes are not thread-safe to paint.
140     bool platformSupported = true;
141 #if OS(DARWIN)
142     platformSupported = false;
143 #endif
144
145     if (!platformSupported || scrollbar->isCustomScrollbar()) {
146         scrollbarGraphicsLayer->setContentsToMedia(0);
147         scrollbarGraphicsLayer->setDrawsContent(true);
148         return nullptr;
149     }
150
151     // All Chromium scrollbar themes derive from ScrollbarThemeComposite.
152     ScrollbarThemeComposite* themeComposite = static_cast<ScrollbarThemeComposite*>(scrollbar->theme());
153     WebKit::WebScrollbarThemePainter painter(themeComposite, scrollbar);
154     OwnPtr<WebKit::WebScrollbarThemeGeometry> geometry(WebKit::WebScrollbarThemeGeometryNative::create(themeComposite));
155
156     OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(WebScrollbarLayer::create(scrollbar, painter, geometry.release()));
157     scrollbarLayer->setScrollLayer(scrollLayer);
158
159     scrollbarGraphicsLayer->setContentsToMedia(scrollbarLayer->layer());
160     scrollbarGraphicsLayer->setDrawsContent(false);
161     scrollbarLayer->layer()->setOpaque(scrollbarGraphicsLayer->contentsOpaque());
162
163     return scrollbarLayer.release();
164 }
165
166 void ScrollingCoordinator::frameViewHorizontalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer* horizontalScrollbarLayer)
167 {
168     if (!horizontalScrollbarLayer || !coordinatesScrollingForFrameView(frameView))
169         return;
170
171     setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
172     m_private->setHorizontalScrollbarLayer(createScrollbarLayer(frameView->horizontalScrollbar(), m_private->scrollLayer(), horizontalScrollbarLayer, frameView));
173 }
174
175 void ScrollingCoordinator::frameViewVerticalScrollbarLayerDidChange(FrameView* frameView, GraphicsLayer* verticalScrollbarLayer)
176 {
177     if (!verticalScrollbarLayer || !coordinatesScrollingForFrameView(frameView))
178         return;
179
180     setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
181     m_private->setVerticalScrollbarLayer(createScrollbarLayer(frameView->verticalScrollbar(), m_private->scrollLayer(), verticalScrollbarLayer, frameView));
182 }
183
184 void ScrollingCoordinator::setScrollLayer(GraphicsLayer* scrollLayer)
185 {
186     m_private->setScrollLayer(scrollLayer ? scrollableLayerForGraphicsLayer(scrollLayer) : 0);
187 }
188
189 void ScrollingCoordinator::setNonFastScrollableRegion(const Region& region)
190 {
191     // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
192     setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
193     if (m_private->scrollLayer()) {
194         Vector<IntRect> rects = region.rects();
195         WebVector<WebRect> webRects(rects.size());
196         for (size_t i = 0; i < rects.size(); ++i)
197             webRects[i] = rects[i];
198         m_private->scrollLayer()->setNonFastScrollableRegion(webRects);
199     }
200 }
201
202 void ScrollingCoordinator::setScrollParameters(const ScrollParameters&)
203 {
204     // FIXME: Implement!
205 }
206
207 void ScrollingCoordinator::setWheelEventHandlerCount(unsigned wheelEventHandlerCount)
208 {
209     // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
210     setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
211     if (m_private->scrollLayer())
212         m_private->scrollLayer()->setHaveWheelEventHandlers(wheelEventHandlerCount > 0);
213 }
214
215 void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(bool should)
216 {
217     // We won't necessarily get a setScrollLayer() call before this one, so grab the root ourselves.
218     setScrollLayer(scrollLayerForFrameView(m_page->mainFrame()->view()));
219     if (m_private->scrollLayer())
220         m_private->scrollLayer()->setShouldScrollOnMainThread(should);
221 }
222
223 bool ScrollingCoordinator::supportsFixedPositionLayers() const
224 {
225     return true;
226 }
227
228 void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable)
229 {
230     if (WebLayer* scrollableLayer = scrollableLayerForGraphicsLayer(layer))
231         scrollableLayer->setIsContainerForFixedPositionLayers(enable);
232 }
233
234 void ScrollingCoordinator::setLayerIsFixedToContainerLayer(GraphicsLayer* layer, bool enable)
235 {
236     if (WebLayer* scrollableLayer = scrollableLayerForGraphicsLayer(layer))
237         scrollableLayer->setFixedToContainerLayer(enable);
238 }
239
240 }