Revert of Compute if a layer is drawn without LayerTree hierarchy (patchset #14 id:250001 of https://codereview.chromium.org/1588093004/ )

Reason for revert:
Speculative; might have broken tests on Chrome OS, see http://crbug.com/580806

Original issue's description:
> This CL :
>   * deletes is_hidden
>   * computes if a layer is drawn using the effect tree
>
> BUG=575413
> CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
>
> Committed: https://crrev.com/5bd215b33e6343d8ae7e52fb822dd552bf8b59a7
> Cr-Commit-Position: refs/heads/master@{#371063}

[email protected],[email protected],[email protected],[email protected],[email protected]
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=575413
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review URL: https://codereview.chromium.org/1621013002

Cr-Commit-Position: refs/heads/master@{#371160}
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 5556bce..2519daa 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -100,7 +100,8 @@
       replica_layer_(nullptr),
       client_(nullptr),
       num_unclipped_descendants_(0),
-      frame_timing_requests_dirty_(false) {
+      frame_timing_requests_dirty_(false),
+      is_hidden_from_property_trees_(false) {
   if (!settings.use_compositor_animation_timelines) {
     layer_animation_controller_ = LayerAnimationController::Create(layer_id_);
     layer_animation_controller_->AddValueObserver(this);
@@ -538,10 +539,6 @@
   SetNeedsCommit();
 }
 
-float Layer::EffectiveOpacity() const {
-  return hide_layer_and_subtree_ ? 0.f : opacity_;
-}
-
 bool Layer::OpacityIsAnimating() const {
   DCHECK(layer_tree_host_);
   return layer_animation_controller_
@@ -1244,6 +1241,7 @@
   layer->set_user_scrollable_vertical(user_scrollable_vertical_);
   layer->SetElementId(element_id_);
   layer->SetMutableProperties(mutable_properties_);
+  layer->set_is_hidden_from_property_trees(is_hidden_from_property_trees_);
 
   LayerImpl* scroll_parent = nullptr;
   if (scroll_parent_) {
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 74fa72b3..94f8271 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -141,7 +141,6 @@
 
   void SetOpacity(float opacity);
   float opacity() const { return opacity_; }
-  float EffectiveOpacity() const;
   bool OpacityIsAnimating() const;
   bool HasPotentiallyRunningOpacityAnimation() const;
   virtual bool OpacityCanAnimateOnImplThread() const;
@@ -561,6 +560,12 @@
   bool layer_or_descendant_is_drawn();
   void set_sorted_for_recursion(bool sorted_for_recursion);
   bool sorted_for_recursion();
+  void set_is_hidden_from_property_trees(bool is_hidden) {
+    if (is_hidden == is_hidden_from_property_trees_)
+      return;
+    is_hidden_from_property_trees_ = is_hidden;
+    SetNeedsPushProperties();
+  }
 
   // LayerAnimationValueProvider implementation.
   gfx::ScrollOffset ScrollOffsetForAnimation() const override;
@@ -787,6 +792,7 @@
 
   std::vector<FrameTimingRequest> frame_timing_requests_;
   bool frame_timing_requests_dirty_;
+  bool is_hidden_from_property_trees_;
 
   DISALLOW_COPY_AND_ASSIGN(Layer);
 };
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index f585bde0..57b62f8 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -100,7 +100,8 @@
       visited_(false),
       layer_or_descendant_is_drawn_(false),
       layer_or_descendant_has_input_handler_(false),
-      sorted_for_recursion_(false) {
+      sorted_for_recursion_(false),
+      is_hidden_from_property_trees_(false) {
   DCHECK_GT(layer_id_, 0);
   DCHECK(layer_tree_impl_);
   layer_tree_impl_->RegisterLayer(this);
@@ -658,6 +659,7 @@
   layer->SetClipTreeIndex(clip_tree_index_);
   layer->SetEffectTreeIndex(effect_tree_index_);
   layer->set_offset_to_transform_parent(offset_to_transform_parent_);
+  layer->set_is_hidden_from_property_trees(is_hidden_from_property_trees_);
 
   LayerImpl* scroll_parent = nullptr;
   if (scroll_parent_) {
@@ -960,7 +962,7 @@
     // started, but might have finished since then on the compositor thread.
     if (node->owner_id != id())
       return;
-    node->data.opacity = EffectiveOpacity();
+    node->data.opacity = opacity_;
     effect_tree.set_needs_update(true);
   }
 }
@@ -989,10 +991,7 @@
 
 void LayerImpl::OnOpacityAnimated(float opacity) {
   SetOpacity(opacity);
-  // When hide_layer_and_subtree is true, the effective opacity is zero and we
-  // need not update the opacity on property trees.
-  if (!hide_layer_and_subtree_)
-    UpdatePropertyTreeOpacity();
+  UpdatePropertyTreeOpacity();
 }
 
 void LayerImpl::OnTransformAnimated(const gfx::Transform& transform) {
@@ -1249,10 +1248,6 @@
   NoteLayerPropertyChangedForSubtree();
 }
 
-float LayerImpl::EffectiveOpacity() const {
-  return hide_layer_and_subtree_ ? 0.f : opacity_;
-}
-
 bool LayerImpl::OpacityIsAnimating() const {
   LayerAnimationController::ObserverType observer_type =
       IsActive() ? LayerAnimationController::ObserverType::ACTIVE
@@ -1928,13 +1923,11 @@
                                            gfx::Rect(scaled_bounds));
 }
 
-bool LayerImpl::IsHidden() const {
+bool LayerImpl::LayerIsHidden() const {
   if (layer_tree_impl()->settings().use_property_trees) {
-    EffectTree& effect_tree = layer_tree_impl_->property_trees()->effect_tree;
-    EffectNode* node = effect_tree.Node(effect_tree_index_);
-    return node->data.screen_space_opacity == 0.f;
+    return is_hidden_from_property_trees_;
   } else {
-    return EffectiveOpacity() == 0.f || (parent() && parent()->IsHidden());
+    return hide_layer_and_subtree_ || (parent() && parent()->LayerIsHidden());
   }
 }
 
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index e3d0c87..12ee4c0 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -321,7 +321,6 @@
 
   void SetOpacity(float opacity);
   float opacity() const { return opacity_; }
-  float EffectiveOpacity() const;
   bool OpacityIsAnimating() const;
   bool HasPotentiallyRunningOpacityAnimation() const;
   bool OpacityIsAnimatingOnImplOnly() const;
@@ -686,7 +685,13 @@
 
   void UpdatePropertyTreeForScrollingAndAnimationIfNeeded();
 
-  bool IsHidden() const;
+  void set_is_hidden_from_property_trees(bool is_hidden) {
+    if (is_hidden == is_hidden_from_property_trees_)
+      return;
+    is_hidden_from_property_trees_ = is_hidden;
+    SetNeedsPushProperties();
+  }
+  bool LayerIsHidden() const;
 
   float GetIdealContentsScale() const;
 
@@ -890,6 +895,7 @@
   // If true, the layer or one of its descendants has a wheel or touch handler.
   bool layer_or_descendant_has_input_handler_;
   bool sorted_for_recursion_;
+  bool is_hidden_from_property_trees_;
 
   DISALLOW_COPY_AND_ASSIGN(LayerImpl);
 };
diff --git a/cc/proto/property_tree.proto b/cc/proto/property_tree.proto
index d35f264b..50cfb45 100644
--- a/cc/proto/property_tree.proto
+++ b/cc/proto/property_tree.proto
@@ -81,13 +81,9 @@
   optional float opacity = 1;
   optional float screen_space_opacity = 2;
   optional bool has_render_surface = 3;
-  optional bool has_copy_request = 4;
-  optional bool has_background_filters = 5;
-  optional bool is_drawn = 6;
-  optional bool screen_space_opacity_is_animating = 7;
-  optional int64 num_copy_requests_in_subtree = 8;
-  optional int64 transform_id = 9;
-  optional int64 clip_id = 10;
+  optional int64 num_copy_requests_in_subtree = 4;
+  optional int64 transform_id = 5;
+  optional int64 clip_id = 6;
 }
 
 message ScrollNodeData {
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 6899816c..fa522368 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -344,7 +344,7 @@
   // The opacity of a layer always applies to its children (either implicitly
   // via a render surface or explicitly if the parent preserves 3D), so the
   // entire subtree can be skipped if this layer is fully transparent.
-  return !layer->EffectiveOpacity();
+  return !layer->opacity();
 }
 
 static inline bool SubtreeShouldBeSkipped(Layer* layer,
@@ -380,8 +380,7 @@
   // In particular, it should not cause the subtree to be skipped.
   // Similarly, for layers that might animate opacity using an impl-only
   // animation, their subtree should also not be skipped.
-  return !layer->EffectiveOpacity() &&
-         !layer->HasPotentiallyRunningOpacityAnimation() &&
+  return !layer->opacity() && !layer->HasPotentiallyRunningOpacityAnimation() &&
          !layer->OpacityCanAnimateOnImplThread();
 }
 
@@ -431,19 +430,18 @@
 template <typename LayerType>
 void FindLayersThatNeedUpdates(
     LayerType* layer,
-    const TransformTree& transform_tree,
-    const EffectTree& effect_tree,
+    const TransformTree& tree,
+    bool subtree_is_visible_from_ancestor,
     typename LayerType::LayerListType* update_layer_list,
     std::vector<LayerType*>* visible_layer_list) {
-  DCHECK_GE(layer->effect_tree_index(), 0);
   bool layer_is_drawn =
-      effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
+      layer->HasCopyRequest() ||
+      (subtree_is_visible_from_ancestor && !layer->hide_layer_and_subtree());
 
-  if (layer->parent() &&
-      SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree))
+  if (layer->parent() && SubtreeShouldBeSkipped(layer, layer_is_drawn, tree))
     return;
 
-  if (!LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree)) {
+  if (!LayerShouldBeSkipped(layer, layer_is_drawn, tree)) {
     visible_layer_list->push_back(layer);
     update_layer_list->push_back(layer);
   }
@@ -459,7 +457,7 @@
   }
 
   for (size_t i = 0; i < layer->children().size(); ++i) {
-    FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree,
+    FindLayersThatNeedUpdates(layer->child_at(i), tree, layer_is_drawn,
                               update_layer_list, visible_layer_list);
   }
 }
@@ -681,8 +679,9 @@
                can_render_to_separate_surface);
   ComputeEffects(&property_trees->effect_tree);
 
+  const bool subtree_is_visible_from_ancestor = true;
   FindLayersThatNeedUpdates(root_layer, property_trees->transform_tree,
-                            property_trees->effect_tree, update_layer_list,
+                            subtree_is_visible_from_ancestor, update_layer_list,
                             visible_layer_list);
   CalculateVisibleRects<LayerType>(
       *visible_layer_list, property_trees->clip_tree,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 14149181..76c91a0 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -668,7 +668,7 @@
   // The opacity of a layer always applies to its children (either implicitly
   // via a render surface or explicitly if the parent preserves 3D), so the
   // entire subtree can be skipped if this layer is fully transparent.
-  return !layer->EffectiveOpacity();
+  return !layer->opacity();
 }
 
 static inline void SavePaintPropertiesLayer(LayerImpl* layer) {}
@@ -1515,7 +1515,7 @@
   // the right results.
   const bool layer_is_visible =
       data_from_ancestor.subtree_is_visible_from_ancestor &&
-      layer->EffectiveOpacity() != 0;
+      !layer->hide_layer_and_subtree();
   const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
 
   // The root layer cannot skip CalcDrawProperties.
@@ -2327,21 +2327,11 @@
 };
 
 void CalculateRenderTargetInternal(LayerImpl* layer,
-                                   PropertyTrees* property_trees,
                                    bool subtree_visible_from_ancestor,
-                                   bool can_render_to_separate_surface,
-                                   bool use_property_trees) {
-  bool layer_is_drawn;
-  if (use_property_trees) {
-    DCHECK_GE(layer->effect_tree_index(), 0);
-    layer_is_drawn =
-        property_trees->effect_tree.Node(layer->effect_tree_index())
-            ->data.is_drawn;
-  } else {
-    layer_is_drawn =
-        (subtree_visible_from_ancestor && layer->EffectiveOpacity() != 0) ||
-        layer->HasCopyRequest();
-  }
+                                   bool can_render_to_separate_surface) {
+  const bool layer_is_visible =
+      subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
+  const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
 
   // The root layer cannot be skipped.
   if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
@@ -2374,8 +2364,7 @@
   for (size_t i = 0; i < layer->children().size(); ++i) {
     CalculateRenderTargetInternal(
         LayerTreeHostCommon::get_layer_as_raw_ptr(layer->children(), i),
-        property_trees, layer_is_drawn, can_render_to_separate_surface,
-        use_property_trees);
+        layer_is_drawn, can_render_to_separate_surface);
   }
 }
 
@@ -2406,17 +2395,14 @@
 
   // |can_render_to_separate_surface| and |current_render_surface_layer_list_id|
   // are settings that should stay the same during recursion.
-  bool layer_is_drawn = false;
-  if (use_property_trees) {
-    DCHECK_GE(layer->effect_tree_index(), 0);
-    layer_is_drawn =
-        property_trees->effect_tree.Node(layer->effect_tree_index())
-            ->data.is_drawn;
-  } else {
-    layer_is_drawn =
-        (subtree_visible_from_ancestor && layer->EffectiveOpacity() != 0) ||
-        layer->HasCopyRequest();
-  }
+
+  // Layers that are marked as hidden will hide themselves and their subtree.
+  // Exception: Layers with copy requests, whether hidden or not, must be drawn
+  // anyway.  In this case, we will inform their subtree they are visible to get
+  // the right results.
+  const bool layer_is_visible =
+      subtree_visible_from_ancestor && !layer->hide_layer_and_subtree();
+  const bool layer_is_drawn = layer_is_visible || layer->HasCopyRequest();
 
   // The root layer cannot be skipped.
   if (!IsRootLayer(layer) && SubtreeShouldBeSkipped(layer, layer_is_drawn)) {
@@ -2465,14 +2451,10 @@
       // target.
       layer->render_surface()->set_contributes_to_drawn_surface(false);
     } else {
-      bool contributes_to_drawn_surface =
-          use_property_trees
-              ? property_trees->effect_tree.ContributesToDrawnSurface(
-                    layer->effect_tree_index())
-              : subtree_visible_from_ancestor &&
-                    layer->EffectiveOpacity() != 0.f;
+      // Even if the |layer_is_drawn|, it only contributes to a drawn surface
+      // when the |layer_is_visible|.
       layer->render_surface()->set_contributes_to_drawn_surface(
-          contributes_to_drawn_surface);
+          layer_is_visible);
     }
 
     // Ignore occlusion from outside the surface when surface contents need to
