Index: cc/layer_tree_host_common.cc |
diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc |
index 37ab677701a226e7bce6ad6e9278a9958fb7cb1c..189e9b2a37c4370f18caf0a9487c4446b41b8e34 100644 |
--- a/cc/layer_tree_host_common.cc |
+++ b/cc/layer_tree_host_common.cc |
@@ -266,21 +266,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(); |
+ int numDescendantsThatDrawContent = layer->drawProperties().num_descendants_that_draw_content; |
// 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 unnecessarily costly so |
+ // instead we conservatively create a surface whenever at least two layers |
+ // draw content for this subtree. |
+ bool atLeastTwoLayersInSubtreeDrawContent = layer->hasDelegatedContent() || |
+ (numDescendantsThatDrawContent > 0 && (layer->drawsContent() || numDescendantsThatDrawContent > 1)); |
jamesr
2012/12/12 16:54:25
nit: odd indentation. 4 spaces for a continuation
|
+ |
+ if (layer->opacity() != 1 && !layer->preserves3D() && atLeastTwoLayersInSubtreeDrawContent) |
return true; |
return false; |
@@ -424,6 +429,23 @@ static inline void removeSurfaceForEarlyExit(LayerType* layerToRemove, LayerList |
layerToRemove->clearRenderSurface(); |
} |
+// 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->drawProperties().num_descendants_that_draw_content; |
+ } |
+ |
+ layer->drawProperties().num_descendants_that_draw_content = 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> |
@@ -887,6 +909,7 @@ void LayerTreeHostCommon::calculateDrawProperties(Layer* rootLayer, const gfx::S |
// This function should have received a root layer. |
DCHECK(isRootLayer(rootLayer)); |
+ cc::preCalculateMetaInformation<Layer>(rootLayer); |
jamesr
2012/12/12 16:54:25
we're in namespace cc:: here, aren't we? we should
|
cc::calculateDrawPropertiesInternal<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface>( |
rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |
@@ -915,6 +938,7 @@ void LayerTreeHostCommon::calculateDrawProperties(LayerImpl* rootLayer, const gf |
// This function should have received a root layer. |
DCHECK(isRootLayer(rootLayer)); |
+ cc::preCalculateMetaInformation<LayerImpl>(rootLayer); |
jamesr
2012/12/12 16:54:25
ditto
|
cc::calculateDrawPropertiesInternal<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl>( |
rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |