Use separate PaintFlags for the spaced tile shader

We would setup the tile shader using the same PaintFlags that we had
(partially) set up for the actual image draw. This meant that we'd draw
the shader picture using the same blend mode, which could easily end up
yielding nothing.

Set up a "fresh" PaintFlags for the tile shader as needed instead, using
only flags relevant for the shader.

Bug: 919637
Change-Id: Id141daca481ce3f90ed0c1f44c801eafcef5964b
Reviewed-on: https://chromium-review.googlesource.com/c/1401045
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#621188}
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc
index 154e994..10b3f47 100644
--- a/third_party/blink/renderer/platform/graphics/image.cc
+++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -303,7 +303,8 @@
 
 sk_sp<PaintShader> CreatePatternShader(const PaintImage& image,
                                        const SkMatrix& shader_matrix,
-                                       const PaintFlags& paint,
+                                       SkFilterQuality quality_to_use,
+                                       bool should_antialias,
                                        const FloatSize& spacing,
                                        SkShader::TileMode tmx,
                                        SkShader::TileMode tmy) {
@@ -318,7 +319,10 @@
 
   PaintRecorder recorder;
   cc::PaintCanvas* canvas = recorder.beginRecording(tile_rect);
-  canvas->drawImage(image, 0, 0, &paint);
+  PaintFlags flags;
+  flags.setAntiAlias(should_antialias);
+  flags.setFilterQuality(quality_to_use);
+  canvas->drawImage(image, 0, 0, &flags);
 
   return PaintShader::MakePaintRecord(recorder.finishRecordingAsPicture(),
                                       tile_rect, tmx, tmy, &shader_matrix);
@@ -389,22 +393,24 @@
   const auto tmy = ComputeTileMode(dest_rect.Y(), dest_rect.MaxY(), adjusted_y,
                                    adjusted_y + tile_size.Height());
 
-  PaintFlags flags = context.FillFlags();
-  flags.setColor(SK_ColorBLACK);
-  flags.setBlendMode(composite_op);
-  flags.setFilterQuality(
-      context.ComputeFilterQuality(this, dest_rect, FloatRect(subset_rect)));
-  flags.setAntiAlias(context.ShouldAntialias());
-  flags.setShader(CreatePatternShader(
-      image, local_matrix, flags,
+  SkFilterQuality quality_to_use =
+      context.ComputeFilterQuality(this, dest_rect, FloatRect(subset_rect));
+  bool should_antialias = context.ShouldAntialias();
+  sk_sp<PaintShader> tile_shader = CreatePatternShader(
+      image, local_matrix, quality_to_use, should_antialias,
       FloatSize(repeat_spacing.Width() / scale_src_to_dest.Width(),
                 repeat_spacing.Height() / scale_src_to_dest.Height()),
-      tmx, tmy));
+      tmx, tmy);
+
+  PaintFlags flags = context.FillFlags();
   // If the shader could not be instantiated (e.g. non-invertible matrix),
   // draw transparent.
   // Note: we can't simply bail, because of arbitrary blend mode.
-  if (!flags.HasShader())
-    flags.setColor(SK_ColorTRANSPARENT);
+  flags.setColor(tile_shader ? SK_ColorBLACK : SK_ColorTRANSPARENT);
+  flags.setBlendMode(composite_op);
+  flags.setFilterQuality(quality_to_use);
+  flags.setAntiAlias(should_antialias);
+  flags.setShader(std::move(tile_shader));
 
   context.DrawRect(dest_rect, flags);
 
diff --git a/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing-expected.html b/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing-expected.html
new file mode 100644
index 0000000..ffc1e19
--- /dev/null
+++ b/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing-expected.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<div style="position: relative">
+  <div style="width: 100px; height: 100px; background-color: green; position: absolute"></div>
+  <div style="width: 100px; height: 100px; background-color: green; position: absolute; left: 110px"></div>
+</div>
diff --git a/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing.html b/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing.html
new file mode 100644
index 0000000..3901b92
--- /dev/null
+++ b/third_party/blink/web_tests/css3/masking/mask-composite-source-in-repeat-spacing.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<style>
+#target {
+  height: 150px;
+  width: 210px;
+  background-color: green;
+  -webkit-mask-image: url("../../images/resources/green-100.png"),
+                      url("../../images/resources/green-100.png");
+  -webkit-mask-size: 100px 100px;
+  -webkit-mask-repeat: space, space;
+  -webkit-mask-composite: source-in;
+  mask-image: url("../../images/resources/green-100.png"),
+              url("../../images/resources/green-100.png");
+  mask-size: 100px 100px;
+  mask-repeat: space, space;
+  mask-composite: intersect;
+}
+</style>
+<div id="target"></div>