@@ -2637,10 +2619,8 @@
 
 void CalculateRenderTarget(
     LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs) {
-  CalculateRenderTargetInternal(
-      inputs->root_layer, inputs->property_trees, true,
-      inputs->can_render_to_separate_surface,
-      inputs->verify_property_trees || inputs->use_property_trees);
+  CalculateRenderTargetInternal(inputs->root_layer, true,
+                                inputs->can_render_to_separate_surface);
 }
 
 void CalculateRenderSurfaceLayerList(
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 15cc8cca..f4e5b60 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -150,10 +150,7 @@
                                   grand_child->screen_space_transform());
 }
 
-TEST_F(LayerTreeHostCommonTest,
-       ScreenSpaceTransformOfSkippedLayersWithHandlers) {
-  // Even for layers that are skipped, we need to compute the correct screen
-  // space transform because it is used during hit testing.
+TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) {
   LayerImpl* parent = root_layer();
   LayerImpl* child = AddChild<LayerImpl>(parent);
   LayerImpl* grand_child = AddChild<LayerImpl>(child);
@@ -166,7 +163,9 @@
   SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(),
                                gfx::PointF(10, 10), gfx::Size(100, 100), true,
                                false);
-  // This will cause the subtree to be skipped.
+  // This would have previously caused us to skip our subtree, but this would be
+  // wrong; we need up-to-date draw properties to do hit testing on the layers
+  // with handlers.
   child->SetOpacity(0.f);
   SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
                                gfx::PointF(10, 10), gfx::Size(100, 100), true,
