External SkImageGenerator API

Introduce an SkImageGenerator API to support the implementation of
externally-managed image decode and scale caches.

BUG=skia:5806
R=reed@google.com

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4720

Change-Id: Ibfe37af5471f78f28f88f9d5e80938882be1a344
Reviewed-on: https://skia-review.googlesource.com/4720
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/gm/imagegeneratorexternal.cpp b/gm/imagegeneratorexternal.cpp
new file mode 100644
index 0000000..7427dd4
--- /dev/null
+++ b/gm/imagegeneratorexternal.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkImage.h"
+#include "SkImageGenerator.h"
+#include "SkMutex.h"
+#include "SkSurface.h"
+#include "SkTArray.h"
+
+namespace {
+
+class ExternalGenerator : public SkImageGenerator {
+public:
+    ExternalGenerator(const SkISize size)
+        : INHERITED(SkImageInfo::MakeN32Premul(size.width(), size.height())) {
+
+        int level = 0;
+        for (int size = kMaxSize; size; size /= 2) {
+            sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size, size);
+            DrawRings(surface->getCanvas(), 0xff008000, level++);
+            fMips.emplace_back(surface->makeImageSnapshot());
+        }
+    }
+
+    virtual ~ExternalGenerator() {}
+
+protected:
+    bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+                     SkPMColor[], int*) override {
+        sk_sp<SkSurface> s = SkSurface::MakeRasterDirect(info, pixels, rowBytes);
+        s->getCanvas()->clear(SK_ColorTRANSPARENT);
+        DrawRings(s->getCanvas(), SK_ColorRED);
+        return true;
+    }
+
+    bool onAccessScaledImage(const SkRect& src, const SkMatrix& matrix, SkFilterQuality,
+                             ScaledImageRec* rec) override {
+        // Not strictly needed for this immutable class.
+        SkAutoExclusive lock(fMutex);
+
+        SkSize scaleSize;
+        if (!matrix.decomposeScale(&scaleSize, nullptr)) {
+            return false;
+        }
+        scaleSize.set(scaleSize.width()  * this->getInfo().width()  / kMaxSize,
+                      scaleSize.height() * this->getInfo().height() / kMaxSize);
+
+        const SkScalar scale = SkTMin(scaleSize.width(), scaleSize.height());
+        const int lvl = SkScalarFloorToInt(-SkScalarLog2(scale));
+
+        rec->fImage = fMips[SkTPin(lvl, 0, fMips.count())];
+
+        const SkRect origBounds = SkRect::Make(this->getInfo().bounds());
+        const SkRect  newBounds = SkRect::Make(rec->fImage->bounds());
+
+        SkMatrix srcMap = SkMatrix::MakeScale(newBounds.width()  / origBounds.width(),
+                                              newBounds.height() / origBounds.height());
+        srcMap.preTranslate(src.x(), src.y());
+        srcMap.mapRect(&rec->fSrcRect, SkRect::MakeWH(src.width(), src.height()));
+
+        rec->fQuality = kLow_SkFilterQuality;
+
+        return true;
+    }
+
+private:
+    static void DrawRings(SkCanvas* c, SkColor color, int lvl = 0) {
+        static constexpr SkScalar kStep = 0.2f;
+
+        SkRect rect = SkRect::MakeWH(1, 1);
+
+        SkPaint p;
+        p.setStyle(SkPaint::kStroke_Style);
+        p.setStrokeWidth(0.02f);
+        p.setAntiAlias(true);
+        p.setColor(color);
+
+        c->concat(SkMatrix::MakeRectToRect(SkRect::MakeWH(1, 1),
+                                           SkRect::MakeIWH(c->imageInfo().width(),
+                                                           c->imageInfo().height()),
+                                           SkMatrix::kFill_ScaleToFit));
+        while (!rect.isEmpty()) {
+            c->drawRect(rect, p);
+            rect.inset(kStep, kStep);
+        }
+
+        static constexpr SkScalar kTxtSize = 0.2f;
+        SkASSERT(lvl >= 0 && lvl <= 9);
+        const char label = '0' + lvl;
+        p.setTextSize(kTxtSize);
+        p.setLinearText(true);
+        p.setStyle(SkPaint::kFill_Style);
+        SkRect labelBounds;
+        p.measureText(&label, 1, &labelBounds);
+
+        c->drawText(&label, 1, 0.5f - labelBounds.width() / 2, 0.5f + labelBounds.height() / 2, p);
+    }
+
+    SkMutex fMutex;
+
+    static constexpr int kMaxSize = 512;
+    SkTArray<sk_sp<SkImage>> fMips;
+
+    typedef SkImageGenerator INHERITED;
+};
+
+} // anonymous ns
+
+class ImageGenExternalGM : public skiagm::GM {
+public:
+    explicit ImageGenExternalGM(bool useShader) : fUseShader(useShader) {}
+
+protected:
+    SkString onShortName() override {
+        return SkStringPrintf("ImageGeneratorExternal%s", fUseShader ? "_shader" : "_rect");
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(800, 800);
+    }
+
+    void onOnceBeforeDraw() override {
+        fImage = SkImage::MakeFromGenerator(new ExternalGenerator(SkISize::Make(kGeneratorSize,
+                                                                                kGeneratorSize)));
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        static const SkRect gSubsets[] = {
+            SkRect::MakeLTRB(0    , 0    , 1    , 1    ),
+            SkRect::MakeLTRB(0    , 0    , 0.5f , 0.5f ),
+            SkRect::MakeLTRB(0.5f , 0    , 1    , 0.5f ),
+            SkRect::MakeLTRB(0.5f , 0.5f , 1    , 1    ),
+            SkRect::MakeLTRB(0    , 0.5f , 0.5f , 1    ),
+            SkRect::MakeLTRB(0.25f, 0.25f, 0.75f, 0.75f),
+        };
+
+        SkPaint p;
+        p.setFilterQuality(kLow_SkFilterQuality);
+
+        for (int i = 1; i <= 4; ++i) {
+            const SkRect dst = SkRect::MakeIWH(kGeneratorSize / i, kGeneratorSize / i);
+
+            canvas->save();
+            for (size_t j = 0; j < SK_ARRAY_COUNT(gSubsets); ++j) {
+                SkRect subset = gSubsets[j];
+                subset.set(kGeneratorSize * subset.left(),
+                           kGeneratorSize * subset.top(),
+                           kGeneratorSize * subset.right(),
+                           kGeneratorSize * subset.bottom());
+                this->drawSubset(canvas, subset, dst, p);
+                canvas->translate(kGeneratorSize * 1.1f, 0);
+            }
+            canvas->restore();
+            canvas->translate(0, dst.height() * 1.2f);
+        }
+    }
+
+private:
+    void drawSubset(SkCanvas* canvas, const SkRect& src, const SkRect& dst,
+                    const SkPaint& paint) const {
+        if (fUseShader) {
+            SkPaint p(paint);
+            SkMatrix localMatrix = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
+            p.setShader(fImage->makeShader(SkShader::kClamp_TileMode,
+                                           SkShader::kClamp_TileMode,
+                                           &localMatrix));
+            canvas->drawRect(dst, p);
+        } else {
+            canvas->drawImageRect(fImage, src, dst, &paint);
+        }
+    }
+
+    static constexpr int kGeneratorSize = 200;
+    sk_sp<SkImage> fImage;
+    bool           fUseShader;
+
+    typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return new ImageGenExternalGM(false); )
+DEF_GM( return new ImageGenExternalGM(true); )
diff --git a/gn/gm.gni b/gn/gm.gni
index 0b11b2e..7e70c89 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -160,6 +160,7 @@
   "$_gm/imagefiltersstroked.cpp",
   "$_gm/imagefilterstransformed.cpp",
   "$_gm/imagefromyuvtextures.cpp",
