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, |