@@ -179,8 +178,10 @@
   EXPECT_FALSE(grand_child->has_render_surface());
   // Check that we've computed draw properties for the subtree rooted at
   // |child|.
-  EXPECT_FALSE(child->render_surface()->screen_space_transform().IsIdentity());
-  EXPECT_FALSE(grand_child->ScreenSpaceTransform().IsIdentity());
+  EXPECT_TRUE(child->draw_properties().target_space_transform.IsIdentity());
+  EXPECT_FALSE(child->render_surface()->draw_transform().IsIdentity());
+  EXPECT_FALSE(
+      grand_child->draw_properties().target_space_transform.IsIdentity());
 }
 
 TEST_F(LayerTreeHostCommonTest, EffectTreeTransformIdTest) {
@@ -1340,8 +1341,6 @@
                                gfx::PointF(), gfx::Size(10, 10), true, false,
                                false);
   render_surface1->SetOpacity(0.f);
-  render_surface1->SetDrawsContent(true);
-  child->SetDrawsContent(true);
   FilterOperations filters;
   filters.Append(FilterOperation::CreateBlurFilter(1.5f));
   render_surface1->SetBackgroundFilters(filters);
@@ -5583,16 +5582,8 @@
   copy_child->SetDrawsContent(true);
   LayerImpl* copy_child_layer = copy_child.get();
 
-  scoped_ptr<LayerImpl> copy_grand_child =
-      LayerImpl::Create(host_impl.pending_tree(), 6);
-  SetLayerPropertiesForTesting(copy_grand_child.get(), identity_matrix,
-                               gfx::Point3F(), gfx::PointF(), gfx::Size(20, 20),
-                               true, false, false);
-  copy_child->SetDrawsContent(true);
-  LayerImpl* copy_grand_child_layer = copy_grand_child.get();
-
   scoped_ptr<LayerImpl> copy_grand_parent_sibling_before =
