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
LayerTreeHostCA(WebPage * webPage)43 LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage)
44 : LayerTreeHost(webPage)
45 , m_isValid(true)
46 , m_notifyAfterScheduledLayerFlush(false)
47 {
48 }
49
initialize()50 void LayerTreeHostCA::initialize()
51 {
52 // Create a root layer.
53 m_rootLayer = GraphicsLayer::create(this);
54 #ifndef NDEBUG
55 m_rootLayer->setName("LayerTreeHost root layer");
56 #endif
57 m_rootLayer->setDrawsContent(false);
58 m_rootLayer->setSize(m_webPage->size());
59 static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true);
60
61 m_nonCompositedContentLayer = GraphicsLayer::create(this);
62 static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false);
63 #ifndef NDEBUG
64 m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content");
65 #endif
66 m_nonCompositedContentLayer->setDrawsContent(true);
67 m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground());
68 m_nonCompositedContentLayer->setSize(m_webPage->size());
69 if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled())
70 m_nonCompositedContentLayer->setAcceleratesDrawing(true);
71
72 m_rootLayer->addChild(m_nonCompositedContentLayer.get());
73
74 if (m_webPage->hasPageOverlay())
75 createPageOverlayLayer();
76
77 platformInitialize(m_layerTreeContext);
78
79 scheduleLayerFlush();
80 }
81
~LayerTreeHostCA()82 LayerTreeHostCA::~LayerTreeHostCA()
83 {
84 ASSERT(!m_isValid);
85 ASSERT(!m_rootLayer);
86 }
87
layerTreeContext()88 const LayerTreeContext& LayerTreeHostCA::layerTreeContext()
89 {
90 return m_layerTreeContext;
91 }
92
setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)93 void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush)
94 {
95 m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush;
96 }
97
setRootCompositingLayer(GraphicsLayer * graphicsLayer)98 void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
99 {
100 m_nonCompositedContentLayer->removeAllChildren();
101
102 // Add the accelerated layer tree hierarchy.
103 if (graphicsLayer)
104 m_nonCompositedContentLayer->addChild(graphicsLayer);
105 }
106
invalidate()107 void LayerTreeHostCA::invalidate()
108 {
109 ASSERT(m_isValid);
110 m_rootLayer = nullptr;
111 m_isValid = false;
112 }
113
setNonCompositedContentsNeedDisplay(const IntRect & rect)114 void LayerTreeHostCA::setNonCompositedContentsNeedDisplay(const IntRect& rect)
115 {
116 m_nonCompositedContentLayer->setNeedsDisplayInRect(rect);
117 if (m_pageOverlayLayer)
118 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
119
120 scheduleLayerFlush();
121 }
122
scrollNonCompositedContents(const IntRect & scrollRect,const IntSize & scrollOffset)123 void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset)
124 {
125 setNonCompositedContentsNeedDisplay(scrollRect);
126 }
127
sizeDidChange(const IntSize & newSize)128 void LayerTreeHostCA::sizeDidChange(const IntSize& newSize)
129 {
130 m_rootLayer->setSize(newSize);
131 m_nonCompositedContentLayer->setSize(newSize);
132
133 if (m_pageOverlayLayer)
134 m_pageOverlayLayer->setSize(newSize);
135
136 scheduleLayerFlush();
137 flushPendingLayerChanges();
138 }
139
forceRepaint()140 void LayerTreeHostCA::forceRepaint()
141 {
142 scheduleLayerFlush();
143 flushPendingLayerChanges();
144 }
145
didInstallPageOverlay()146 void LayerTreeHostCA::didInstallPageOverlay()
147 {
148 createPageOverlayLayer();
149 scheduleLayerFlush();
150 }
151
didUninstallPageOverlay()152 void LayerTreeHostCA::didUninstallPageOverlay()
153 {
154 destroyPageOverlayLayer();
155 scheduleLayerFlush();
156 }
157
setPageOverlayNeedsDisplay(const IntRect & rect)158 void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect)
159 {
160 ASSERT(m_pageOverlayLayer);
161 m_pageOverlayLayer->setNeedsDisplayInRect(rect);
162 scheduleLayerFlush();
163 }
164
notifyAnimationStarted(const WebCore::GraphicsLayer *,double time)165 void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
166 {
167 }
168
notifySyncRequired(const WebCore::GraphicsLayer *)169 void LayerTreeHostCA::notifySyncRequired(const WebCore::GraphicsLayer*)
170 {
171 }
172
paintContents(const GraphicsLayer * graphicsLayer,GraphicsContext & graphicsContext,GraphicsLayerPaintingPhase,const IntRect & clipRect)173 void LayerTreeHostCA::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect)
174 {
175 if (graphicsLayer == m_nonCompositedContentLayer) {
176 m_webPage->drawRect(graphicsContext, clipRect);
177 return;
178 }
179
180 if (graphicsLayer == m_pageOverlayLayer) {
181 m_webPage->drawPageOverlay(graphicsContext, clipRect);
182 return;
183 }
184 }
185
showDebugBorders() const186 bool LayerTreeHostCA::showDebugBorders() const
187 {
188 return m_webPage->corePage()->settings()->showDebugBorders();
189 }
190
showRepaintCounter() const191 bool LayerTreeHostCA::showRepaintCounter() const
192 {
193 return m_webPage->corePage()->settings()->showRepaintCounter();
194 }
195
performScheduledLayerFlush()196 void LayerTreeHostCA::performScheduledLayerFlush()
197 {
198 {
199 RefPtr<LayerTreeHostCA> protect(this);
200 m_webPage->layoutIfNeeded();
201
202 if (!m_isValid)
203 return;
204 }
205
206 if (!flushPendingLayerChanges())
207 return;
208
209 didPerformScheduledLayerFlush();
210 }
211
didPerformScheduledLayerFlush()212 void LayerTreeHostCA::didPerformScheduledLayerFlush()
213 {
214 if (m_notifyAfterScheduledLayerFlush) {
215 // Let the drawing area know that we've done a flush of the layer changes.
216 static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers();
217 m_notifyAfterScheduledLayerFlush = false;
218 }
219 }
220
flushPendingLayerChanges()221 bool LayerTreeHostCA::flushPendingLayerChanges()
222 {
223 m_rootLayer->syncCompositingStateForThisLayerOnly();
224 m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly();
225 if (m_pageOverlayLayer)
226 m_pageOverlayLayer->syncCompositingStateForThisLayerOnly();
227
228 return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes();
229 }
230
createPageOverlayLayer()231 void LayerTreeHostCA::createPageOverlayLayer()
232 {
233 ASSERT(!m_pageOverlayLayer);
234
235 m_pageOverlayLayer = GraphicsLayer::create(this);
236 #ifndef NDEBUG
237 m_pageOverlayLayer->setName("LayerTreeHost page overlay content");
238 #endif
239
240 m_pageOverlayLayer->setDrawsContent(true);
241 m_pageOverlayLayer->setSize(m_webPage->size());
242
243 m_rootLayer->addChild(m_pageOverlayLayer.get());
244 }
245
destroyPageOverlayLayer()246 void LayerTreeHostCA::destroyPageOverlayLayer()
247 {
248 ASSERT(m_pageOverlayLayer);
249 m_pageOverlayLayer->removeFromParent();
250 m_pageOverlayLayer = nullptr;
251 }
252
253 } // namespace WebKit
254