[Impeller] Map UVs correctly for TiledTextureContents (#38894)

diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc
index 3a501cc..c4913e5 100644
--- a/impeller/aiks/aiks_unittests.cc
+++ b/impeller/aiks/aiks_unittests.cc
@@ -163,7 +163,7 @@
       contents->SetTexture(texture);
       contents->SetTileModes(x_tile_mode, y_tile_mode);
       contents->SetSamplerDescriptor(descriptor);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     paint.color = Color(1, 1, 1, alpha);
@@ -347,7 +347,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     paint.color = Color(1.0, 1.0, 1.0, alpha);
@@ -412,7 +412,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     paint.color = Color(1.0, 1.0, 1.0, alpha);
@@ -468,7 +468,7 @@
       contents->SetColors(colors);
       contents->SetStops(stops);
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -525,7 +525,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -573,7 +573,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -635,7 +635,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -682,7 +682,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -744,7 +744,7 @@
       contents->SetStops(std::move(stops));
       contents->SetColors(std::move(colors));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
     canvas.DrawRect({0, 0, 600, 600}, paint);
@@ -1509,7 +1509,7 @@
       contents->SetColors(std::move(colors));
       contents->SetStops(std::move(stops));
       contents->SetTileMode(tile_mode);
-      contents->SetMatrix(matrix);
+      contents->SetEffectTransform(matrix);
       return contents;
     };
 
@@ -1718,21 +1718,30 @@
   auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
     Paint paint;
 
+    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
+    static Scalar distance = 2;
+    ImGui::SliderFloat("Distance", &distance, 0, 4);
+    static Scalar y_pos = 0;
+    ImGui::SliderFloat("Y", &y_pos, -3, 3);
+    static Scalar fov = 45;
+    ImGui::SliderFloat("FOV", &fov, 1, 180);
+    ImGui::End();
+
     paint.color_source_type = Paint::ColorSourceType::kScene;
-    paint.color_source = [this, gltf_scene]() {
+    paint.color_source = [&]() {
       Scalar angle = GetSecondsElapsed();
-      Scalar distance = 2;
-      auto camera_position =
-          Vector3(distance * std::sin(angle), 2, -distance * std::cos(angle));
+      auto camera_position = Vector3(distance * std::sin(angle), y_pos,
+                                     -distance * std::cos(angle));
       auto contents = std::make_shared<SceneContents>();
       contents->SetNode(gltf_scene);
       contents->SetCameraTransform(
-          Matrix::MakePerspective(Degrees(45), GetWindowSize(), 0.1, 1000) *
+          Matrix::MakePerspective(Degrees(fov), GetWindowSize(), 0.1, 1000) *
           Matrix::MakeLookAt(camera_position, {0, 0, 0}, {0, 1, 0}));
       return contents;
     };
 
     Canvas canvas;
+    canvas.DrawPaint(Paint{.color = Color::MakeRGBA8(0xf9, 0xf9, 0xf9, 0xff)});
     canvas.Scale(GetContentScale());
     canvas.DrawPaint(paint);
     return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc
index 0f9b0de..937a987 100644
--- a/impeller/display_list/display_list_dispatcher.cc
+++ b/impeller/display_list/display_list_dispatcher.cc
@@ -394,7 +394,7 @@
         contents->SetStops(stops);
         contents->SetEndPoints(start_point, end_point);
         contents->SetTileMode(tile_mode);
-        contents->SetMatrix(matrix);
+        contents->SetEffectTransform(matrix);
         return contents;
       };
       return;
@@ -418,7 +418,7 @@
         contents->SetStops(stops);
         contents->SetCenterAndRadius(center, radius);
         contents->SetTileMode(tile_mode);
-        contents->SetMatrix(matrix);
+        contents->SetEffectTransform(matrix);
         return contents;
       };
       return;
@@ -445,7 +445,7 @@
         contents->SetColors(colors);
         contents->SetStops(stops);
         contents->SetTileMode(tile_mode);
-        contents->SetMatrix(matrix);
+        contents->SetEffectTransform(matrix);
         return contents;
       };
       return;
@@ -465,7 +465,7 @@
         contents->SetTexture(texture);
         contents->SetTileModes(x_tile_mode, y_tile_mode);
         contents->SetSamplerDescriptor(desc);
-        contents->SetMatrix(matrix);
+        contents->SetEffectTransform(matrix);
         return contents;
       };
       return;
diff --git a/impeller/entity/contents/color_source_contents.cc b/impeller/entity/contents/color_source_contents.cc
index c95507e..6f0d88d 100644
--- a/impeller/entity/contents/color_source_contents.cc
+++ b/impeller/entity/contents/color_source_contents.cc
@@ -29,7 +29,7 @@
   return alpha_;
 }
 