-      LayerImpl::Create(host_impl.pending_tree(), 7);
+      LayerImpl::Create(host_impl.pending_tree(), 6);
   SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(),
                                identity_matrix, gfx::Point3F(), gfx::PointF(),
                                gfx::Size(40, 40), true, false, false);
@@ -5601,7 +5592,7 @@
       copy_grand_parent_sibling_before.get();
 
   scoped_ptr<LayerImpl> copy_grand_parent_sibling_after =
-      LayerImpl::Create(host_impl.pending_tree(), 8);
+      LayerImpl::Create(host_impl.pending_tree(), 7);
   SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(),
                                identity_matrix, gfx::Point3F(), gfx::PointF(),
                                gfx::Size(40, 40), true, false, false);
@@ -5609,7 +5600,6 @@
   LayerImpl* copy_grand_parent_sibling_after_layer =
       copy_grand_parent_sibling_after.get();
 
-  copy_child->AddChild(std::move(copy_grand_child));
   copy_request->AddChild(std::move(copy_child));
   copy_parent->AddChild(std::move(copy_request));
   copy_grand_parent->AddChild(std::move(copy_parent));
@@ -5618,12 +5608,10 @@
   root->AddChild(std::move(copy_grand_parent_sibling_after));
 
   // Hide the copy_grand_parent and its subtree. But make a copy request in that
-  // hidden subtree on copy_layer. Also hide the copy grand child and its
-  // subtree.
+  // hidden subtree on copy_layer.
   copy_grand_parent_layer->SetHideLayerAndSubtree(true);
   copy_grand_parent_sibling_before_layer->SetHideLayerAndSubtree(true);
   copy_grand_parent_sibling_after_layer->SetHideLayerAndSubtree(true);
-  copy_grand_child_layer->SetHideLayerAndSubtree(true);
 
   std::vector<scoped_ptr<CopyOutputRequest>> copy_requests;
   copy_requests.push_back(
@@ -5644,27 +5632,27 @@
   EXPECT_GT(copy_parent_layer->num_copy_requests_in_target_subtree(), 0);
   EXPECT_GT(copy_layer->num_copy_requests_in_target_subtree(), 0);
 
-  // We should have four render surfaces, one for the root, one for the grand
-  // parent since it has opacity and two drawing descendants, one for the parent
+  // We should have three render surfaces, one for the root, one for the parent
   // since it owns a surface, and one for the copy_layer.
-  ASSERT_EQ(4u, render_surface_layer_list.size());
+  ASSERT_EQ(3u, render_surface_layer_list.size());
   EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());
-  EXPECT_EQ(copy_grand_parent_layer->id(),
-            render_surface_layer_list.at(1)->id());
-  EXPECT_EQ(copy_parent_layer->id(), render_surface_layer_list.at(2)->id());
-  EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(3)->id());
+  EXPECT_EQ(copy_parent_layer->id(), render_surface_layer_list.at(1)->id());
+  EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(2)->id());
 
-  // The root render surface should have 2 contributing layers.
+  // The root render surface should have 2 contributing layers. The
+  // copy_grand_parent is hidden along with its siblings, but the copy_parent
+  // will appear since something in its subtree needs to be drawn for a copy
+  // request.
   ASSERT_EQ(2u, root->render_surface()->layer_list().size());
   EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
-  EXPECT_EQ(copy_grand_parent_layer->id(),
+  EXPECT_EQ(copy_parent_layer->id(),
             root->render_surface()->layer_list().at(1)->id());
 
   // Nothing actually draws into the copy parent, so only the copy_layer will
   // appear in its list, since it needs to be drawn for the copy request.
   ASSERT_EQ(1u, copy_parent_layer->render_surface()->layer_list().size());
   EXPECT_EQ(copy_layer->id(),
-            copy_layer->render_surface()->layer_list().at(0)->id());
+            copy_parent_layer->render_surface()->layer_list().at(0)->id());
 
   // The copy_layer's render surface should have two contributing layers.
   ASSERT_EQ(2u, copy_layer->render_surface()->layer_list().size());
@@ -5672,26 +5660,6 @@
             copy_layer->render_surface()->layer_list().at(0)->id());
   EXPECT_EQ(copy_child_layer->id(),
             copy_layer->render_surface()->layer_list().at(1)->id());
-
-  // copy_grand_parent, copy_parent shouldn't be drawn because they are hidden,
-  // but the copy_layer and copy_child should be drawn for the copy request.
-  // copy grand child should not be drawn as its hidden even in the copy
-  // request.
-  EffectTree tree = root->layer_tree_impl()->property_trees()->effect_tree;
-  EffectNode* node = tree.Node(copy_grand_parent_layer->effect_tree_index());
-  EXPECT_FALSE(node->data.is_drawn);
-  node = tree.Node(copy_parent_layer->effect_tree_index());
-  EXPECT_FALSE(node->data.is_drawn);
-  node = tree.Node(copy_layer->effect_tree_index());
-  EXPECT_TRUE(node->data.is_drawn);
-  node = tree.Node(copy_child_layer->effect_tree_index());
-  EXPECT_TRUE(node->data.is_drawn);
-  node = tree.Node(copy_grand_child_layer->effect_tree_index());
-  EXPECT_FALSE(node->data.is_drawn);
-
-  // Though copy_layer is drawn, it shouldn't contribute to drawn surface as its
-  // actually hidden.
-  EXPECT_FALSE(copy_layer->render_surface()->contributes_to_drawn_surface());
 }
 
 TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
@@ -8872,11 +8840,11 @@
   // Now, even though child has zero opacity, we will configure |grandchild| and
   // |greatgrandchild| in several ways that should force the subtree to be
   // processed anyhow.
-  grandchild->RequestCopyOfOutput(
+  greatgrandchild->RequestCopyOfOutput(
       CopyOutputRequest::CreateBitmapRequest(base::Bind(&CopyOutputCallback)));
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
   EXPECT_EQ(gfx::Rect(10, 10), grandchild->visible_rect_from_property_trees());
-  greatgrandchild->set_visible_rect_from_property_trees(gfx::Rect());
+  grandchild->set_visible_rect_from_property_trees(gfx::Rect());
 
   // Add an opacity animation with a start delay.
   animation_id = 1;
@@ -8924,10 +8892,15 @@
   SetLayerPropertiesForTesting(grandchild.get(), identity, gfx::Point3F(),
                                gfx::PointF(), gfx::Size(10, 10), true, false,
                                false);
+  SetLayerPropertiesForTesting(greatgrandchild.get(), identity, gfx::Point3F(),
+                               gfx::PointF(), gfx::Size(10, 10), true, false,
+                               true);
 
   LayerImpl* child_ptr = child.get();
   LayerImpl* grandchild_ptr = grandchild.get();
+  LayerImpl* greatgrandchild_ptr = greatgrandchild.get();
 
+  grandchild->AddChild(std::move(greatgrandchild));
   child->AddChild(std::move(grandchild));
   root->AddChild(std::move(child));
 
@@ -8967,7 +8940,7 @@
   std::vector<scoped_ptr<CopyOutputRequest>> requests;
   requests.push_back(CopyOutputRequest::CreateEmptyRequest());
 
-  grandchild_ptr->PassCopyRequests(&requests);
+  greatgrandchild_ptr->PassCopyRequests(&requests);
   root.get()->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawPropertiesWithPropertyTrees(root.get());
   EXPECT_EQ(gfx::Rect(10, 10),
@@ -9559,9 +9532,7 @@
   SetLayerPropertiesForTesting(render_surface, identity_matrix, gfx::Point3F(),
                                gfx::PointF(), gfx::Size(30, 30), true, false,
                                true);
-  gfx::Transform translation;
-  translation.Translate(10, 10);
-  SetLayerPropertiesForTesting(test_layer, translation, gfx::Point3F(),
+  SetLayerPropertiesForTesting(test_layer, identity_matrix, gfx::Point3F(),
                                gfx::PointF(), gfx::Size(20, 20), true, false,
                                false);
 
@@ -9571,7 +9542,9 @@
   test_layer->SetHaveWheelEventHandlers(true);
 
   ExecuteCalculateDrawProperties(root);
-  EXPECT_EQ(translation, test_layer->ScreenSpaceTransform());
+  EXPECT_EQ(gfx::Rect(20, 20), test_layer->drawable_content_rect());
+  EXPECT_EQ(gfx::RectF(20, 20),
+            render_surface->render_surface()->DrawableContentRect());
 }
 
 TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) {
@@ -9654,12 +9627,12 @@
 
   hidden->SetHideLayerAndSubtree(true);
   ExecuteCalculateDrawProperties(root);
-  EXPECT_TRUE(test->IsHidden());
+  EXPECT_TRUE(test->LayerIsHidden());
 
   hidden->SetHideLayerAndSubtree(false);
   root->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(root);
-  EXPECT_FALSE(test->IsHidden());
+  EXPECT_FALSE(test->LayerIsHidden());
 }
 
 TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) {
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc
index 4bcb762..250ac4d0 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -174,7 +174,7 @@
   // Readbacks always happen on render targets so we only need to check
   // for readbacks here.
   bool target_is_only_for_copy_request =
-      finished_target->HasCopyRequest() && finished_target->IsHidden();
+      finished_target->HasCopyRequest() && finished_target->LayerIsHidden();
 
   // If the occlusion within the surface can not be applied to things outside of
   // the surface's subtree, then clear the occlusion here so it won't be used.
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 00c620b5..64209e93 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -415,10 +415,6 @@
     : opacity(1.f),
       screen_space_opacity(1.f),
       has_render_surface(false),
-      has_copy_request(false),
-      has_background_filters(false),
-      is_drawn(true),
-      screen_space_opacity_is_animating(false),
       num_copy_requests_in_subtree(0),
       transform_id(0),
       clip_id(0) {}
@@ -427,11 +423,6 @@
   return opacity == other.opacity &&
          screen_space_opacity == other.screen_space_opacity &&
          has_render_surface == other.has_render_surface &&
-         has_copy_request == other.has_copy_request &&
-         has_background_filters == other.has_background_filters &&
-         is_drawn == other.is_drawn &&
-         screen_space_opacity_is_animating ==
-             other.screen_space_opacity_is_animating &&
          num_copy_requests_in_subtree == other.num_copy_requests_in_subtree &&
          transform_id == other.transform_id && clip_id == other.clip_id;
 }
@@ -442,11 +433,6 @@
   data->set_opacity(opacity);
   data->set_screen_space_opacity(screen_space_opacity);
   data->set_has_render_surface(has_render_surface);
-  data->set_has_copy_request(has_copy_request);
-  data->set_has_background_filters(has_background_filters);
-  data->set_is_drawn(is_drawn);
-  data->set_screen_space_opacity_is_animating(
-      screen_space_opacity_is_animating);
   data->set_num_copy_requests_in_subtree(num_copy_requests_in_subtree);
   data->set_transform_id(transform_id);
   data->set_clip_id(clip_id);
@@ -459,10 +445,6 @@
   opacity = data.opacity();
   screen_space_opacity = data.screen_space_opacity();
   has_render_surface = data.has_render_surface();
-  has_copy_request = data.has_copy_request();
-  has_background_filters = data.has_background_filters();
-  is_drawn = data.is_drawn();
-  screen_space_opacity_is_animating = data.screen_space_opacity_is_animating();
   num_copy_requests_in_subtree = data.num_copy_requests_in_subtree();
   transform_id = data.transform_id();
   clip_id = data.clip_id();
@@ -1093,53 +1075,16 @@
     node->data.screen_space_opacity *= parent_node->data.screen_space_opacity;
 }
 
-void EffectTree::UpdateIsDrawn(EffectNode* node, EffectNode* parent_node) {
-  // Nodes that have screen space opacity 0 are hidden. So they are not drawn.
-  // Exceptions:
-  // 1) Nodes that contribute to copy requests, whether hidden or not, must be
-  //    drawn.
-  // 2) Nodes that have a background filter.
-  // 3) Nodes with animating screen space opacity.
-  if (node->data.has_copy_request ||
-      node->data.screen_space_opacity_is_animating ||
-      node->data.has_background_filters)
-    node->data.is_drawn = true;
-  else if (node->data.opacity == 0.f)
-    node->data.is_drawn = false;
-  else if (parent_node)
-    node->data.is_drawn = parent_node->data.is_drawn;
-  else
-    node->data.is_drawn = true;
-}
-
 void EffectTree::UpdateEffects(int id) {
   EffectNode* node = Node(id);
   EffectNode* parent_node = parent(node);
 
   UpdateOpacities(node, parent_node);
-  UpdateIsDrawn(node, parent_node);
 }
 
 void EffectTree::ClearCopyRequests() {
-  for (auto& node : nodes()) {
+  for (auto& node : nodes())
     node.data.num_copy_requests_in_subtree = 0;
-    node.data.has_copy_request = false;
-  }
-  set_needs_update(true);
-}
-
-bool EffectTree::ContributesToDrawnSurface(int id) {
-  // All drawn nodes contribute to drawn surface.
-  // Exception : Nodes that are hidden and are drawn only for the sake of
-  // copy requests.
-  EffectNode* node = Node(id);
-  EffectNode* parent_node = parent(node);
-  bool contributes_to_drawn_surface =
-      node->data.is_drawn &&
-      (node->data.opacity != 0.f || node->data.has_background_filters);
-  if (parent_node && !parent_node->data.is_drawn)
-    contributes_to_drawn_surface = false;
-  return contributes_to_drawn_surface;
 }
 
 void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations(
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index dc479a94..db0396d 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -244,10 +244,6 @@
   float screen_space_opacity;
 
   bool has_render_surface;
-  bool has_copy_request;
-  bool has_background_filters;
-  bool is_drawn;
-  bool screen_space_opacity_is_animating;
   int num_copy_requests_in_subtree;
   int transform_id;
   int clip_id;
@@ -503,14 +499,11 @@
 
   void ClearCopyRequests();
 
-  bool ContributesToDrawnSurface(int id);
-
   void ToProtobuf(proto::PropertyTree* proto) const;
   void FromProtobuf(const proto::PropertyTree& proto);
 
  private:
   void UpdateOpacities(EffectNode* node, EffectNode* parent_node);
-  void UpdateIsDrawn(EffectNode* node, EffectNode* parent_node);
 };
 
 class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 8af9eb8..a27bd3c 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -520,7 +520,7 @@
       num_descendants_that_draw_content > 0 &&
       (layer->DrawsContent() || num_descendants_that_draw_content > 1);
 
