remove unused mode parameter from SkMergeImageFilter

Bug: skia:
Change-Id: Iaa46aaef130a337987c3528685f59c56387d4a7d
Reviewed-on: https://skia-review.googlesource.com/20210
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/bench/ImageFilterDAGBench.cpp b/bench/ImageFilterDAGBench.cpp
index 350510b..aa65a1e 100644
--- a/bench/ImageFilterDAGBench.cpp
+++ b/bench/ImageFilterDAGBench.cpp
@@ -32,13 +32,11 @@
         for (int j = 0; j < loops; j++) {
             sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr));
             sk_sp<SkImageFilter> inputs[kNumInputs];
-            SkBlendMode modes[kNumInputs];
             for (int i = 0; i < kNumInputs; ++i) {
                 inputs[i] = blur;
-                modes[i] = SkBlendMode::kSrcOver;
             }
             SkPaint paint;
-            paint.setImageFilter(SkMergeImageFilter::MakeN(inputs, kNumInputs, modes));
+            paint.setImageFilter(SkMergeImageFilter::Make(inputs, kNumInputs));
             canvas->drawRect(rect, paint);
         }
     }
@@ -71,12 +69,10 @@
         for (int j = 0; j < loops; j++) {
             sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(20.0f, 20.0f, nullptr));
             sk_sp<SkImageFilter> inputs[kNumInputs];
-            SkBlendMode modes[kNumInputs];
             for (int i = 0; i < kNumInputs; ++i) {
                 inputs[i] = blur;
-                modes[i] = SkBlendMode::kSrcOver;
             }
-            sk_sp<SkImageFilter> mergeFilter = SkMergeImageFilter::MakeN(inputs, kNumInputs, modes);
+            sk_sp<SkImageFilter> mergeFilter = SkMergeImageFilter::Make(inputs, kNumInputs);
             image = image->makeWithFilter(mergeFilter.get(), subset, subset, &discardSubset,
                                           &offset);
             SkASSERT(image && image->dimensions() == fImage->dimensions());
diff --git a/bench/MergeBench.cpp b/bench/MergeBench.cpp
index c37d198..10aa8b8 100644
--- a/bench/MergeBench.cpp
+++ b/bench/MergeBench.cpp
@@ -81,7 +81,7 @@
 private:
     sk_sp<SkImageFilter> mergeBitmaps() {
         return SkMergeImageFilter::Make(SkImageSource::Make(fCheckerboard),
-                                        SkImageSource::Make(fImage), SkBlendMode::kSrcOver);
+                                        SkImageSource::Make(fImage));
     }
 
     bool fIsSmall;
