Handle device scale factor properly in cc::MirrorLayerImpl

To avoid applying device scale factor twice,
MirrorLayerImpl::AppendQuads() should first undo the scale factor
applied to draw transform as it will be applied later again (similar to
what LayerImpl::PopulateScaledSharedQuadState() does).

BUG=947565

Change-Id: I7e8bdb21ca9883f6639166dfa9b7b58fc33b90dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1685892
Commit-Queue: Mohsen Izadi <mohsen@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#674954}
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index 850fbc4..f98f342 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -187,7 +187,7 @@
   viz::SharedQuadState* shared_quad_state =
       render_pass->CreateAndAppendSharedQuadState();
   PopulateScaledSharedQuadState(shared_quad_state, internal_contents_scale_,
-                                internal_contents_scale_, contents_opaque());
+                                contents_opaque());
 
   // Appends a dummy quad here, which will be updated later once the resource
   // is ready in UpdateHudTexture(). We don't add a TextureDrawQuad directly
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 5acf62e..acdbecbc 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -151,22 +151,32 @@
 }
 
 void LayerImpl::PopulateScaledSharedQuadState(viz::SharedQuadState* state,
-                                              float layer_to_content_scale_x,
-                                              float layer_to_content_scale_y,
+                                              float layer_to_content_scale,
                                               bool contents_opaque) const {
-  gfx::Transform scaled_draw_transform =
-      draw_properties_.target_space_transform;
-  scaled_draw_transform.Scale(SK_MScalar1 / layer_to_content_scale_x,
-                              SK_MScalar1 / layer_to_content_scale_y);
-  gfx::Size scaled_bounds = gfx::ScaleToCeiledSize(
-      bounds(), layer_to_content_scale_x, layer_to_content_scale_y);
-  gfx::Rect scaled_visible_layer_rect = gfx::ScaleToEnclosingRect(
-      visible_layer_rect(), layer_to_content_scale_x, layer_to_content_scale_y);
+  gfx::Size scaled_bounds =
+      gfx::ScaleToCeiledSize(bounds(), layer_to_content_scale);
+  gfx::Rect scaled_visible_layer_rect =
+      gfx::ScaleToEnclosingRect(visible_layer_rect(), layer_to_content_scale);
   scaled_visible_layer_rect.Intersect(gfx::Rect(scaled_bounds));
 
+  PopulateScaledSharedQuadStateWithContentRects(
+      state, layer_to_content_scale, gfx::Rect(scaled_bounds),
+      scaled_visible_layer_rect, contents_opaque);
+}
+
+void LayerImpl::PopulateScaledSharedQuadStateWithContentRects(
+    viz::SharedQuadState* state,
+    float layer_to_content_scale,
+    const gfx::Rect& content_rect,
+    const gfx::Rect& visible_content_rect,
+    bool contents_opaque) const {
+  gfx::Transform scaled_draw_transform =
+      draw_properties_.target_space_transform;
+  scaled_draw_transform.Scale(SK_MScalar1 / layer_to_content_scale,
+                              SK_MScalar1 / layer_to_content_scale);
+
   EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_);
-  state->SetAll(scaled_draw_transform, gfx::Rect(scaled_bounds),
-                scaled_visible_layer_rect,
+  state->SetAll(scaled_draw_transform, content_rect, visible_content_rect,
                 draw_properties().rounded_corner_bounds,
                 draw_properties().clip_rect, draw_properties().is_clipped,
                 contents_opaque, draw_properties().opacity,
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 423eb7b..9b9d883 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -129,13 +129,19 @@
   void PopulateSharedQuadState(viz::SharedQuadState* state,
                                bool contents_opaque) const;
 
-  // If using this, you need to override GetEnclosingRectInTargetSpace() to
+  // If using these two, you need to override GetEnclosingRectInTargetSpace() to
   // use GetScaledEnclosingRectInTargetSpace(). To do otherwise may result in
   // inconsistent values, and drawing/clipping problems.
   void PopulateScaledSharedQuadState(viz::SharedQuadState* state,
-                                     float layer_to_content_scale_x,
-                                     float layer_to_content_scale_y,
+                                     float layer_to_content_scale,
                                      bool contents_opaque) const;
+  void PopulateScaledSharedQuadStateWithContentRects(
+      viz::SharedQuadState* state,
+      float layer_to_content_scale,
+      const gfx::Rect& content_rect,
+      const gfx::Rect& content_visible_rect,
+      bool contents_opaque) const;
+
   // WillDraw must be called before AppendQuads. If WillDraw returns false,
   // AppendQuads and DidDraw will not be called. If WillDraw returns true,
   // DidDraw is guaranteed to be called before another WillDraw or before
diff --git a/cc/layers/mirror_layer_impl.cc b/cc/layers/mirror_layer_impl.cc
index 00de04dc..b36f293 100644
--- a/cc/layers/mirror_layer_impl.cc
+++ b/cc/layers/mirror_layer_impl.cc
@@ -37,19 +37,12 @@
   if (unoccluded_content_rect.IsEmpty())
     return;
 
+  const bool contents_opaque = false;
   viz::SharedQuadState* shared_quad_state =
       render_pass->CreateAndAppendSharedQuadState();
-  bool contents_opaque = false;
-  auto* effect_node = GetEffectTree().Node(effect_tree_index());
-  shared_quad_state->SetAll(
-      draw_properties().target_space_transform, content_rect, content_rect,
-      draw_properties().rounded_corner_bounds, draw_properties().clip_rect,
-      draw_properties().is_clipped, contents_opaque, draw_properties().opacity,
-      effect_node->HasRenderSurface() ? SkBlendMode::kSrcOver
-                                      : effect_node->blend_mode,
-      GetSortingContextId());
-  shared_quad_state->is_fast_rounded_corner =
-      draw_properties().is_fast_rounded_corner;
+  PopulateScaledSharedQuadStateWithContentRects(
+      shared_quad_state, GetIdealContentsScale(), content_rect, content_rect,
+      contents_opaque);
 
   AppendDebugBorderQuad(render_pass, content_rect, shared_quad_state,
                         append_quads_data);
@@ -81,6 +74,10 @@
   return gfx::Rect(bounds());
 }
 
+gfx::Rect MirrorLayerImpl::GetEnclosingRectInTargetSpace() const {
+  return GetScaledEnclosingRectInTargetSpace(GetIdealContentsScale());
+}
+
 const char* MirrorLayerImpl::LayerTypeAsString() const {
   return "cc::MirrorLayerImpl";
 }
diff --git a/cc/layers/mirror_layer_impl.h b/cc/layers/mirror_layer_impl.h
index 0ab1a270..b2e6204 100644
--- a/cc/layers/mirror_layer_impl.h
+++ b/cc/layers/mirror_layer_impl.h
@@ -47,6 +47,7 @@
                    AppendQuadsData* append_quads_data) override;
   void PushPropertiesTo(LayerImpl* layer) override;
   gfx::Rect GetDamageRect() const override;
