[chromium] Apply sent deltas on finishCommit
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / LayerChromium.cpp
1 /*
2  * Copyright (C) 2010 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 are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #if USE(ACCELERATED_COMPOSITING)
34 #include "LayerChromium.h"
35
36 #include "cc/CCLayerImpl.h"
37 #include "cc/CCLayerTreeHost.h"
38 #if USE(SKIA)
39 #include "NativeImageSkia.h"
40 #include "PlatformContextSkia.h"
41 #endif
42 #include "RenderLayerBacking.h"
43 #include "TextStream.h"
44 #include "skia/ext/platform_canvas.h"
45
46 namespace WebCore {
47
48 using namespace std;
49
50 static int s_nextLayerId = 1;
51
52 PassRefPtr<LayerChromium> LayerChromium::create(CCLayerDelegate* delegate)
53 {
54     return adoptRef(new LayerChromium(delegate));
55 }
56
57 LayerChromium::LayerChromium(CCLayerDelegate* delegate)
58     : m_delegate(delegate)
59     , m_needsDisplay(false)
60     , m_layerId(s_nextLayerId++)
61     , m_parent(0)
62     , m_scrollable(false)
63     , m_anchorPoint(0.5, 0.5)
64     , m_backgroundColor(0, 0, 0, 0)
65     , m_debugBorderWidth(0)
66     , m_opacity(1.0)
67     , m_anchorPointZ(0)
68     , m_masksToBounds(false)
69     , m_opaque(false)
70     , m_doubleSided(true)
71     , m_usesLayerClipping(false)
72     , m_isNonCompositedContent(false)
73     , m_preserves3D(false)
74     , m_replicaLayer(0)
75     , m_drawOpacity(0)
76     , m_targetRenderSurface(0)
77     , m_contentsScale(1.0)
78     , m_pageScaleDirty(false)
79 {
80 }
81
82 LayerChromium::~LayerChromium()
83 {
84     // Our parent should be holding a reference to us so there should be no
85     // way for us to be destroyed while we still have a parent.
86     ASSERT(!parent());
87
88     // Remove the parent reference from all children.
89     removeAllChildren();
90 }
91
92 void LayerChromium::cleanupResources()
93 {
94 }
95
96 void LayerChromium::cleanupResourcesRecursive()
97 {
98     for (size_t i = 0; i < children().size(); ++i)
99         children()[i]->cleanupResourcesRecursive();
100
101     if (maskLayer())
102         maskLayer()->cleanupResourcesRecursive();
103     if (replicaLayer())
104         replicaLayer()->cleanupResourcesRecursive();
105
106     cleanupResources();
107 }
108
109 void LayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
110 {
111     // If we're changing layer renderers then we need to free up any resources
112     // allocated by the old renderer.
113     if (layerTreeHost() && layerTreeHost() != host) {
114         cleanupResources();
115         setNeedsDisplay();
116     }
117
118     m_layerTreeHost = host;
119 }
120
121 void LayerChromium::setNeedsCommit()
122 {
123     // Call notifySyncRequired(), which for non-root layers plumbs through to
124     // call setRootLayerNeedsDisplay() on the WebView, which will cause LayerRendererChromium
125     // to render a frame.
126     // This function has no effect on root layers.
127     if (m_delegate)
128         m_delegate->notifySyncRequired();
129 }
130
131 void LayerChromium::setParent(LayerChromium* layer)
132 {
133     ASSERT(!layer || !layer->hasAncestor(this));
134     m_parent = layer;
135 }
136
137 bool LayerChromium::hasAncestor(LayerChromium* ancestor) const
138 {
139     for (LayerChromium* layer = parent(); layer; layer = layer->parent()) {
140         if (layer == ancestor)
141             return true;
142     }
143     return false;
144 }
145
146 void LayerChromium::addChild(PassRefPtr<LayerChromium> child)
147 {
148     insertChild(child, numChildren());
149 }
150
151 void LayerChromium::insertChild(PassRefPtr<LayerChromium> child, size_t index)
152 {
153     index = min(index, m_children.size());
154     child->removeFromParent();
155     child->setParent(this);
156     m_children.insert(index, child);
157     setNeedsCommit();
158 }
159
160 void LayerChromium::removeFromParent()
161 {
162     if (m_parent)
163         m_parent->removeChild(this);
164 }
165
166 void LayerChromium::removeChild(LayerChromium* child)
167 {
168     int foundIndex = indexOfChild(child);
169     if (foundIndex == -1)
170         return;
171
172     child->setParent(0);
173     m_children.remove(foundIndex);
174     setNeedsCommit();
175 }
176
177 void LayerChromium::replaceChild(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer)
178 {
179     ASSERT_ARG(reference, reference);
180     ASSERT_ARG(reference, reference->parent() == this);
181
182     if (reference == newLayer)
183         return;
184
185     int referenceIndex = indexOfChild(reference);
186     if (referenceIndex == -1) {
187         ASSERT_NOT_REACHED();
188         return;
189     }
190
191     reference->removeFromParent();
192
193     if (newLayer) {
194         newLayer->removeFromParent();
195         insertChild(newLayer, referenceIndex);
196     }
197 }
198
199 int LayerChromium::indexOfChild(const LayerChromium* reference)
200 {
201     for (size_t i = 0; i < m_children.size(); i++) {
202         if (m_children[i] == reference)
203             return i;
204     }
205     return -1;
206 }
207
208 void LayerChromium::setBounds(const IntSize& size)
209 {
210     if (bounds() == size)
211         return;
212
213     bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height();
214
215     m_bounds = size;
216
217     if (firstResize || m_pageScaleDirty)
218         setNeedsDisplay();
219     else
220         setNeedsCommit();
221
222     m_pageScaleDirty = false;
223 }
224
225 const LayerChromium* LayerChromium::rootLayer() const
226 {
227     const LayerChromium* layer = this;
228     for (LayerChromium* parent = layer->parent(); parent; layer = parent, parent = parent->parent()) { }
229     return layer;
230 }
231
232 void LayerChromium::removeAllChildren()
233 {
234     while (m_children.size()) {
235         LayerChromium* layer = m_children[0].get();
236         ASSERT(layer->parent());
237         layer->removeFromParent();
238     }
239 }
240
241 void LayerChromium::setChildren(const Vector<RefPtr<LayerChromium> >& children)
242 {
243     if (children == m_children)
244         return;
245
246     removeAllChildren();
247     size_t listSize = children.size();
248     for (size_t i = 0; i < listSize; i++)
249         addChild(children[i]);
250 }
251
252 LayerChromium* LayerChromium::parent() const
253 {
254     return m_parent;
255 }
256
257 void LayerChromium::setName(const String& name)
258 {
259     m_name = name;
260 }
261
262 void LayerChromium::setNeedsDisplayRect(const FloatRect& dirtyRect)
263 {
264     // Simply mark the contents as dirty. For non-root layers, the call to
265     // setNeedsCommit will schedule a fresh compositing pass.
266     // For the root layer, setNeedsCommit has no effect.
267     if (!dirtyRect.isEmpty())
268         m_needsDisplay = true;
269
270     setNeedsCommit();
271 }
272
273 void LayerChromium::pushPropertiesTo(CCLayerImpl* layer)
274 {
275     layer->setAnchorPoint(m_anchorPoint);
276     layer->setAnchorPointZ(m_anchorPointZ);
277     layer->setBackgroundColor(m_backgroundColor);
278     layer->setBounds(m_bounds);
279     layer->setContentBounds(contentBounds());
280     layer->setDebugBorderColor(m_debugBorderColor);
281     layer->setDebugBorderWidth(m_debugBorderWidth);
282     layer->setDoubleSided(m_doubleSided);
283     layer->setDrawsContent(drawsContent());
284     layer->setIsNonCompositedContent(m_isNonCompositedContent);
285     layer->setMasksToBounds(m_masksToBounds);
286     layer->setScrollable(m_scrollable);
287     layer->setName(m_name);
288     layer->setOpaque(m_opaque);
289     layer->setOpacity(m_opacity);
290     layer->setPosition(m_position);
291     layer->setPreserves3D(preserves3D());
292     layer->setScrollPosition(m_scrollPosition);
293     layer->setSublayerTransform(m_sublayerTransform);
294     layer->setTransform(m_transform);
295     layer->setUpdateRect(m_updateRect);
296
297     layer->setScrollDelta(layer->scrollDelta() - layer->sentScrollDelta());
298     layer->setSentScrollDelta(IntSize());
299
300     if (maskLayer())
301         maskLayer()->pushPropertiesTo(layer->maskLayer());
302     if (replicaLayer())
303         replicaLayer()->pushPropertiesTo(layer->replicaLayer());
304
305     // Reset any state that should be cleared for the next update.
306     m_updateRect = FloatRect();
307 }
308
309 PassRefPtr<CCLayerImpl> LayerChromium::createCCLayerImpl()
310 {
311     return CCLayerImpl::create(m_layerId);
312 }
313
314 void LayerChromium::setDebugBorderColor(const Color& color)
315 {
316     m_debugBorderColor = color;
317     setNeedsCommit();
318 }
319
320 void LayerChromium::setDebugBorderWidth(float width)
321 {
322     m_debugBorderWidth = width;
323     setNeedsCommit();
324 }
325
326 void LayerChromium::setContentsScale(float contentsScale)
327 {
328     if (!needsContentsScale())
329         return;
330     m_contentsScale = contentsScale;
331 }
332
333 void LayerChromium::createRenderSurface()
334 {
335     ASSERT(!m_renderSurface);
336     m_renderSurface = adoptPtr(new RenderSurfaceChromium(this));
337 }
338
339 bool LayerChromium::descendantDrawsContent()
340 {
341     for (size_t i = 0; i < m_children.size(); ++i) {
342         if (m_children[i]->drawsContent() || m_children[i]->descendantDrawsContent())
343             return true;
344     }
345     return false;
346 }
347
348 void sortLayers(Vector<RefPtr<LayerChromium> >::iterator, Vector<RefPtr<LayerChromium> >::iterator, void*)
349 {
350     // Currently we don't use z-order to decide what to paint, so there's no need to actually sort LayerChromiums.
351 }
352
353 }
354 #endif // USE(ACCELERATED_COMPOSITING)