-void ColorSourceContents::SetMatrix(Matrix matrix) {
+void ColorSourceContents::SetEffectTransform(Matrix matrix) {
   inverse_matrix_ = matrix.Invert();
 }
 
diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h
index 4396c38..89a86cf 100644
--- a/impeller/entity/contents/color_source_contents.h
+++ b/impeller/entity/contents/color_source_contents.h
@@ -20,7 +20,7 @@
 
   void SetGeometry(std::shared_ptr<Geometry> geometry);
 
-  void SetMatrix(Matrix matrix);
+  void SetEffectTransform(Matrix matrix);
 
   void SetAlpha(Scalar alpha);
 
diff --git a/impeller/entity/contents/scene_contents.cc b/impeller/entity/contents/scene_contents.cc
index 3cc574f..ffcb1af 100644
--- a/impeller/entity/contents/scene_contents.cc
+++ b/impeller/entity/contents/scene_contents.cc
@@ -71,7 +71,7 @@
   TiledTextureContents contents;
   contents.SetGeometry(GetGeometry());
   contents.SetTexture(subpass_target.GetRenderTargetTexture());
-  contents.SetMatrix(
+  contents.SetEffectTransform(
       Matrix::MakeScale(1 / entity.GetTransformation().GetScale()));
   return contents.Render(renderer, entity, pass);
 }
diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc
index 31f2458..90f1c15 100644
--- a/impeller/entity/contents/tiled_texture_contents.cc
+++ b/impeller/entity/contents/tiled_texture_contents.cc
@@ -50,14 +50,21 @@
 
   auto& host_buffer = pass.GetTransientsBuffer();
 
+  auto geometry = GetGeometry();
   auto geometry_result =
       GetGeometry()->GetPositionBuffer(renderer, entity, pass);
 
+  // TODO(bdero): The geometry should be fetched from GetPositionUVBuffer and
+  //              contain coverage-mapped UVs, and this should use
+  //              position_uv.vert.
+  //              https://github.com/flutter/flutter/issues/118553
+
   VS::VertInfo vert_info;
   vert_info.mvp = geometry_result.transform;
-  vert_info.matrix = GetInverseMatrix();
-  vert_info.texture_size = Vector2{static_cast<Scalar>(texture_size.width),
-                                   static_cast<Scalar>(texture_size.height)};
+  vert_info.effect_transform = GetInverseMatrix();
+  vert_info.bounds_origin = geometry->GetCoverage(Matrix())->origin;
+  vert_info.texture_size = Vector2(static_cast<Scalar>(texture_size.width),
+                                   static_cast<Scalar>(texture_size.height));
 
   FS::FragInfo frag_info;
   frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
diff --git a/impeller/entity/contents/tiled_texture_contents.h b/impeller/entity/contents/tiled_texture_contents.h
index 9580611..b83ff3e 100644
--- a/impeller/entity/contents/tiled_texture_contents.h
+++ b/impeller/entity/contents/tiled_texture_contents.h
@@ -36,8 +36,8 @@
  private:
   std::shared_ptr<Texture> texture_;
   SamplerDescriptor sampler_descriptor_ = {};
-  Entity::TileMode x_tile_mode_;
-  Entity::TileMode y_tile_mode_;
+  Entity::TileMode x_tile_mode_ = Entity::TileMode::kClamp;
+  Entity::TileMode y_tile_mode_ = Entity::TileMode::kClamp;
 
   FML_DISALLOW_COPY_AND_ASSIGN(TiledTextureContents);
 };
diff --git a/impeller/entity/shaders/tiled_texture_fill.vert b/impeller/entity/shaders/tiled_texture_fill.vert
index dabcdf7..1b90e59 100644
--- a/impeller/entity/shaders/tiled_texture_fill.vert
+++ b/impeller/entity/shaders/tiled_texture_fill.vert
@@ -7,7 +7,8 @@
 
 uniform VertInfo {
   mat4 mvp;
-  mat4 matrix;
+  mat4 effect_transform;
+  vec2 bounds_origin;
   vec2 texture_size;
 }
 vert_info;
@@ -18,6 +19,7 @@
 
 void main() {
   gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0);
-  vec2 transformed = IPVec2TransformPosition(vert_info.matrix, position);
-  v_texture_coords = transformed / vert_info.texture_size;
+  v_texture_coords = IPVec2TransformPosition(
+      vert_info.effect_transform,
+      (position - vert_info.bounds_origin) / vert_info.texture_size);
 }