+  "$_gm/imagegeneratorexternal.cpp",
   "$_gm/imagemagnifier.cpp",
   "$_gm/imagemakewithfilter.cpp",
   "$_gm/imagemasksubset.cpp",
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index d521fec..b0aac41 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -255,7 +255,6 @@
 
     virtual GrContext* context() const { return nullptr; }
 
-protected:
     virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);
     virtual bool onPeekPixels(SkPixmap*) { return false; }
 
@@ -359,6 +358,10 @@
         *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeWH(w, h);
     }
 
+    bool drawExternallyScaledImage(const SkDraw& draw, const SkImage* image, const SkRect* src,
+                                   const SkRect& dst, const SkPaint& paint,
+                                   SkCanvas::SrcRectConstraint constraint);
+
     SkIPoint    fOrigin;
     SkMetaData* fMetaData;
     const SkImageInfo    fInfo;
diff --git a/include/core/SkImageGenerator.h b/include/core/SkImageGenerator.h
index 5e7214c..2e34bfe 100644
--- a/include/core/SkImageGenerator.h
+++ b/include/core/SkImageGenerator.h
@@ -19,6 +19,7 @@
 class GrTextureParams;
 class SkBitmap;
 class SkData;
+class SkImage;
 class SkImageGenerator;
 class SkMatrix;
 class SkPaint;
