tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / platform / graphics / chromium / cc / CCLayerTreeHostCommon.cpp
1 /*
2  * Copyright (C) 2011 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'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25
26 #include "config.h"
27
28 #include "cc/CCLayerTreeHostCommon.h"
29
30 #include "FloatQuad.h"
31 #include "IntRect.h"
32 #include "LayerChromium.h"
33 #include "RenderSurfaceChromium.h"
34 #include "TransformationMatrix.h"
35 #include "cc/CCLayerImpl.h"
36 #include "cc/CCLayerSorter.h"
37 #include "cc/CCRenderSurface.h"
38
39 namespace WebCore {
40
41 IntRect CCLayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix& transform)
42 {
43     // Is this layer fully contained within the target surface?
44     IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
45     if (targetSurfaceRect.contains(layerInSurfaceSpace))
46         return layerBoundRect;
47
48     // If the layer doesn't fill up the entire surface, then find the part of
49     // the surface rect where the layer could be visible. This avoids trying to
50     // project surface rect points that are behind the projection point.
51     IntRect minimalSurfaceRect = targetSurfaceRect;
52     minimalSurfaceRect.intersect(layerInSurfaceSpace);
53
54     // Project the corners of the target surface rect into the layer space.
55     // This bounding rectangle may be larger than it needs to be (being
56     // axis-aligned), but is a reasonable filter on the space to consider.
57     // Non-invertible transforms will create an empty rect here.
58     const TransformationMatrix surfaceToLayer = transform.inverse();
59     IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
60     layerRect.intersect(layerBoundRect);
61     return layerRect;
62 }
63
64 static bool isScaleOrTranslation(const TransformationMatrix& m)
65 {
66     return !m.m12() && !m.m13() && !m.m14()
67            && !m.m21() && !m.m23() && !m.m24()
68            && !m.m31() && !m.m32() && !m.m43()
69            && m.m44();
70
71 }
72
73 template<typename LayerType>
74 bool layerShouldBeSkipped(LayerType* layer)
75 {
76     // Layers can be skipped if any of these conditions are met.
77     //   - does not draw content.
78     //   - is transparent
79     //   - has empty bounds
80     //   - the layer is not double-sided, but its back face is visible.
81     //
82     // Some additional conditions need to be computed at a later point after the recursion is finished.
83     //   - the intersection of render surface content and layer clipRect is empty
84     //   - the visibleLayerRect is empty
85
86     if (!layer->drawsContent() || !layer->opacity() || layer->bounds().isEmpty())
87         return true;
88
89     // The layer should not be drawn if (1) it is not double-sided and (2) the back of the layer is facing the screen.
90     // This second condition is checked by computing the transformed normal of the layer.
91     if (!layer->doubleSided()) {
92         FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
93         FloatQuad mappedLayer = layer->screenSpaceTransform().mapQuad(FloatQuad(layerRect));
94         FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
95         FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
96         FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
97         FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
98         FloatPoint3D zAxis = xAxis.cross(yAxis);
99         if (zAxis.z() < 0)
100             return true;
101     }
102
103     return false;
104 }
105
106 // Recursively walks the layer tree starting at the given node and computes all the
107 // necessary transformations, clipRects, render surfaces, etc.
108 template<typename LayerType, typename RenderSurfaceType, typename LayerSorter>
109 static void calculateDrawTransformsAndVisibilityInternal(LayerType* layer, LayerType* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerType> >& renderSurfaceLayerList, Vector<RefPtr<LayerType> >& layerList, LayerSorter* layerSorter, int maxTextureSize)
110 {
111     typedef Vector<RefPtr<LayerType> > LayerList;
112
113     // This function computes the new matrix transformations recursively for this
114     // layer and all its descendants. It also computes the appropriate render surfaces.
115     // Some important points to remember:
116     //
117     // 0. Here, transforms are notated in Matrix x Vector order, and in words we describe what
118     //    the transform does from left to right.
119     //
120     // 1. In our terminology, the "layer origin" refers to the top-left corner of a layer, and the
121     //    positive Y-axis points downwards. This interpretation is valid because the orthographic
122     //    projection applied at draw time flips the Y axis appropriately.
123     //
124     // 2. The anchor point, when given as a FloatPoint object, is specified in "unit layer space",
125     //    where the bounds of the layer map to [0, 1]. However, as a TransformationMatrix object,
126     //    the transform to the anchor point is specified in "pixel layer space", where the bounds
127     //    of the layer map to [bounds.width(), bounds.height()].
128     //
129     // 3. The value of layer->position() is actually the position of the anchor point with respect to the position
130     //    of the layer's origin. That is:
131     //        layer->position() = positionOfLayerOrigin + anchorPoint (in pixel units)
132     //
133     //    Or, equivalently,
134     //        positionOfLayerOrigin.x =  layer->position.x - (layer->anchorPoint.x * bounds.width)
135     //        positionOfLayerOrigin.y =  layer->position.y - (layer->anchorPoint.y * bounds.height)
136     //
137     // 4. Definition of various transforms used:
138     //        M[parent] is the parent matrix, with respect to the nearest render surface, passed down recursively.
139     //        M[root] is the full hierarchy, with respect to the root, passed down recursively.
140     //        Tr[origin] is the translation matrix from the parent's origin to this layer's origin.
141     //        Tr[origin2anchor] is the translation from the layer's origin to its anchor point
142     //        Tr[origin2center] is the translation from the layer's origin to its center
143     //        M[layer] is the layer's matrix (applied at the anchor point)
144     //        M[sublayer] is the layer's sublayer transform (applied at the layer's center)
145     //        Tr[anchor2center] is the translation offset from the anchor point and the center of the layer
146     //
147     //    Some shortcuts and substitutions are used in the code to reduce matrix multiplications:
148     //        Translating by the value of layer->position(), Tr[layer->position()] = Tr[origin] * Tr[origin2anchor]
149     //        Tr[anchor2center] = Tr[origin2anchor].inverse() * Tr[origin2center]
150     //
151     //    Some composite transforms can help in understanding the sequence of transforms:
152     //        compositeLayerTransform = Tr[origin2anchor] * M[layer] * Tr[origin2anchor].inverse()
153     //        compositeSublayerTransform = Tr[origin2center] * M[sublayer] * Tr[origin2center].inverse()
154     //
155     //    In words, the layer transform is applied about the anchor point, and the sublayer transform is
156     //    applied about the center of the layer.
157     //
158     // 5. When a layer (or render surface) is drawn, it is drawn into a "target render surface". Therefore the draw
159     //    transform does not necessarily transform from screen space to local layer space. Instead, the draw transform
160     //    is the transform between the "target render surface space" and local layer space. Note that render surfaces,
161     //    except for the root, also draw themselves into a different target render surface, and so their draw
162     //    transform and origin transforms are also described with respect to the target.
163     //
164     // Using these definitions, then:
165     //
166     // The draw transform for the layer is:
167     //        M[draw] = M[parent] * Tr[origin] * compositeLayerTransform * Tr[origin2center]
168     //                = M[parent] * Tr[layer->position()] * M[layer] * Tr[anchor2center]
169     //
170     //        Interpreting the math left-to-right, this transforms from the layer's render surface to the center of the layer.
171     //
172     // The screen space transform is:
173     //        M[screenspace] = M[root] * Tr[origin] * compositeLayerTransform
174     //                       = M[root] * Tr[layer->position()] * M[layer] * Tr[origin2anchor].inverse()
175     //
176     //        Interpreting the math left-to-right, this transforms from the root layer space to the local layer's origin.
177     //
178     // The transform hierarchy that is passed on to children (i.e. the child's parentMatrix) is:
179     //        M[parent]_for_child = M[parent] * Tr[origin] * compositeLayerTransform * compositeSublayerTransform
180     //                            = M[parent] * Tr[layer->position()] * M[layer] * Tr[anchor2center] * M[sublayer] * Tr[origin2center].inverse()
181     //                            = M[draw] * M[sublayer] * Tr[origin2center].inverse()
182     //
183     //        and a similar matrix for the full hierarchy with respect to the root.
184     //
185     // Finally, note that the final matrix used by the shader for the layer is P * M[draw] * S . This final product
186     // is computed in drawTexturedQuad(), where:
187     //        P is the projection matrix
188     //        S is the scale adjustment (to scale up to the layer size)
189     //
190
191     float drawOpacity = layer->opacity();
192     if (layer->parent() && layer->parent()->preserves3D())
193         drawOpacity *= layer->parent()->drawOpacity();
194     // The opacity of a layer always applies to its children (either implicitly
195     // via a render surface or explicitly if the parent preserves 3D), so the
196     // entire subtree can be skipped if this layer is fully transparent.
197     if (!drawOpacity)
198         return;
199
200     IntSize bounds = layer->bounds();
201     FloatPoint anchorPoint = layer->anchorPoint();
202     FloatPoint position = layer->position() - layer->scrollDelta();
203
204     // Offset between anchor point and the center of the quad.
205     float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
206     float centerOffsetY = (0.5 - anchorPoint.y()) * bounds.height();
207
208     TransformationMatrix layerLocalTransform;
209     // LT = Tr[origin] * M[zoomAnimator]
210     layerLocalTransform.multiply(layer->zoomAnimatorTransform());
211     // LT = Tr[origin] * M[zoomAnimator] * S[pageScaleDelta]
212     layerLocalTransform.scale(layer->pageScaleDelta());
213     // LT = Tr[origin] * M[zoomAnimator] * S[pageScaleDelta] * Tr[origin2anchor]
214     layerLocalTransform.translate3d(position.x(), position.y(), layer->anchorPointZ());
215     // LT = Tr[origin] * M[zoomAnimator] * S[pageScaleDelta] * Tr[origin2anchor] * M[layer]
216     layerLocalTransform.multiply(layer->transform());
217     // LT = Tr[origin] * M[zoomAnimator] * S[pageScaleDelta] * Tr[origin2anchor] * M[layer] * Tr[anchor2center]
218     layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
219
220     TransformationMatrix combinedTransform = parentMatrix;
221     combinedTransform = combinedTransform.multiply(layerLocalTransform);
222
223     FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height());
224     IntRect transformedLayerRect;
225
226     // fullHierarchyMatrix is the matrix that transforms objects between screen space (except projection matrix) and the most recent RenderSurface's space.
227     // nextHierarchyMatrix will only change if this layer uses a new RenderSurface, otherwise remains the same.
228     TransformationMatrix nextHierarchyMatrix = fullHierarchyMatrix;
229
230     // FIXME: This seems like the wrong place to set this
231     layer->setUsesLayerClipping(false);
232
233     // The layer and its descendants render on a new RenderSurface if any of
234     // these conditions hold:
235     // 1. The layer clips its descendants and its transform is not a simple translation.
236     // 2. If the layer has opacity != 1 and does not have a preserves-3d transform style.
237     // 3. The layer uses a mask
238     // 4. The layer has a replica (used for reflections)
239     // 5. The layer doesn't preserve-3d but is the child of a layer which does.
240     // If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening
241     // out its children. The opacity value of the children layers is multiplied by the opacity
242     // of their parent.
243     bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
244     bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
245     bool useSurfaceForMasking = layer->maskLayer();
246     bool useSurfaceForReflection = layer->replicaLayer();
247     bool useSurfaceForFlatDescendants = layer->parent() && layer->parent()->preserves3D() && !layer->preserves3D() && layer->descendantDrawsContent();
248     if (useSurfaceForMasking || useSurfaceForReflection || useSurfaceForFlatDescendants || ((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantDrawsContent())) {
249         if (!layer->renderSurface())
250             layer->createRenderSurface();
251
252         RenderSurfaceType* renderSurface = layer->renderSurface();
253         renderSurface->clearLayerList();
254
255         // The origin of the new surface is the upper left corner of the layer.
256         TransformationMatrix drawTransform;
257         drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0);
258         layer->setDrawTransform(drawTransform);
259
260         transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height());
261
262         renderSurface->setDrawOpacity(drawOpacity);
263         layer->setDrawOpacity(1);
264
265         TransformationMatrix layerOriginTransform = combinedTransform;
266         layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
267         renderSurface->setOriginTransform(layerOriginTransform);
268
269         // Update the aggregate hierarchy matrix to include the transform of the newly created RenderSurface.
270         nextHierarchyMatrix.multiply(layerOriginTransform);
271
272         // The render surface clipRect contributes to the scissor rect that needs to
273         // be applied before drawing the render surface onto its containing
274         // surface and is therefore expressed in the parent's coordinate system.
275         renderSurface->setClipRect(layer->parent() ? layer->parent()->clipRect() : layer->clipRect());
276
277         if (layer->maskLayer()) {
278             renderSurface->setMaskLayer(layer->maskLayer());
279             layer->maskLayer()->setTargetRenderSurface(renderSurface);
280         } else
281             renderSurface->setMaskLayer(0);
282
283         if (layer->replicaLayer() && layer->replicaLayer()->maskLayer())
284             layer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface);
285
286         renderSurfaceLayerList.append(layer);
287     } else {
288         layer->setDrawTransform(combinedTransform);
289         transformedLayerRect = enclosingIntRect(layer->drawTransform().mapRect(layerRect));
290
291         layer->setDrawOpacity(drawOpacity);
292
293         if (layer->parent()) {
294             // Layers inherit the clip rect from their parent.
295             layer->setClipRect(layer->parent()->clipRect());
296             if (layer->parent()->usesLayerClipping())
297                 layer->setUsesLayerClipping(true);
298
299             layer->setTargetRenderSurface(layer->parent()->targetRenderSurface());
300         }
301
302         if (layer != rootLayer)
303             layer->clearRenderSurface();
304
305         if (layer->masksToBounds()) {
306             IntRect clipRect = transformedLayerRect;
307             clipRect.intersect(layer->clipRect());
308             layer->setClipRect(clipRect);
309             layer->setUsesLayerClipping(true);
310         }
311     }
312
313     // Note that at this point, layer->drawTransform() is not necessarily the same as local variable drawTransform.
314     // layerScreenSpaceTransform represents the transform between root layer's "screen space" and local layer space.
315     TransformationMatrix layerScreenSpaceTransform = nextHierarchyMatrix;
316     layerScreenSpaceTransform.multiply(layer->drawTransform());
317     layerScreenSpaceTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
318     layer->setScreenSpaceTransform(layerScreenSpaceTransform);
319
320     if (layer->renderSurface())
321         layer->setTargetRenderSurface(layer->renderSurface());
322     else {
323         ASSERT(layer->parent());
324         layer->setTargetRenderSurface(layer->parent()->targetRenderSurface());
325     }
326
327     // drawableContentRect() is always stored in the coordinate system of the
328     // RenderSurface the layer draws into.
329     if (layer->drawsContent()) {
330         IntRect drawableContentRect = transformedLayerRect;
331         if (layer->usesLayerClipping())
332             drawableContentRect.intersect(layer->clipRect());
333         layer->setDrawableContentRect(drawableContentRect);
334     } else
335         layer->setDrawableContentRect(IntRect());
336
337     TransformationMatrix sublayerMatrix = layer->drawTransform();
338
339     // Flatten to 2D if the layer doesn't preserve 3D.
340     if (!layer->preserves3D()) {
341         sublayerMatrix.setM13(0);
342         sublayerMatrix.setM23(0);
343         sublayerMatrix.setM31(0);
344         sublayerMatrix.setM32(0);
345         sublayerMatrix.setM33(1);
346         sublayerMatrix.setM34(0);
347         sublayerMatrix.setM43(0);
348     }
349
350     // Apply the sublayer transform at the center of the layer.
351     sublayerMatrix.multiply(layer->sublayerTransform());
352
353     // The coordinate system given to children is located at the layer's origin, not the center.
354     sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
355
356     LayerList& descendants = (layer->renderSurface() ? layer->renderSurface()->layerList() : layerList);
357
358     // Any layers that are appended after this point are in the layer's subtree and should be included in the sorting process.
359     unsigned sortingStartIndex = descendants.size();
360
361     if (!layerShouldBeSkipped(layer))
362         descendants.append(layer);
363
364     for (size_t i = 0; i < layer->children().size(); ++i) {
365         LayerType* child = layer->children()[i].get();
366         calculateDrawTransformsAndVisibilityInternal<LayerType, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, renderSurfaceLayerList, descendants, layerSorter, maxTextureSize);
367
368         if (child->renderSurface()) {
369             RenderSurfaceType* childRenderSurface = child->renderSurface();
370             IntRect drawableContentRect = layer->drawableContentRect();
371             drawableContentRect.unite(enclosingIntRect(childRenderSurface->drawableContentRect()));
372             layer->setDrawableContentRect(drawableContentRect);
373             descendants.append(child);
374         } else {
375             IntRect drawableContentRect = layer->drawableContentRect();
376             drawableContentRect.unite(child->drawableContentRect());
377             layer->setDrawableContentRect(drawableContentRect);
378         }
379     }
380
381     if (layer->masksToBounds() || useSurfaceForMasking) {
382         IntRect drawableContentRect = layer->drawableContentRect();
383         drawableContentRect.intersect(transformedLayerRect);
384         layer->setDrawableContentRect(drawableContentRect);
385     }
386
387     if (layer->renderSurface() && layer != rootLayer) {
388         RenderSurfaceType* renderSurface = layer->renderSurface();
389         IntRect clippedContentRect = layer->drawableContentRect();
390         FloatPoint surfaceCenter = FloatRect(clippedContentRect).center();
391
392         // Restrict the RenderSurface size to the portion that's visible.
393         FloatSize centerOffsetDueToClipping;
394
395         // Don't clip if the layer is reflected as the reflection shouldn't be
396         // clipped.
397         if (!layer->replicaLayer()) {
398             if (!renderSurface->clipRect().isEmpty() && !clippedContentRect.isEmpty()) {
399                 IntRect surfaceClipRect = CCLayerTreeHostCommon::calculateVisibleRect(renderSurface->clipRect(), clippedContentRect, renderSurface->originTransform());
400                 clippedContentRect.intersect(surfaceClipRect);
401             }
402             FloatPoint clippedSurfaceCenter = FloatRect(clippedContentRect).center();
403             centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
404         }
405
406         // The RenderSurface backing texture cannot exceed the maximum supported
407         // texture size.
408         clippedContentRect.setWidth(std::min(clippedContentRect.width(), maxTextureSize));
409         clippedContentRect.setHeight(std::min(clippedContentRect.height(), maxTextureSize));
410
411         if (clippedContentRect.isEmpty())
412             renderSurface->clearLayerList();
413
414         renderSurface->setContentRect(clippedContentRect);
415
416         // Since the layer starts a new render surface we need to adjust its
417         // clipRect to be expressed in the new surface's coordinate system.
418         layer->setClipRect(layer->drawableContentRect());
419
420         // Adjust the origin of the transform to be the center of the render surface.
421         TransformationMatrix drawTransform = renderSurface->originTransform();
422         drawTransform.translate3d(surfaceCenter.x() + centerOffsetDueToClipping.width(), surfaceCenter.y() + centerOffsetDueToClipping.height(), 0);
423         renderSurface->setDrawTransform(drawTransform);
424
425         // Compute the transformation matrix used to draw the replica of the render
426         // surface.
427         if (layer->replicaLayer()) {
428             TransformationMatrix replicaDrawTransform = renderSurface->originTransform();
429             replicaDrawTransform.translate3d(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y(), 0);
430             replicaDrawTransform.multiply(layer->replicaLayer()->transform());
431             replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0);
432             renderSurface->setReplicaDrawTransform(replicaDrawTransform);
433         }
434
435         // If a render surface has no layer list, then it and none of its
436         // children needed to get drawn. Therefore, it should be the last layer
437         // in the render surface list and we can trivially remove it.
438         if (!layer->renderSurface()->layerList().size()) {
439             ASSERT(renderSurfaceLayerList.last() == layer);
440             renderSurfaceLayerList.removeLast();
441             layer->clearRenderSurface();
442             return;
443         }
444     }
445
446     // If neither this layer nor any of its children were added, early out.
447     if (sortingStartIndex == descendants.size())
448         return;
449
450     // If preserves-3d then sort all the descendants in 3D so that they can be
451     // drawn from back to front. If the preserves-3d property is also set on the parent then
452     // skip the sorting as the parent will sort all the descendants anyway.
453     if (descendants.size() && layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D()))
454         sortLayers(&descendants.at(sortingStartIndex), descendants.end(), layerSorter);
455 }
456
457 // FIXME: Instead of using the following function to set visibility rects on a second
458 // tree pass, revise calculateVisibleLayerRect() so that this can be done in a single
459 // pass inside calculateDrawTransformsAndVisibilityInternal<>().
460 template<typename LayerType, typename RenderSurfaceType>
461 static void walkLayersAndCalculateVisibleLayerRects(const Vector<RefPtr<LayerType> >& renderSurfaceLayerList)
462 {
463     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
464         LayerType* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
465         RenderSurfaceType* renderSurface = renderSurfaceLayer->renderSurface();
466
467         Vector<RefPtr<LayerType> >& layerList = renderSurface->layerList();
468         for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
469             LayerType* layer = layerList[layerIndex].get();
470             IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<LayerType>(layer);
471             layer->setVisibleLayerRect(visibleLayerRect);
472         }
473     }
474 }
475
476 void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(LayerChromium* layer, LayerChromium* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList, Vector<RefPtr<LayerChromium> >& layerList, int maxTextureSize)
477 {
478     WebCore::calculateDrawTransformsAndVisibilityInternal<LayerChromium, RenderSurfaceChromium, void*>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, renderSurfaceLayerList, layerList, 0, maxTextureSize);
479     walkLayersAndCalculateVisibleLayerRects<LayerChromium, RenderSurfaceChromium>(renderSurfaceLayerList);
480 }
481
482 void CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(CCLayerImpl* layer, CCLayerImpl* rootLayer, const TransformationMatrix& parentMatrix, const TransformationMatrix& fullHierarchyMatrix, Vector<RefPtr<CCLayerImpl> >& renderSurfaceLayerList, Vector<RefPtr<CCLayerImpl> >& layerList, CCLayerSorter* layerSorter, int maxTextureSize)
483 {
484     calculateDrawTransformsAndVisibilityInternal<CCLayerImpl, CCRenderSurface, CCLayerSorter>(layer, rootLayer, parentMatrix, fullHierarchyMatrix, renderSurfaceLayerList, layerList, layerSorter, maxTextureSize);
485     walkLayersAndCalculateVisibleLayerRects<CCLayerImpl, CCRenderSurface>(renderSurfaceLayerList);
486 }
487
488 } // namespace WebCore