| Index: cc/trees/property_tree_builder.cc | 
| diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc | 
| index 2f287ca57099fae79470042fd192a0ca9b7c68a2..8596be1a4e416c950fe2635f219a2db36e2ed234 100644 | 
| --- a/cc/trees/property_tree_builder.cc | 
| +++ b/cc/trees/property_tree_builder.cc | 
| @@ -647,9 +647,7 @@ static inline float EffectiveOpacity(Layer* layer) { | 
| } | 
|  | 
| static inline float EffectiveOpacity(LayerImpl* layer) { | 
| -  return layer->test_properties()->hide_layer_and_subtree | 
| -             ? 0.f | 
| -             : layer->test_properties()->opacity; | 
| +  return layer->test_properties()->opacity; | 
| } | 
|  | 
| static inline float Opacity(Layer* layer) { | 
| @@ -689,7 +687,7 @@ static inline bool HideLayerAndSubtree(Layer* layer) { | 
| } | 
|  | 
| static inline bool HideLayerAndSubtree(LayerImpl* layer) { | 
| -  return layer->test_properties()->hide_layer_and_subtree; | 
| +  return false; | 
| } | 
|  | 
| static inline bool HasCopyRequest(Layer* layer) { | 
| @@ -829,16 +827,14 @@ static void SetSubtreeHasCopyRequest(Layer* layer, | 
| } | 
|  | 
| static void SetSubtreeHasCopyRequest(LayerImpl* layer, | 
| -                                     bool subtree_has_copy_request) { | 
| -  layer->test_properties()->subtree_has_copy_request = subtree_has_copy_request; | 
| -} | 
| +                                     bool subtree_has_copy_request) {} | 
|  | 
| static bool SubtreeHasCopyRequest(Layer* layer) { | 
| return layer->SubtreeHasCopyRequest(); | 
| } | 
|  | 
| static bool SubtreeHasCopyRequest(LayerImpl* layer) { | 
| -  return layer->test_properties()->subtree_has_copy_request; | 
| +  return false; | 
| } | 
|  | 
| template <typename LayerType> | 
| @@ -1134,29 +1130,60 @@ static void SetLayerPropertyChangedForChild(Layer* parent, Layer* child) { | 
| static void SetLayerPropertyChangedForChild(LayerImpl* parent, | 
| LayerImpl* child) {} | 
|  | 
| +static bool SubtreeIsHidden(Layer* layer) { | 
| +  return !SubtreeHasCopyRequest(layer) && layer->parent() && | 
| +         layer->hide_layer_and_subtree(); | 
| +} | 
| + | 
| +static bool SubtreeIsHidden(LayerImpl* layer) { | 
| +  return false; | 
| +} | 
| + | 
| +static void SetIsHidden(Layer* layer, bool is_hidden) { | 
| +  layer->SetIsHidden(is_hidden); | 
| +  if (MaskLayer(layer)) | 
| +    MaskLayer(layer)->SetIsHidden(is_hidden); | 
| +} | 
| + | 
| +static void SetIsHidden(LayerImpl* layer, bool is_hidden) {} | 
| + | 
| template <typename LayerType> | 
| -void BuildPropertyTreesInternal( | 
| +void AddPropertyTreeNodesIfNeeded( | 
| LayerType* layer, | 
| -    const DataForRecursion<LayerType>& data_from_parent) { | 
| +    const DataForRecursion<LayerType>& data_from_parent, | 
| +    DataForRecursion<LayerType>* data_for_children) { | 
| +  DCHECK(!data_for_children->is_hidden); | 
| layer->set_property_tree_sequence_number( | 
| data_from_parent.property_trees->sequence_number); | 
| - | 
| -  DataForRecursion<LayerType> data_for_children(data_from_parent); | 
| - | 
| bool created_render_surface = | 
| -      AddEffectNodeIfNeeded(data_from_parent, layer, &data_for_children); | 
| - | 
| +      AddEffectNodeIfNeeded(data_from_parent, layer, data_for_children); | 
|  | 
| bool created_transform_node = AddTransformNodeIfNeeded( | 
| -      data_from_parent, layer, created_render_surface, &data_for_children); | 
| +      data_from_parent, layer, created_render_surface, data_for_children); | 
| SetHasTransformNode(layer, created_transform_node); | 
| AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node, | 
| -                      &data_for_children); | 
| +                      data_for_children); | 
|  | 
| -  AddScrollNodeIfNeeded(data_from_parent, layer, &data_for_children); | 
| +  AddScrollNodeIfNeeded(data_from_parent, layer, data_for_children); | 
|  | 
| SetBackfaceVisibilityTransform(layer, created_transform_node); | 
| -  SetSafeOpaqueBackgroundColor(data_from_parent, layer, &data_for_children); | 
| +  SetSafeOpaqueBackgroundColor(data_from_parent, layer, data_for_children); | 
| +} | 
| + | 
| +template <typename LayerType> | 
| +void BuildPropertyTreesInternal( | 
| +    LayerType* layer, | 
| +    const DataForRecursion<LayerType>& data_from_parent) { | 
| +  DataForRecursion<LayerType> data_for_children(data_from_parent); | 
| + | 
| +  data_for_children.is_hidden = | 
| +      data_from_parent.is_hidden || SubtreeIsHidden(layer); | 
| + | 
| +  SetIsHidden(layer, data_for_children.is_hidden); | 
| + | 
| +  // We do not create property tree nodes for hidden layers. | 
| +  if (!data_for_children.is_hidden) | 
| +    AddPropertyTreeNodesIfNeeded(layer, data_from_parent, &data_for_children); | 
|  | 
| bool not_axis_aligned_since_last_clip = | 
| data_from_parent.not_axis_aligned_since_last_clip | 
| @@ -1190,6 +1217,9 @@ void BuildPropertyTreesInternal( | 
| } | 
| } | 
|  | 
| +  if (data_for_children.is_hidden) | 
| +    return; | 
| + | 
| if (MaskLayer(layer)) { | 
| MaskLayer(layer)->set_property_tree_sequence_number( | 
| data_from_parent.property_trees->sequence_number); | 
|  |