@@ -199,6 +200,40 @@
     }
 
     /**
+     *  External generator API: provides efficient access to externally-managed image data.
+     *
+     *  Skia calls accessScaledPixels() during rasterization, to gain temporary access to
+     *  the external pixel data, packaged as a raster SkImage.
+     *
+     *  @param srcRect     the source rect in use for the current draw
+     *  @param totalMatrix full matrix in effect (mapping srcRect -> device space)
+     *  @param quality     the SkFilterQuality requested for rasterization.
+     *  @param rec         out param, expected to be set when the call succeeds:
+     *
+     *                       - fImage wraps the external pixel data
+     *                       - fSrcRect is an adjusted srcRect
+     *                       - fQuality is the adjusted filter quality
+     *
+     *  @return            true on success, false otherwise (error or if this API is not supported;
+     *                     in this case Skia will fall back to its internal scaling and caching
+     *                     heuristics)
+     *
+     *  Implementors can return pixmaps with a different size than requested, by adjusting the
+     *  src rect.  The contract is that Skia will observe the adjusted src rect, and will map it
+     *  to the same dest as the original draw (the impl doesn't get to control the destination).
+     *
+     */
+
+    struct ScaledImageRec {
+        sk_sp<SkImage>  fImage;
+        SkRect          fSrcRect;
+        SkFilterQuality fQuality;
+    };
+
+    bool accessScaledImage(const SkRect& srcRect, const SkMatrix& totalMatrix,
+                           SkFilterQuality quality, ScaledImageRec* rec);
+
+    /**
      *  If the default image decoder system can interpret the specified (encoded) data, then
      *  this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
      *  the caller is still responsible for managing their ownership of the data.
@@ -263,6 +298,11 @@
         return false;
     }
 
+    virtual bool onAccessScaledImage(const SkRect&, const SkMatrix&, SkFilterQuality,
+                                     ScaledImageRec*) {
+        return false;
+    }
+
     bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo* optionalInfo, SkBitmap::Allocator*);
 
 private:
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android.json
index 4b8eca8..bb5061f 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu CPU cpu_or_gpu_value MT6582 extra_config GN_Android model AndroidOne os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nogpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut --match ~WritePixels; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-AndroidOne-CPU-MT6582-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu CPU cpu_or_gpu_value MT6582 extra_config GN_Android model AndroidOne os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nogpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut --match ~WritePixels; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android.json
index bf174df..313ccf4 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value Mali400MP2 extra_config GN_Android model AndroidOne os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~WritePixels; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value Mali400MP2 extra_config GN_Android model AndroidOne os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~WritePixels; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android.json
index 6f420d8..5e54973 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Adreno530 extra_config GN_Android model GalaxyS7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --threads 0 --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-GalaxyS7-GPU-Adreno530-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Adreno530 extra_config GN_Android model GalaxyS7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --threads 0 --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android.json
index b50eccc..a84eb8d 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config GN_Android model NVIDIA_Shield os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gl gldft glsrgb glmsaa4 glinstdit4 serialize-8888 tiles_rt-8888 pic-8888 glinst --src tests gm image colorImage svg --blacklist glsrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-NVIDIA_Shield-GPU-TegraX1-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config GN_Android model NVIDIA_Shield os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gl gldft glsrgb glmsaa4 glinstdit4 serialize-8888 tiles_rt-8888 pic-8888 glinst --src tests gm image colorImage svg --blacklist glsrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android.json
index 58a37b5..3f242a6 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value MaliT604 extra_config GN_Android model Nexus10 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~CopySurface; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus10-GPU-MaliT604-arm-Release-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Release cpu_or_gpu GPU cpu_or_gpu_value MaliT604 extra_config GN_Android model Nexus10 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~CopySurface; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android.json
index 5210b4d..b08f032 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Adreno420 extra_config GN_Android model Nexus6 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 esinst --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus6-GPU-Adreno420-arm-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Adreno420 extra_config GN_Android model Nexus6 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 esinst --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android.json
index 163fe45..cebfd77 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Tegra3 extra_config GN_Android model Nexus7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Tegra3 extra_config GN_Android model Nexus7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android.json
index 9af895a..d0dfddc 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu CPU cpu_or_gpu_value Denver extra_config GN_Android model Nexus9 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nogpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --noRAW_threading; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus9-CPU-Denver-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu CPU cpu_or_gpu_value Denver extra_config GN_Android model Nexus9 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nogpu --config 8888 gpu gpudft gpusrgb msaa4 serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --noRAW_threading; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android.json b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android.json
index 9b2361a..652b951 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android.json
@@ -504,7 +504,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config GN_Android model PixelC os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 esinstdit4 serialize-8888 tiles_rt-8888 pic-8888 esinst --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-PixelC-GPU-TegraX1-arm64-Debug-GN_Android build_number 5 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm64 compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value TegraX1 extra_config GN_Android model PixelC os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb msaa4 esinstdit4 serialize-8888 tiles_rt-8888 pic-8888 esinst --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini4.1-GPU-GeForce320M-x86_64-Debug.json b/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini4.1-GPU-GeForce320M-x86_64-Debug.json
index 33600db..eae7d03 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini4.1-GPU-GeForce320M-x86_64-Debug.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini4.1-GPU-GeForce320M-x86_64-Debug.json
@@ -438,6 +438,14 @@
       "gm",
       "_",
       "parsedpaths",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
       "pic-8888",
       "gm",
       "_",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini6.2-CPU-AVX-x86_64-Debug.json b/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini6.2-CPU-AVX-x86_64-Debug.json
index 3191849..15391a9 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini6.2-CPU-AVX-x86_64-Debug.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Mac-Clang-MacMini6.2-CPU-AVX-x86_64-Debug.json
@@ -440,6 +440,14 @@
       "gm",
       "_",
       "parsedpaths",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
       "pic-8888",
       "gm",
       "_",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Debug.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Debug.json
index e94eb72..b7c0126 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Debug.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Debug.json
@@ -370,6 +370,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-ASAN.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-ASAN.json
index 498a4bd..8a11d65 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-ASAN.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-ASAN.json
@@ -251,6 +251,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-MSAN.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-MSAN.json
index 30d7124..1f38798 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-MSAN.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-MSAN.json
@@ -251,6 +251,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug.json
index ada45dd..d17a8d1 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug.json
@@ -368,6 +368,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Shared.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Shared.json
index 3af05d3..0d2092a 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Shared.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-Shared.json
@@ -370,6 +370,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-TSAN.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-TSAN.json
index a2e1c3d..a4a90c8 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-TSAN.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-TSAN.json
@@ -251,6 +251,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-ShuttleA-GPU-GTX550Ti-x86_64-Release-Valgrind.json b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-ShuttleA-GPU-GTX550Ti-x86_64-Release-Valgrind.json
index 09d2bf6..c49f519 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-ShuttleA-GPU-GTX550Ti-x86_64-Release-Valgrind.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Ubuntu-GCC-ShuttleA-GPU-GTX550Ti-x86_64-Release-Valgrind.json
@@ -265,6 +265,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
@@ -614,6 +622,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
@@ -964,6 +980,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-Win8-MSVC-ShuttleB-CPU-AVX2-x86_64-Release-Trybot.json b/infra/bots/recipes/swarm_test.expected/Test-Win8-MSVC-ShuttleB-CPU-AVX2-x86_64-Release-Trybot.json
index b5ec4ef..a2cd633 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-Win8-MSVC-ShuttleB-CPU-AVX2-x86_64-Release-Trybot.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-Win8-MSVC-ShuttleB-CPU-AVX2-x86_64-Release-Trybot.json
@@ -411,6 +411,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/Test-iOS-Clang-iPad4-GPU-SGX554-Arm7-Debug.json b/infra/bots/recipes/swarm_test.expected/Test-iOS-Clang-iPad4-GPU-SGX554-Arm7-Debug.json
index 51b2fea..1802f66 100644
--- a/infra/bots/recipes/swarm_test.expected/Test-iOS-Clang-iPad4-GPU-SGX554-Arm7-Debug.json
+++ b/infra/bots/recipes/swarm_test.expected/Test-iOS-Clang-iPad4-GPU-SGX554-Arm7-Debug.json
@@ -758,6 +758,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/big_issue_number.json b/infra/bots/recipes/swarm_test.expected/big_issue_number.json
index 7d92a80..cd6118b 100644
--- a/infra/bots/recipes/swarm_test.expected/big_issue_number.json
+++ b/infra/bots/recipes/swarm_test.expected/big_issue_number.json
@@ -411,6 +411,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/failed_dm.json b/infra/bots/recipes/swarm_test.expected/failed_dm.json
index 8c23968..900b8a6 100644
--- a/infra/bots/recipes/swarm_test.expected/failed_dm.json
+++ b/infra/bots/recipes/swarm_test.expected/failed_dm.json
@@ -368,6 +368,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/failed_get_hashes.json b/infra/bots/recipes/swarm_test.expected/failed_get_hashes.json
index c67eda9..5f233db 100644
--- a/infra/bots/recipes/swarm_test.expected/failed_get_hashes.json
+++ b/infra/bots/recipes/swarm_test.expected/failed_get_hashes.json
@@ -506,7 +506,7 @@
       "python",
       "-u",
       "\nimport shutil\nimport sys\nshutil.copy(sys.argv[1], sys.argv[2])\n",
-      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android build_number 6 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Tegra3 extra_config GN_Android model Nexus7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
+      "set -x; /data/local/tmp/dm --undefok --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 master client.skia builder Test-Android-Clang-Nexus7-GPU-Tegra3-arm-Debug-GN_Android build_number 6 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Tegra3 extra_config GN_Android model Nexus7 os Android --uninterestingHashesFile /sdcard/revenge_of_the_skiabot/uninteresting_hashes.txt --writePath /sdcard/revenge_of_the_skiabot/dm_out --nocpu --config 8888 gpu gpudft gpusrgb serialize-8888 tiles_rt-8888 pic-8888 --src tests gm image colorImage svg --blacklist gpusrgb image _ _ _ test _ GrShape serialize-8888 gm _ bleed_image serialize-8888 gm _ c_gms serialize-8888 gm _ colortype serialize-8888 gm _ colortype_xfermodes serialize-8888 gm _ drawfilter serialize-8888 gm _ fontmgr_bounds_0.75_0 serialize-8888 gm _ fontmgr_bounds_1_-0.25 serialize-8888 gm _ fontmgr_bounds serialize-8888 gm _ fontmgr_match serialize-8888 gm _ fontmgr_iter serialize-8888 gm _ imagemasksubset serialize-8888 gm _ bitmapfilters serialize-8888 gm _ bitmapshaders serialize-8888 gm _ bleed serialize-8888 gm _ bleed_alpha_bmp serialize-8888 gm _ bleed_alpha_bmp_shader serialize-8888 gm _ convex_poly_clip serialize-8888 gm _ extractalpha serialize-8888 gm _ filterbitmap_checkerboard_32_32_g8 serialize-8888 gm _ filterbitmap_image_mandrill_64 serialize-8888 gm _ shadows serialize-8888 gm _ simpleaaclip_aaclip serialize-8888 gm _ composeshader_bitmap serialize-8888 gm _ scaled_tilemodes_npot serialize-8888 gm _ scaled_tilemodes serialize-8888 gm _ typefacerendering_pfaMac serialize-8888 gm _ parsedpaths serialize-8888 gm _ ImageGeneratorExternal_rect serialize-8888 gm _ ImageGeneratorExternal_shader serialize-8888 gm _ bleed_alpha_image serialize-8888 gm _ bleed_alpha_image_shader serialize-8888 gm _ verylargebitmap serialize-8888 gm _ verylarge_picture_image pic-8888 gm _ drawfilter pic-8888 gm _ image-cacherator-from-picture serialize-8888 gm _ image-cacherator-from-picture pic-8888 gm _ image-cacherator-from-raster serialize-8888 gm _ image-cacherator-from-raster pic-8888 gm _ image-cacherator-from-ctable serialize-8888 gm _ image-cacherator-from-ctable pic-8888 gm _ gamut serialize-8888 gm _ gamut _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW; echo $? >/data/local/tmp/rc",
       "[SLAVE_BUILD]/tmp/dm.sh"
     ],
     "name": "write dm.sh"
diff --git a/infra/bots/recipes/swarm_test.expected/missing_SKP_VERSION_device.json b/infra/bots/recipes/swarm_test.expected/missing_SKP_VERSION_device.json
index 95c031d..d669f46 100644
--- a/infra/bots/recipes/swarm_test.expected/missing_SKP_VERSION_device.json
+++ b/infra/bots/recipes/swarm_test.expected/missing_SKP_VERSION_device.json
@@ -762,6 +762,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/nobuildbot.json b/infra/bots/recipes/swarm_test.expected/nobuildbot.json
index b39bb71..0acebad 100644
--- a/infra/bots/recipes/swarm_test.expected/nobuildbot.json
+++ b/infra/bots/recipes/swarm_test.expected/nobuildbot.json
@@ -408,6 +408,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.expected/recipe_with_gerrit_patch.json b/infra/bots/recipes/swarm_test.expected/recipe_with_gerrit_patch.json
index c5445cf..50afad0 100644
--- a/infra/bots/recipes/swarm_test.expected/recipe_with_gerrit_patch.json
+++ b/infra/bots/recipes/swarm_test.expected/recipe_with_gerrit_patch.json
@@ -374,6 +374,14 @@
       "serialize-8888",
       "gm",
       "_",
+      "ImageGeneratorExternal_rect",
+      "serialize-8888",
+      "gm",
+      "_",
+      "ImageGeneratorExternal_shader",
+      "serialize-8888",
+      "gm",
+      "_",
       "bleed_alpha_image",
       "serialize-8888",
       "gm",
diff --git a/infra/bots/recipes/swarm_test.py b/infra/bots/recipes/swarm_test.py
index a4f5dd0..3a51843 100644
--- a/infra/bots/recipes/swarm_test.py
+++ b/infra/bots/recipes/swarm_test.py
@@ -278,6 +278,11 @@
   bad_serialize_gms.append('typefacerendering_pfaMac')
   # skia:5942
   bad_serialize_gms.append('parsedpaths')
+
+  # these use a custom image generator which doesn't serialize
+  bad_serialize_gms.append('ImageGeneratorExternal_rect')
+  bad_serialize_gms.append('ImageGeneratorExternal_shader')
+
   for test in bad_serialize_gms:
     blacklist(['serialize-8888', 'gm', '_', test])
 
diff --git a/src/core/SkBitmapController.cpp b/src/core/SkBitmapController.cpp
index 4fee11d..ed9903e 100644
--- a/src/core/SkBitmapController.cpp
+++ b/src/core/SkBitmapController.cpp
@@ -48,6 +48,7 @@
     SkDestinationSurfaceColorMode fColorMode;
     sk_sp<const SkMipMap>         fCurrMip;
 
+    bool processExternalRequest(const SkBitmapProvider&);
     bool processHQRequest(const SkBitmapProvider&);
     bool processMediumRequest(const SkBitmapProvider&);
 };
@@ -68,6 +69,28 @@
 }
 
 /*
+ *  Image generators can provide access to externally managed pixels
+ *  (external scale/decode caches).
+ */
+bool SkDefaultBitmapControllerState::processExternalRequest(const SkBitmapProvider& provider) {
+    // TODO: actual srcRect
+
+    const SkRect src = SkRect::MakeIWH(provider.width(), provider.height());
+    SkRect          adjustedSrc;
+
+    if (!provider.accessScaledImage(src, fInvMatrix, fQuality,
+                                    &fResultBitmap, &adjustedSrc, &fQuality)) {
+        return false;
+    }
+
+    fInvMatrix.postConcat(SkMatrix::MakeRectToRect(src, adjustedSrc, SkMatrix::kFill_ScaleToFit));
+    fResultBitmap.lockPixels();
+    SkASSERT(fResultBitmap.getPixels());
+
+    return true;
+}
+
+/*
  *  High quality is implemented by performing up-right scale-only filtering and then
  *  using bilerp for any remaining transformations.
  */