diff --git a/fuzz/FilterFuzz.cpp b/fuzz/FilterFuzz.cpp
index b2d99b7..d153707 100644
--- a/fuzz/FilterFuzz.cpp
+++ b/fuzz/FilterFuzz.cpp
@@ -595,8 +595,7 @@
     case MERGE: {
         sk_sp<SkImageFilter> filA = make_image_filter();
         sk_sp<SkImageFilter> filB = make_image_filter();
-        SkBlendMode blend = make_blendmode();
-        filter = SkMergeImageFilter::Make(filA, filB, blend);
+        filter = SkMergeImageFilter::Make(filA, filB);
         break;
     }
     case COLOR: {
diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp
index fb90c06..cdca731 100644
--- a/fuzz/FuzzCanvas.cpp
+++ b/fuzz/FuzzCanvas.cpp
@@ -838,34 +838,30 @@
         case 14: {
             sk_sp<SkImageFilter> first = make_fuzz_imageFilter(fuzz, depth - 1);
             sk_sp<SkImageFilter> second = make_fuzz_imageFilter(fuzz, depth - 1);
-            SkBlendMode blendMode;
-            bool useCropRect;
-            fuzz->next(&useCropRect, &blendMode);
-            SkImageFilter::CropRect cropRect;
-            if (useCropRect) {
-                fuzz->next(&cropRect);
-            }
-            return SkMergeImageFilter::Make(std::move(first), std::move(second), blendMode,
-                                            useCropRect ? &cropRect : nullptr);
-        }
-        case 15: {
-            constexpr int kMaxCount = 4;
-            sk_sp<SkImageFilter> ifs[kMaxCount];
-            SkBlendMode blendModes[kMaxCount];
-            int count;
-            fuzz->nextRange(&count, 1, kMaxCount);
-            for (int i = 0; i < count; ++i) {
-                ifs[i] = make_fuzz_imageFilter(fuzz, depth - 1);
-            }
-            fuzz->nextN(blendModes, count);
             bool useCropRect;
             fuzz->next(&useCropRect);
             SkImageFilter::CropRect cropRect;
             if (useCropRect) {
                 fuzz->next(&cropRect);
             }
-            return SkMergeImageFilter::MakeN(ifs, count, blendModes,
-                                             useCropRect ? &cropRect : nullptr);
+            return SkMergeImageFilter::Make(std::move(first), std::move(second),
+                                            useCropRect ? &cropRect : nullptr);
+        }
+        case 15: {
+            constexpr int kMaxCount = 4;
+            sk_sp<SkImageFilter> ifs[kMaxCount];
+            int count;
+            fuzz->nextRange(&count, 1, kMaxCount);
+            for (int i = 0; i < count; ++i) {
+                ifs[i] = make_fuzz_imageFilter(fuzz, depth - 1);
+            }
+            bool useCropRect;
+            fuzz->next(&useCropRect);
+            SkImageFilter::CropRect cropRect;
+            if (useCropRect) {
+                fuzz->next(&cropRect);
+            }
+            return SkMergeImageFilter::Make(ifs, count, useCropRect ? &cropRect : nullptr);
         }
         case 16: {
             int rx, ry;
diff --git a/gm/imagefilterscropped.cpp b/gm/imagefilterscropped.cpp
index 5af6492..92b5fe0 100644
--- a/gm/imagefilterscropped.cpp
+++ b/gm/imagefilterscropped.cpp
@@ -145,7 +145,6 @@
             SkErodeImageFilter::Make(8, 8, nullptr, &cropRect),
             SkMergeImageFilter::Make(nullptr,
                                      std::move(cfOffset),
-                                     SkBlendMode::kSrcOver,
                                      &cropRect),
             SkBlurImageFilter::Make(8.0f, 8.0f, nullptr, &bogusRect),
             SkColorFilterImageFilter::Make(cf, nullptr, &bogusRect),
diff --git a/gm/imagefiltersgraph.cpp b/gm/imagefiltersgraph.cpp
index 3436d69..a369dc0 100644
--- a/gm/imagefiltersgraph.cpp
+++ b/gm/imagefiltersgraph.cpp
@@ -52,8 +52,7 @@
             sk_sp<SkImageFilter> erode(SkErodeImageFilter::Make(4, 4, blur));
             sk_sp<SkImageFilter> color(SkColorFilterImageFilter::Make(std::move(cf),
                                                                       std::move(erode)));
-            sk_sp<SkImageFilter> merge(SkMergeImageFilter::Make(blur, color,
-                                                                SkBlendMode::kSrcOver));
+            sk_sp<SkImageFilter> merge(SkMergeImageFilter::Make(blur, color));
 
             SkPaint paint;
             paint.setImageFilter(std::move(merge));
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index f90e17a..e1d8bba 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -202,10 +202,11 @@
     // V52: Remove SkTextBlob::fRunCount
     // V53: SaveLayerRec clip mask
     // V54: ComposeShader can use a Mode or a Lerp
+    // V55: Drop blendmode[] from MergeImageFilter
 
     // Only SKPs within the min/current picture version range (inclusive) can be read.
     static const uint32_t     MIN_PICTURE_VERSION = 51;     // Produced by Chrome ~M56.
-    static const uint32_t CURRENT_PICTURE_VERSION = 54;
+    static const uint32_t CURRENT_PICTURE_VERSION = 55;
 
     static bool IsValidPictInfo(const SkPictInfo& info);
     static sk_sp<SkPicture> Forwardport(const SkPictInfo&,
diff --git a/include/effects/SkMergeImageFilter.h b/include/effects/SkMergeImageFilter.h
index 03f0cea..6793361 100644
--- a/include/effects/SkMergeImageFilter.h
+++ b/include/effects/SkMergeImageFilter.h
@@ -8,17 +8,27 @@
 #ifndef SkMergeImageFilter_DEFINED
 #define SkMergeImageFilter_DEFINED
 
-#include "SkBlendMode.h"
 #include "SkImageFilter.h"
 
 class SK_API SkMergeImageFilter : public SkImageFilter {
 public:
-    ~SkMergeImageFilter() override;
+    static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter>* const filters, int count,
+                                     const CropRect* cropRect = nullptr);
 
     static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> first, sk_sp<SkImageFilter> second,
-                                     SkBlendMode, const CropRect* cropRect = nullptr);
-    static sk_sp<SkImageFilter> MakeN(sk_sp<SkImageFilter>[], int count, const SkBlendMode[],
-                                     const CropRect* cropRect = nullptr);
+                                     const CropRect* cropRect = nullptr) {
+        sk_sp<SkImageFilter> array[] = {
+            std::move(first),
+            std::move(second),
+        };
+        return Make(array, 2, cropRect);
+    }
+
+    // Change caller in chrome to use Make(...) instead
+    static sk_sp<SkImageFilter> MakeN(sk_sp<SkImageFilter> array[], int count, std::nullptr_t,
+                                      const CropRect* cropRect = nullptr) {
+        return Make(array, count, cropRect);
+    }
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
@@ -31,17 +41,7 @@
     bool onCanHandleComplexCTM() const override { return true; }
 
 private:
-    SkMergeImageFilter(sk_sp<SkImageFilter> filters[], int count, const SkBlendMode modes[],
-                       const CropRect* cropRect);
-
-    uint8_t*    fModes; // SkBlendMode
-
-    // private storage, to avoid dynamically allocating storage for our copy
-    // of the modes (unless the count is so large we can't fit).
-    intptr_t    fStorage[16];
-
-    void initAllocModes();
-    void initModes(const SkBlendMode[]);
+    SkMergeImageFilter(sk_sp<SkImageFilter>* const filters, int count, const CropRect* cropRect);
 
     typedef SkImageFilter INHERITED;
 };
diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp
index 7254192..dcb740d 100644
--- a/samplecode/SampleFilterFuzz.cpp
+++ b/samplecode/SampleFilterFuzz.cpp
@@ -555,8 +555,7 @@
         break;
     case MERGE:
         filter = SkMergeImageFilter::Make(make_image_filter(),
-                                          make_image_filter(),
-                                          make_xfermode());
+                                          make_image_filter());
         break;
     case COLOR: {
         sk_sp<SkColorFilter> cf(make_color_filter());
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 6a2c525..d14558f 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -72,6 +72,7 @@
          */
         kTextBlobImplicitRunCount_Version  = 52,
         kComposeShaderCanLerp_Version      = 54,
+        kNoModesInMergeImageFilter_Verison = 55,
     };
 
     /**
diff --git a/src/effects/SkMergeImageFilter.cpp b/src/effects/SkMergeImageFilter.cpp
index e7c3f51..e109880 100644
--- a/src/effects/SkMergeImageFilter.cpp
+++ b/src/effects/SkMergeImageFilter.cpp
@@ -14,62 +14,17 @@
 #include "SkWriteBuffer.h"
 #include "SkValidationUtils.h"
 
-sk_sp<SkImageFilter> SkMergeImageFilter::Make(sk_sp<SkImageFilter> first,
-                                              sk_sp<SkImageFilter> second,
-                                              SkBlendMode mode,
-                                              const CropRect* cropRect) {
-    sk_sp<SkImageFilter> inputs[2] = { first, second };
-    SkBlendMode modes[2] = { mode, mode };
-    return sk_sp<SkImageFilter>(new SkMergeImageFilter(inputs, 2, modes, cropRect));
-}
-
-sk_sp<SkImageFilter> SkMergeImageFilter::MakeN(sk_sp<SkImageFilter> filters[], int count,
-                                               const SkBlendMode modes[],
+sk_sp<SkImageFilter> SkMergeImageFilter::Make(sk_sp<SkImageFilter>* const filters, int count,
                                                const CropRect* cropRect) {
-    return sk_sp<SkImageFilter>(new SkMergeImageFilter(filters, count, modes, cropRect));
+    return sk_sp<SkImageFilter>(new SkMergeImageFilter(filters, count, cropRect));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkMergeImageFilter::initAllocModes() {
-    int inputCount = this->countInputs();
-    if (inputCount) {
-        size_t size = sizeof(uint8_t) * inputCount;
-        if (size <= sizeof(fStorage)) {
-            fModes = SkTCast<uint8_t*>(fStorage);
-        } else {
-            fModes = SkTCast<uint8_t*>(sk_malloc_throw(size));
-        }
-    } else {
-        fModes = nullptr;
-    }
-}
-
-void SkMergeImageFilter::initModes(const SkBlendMode modes[]) {
-    if (modes) {
-        this->initAllocModes();
-        int inputCount = this->countInputs();
-        for (int i = 0; i < inputCount; ++i) {
-            fModes[i] = SkToU8((unsigned)modes[i]);
-        }
-    } else {
-        fModes = nullptr;
-    }
-}
-
-SkMergeImageFilter::SkMergeImageFilter(sk_sp<SkImageFilter> filters[], int count,
-                                       const SkBlendMode modes[],
+SkMergeImageFilter::SkMergeImageFilter(sk_sp<SkImageFilter>* const filters, int count,
                                        const CropRect* cropRect)
     : INHERITED(filters, count, cropRect) {
     SkASSERT(count >= 0);
-    this->initModes(modes);
-}
-
-SkMergeImageFilter::~SkMergeImageFilter() {
-
-    if (fModes != SkTCast<uint8_t*>(fStorage)) {
-        sk_free(fModes);
-    }
 }
 
 sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
@@ -128,14 +83,9 @@
             continue;
         }
 
-        SkPaint paint;
-        if (fModes) {
-            paint.setBlendMode((SkBlendMode)fModes[i]);
-        }
-
         inputs[i]->draw(canvas,
                         SkIntToScalar(offsets[i].x() - x0), SkIntToScalar(offsets[i].y() - y0),
-                        &paint);
+                        nullptr);
     }
 
     offset->fX = bounds.left();
@@ -145,14 +95,12 @@
 
 sk_sp<SkImageFilter> SkMergeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
     SkSTArray<5, sk_sp<SkImageFilter>> inputs(this->countInputs());
-    SkSTArray<5, SkBlendMode> modes(this->countInputs());
     for (int i = 0; i < this->countInputs(); i++) {
         inputs.push_back(this->getInput(i) ? this->getInput(i)->makeColorSpace(xformer) : nullptr);
-        modes.push_back(fModes ? (SkBlendMode) fModes[i] : SkBlendMode::kSrcOver);
     }
 
-    return SkMergeImageFilter::MakeN(inputs.begin(), this->countInputs(), modes.begin(),
-                                     this->getCropRectIfSet());
+    return SkMergeImageFilter::Make(inputs.begin(), this->countInputs(),
+                                    this->getCropRectIfSet());
 }
 
 sk_sp<SkFlattenable> SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) {
@@ -162,31 +110,25 @@
     }
 
     const int count = common.inputCount();
-    bool hasModes = buffer.readBool();
-    if (hasModes) {
-        SkAutoSTArray<4, SkBlendMode> modes(count);
-        SkAutoSTArray<4, uint8_t> modes8(count);
-        if (!buffer.readByteArray(modes8.get(), count)) {
-            return nullptr;
+    if (buffer.isVersionLT(SkReadBuffer::kNoModesInMergeImageFilter_Verison)) {
+        bool hasModes = buffer.readBool();
+        if (hasModes) {
+            // Older pictures may have stored blendmodes, but by inspection we think these were
+            // all src-over, so we have removed support for storing these.
+            SkAutoSTArray<4, uint8_t> modes8(count);
+            if (!buffer.readByteArray(modes8.get(), count)) {
+                return nullptr;
+            }
+            if (!buffer.isValid()) {
+                return nullptr;
+            }
         }
-        for (int i = 0; i < count; ++i) {
-            modes[i] = (SkBlendMode)modes8[i];
-            buffer.validate(SkIsValidMode(modes[i]));
-        }
-        if (!buffer.isValid()) {
-            return nullptr;
-        }
-        return MakeN(common.inputs(), count, modes.get(), &common.cropRect());
     }
-    return MakeN(common.inputs(), count, nullptr, &common.cropRect());
+    return Make(common.inputs(), count, &common.cropRect());
 }
 
 void SkMergeImageFilter::flatten(SkWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    buffer.writeBool(fModes != nullptr);
-    if (fModes) {
-        buffer.writeByteArray(fModes, this->countInputs() * sizeof(fModes[0]));
-    }
 }
 
 #ifndef SK_IGNORE_TO_STRING
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index d884644..95a1333 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -196,9 +196,7 @@
                       input, cropRect));
         }
 
-        this->addFilter("merge", SkMergeImageFilter::Make(input, input,
-                                                          SkBlendMode::kSrcOver,
-                                                          cropRect));
+        this->addFilter("merge", SkMergeImageFilter::Make(input, input, cropRect));
 
         {
             SkPaint greenColorShaderPaint;
@@ -213,8 +211,7 @@
 
 
             this->addFilter("merge with disjoint inputs", SkMergeImageFilter::Make(
-                  std::move(paintFilterLeft), std::move(paintFilterRight),
-                  SkBlendMode::kSrcOver, cropRect));
+                  std::move(paintFilterLeft), std::move(paintFilterRight), cropRect));
         }
 
         this->addFilter("offset",
@@ -959,7 +956,7 @@
     greenBM.eraseColor(SK_ColorGREEN);
     sk_sp<SkImage> greenImage(SkImage::MakeFromBitmap(greenBM));
     sk_sp<SkImageFilter> source(SkImageSource::Make(std::move(greenImage)));
-    sk_sp<SkImageFilter> merge(SkMergeImageFilter::Make(source, source, SkBlendMode::kSrcOver));
+    sk_sp<SkImageFilter> merge(SkMergeImageFilter::Make(source, source));
 
     sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 1));
 
@@ -1865,13 +1862,13 @@
     } recs[] = {
         { cfif,                                     true  },
         { SkColorFilterImageFilter::Make(cf, cfif), true  },
-        { SkMergeImageFilter::Make(cfif, cfif, SkBlendMode::kSrcOver),     true  },
+        { SkMergeImageFilter::Make(cfif, cfif),     true  },
         { SkComposeImageFilter::Make(cfif, cfif),   true  },
 
         { blif,                                     false },
         { SkBlurImageFilter::Make(3, 3, cfif),      false },
         { SkColorFilterImageFilter::Make(cf, blif), false },
-        { SkMergeImageFilter::Make(cfif, blif, SkBlendMode::kSrcOver),     false },
+        { SkMergeImageFilter::Make(cfif, blif),     false },
         { SkComposeImageFilter::Make(blif, cfif),   false },
     };