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