tizen beta release
[profile/ivi/webkit-efl.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_layerId(s_nextLayerId++)
60     , m_parent(0)
61     , m_scrollable(false)
62     , m_anchorPoint(0.5, 0.5)
63     , m_backgroundColor(0, 0, 0, 0)
64     , m_debugBorderWidth(0)
65     , m_opacity(1.0)
66     , m_anchorPointZ(0)
67     , m_masksToBounds(false)
68     , m_opaque(false)
69     , m_doubleSided(true)
70     , m_usesLayerClipping(false)
71     , m_isNonCompositedContent(false)
72     , m_preserves3D(false)
73     , m_replicaLayer(0)
74     , m_drawOpacity(0)
75     , m_targetRenderSurface(0)
76     , m_contentsScale(1.0)
77     , m_pageScaleDirty(false)
78 {
79 }
80
81 LayerChromium::~LayerChromium()
82 {
83     // Our parent should be holding a reference to us so there should be no
84     // way for us to be destroyed while we still have a parent.
85     ASSERT(!parent());
86
87     // Remove the parent reference from all children.
88     removeAllChildren();
89 }
90
91 void LayerChromium::cleanupResources()
92 {
93 }
94
95 void LayerChromium::cleanupResourcesRecursive()
96 {
97     for (size_t i = 0; i < children().size(); ++i)
98         children()[i]->cleanupResourcesRecursive();
99
100     if (maskLayer())
101         maskLayer()->cleanupResourcesRecursive();
102     if (replicaLayer())
103         replicaLayer()->cleanupResourcesRecursive();
104
105     cleanupResources();
106 }
107
108 void LayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
109 {
110     // If we're changing layer renderers then we need to free up any resources
111     // allocated by the old renderer.
112     if (layerTreeHost() && layerTreeHost() != host) {
113         cleanupResources();
114         setNeedsDisplay();
115     }
116
117     m_layerTreeHost = host;
118 }
119
120 void LayerChromium::setNeedsCommit()
121 {
122     // Call notifySyncRequired(), which for non-root layers plumbs through to
123     // call setRootLayerNeedsDisplay() on the WebView, which will cause LayerRendererChromium
124     // to render a frame.
125     // This function has no effect on root layers.
126     if (m_delegate)
127         m_delegate->notifySyncRequired();
128 }
129
130 void LayerChromium::setParent(LayerChromium* layer)
131 {
132     ASSERT(!layer || !layer->hasAncestor(this));
133     m_parent = layer;
134 }
135
136 bool LayerChromium::hasAncestor(LayerChromium* ancestor) const
137 {
138     for (LayerChromium* layer = parent(); layer; layer = layer->parent()) {
139         if (layer == ancestor)
140             return true;
141     }
142     return false;
143 }
144
145 void LayerChromium::addChild(PassRefPtr<LayerChromium> child)
146 {
147     insertChild(child, numChildren());
148 }
149
150 void LayerChromium::insertChild(PassRefPtr<LayerChromium> child, size_t index)
151 {
152     index = min(index, m_children.size());
153     child->removeFromParent();
154     child->setParent(this);
155     m_children.insert(index, child);
156     setNeedsCommit();
157 }
158
159 void LayerChromium::removeFromParent()
160 {
161     if (m_parent)
162         m_parent->removeChild(this);
163 }
164
165 void LayerChromium::removeChild(LayerChromium* child)
166 {
167     int foundIndex = indexOfChild(child);
168     if (foundIndex == -1)
169         return;
170
171     child->setParent(0);
172     m_children.remove(foundIndex);
173     setNeedsCommit();
174 }
175
176 void LayerChromium::replaceChild(LayerChromium* reference, PassRefPtr<LayerChromium> newLayer)
177 {
178     ASSERT_ARG(reference, reference);
179     ASSERT_ARG(reference, reference->parent() == this);
180
181     if (reference == newLayer)
182         return;
183
184     int referenceIndex = indexOfChild(reference);
185     if (referenceIndex == -1) {
186         ASSERT_NOT_REACHED();
187         return;
188     }
189
190     reference->removeFromParent();
191
192     if (newLayer) {
193         newLayer->removeFromParent();
194         insertChild(newLayer, referenceIndex);
195     }
196 }
197
198 int LayerChromium::indexOfChild(const LayerChromium* reference)
199 {
200     for (size_t i = 0; i < m_children.size(); i++) {
201         if (m_children[i] == reference)
202             return i;
203     }
204     return -1;
205 }
206
207 void LayerChromium::setBounds(const IntSize& size)
208 {
209     if (bounds() == size)
210         return;
211
212     bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height();
213
214     m_bounds = size;
215
216     if (firstResize || m_pageScaleDirty)
217         setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height()));
218     else
219         setNeedsCommit();
220
221     m_pageScaleDirty = false;
222 }
223
224 const LayerChromium* LayerChromium::rootLayer() const
225 {
226     const LayerChromium* layer = this;
227     for (LayerChromium* parent = layer->parent(); parent; layer = parent, parent = parent->parent()) { }
228     return layer;
229 }
230
231 void LayerChromium::removeAllChildren()
232 {
233     while (m_children.size()) {
234         LayerChromium* layer = m_children[0].get();
235         ASSERT(layer->parent());
236         layer->removeFromParent();
237     }
238 }
239
240 void LayerChromium::setChildren(const Vector<RefPtr<LayerChromium> >& children)
241 {
242     if (children == m_children)
243         return;
244
245     removeAllChildren();
246     size_t listSize = children.size();
247     for (size_t i = 0; i < listSize; i++)
248         addChild(children[i]);
249 }
250
251 LayerChromium* LayerChromium::parent() const
252 {
253     return m_parent;
254 }
255
256 void LayerChromium::setName(const String& name)
257 {
258     m_name = name;
259 }
260
261 void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
262 {
263     // Simply mark the contents as dirty. For non-root layers, the call to
264     // setNeedsCommit will schedule a fresh compositing pass.
265     // For the root layer, setNeedsCommit has no effect.
266     m_dirtyRect.unite(dirtyRect);
267     setNeedsCommit();
268 }
269
270 void LayerChromium::setNeedsDisplay()
271 {
272     m_dirtyRect.setLocation(FloatPoint());
273     m_dirtyRect.setSize(bounds());
274     setNeedsCommit();
275 }
276
277 void LayerChromium::resetNeedsDisplay()
278 {
279     m_dirtyRect = FloatRect();
280 }
281
282 void LayerChromium::pushPropertiesTo(CCLayerImpl* layer)
283 {
284     layer->setAnchorPoint(m_anchorPoint);
285     layer->setAnchorPointZ(m_anchorPointZ);
286     layer->setBackgroundColor(m_backgroundColor);
287     layer->setBounds(m_bounds);
288     layer->setContentBounds(contentBounds());
289     layer->setDebugBorderColor(m_debugBorderColor);
290     layer->setDebugBorderWidth(m_debugBorderWidth);
291     layer->setDoubleSided(m_doubleSided);
292     layer->setDrawsContent(drawsContent());
293     layer->setIsNonCompositedContent(m_isNonCompositedContent);
294     layer->setMasksToBounds(m_masksToBounds);
295     layer->setScrollable(m_scrollable);
296     layer->setName(m_name);
297     layer->setOpaque(m_opaque);
298     layer->setOpacity(m_opacity);
299     layer->setPosition(m_position);
300     layer->setPreserves3D(preserves3D());
301     layer->setScrollPosition(m_scrollPosition);
302     layer->setSublayerTransform(m_sublayerTransform);
303     layer->setTransform(m_transform);
304     layer->setUpdateRect(m_updateRect);
305     layer->setSentScrollDelta(IntSize());
306
307     if (maskLayer())
308         maskLayer()->pushPropertiesTo(layer->maskLayer());
309     if (replicaLayer())
310         replicaLayer()->pushPropertiesTo(layer->replicaLayer());
311
312     // Reset any state that should be cleared for the next update.
313     m_updateRect = FloatRect();
314 }
315
316 PassRefPtr<CCLayerImpl> LayerChromium::createCCLayerImpl()
317 {
318     return CCLayerImpl::create(m_layerId);
319 }
320
321 void LayerChromium::setDebugBorderColor(const Color& color)
322 {
323     m_debugBorderColor = color;
324     setNeedsCommit();
325 }
326
327 void LayerChromium::setDebugBorderWidth(float width)
328 {
329     m_debugBorderWidth = width;
330     setNeedsCommit();
331 }
332
333 void LayerChromium::setContentsScale(float contentsScale)
334 {
335     if (!needsContentsScale())
336         return;
337     m_contentsScale = contentsScale;
338 }
339
340 void LayerChromium::createRenderSurface()
341 {
342     ASSERT(!m_renderSurface);
343     m_renderSurface = adoptPtr(new RenderSurfaceChromium(this));
344 }
345
346 bool LayerChromium::descendantDrawsContent()
347 {
348     for (size_t i = 0; i < m_children.size(); ++i) {
349         if (m_children[i]->drawsContent() || m_children[i]->descendantDrawsContent())
350             return true;
351     }
352     return false;
353 }
354
355 void sortLayers(Vector<RefPtr<LayerChromium> >::iterator, Vector<RefPtr<LayerChromium> >::iterator, void*)
356 {
357     // Currently we don't use z-order to decide what to paint, so there's no need to actually sort LayerChromiums.
358 }
359
360 }
361 #endif // USE(ACCELERATED_COMPOSITING)