@@ -205,7 +228,13 @@
     fQuality = qual;
     fColorMode = colorMode;
 
-    if (this->processHQRequest(provider) || this->processMediumRequest(provider)) {
+    bool processed = this->processExternalRequest(provider);
+
+    // Externally handled requests are not guaranteed to reduce quality below kMedium -- so we
+    // always give our internal processors a shot.
+    processed |= this->processHQRequest(provider) || this->processMediumRequest(provider);
+
+    if (processed) {
         SkASSERT(fResultBitmap.getPixels());
     } else {
         (void)provider.asBitmap(&fResultBitmap);
diff --git a/src/core/SkBitmapProvider.cpp b/src/core/SkBitmapProvider.cpp
index 8347d32..11b1ac9 100644
--- a/src/core/SkBitmapProvider.cpp
+++ b/src/core/SkBitmapProvider.cpp
@@ -7,6 +7,7 @@
 
 #include "SkBitmapProvider.h"
 #include "SkImage_Base.h"
+#include "SkImageCacherator.h"
 #include "SkPixelRef.h"
 
 int SkBitmapProvider::width() const {
@@ -46,3 +47,36 @@
 bool SkBitmapProvider::asBitmap(SkBitmap* bm) const {
     return as_IB(fImage)->getROPixels(bm, SkImage::kAllow_CachingHint);
 }
+
+bool SkBitmapProvider::accessScaledImage(const SkRect& srcRect,
+                                         const SkMatrix& invMatrix,
+                                         SkFilterQuality fq,
+                                         SkBitmap* scaledBitmap,
+                                         SkRect* adjustedSrcRect,
+                                         SkFilterQuality* adjustedFilterQuality) const {
+    if (!fImage) {
+        return false;
+    }
+
+    SkImageCacherator* cacherator = as_IB(fImage)->peekCacherator();
+    if (!cacherator) {
+        return false;
+    }
+
+    // TODO: stash the matrix someplace to avoid invert()?
+    SkMatrix m;
+    if (!invMatrix.invert(&m)) {
+        return false;
+    }
+
+    SkImageGenerator::ScaledImageRec rec;
+    if (!cacherator->directAccessScaledImage(srcRect, m, fq, &rec) ||
+        !rec.fImage->asLegacyBitmap(scaledBitmap, SkImage::kRO_LegacyBitmapMode)) {
+        return false;
+    }
+
+    *adjustedSrcRect       = rec.fSrcRect;
+    *adjustedFilterQuality = rec.fQuality;
+
+    return true;
+}
diff --git a/src/core/SkBitmapProvider.h b/src/core/SkBitmapProvider.h
index 2e878b1..fd5b662 100644
--- a/src/core/SkBitmapProvider.h
+++ b/src/core/SkBitmapProvider.h
@@ -33,6 +33,10 @@
     // ... cause a decode and cache, or gpu-readback
     bool asBitmap(SkBitmap*) const;
 
+    bool accessScaledImage(const SkRect& srcRect, const SkMatrix& invMatrix, SkFilterQuality fq,
+                           SkBitmap* scaledBitmap, SkRect* adjustedSrcRect,
+                           SkFilterQuality* adjustedFilterQuality) const;
+
 private:
     // Stack-allocated only.
     void* operator new(size_t) = delete;
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index b2ff242..4caa875 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -10,6 +10,7 @@
 #include "SkDraw.h"
 #include "SkDrawFilter.h"
 #include "SkImage_Base.h"
+#include "SkImageCacherator.h"
 #include "SkImageFilter.h"
 #include "SkImageFilterCache.h"
 #include "SkImagePriv.h"
@@ -24,6 +25,7 @@
 #include "SkSpecialImage.h"
 #include "SkTextBlobRunIterator.h"
 #include "SkTextToPathIter.h"
+#include "SkTLazy.h"
 
 SkBaseDevice::SkBaseDevice(const SkImageInfo& info, const SkSurfaceProps& surfaceProps)
     : fInfo(info)
@@ -177,9 +179,60 @@
     }
 }
 
+bool SkBaseDevice::drawExternallyScaledImage(const SkDraw& draw,
+                                             const SkImage* image,
+                                             const SkRect* src,
+                                             const SkRect& dst,
+                                             const SkPaint& paint,
+                                             SkCanvas::SrcRectConstraint constraint) {
+    SkImageCacherator* cacherator = as_IB(image)->peekCacherator();
+    if (!cacherator) {
+        return false;
+    }
+
+    SkTLazy<SkRect> tmpSrc(src);
+    if (!tmpSrc.isValid()) {
+        tmpSrc.init(SkRect::Make(image->bounds()));
+    }
+
+    SkMatrix m = *draw.fMatrix;
+    m.preConcat(SkMatrix::MakeRectToRect(*tmpSrc.get(), dst, SkMatrix::kFill_ScaleToFit));
+
+    // constrain src to our bounds
+    if (!image->bounds().contains(*tmpSrc.get()) &&
+        !tmpSrc.get()->intersect(SkRect::Make(image->bounds()))) {
+        return false;
+    }
+
+    SkImageGenerator::ScaledImageRec rec;
+    if (!cacherator->directAccessScaledImage(*tmpSrc.get(), m, paint.getFilterQuality(), &rec)) {
+        return false;
+    }
+
+    SkBitmap bm;
+    if (!as_IB(rec.fImage)->getROPixels(&bm)) {
+        return false;
+    }
+
+    SkTCopyOnFirstWrite<SkPaint> adjustedPaint(paint);
+    if (rec.fQuality != paint.getFilterQuality()) {
+        adjustedPaint.writable()->setFilterQuality(rec.fQuality);
+    }
+
+    this->drawBitmapRect(draw, bm, &rec.fSrcRect, dst, *adjustedPaint, constraint);
+
+    return true;
+}
 void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
                              const SkPaint& paint) {
     // Default impl : turns everything into raster bitmap
+
+    if (this->drawExternallyScaledImage(draw, image, nullptr,
+                                        SkRect::Make(image->bounds()).makeOffset(x, y),
+                                        paint, SkCanvas::kFast_SrcRectConstraint)) {
+        return;
+    }
+
     SkBitmap bm;
     if (as_IB(image)->getROPixels(&bm)) {
         this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
@@ -190,6 +243,11 @@
                                  const SkRect& dst, const SkPaint& paint,
                                  SkCanvas::SrcRectConstraint constraint) {
     // Default impl : turns everything into raster bitmap
+
+    if (this->drawExternallyScaledImage(draw, image, src, dst, paint, constraint)) {
+        return;
+    }
+
     SkBitmap bm;
     if (as_IB(image)->getROPixels(&bm)) {
         this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp
index 54045d5..471dbd6 100644
--- a/src/core/SkImageCacherator.cpp
+++ b/src/core/SkImageCacherator.cpp
@@ -157,6 +157,13 @@
     return generator->getPixels(info, pixels, rb);
 }
 
+bool SkImageCacherator::directAccessScaledImage(const SkRect& srcRect,
+                                                const SkMatrix& totalMatrix,
+                                                SkFilterQuality fq,
+                                                SkImageGenerator::ScaledImageRec* rec) {
+    return ScopedGenerator(fSharedGenerator)->accessScaledImage(srcRect, totalMatrix, fq, rec);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 bool SkImageCacherator::lockAsBitmapOnlyIfAlreadyCached(SkBitmap* bitmap) {
diff --git a/src/core/SkImageCacherator.h b/src/core/SkImageCacherator.h
index a8a05a1..0e8a953 100644
--- a/src/core/SkImageCacherator.h
+++ b/src/core/SkImageCacherator.h
@@ -69,6 +69,9 @@
     bool directGeneratePixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
                               int srcX, int srcY);
 
+    bool directAccessScaledImage(const SkRect& srcRect, const SkMatrix& totalMatrix,
+                                 SkFilterQuality, SkImageGenerator::ScaledImageRec*);
+
 private:
     // Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing of one generator
     // among several cacherators.
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp
index ffa845b..5bb385e 100644
--- a/src/core/SkImageGenerator.cpp
+++ b/src/core/SkImageGenerator.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "SkImage.h"
 #include "SkImageGenerator.h"
 #include "SkNextID.h"
 
@@ -107,6 +108,12 @@
     return this->onGenerateScaledPixels(scaledSize, subsetOrigin, subsetPixels);
 }
 
+bool SkImageGenerator::accessScaledImage(const SkRect& src, const SkMatrix& matrix,
+                                         SkFilterQuality fq, ScaledImageRec* rec) {
+    SkASSERT(fInfo.bounds().contains(src));
+    return this->onAccessScaledImage(src, matrix, fq, rec);
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////////
 
 SkData* SkImageGenerator::onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM) {