-  if (layer->EffectiveOpacity() != 1.f && layer->should_flatten_transform() &&
+  if (layer->opacity() != 1.f && layer->should_flatten_transform() &&
       at_least_two_layers_in_subtree_draw_content) {
     TRACE_EVENT_INSTANT0(
         "cc", "PropertyTreeBuilder::ShouldCreateRenderSurface opacity",
@@ -557,7 +557,7 @@
     LayerType* layer,
     DataForRecursion<LayerType>* data_for_children) {
   const bool is_root = !layer->parent();
-  const bool has_transparency = layer->EffectiveOpacity() != 1.f;
+  const bool has_transparency = layer->opacity() != 1.f;
   const bool has_animated_opacity = IsAnimatingOpacity(layer);
   const bool should_create_render_surface = ShouldCreateRenderSurface(
       layer, data_from_ancestor.compound_transform_since_render_target,
@@ -580,10 +580,9 @@
 
   EffectNode node;
   node.owner_id = layer->id();
-  node.data.opacity = layer->EffectiveOpacity();
+  node.data.opacity = layer->opacity();
+  node.data.screen_space_opacity = layer->opacity();
   node.data.has_render_surface = should_create_render_surface;
-  node.data.has_copy_request = layer->HasCopyRequest();
-  node.data.has_background_filters = !layer->background_filters().IsEmpty();
 
   if (!is_root) {
     // The effect node's transform id is used only when we create a render
@@ -598,9 +597,9 @@
     }
     node.data.clip_id = data_from_ancestor.clip_tree_parent;
 
-    EffectNode* parent = data_from_ancestor.effect_tree->Node(parent_id);
-    node.data.screen_space_opacity_is_animating =
-        parent->data.screen_space_opacity_is_animating || has_animated_opacity;
+    node.data.screen_space_opacity *=
+        data_from_ancestor.effect_tree->Node(parent_id)
+            ->data.screen_space_opacity;
   } else {
     // Root render surface acts the unbounded and untransformed to draw content
     // into. Transform node created from root layer (includes device scale
@@ -608,7 +607,6 @@
     // to root render surface's content, but not root render surface itself.
     node.data.transform_id = kRootPropertyTreeNodeId;
     node.data.clip_id = kRootPropertyTreeNodeId;
-    node.data.screen_space_opacity_is_animating = has_animated_opacity;
   }
   data_for_children->effect_tree_parent =
       data_for_children->effect_tree->Insert(node, parent_id);
@@ -648,6 +646,10 @@
   AddClipNodeIfNeeded(data_from_parent, layer, created_render_surface,
                       created_transform_node, &data_for_children);
 
+  data_for_children.is_hidden =
+      layer->hide_layer_and_subtree() || data_from_parent.is_hidden;
+  layer->set_is_hidden_from_property_trees(data_for_children.is_hidden);
+
   for (size_t i = 0; i < layer->children().size(); ++i) {
     if (!layer->child_at(i)->scroll_parent()) {
       DataForRecursionFromChild<LayerType> data_from_child;
@@ -766,11 +768,11 @@
   property_trees->needs_rebuild = false;
 
   // The transform tree is kept up-to-date as it is built, but the
-  // combined_clips stored in the clip tree and the screen_space_opacity and
-  // is_drawn in the effect tree aren't computed during tree building.
+  // combined_clips stored in the clip tree aren't computed during tree
+  // building.
   property_trees->transform_tree.set_needs_update(false);
   property_trees->clip_tree.set_needs_update(true);
-  property_trees->effect_tree.set_needs_update(true);
+  property_trees->effect_tree.set_needs_update(false);
 }
 
 void PropertyTreeBuilder::BuildPropertyTrees(