+  gfx::Rect GetEnclosingRectInTargetSpace() const override;
 
  protected:
   MirrorLayerImpl(LayerTreeImpl* tree_impl, int id);
diff --git a/cc/layers/painted_scrollbar_layer_impl.cc b/cc/layers/painted_scrollbar_layer_impl.cc
index dc0653c..c6426b6 100644
--- a/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/cc/layers/painted_scrollbar_layer_impl.cc
@@ -100,7 +100,7 @@
   viz::SharedQuadState* shared_quad_state =
       render_pass->CreateAndAppendSharedQuadState();
   PopulateScaledSharedQuadState(shared_quad_state, internal_contents_scale_,
-                                internal_contents_scale_, contents_opaque());
+                                contents_opaque());
 
   AppendDebugBorderQuad(render_pass, gfx::Rect(internal_content_bounds_),
                         shared_quad_state, append_quads_data);
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 07afe94..0000c0b 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -205,7 +205,7 @@
     // The downstream CA layers use shared_quad_state to generate resources of
     // the right size even if it is a solid color picture layer.
     PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
-                                  max_contents_scale, contents_opaque());
+                                  contents_opaque());
 
     AppendDebugBorderQuad(render_pass, gfx::Rect(bounds()), shared_quad_state,
                           append_quads_data);
@@ -230,7 +230,7 @@
   float device_scale_factor = layer_tree_impl()->device_scale_factor();
   float max_contents_scale = MaximumTilingContentsScale();
   PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
-                                max_contents_scale, contents_opaque());
+                                contents_opaque());
   Occlusion scaled_occlusion;
   if (mask_type_ == Layer::LayerMaskType::NOT_MASK) {
     scaled_occlusion =
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 0b242606..21f0fa23 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -722,8 +722,7 @@
       gfx::Rect(layer_bounds);
   viz::SharedQuadState state;
   active_layer()->PopulateScaledSharedQuadState(
-      &state, adjusted_scale, adjusted_scale,
-      active_layer()->contents_opaque());
+      &state, adjusted_scale, active_layer()->contents_opaque());
 }
 
 TEST_F(PictureLayerImplTest, PinchGestureTilings) {
diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc
index 8e5ca03..5eac17c 100644
--- a/cc/layers/render_surface_unittest.cc
+++ b/cc/layers/render_surface_unittest.cc
@@ -65,7 +65,7 @@
         render_pass->CreateAndAppendSharedQuadState();
     float max_contents_scale = 1.f;
     PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale,
-                                  max_contents_scale, contents_opaque());
+                                  contents_opaque());
     bool needs_blending = false;
     for (const auto& rect : quad_rects_) {
       auto* quad = render_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc
index 9d4a37a..6ef4249 100644
--- a/cc/layers/surface_layer_impl.cc
+++ b/cc/layers/surface_layer_impl.cc
@@ -143,7 +143,7 @@
       render_pass->CreateAndAppendSharedQuadState();
 
   PopulateScaledSharedQuadState(shared_quad_state, device_scale_factor,
-                                device_scale_factor, contents_opaque());
+                                contents_opaque());
 
   if (surface_range_.IsValid()) {
     auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
diff --git a/cc/trees/layer_tree_host_pixeltest_mirror.cc b/cc/trees/layer_tree_host_pixeltest_mirror.cc
index ed011f43..cbd67e31 100644
--- a/cc/trees/layer_tree_host_pixeltest_mirror.cc
+++ b/cc/trees/layer_tree_host_pixeltest_mirror.cc
@@ -20,6 +20,12 @@
       public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
  protected:
   RendererType renderer_type() { return GetParam(); }
+
+  void InitializeSettings(LayerTreeSettings* settings) override {
+    // MirrorLayer is only used by UI compositor; so, match its behavior by
+    // setting layer_transforms_should_scale_layer_contents to false.
+    settings->layer_transforms_should_scale_layer_contents = false;
+  }
 };
 
 const LayerTreeTest::RendererType kRendererTypes[] = {