Final part of "sync" to "flush" renaming
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / ca / LayerTreeHostCA.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "LayerTreeHostCA.h"
28
29 #include "DrawingAreaImpl.h"
30 #include "WebPage.h"
31 #include "WebProcess.h"
32 #include <WebCore/Frame.h>
33 #include <WebCore/FrameView.h>
34 #include <WebCore/GraphicsLayerCA.h>
35 #include <WebCore/Page.h>
36 #include <WebCore/PlatformCALayer.h>
37 #include <WebCore/Settings.h>
38
39 using namespace WebCore;
40
41 namespace WebKit {
42
43 LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage)
44     : LayerTreeHost(webPage)
45     , m_layerFlushSchedulingEnabled(true)
46     , m_isValid(true)
47     , m_notifyAfterScheduledLayerFlush(false)
48 {
49 }
50
51 void LayerTreeHostCA::initialize()
52 {
53     // Create a root layer.
54     m_rootLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
55 #ifndef NDEBUG
56     m_rootLayer->setName("LayerTreeHost root layer");
57 #endif
58     m_rootLayer->setDrawsContent(false);
59     m_rootLayer->setSize(m_webPage->size());
60     static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true);
61
62     m_nonCompositedContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
63     static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false);
64 #ifndef NDEBUG
65     m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content");
66 #endif
67     m_nonCompositedContentLayer->setDrawsContent(true);
68     m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
69     m_nonCompositedContentLayer->setSize(m_webPage->size());
70     if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled())
71         m_nonCompositedContentLayer->setAcceleratesDrawing(true);
72
73     m_rootLayer->addChild(m_nonCompositedContentLayer.get());
74
75     if (m_webPage->hasPageOverlay())
76         createPageOverlayLayer();
77
78     platformInitialize();
79
80     setLayerFlushSchedulingEnabled(!m_webPage->drawingArea() || !m_webPage->drawingArea()->layerTreeStateIsFrozen());
81     scheduleLayerFlush();
82 }
83
84 LayerTreeHostCA::~LayerTreeHostCA()
85 {
86     ASSERT(!m_isValid);
87     ASSERT(!m_rootLayer);
88 }
89
90 const LayerTreeContext& LayerTreeHostCA::layerTreeContext()
91 {
92     return m_layerTreeContext;
93 }
94
95 void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
96 {
97     m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
98 }
99
100 void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
101 {
102     m_nonCompositedContentLayer->removeAllChildren();
103
104     // Add the accelerated layer tree hierarchy.
105     if (graphicsLayer)
106         m_nonCompositedContentLayer->addChild(graphicsLayer);
107 }
108
109 void LayerTreeHostCA::invalidate()
110 {
111     ASSERT(m_isValid);
112     m_rootLayer = nullptr;
113     m_isValid = false;
114 }
115
116 void LayerTreeHostCA::setNonCompositedContentsNeedDisplay(const IntRect& rect)
117 {
118     m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
119     if (m_pageOverlayLayer)
120         m_pageOverlayLayer->setNeedsDisplayInRect(rect);
121
122     scheduleLayerFlush();
123 }
124
125 void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset)
126 {
127     setNonCompositedContentsNeedDisplay(scrollRect);
128 }
129
130 void LayerTreeHostCA::sizeDidChange(const IntSize& newSize)
131 {
132     m_rootLayer->setSize(newSize);
133
134     // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed
135     // for those newly exposed areas.
136     FloatSize oldSize = m_nonCompositedContentLayer->size();
137     m_nonCompositedContentLayer->setSize(newSize);
138
139     if (newSize.width() > oldSize.width()) {
140         float height = std::min(static_cast<float>(newSize.height()), oldSize.height());
141         m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height));
142     }
143
144     if (newSize.height() > oldSize.height())
145         m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height()));
146
147     if (m_pageOverlayLayer)
148         m_pageOverlayLayer->setSize(newSize);
149
150     scheduleLayerFlush();
151     flushPendingLayerChanges();
152 }
153
154 void LayerTreeHostCA::deviceScaleFactorDidChange()
155 {
156     // Other layers learn of the scale factor change via WebPage::setDeviceScaleFactor.
157     m_nonCompositedContentLayer->deviceOrPageScaleFactorChanged();
158 }
159
160 void LayerTreeHostCA::forceRepaint()
161 {
162     scheduleLayerFlush();
163     flushPendingLayerChanges();
164 }    
165
166 void LayerTreeHostCA::didInstallPageOverlay()
167 {
168     createPageOverlayLayer();
169     scheduleLayerFlush();
170 }
171
172 void LayerTreeHostCA::didUninstallPageOverlay()
173 {
174     destroyPageOverlayLayer();
175     scheduleLayerFlush();
176 }
177
178 void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect)
179 {
180     ASSERT(m_pageOverlayLayer);
181     m_pageOverlayLayer->setNeedsDisplayInRect(rect);
182     scheduleLayerFlush();
183 }
184
185 void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
186 {
187 }
188
189 void LayerTreeHostCA::notifyFlushRequired(const WebCore::GraphicsLayer*)
190 {
191 }
192
193 void LayerTreeHostCA::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
194 {
195     if (graphicsLayer == m_nonCompositedContentLayer) {
196         m_webPage->drawRect(graphicsContext, clipRect);
197         return;
198     }
199
200     if (graphicsLayer == m_pageOverlayLayer) {
201         m_webPage->drawPageOverlay(graphicsContext, clipRect);
202         return;
203     }
204 }
205
206 bool LayerTreeHostCA::showDebugBorders(const GraphicsLayer*) const
207 {
208     return m_webPage->corePage()->settings()->showDebugBorders();
209 }
210
211 bool LayerTreeHostCA::showRepaintCounter(const GraphicsLayer*) const
212 {
213     return m_webPage->corePage()->settings()->showRepaintCounter();
214 }
215
216 float LayerTreeHostCA::deviceScaleFactor() const
217 {
218     return m_webPage->corePage()->deviceScaleFactor();
219 }
220
221 void LayerTreeHostCA::performScheduledLayerFlush()
222 {
223     {
224         RefPtr<LayerTreeHostCA> protect(this);
225         m_webPage->layoutIfNeeded();
226
227         if (!m_isValid)
228             return;
229     }
230
231     if (!flushPendingLayerChanges())
232         return;
233
234     didPerformScheduledLayerFlush();
235 }
236
237 void LayerTreeHostCA::didPerformScheduledLayerFlush()
238 {
239     if (m_notifyAfterScheduledLayerFlush) {
240         // Let the drawing area know that we've done a flush of the layer changes.
241         static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
242         m_notifyAfterScheduledLayerFlush = false;
243     }
244 }
245
246 bool LayerTreeHostCA::flushPendingLayerChanges()
247 {
248     m_rootLayer->flushCompositingStateForThisLayerOnly();
249     m_nonCompositedContentLayer->flushCompositingStateForThisLayerOnly();
250     if (m_pageOverlayLayer)
251         m_pageOverlayLayer->flushCompositingStateForThisLayerOnly();
252
253     return m_webPage->corePage()->mainFrame()->view()->flushCompositingStateIncludingSubframes();
254 }
255
256 void LayerTreeHostCA::createPageOverlayLayer()
257 {
258     ASSERT(!m_pageOverlayLayer);
259
260     m_pageOverlayLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
261 #ifndef NDEBUG
262     m_pageOverlayLayer->setName("LayerTreeHost page overlay content");
263 #endif
264
265     m_pageOverlayLayer->setDrawsContent(true);
266     m_pageOverlayLayer->setSize(m_webPage->size());
267
268     m_rootLayer->addChild(m_pageOverlayLayer.get());
269 }
270
271 void LayerTreeHostCA::destroyPageOverlayLayer()
272 {
273     ASSERT(m_pageOverlayLayer);
274     m_pageOverlayLayer->removeFromParent();
275     m_pageOverlayLayer = nullptr;
276 }
277
278 } // namespace WebKit