cc: Make solid color mask layer ignore occlusion

Mask layer's occlusion is actually its render surface's occlusion in the
contributed parent surface space.

However, when tiling a solid color mask layer, we used to adopt the logic
from normal picture layers: overwrite the occlusion's transform with the
layer's draw transform. This is problematic because mask layer's draw
transform is to the render surface that owns the mask. In this way, we
can generate the wrong visible quad rect and result in blanks when
rendering.

Since solid color mask layer does not do anything but cannot be fully
avoided in the current code base, we should never apply an occlusion to
it. Any occlusion to the masked content can still take effect by
applying itself to the owning render surface.

Bug: 811143, 810820, 808372
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel
Change-Id: I821492c107c2abadb9b9e6986369c9f6262d0ad4
Reviewed-on: https://chromium-review.googlesource.com/916625
Commit-Queue: Xianda Sun <sunxd@chromium.org>
Reviewed-by: enne <enne@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#537794}(cherry picked from commit cf699d7fef4e3f03743cc916209c7ebff5dc7b7a)
Reviewed-on: https://chromium-review.googlesource.com/931903
Reviewed-by: Xianda Sun <sunxd@chromium.org>
Cr-Commit-Position: refs/branch-heads/3325@{#549}
Cr-Branched-From: bc084a8b5afa3744a74927344e304c02ae54189f-refs/heads/master@{#530369}
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 6b9a345..bd84a63 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -277,13 +277,14 @@
 
     gfx::Rect scaled_visible_layer_rect =
         shared_quad_state->visible_quad_layer_rect;
-    Occlusion scaled_occlusion =
-        draw_properties()
-            .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform(
-                shared_quad_state->quad_to_target_transform);
+    Occlusion occlusion;
+    // TODO(sunxd): Compute the correct occlusion for mask layers.
+    if (mask_type_ == Layer::LayerMaskType::NOT_MASK) {
+      occlusion = draw_properties().occlusion_in_content_space;
+    }
     SolidColorLayerImpl::AppendSolidQuads(
-        render_pass, scaled_occlusion, shared_quad_state,
-        scaled_visible_layer_rect, raster_source_->GetSolidColor(),
+        render_pass, occlusion, shared_quad_state, scaled_visible_layer_rect,
+        raster_source_->GetSolidColor(),
         !layer_tree_impl()->settings().enable_edge_anti_aliasing,
         append_quads_data);
     return;
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 34e4f19..327e479 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -3366,6 +3366,39 @@
   scoped_refptr<FakeRasterSource> pending_raster_source =
       FakeRasterSource::CreateFilledSolidColor(layer_bounds);
   SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region(),
+                   Layer::LayerMaskType::NOT_MASK);
+  // Device scale factor should not affect a non-mask solid color layer.
+  host_impl()->pending_tree()->SetDeviceScaleFactor(2.f);
+  ActivateTree();
+
+  {
+    SCOPED_TRACE("Scaled occlusion");
+    gfx::Rect occluded(300, 0, 400, 2000);
+    impl.AppendQuadsWithOcclusion(active_layer(), occluded);
+
+    size_t partial_occluded_count = 0;
+    LayerTestCommon::VerifyQuadsAreOccluded(impl.quad_list(), occluded,
+                                            &partial_occluded_count);
+    // Because of the implementation of test helper AppendQuadsWithOcclusion,
+    // the occlusion will have a scale transform resulted from the device scale
+    // factor. However, the AppendQuads function will try to tile a solid color
+    // layer ignoring the scale factor, and its visible layer bounds is 500x500.
+    // So we end up having 4 partially occluded quads.
+    EXPECT_EQ(4u, impl.quad_list().size());
+    EXPECT_EQ(4u, partial_occluded_count);
+  }
+}
+
+TEST_F(PictureLayerImplTest, IgnoreOcclusionOnSolidColorMask) {
+  gfx::Size layer_bounds(1000, 1000);
+  gfx::Size viewport_size(1000, 1000);
+
+  LayerTestCommon::LayerImplTest impl;
+  host_impl()->SetViewportSize(viewport_size);
+
+  scoped_refptr<FakeRasterSource> pending_raster_source =
+      FakeRasterSource::CreateFilledSolidColor(layer_bounds);
+  SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region(),
                    Layer::LayerMaskType::MULTI_TEXTURE_MASK);
   host_impl()->pending_tree()->SetDeviceScaleFactor(2.f);
   ActivateTree();
@@ -3376,12 +3409,12 @@
     impl.AppendQuadsWithOcclusion(active_layer(), occluded);
 
     size_t partial_occluded_count = 0;
-    LayerTestCommon::VerifyQuadsAreOccluded(impl.quad_list(), occluded,
+    LayerTestCommon::VerifyQuadsAreOccluded(impl.quad_list(), gfx::Rect(),
                                             &partial_occluded_count);
-    // None of the quads shall be occluded and half of them are partially
-    // occluded.
+    // None of the quads shall be occluded because mask layers ignores
+    // occlusion.
     EXPECT_EQ(16u, impl.quad_list().size());
-    EXPECT_EQ(8u, partial_occluded_count);
+    EXPECT_EQ(0u, partial_occluded_count);
   }
 }