Chromium Code Reviews| Index: cc/layer_tree_host_common.cc |
| diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc |
| index 8aff2029e27fd339917cf9b5afdec7beac69b28e..5d0b2d63619469c837d43c8dbafb762936ae2ff2 100644 |
| --- a/cc/layer_tree_host_common.cc |
| +++ b/cc/layer_tree_host_common.cc |
| @@ -249,21 +249,26 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig |
| if (!layer->filters().isEmpty() || !layer->backgroundFilters().isEmpty() || layer->filter()) |
| return true; |
| - // Cache this value, because otherwise it walks the entire subtree several times. |
| - int descendantsDrawContent = layer->descendantsDrawContent(); |
| + // Caching this value avoids unnecessary virtual function overheads. |
| + int numDescendantsThatDrawContent = layer->numDescendantsThatDrawContent(); |
| // If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but it is |
| // treated as a 3D object by its parent (i.e. parent does preserve-3d). |
| - if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantsDrawContent > 0) |
| + if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && numDescendantsThatDrawContent > 0) |
| return true; |
| // If the layer clips its descendants but it is not axis-aligned with respect to its parent. |
| - if (layerClipsSubtree(layer) && !axisAlignedWithRespectToParent && descendantsDrawContent > 0) |
| + if (layerClipsSubtree(layer) && !axisAlignedWithRespectToParent && numDescendantsThatDrawContent > 0) |
| return true; |
| - // If the layer has opacity != 1 and does not have a preserves-3d transform style. |
| - if (layer->opacity() != 1 && !layer->preserves3D() && descendantsDrawContent > 0 |
| - && (layer->drawsContent() || descendantsDrawContent > 1)) |
| + // If the layer has some translucency and does not have a preserves-3d transform style. |
| + // This condition only needs a render surface if two or more layers in the |
| + // subtree overlap. But checking layer overlaps is unnecesarily costly so |
| + // instead we conservatively create a surface whenever at least two layers |
| + // draw content for this subtree. |
| + bool atLeastTwoLayersInSubtreeDrawContent = numDescendantsThatDrawContent > 0 |
|
danakj
2012/12/03 18:33:41
i like this var name
|
| + && (layer->drawsContent() || numDescendantsThatDrawContent > 1); |
|
danakj
2012/12/03 18:33:41
the "if" seems to have disappeared entirely.
|
| + if (layer->opacity() != 1 && !layer->preserves3D() && atLeastTwoLayersInSubtreeDrawContent) |
| return true; |
| return false; |
| @@ -388,6 +393,24 @@ static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform& |
| replicaMaskLayer->setContentsScale(contentsScale); |
| } |
| +// Recursively walks the layer tree to compute any information that is needed |
| +// before doing the main recursion. |
| +template<typename LayerType> |
| +static void preCalculateMetaInformation(LayerType* layer) |
| +{ |
| + int numDescendantsThatDrawContent = 0; |
| + |
| + for (size_t i = 0; i < layer->children().size(); ++i) { |
| + LayerType* childLayer = layer->children()[i]; |
| + preCalculateMetaInformation<LayerType>(childLayer); |
| + |
| + numDescendantsThatDrawContent += childLayer->drawsContent() ? 1 : 0; |
| + numDescendantsThatDrawContent += childLayer->numDescendantsThatDrawContent(); |
| + } |
| + |
| + layer->setNumDescendantsThatDrawContent(numDescendantsThatDrawContent); |
| +} |
| + |
| // Recursively walks the layer tree starting at the given node and computes all the |
| // necessary transformations, clipRects, render surfaces, etc. |
| template<typename LayerType, typename LayerList, typename RenderSurfaceType, typename LayerSorter> |
| @@ -837,6 +860,7 @@ void LayerTreeHostCommon::calculateDrawTransforms(Layer* rootLayer, const gfx::S |
| // This function should have received a root layer. |
| DCHECK(isRootLayer(rootLayer)); |
| + cc::preCalculateMetaInformation<Layer>(rootLayer); |
| cc::calculateDrawTransformsInternal<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface, void>( |
| rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
| deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |
| @@ -864,6 +888,7 @@ void LayerTreeHostCommon::calculateDrawTransforms(LayerImpl* rootLayer, const gf |
| // This function should have received a root layer. |
| DCHECK(isRootLayer(rootLayer)); |
| + cc::preCalculateMetaInformation<LayerImpl>(rootLayer); |
| cc::calculateDrawTransformsInternal<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerSorter>( |
| rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
| deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |