Allow Srcs to veto Sinks based on their broad type.

This breaks Sinks down into three auto-detected types:
  - GPU:    anything that requests to be run in the GPU enclave
  - Vector: anything that writes to the stream instead of the bitmap
  - Raster: everything else

Some examples: gpu -> GPU, msaa16 -> GPU, 8888 -> raster, pdf -> vector,
               svg -> vector, pipe-8888 -> raster, tiles_rt-gpu -> GPU

This lets image decoding sinks veto non-raster backends explicitly,
and can let particular GMs veto GPU or non-GPU sinks as they like.

BUG=skia:

Review URL: https://codereview.chromium.org/1239953004
diff --git a/dm/DM.cpp b/dm/DM.cpp
index c488bca..f194304 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -165,16 +165,21 @@
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
-template <typename T>
-struct Tagged : public SkAutoTDelete<T> {
-  const char* tag;
-  const char* options;
+struct TaggedSrc : public SkAutoTDelete<Src> {
+    const char* tag;
+    const char* options;
+};
+
+struct TaggedSink : public SkAutoTDelete<Sink> {
+    const char* tag;
+    const char* options;
+    SinkType type;
 };
 
 static const bool kMemcpyOK = true;
 
-static SkTArray<Tagged<Src>,  kMemcpyOK>  gSrcs;
-static SkTArray<Tagged<Sink>, kMemcpyOK> gSinks;
+static SkTArray<TaggedSrc,  kMemcpyOK>  gSrcs;
+static SkTArray<TaggedSink, kMemcpyOK> gSinks;
 
 static bool in_shard() {
     static int N = 0;
@@ -186,7 +191,7 @@
     if (in_shard() &&
         FLAGS_src.contains(tag) &&
         !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) {
-        Tagged<Src>& s = gSrcs.push_back();
+        TaggedSrc& s = gSrcs.push_back();
         s.reset(src.detach());
         s.tag = tag;
         s.options = options;
@@ -334,25 +339,33 @@
     if (!FLAGS_config.contains(tag)) {
         return;
     }
-    // Try a noop Src as a canary.  If it fails, skip this sink.
+    // Try a simple Src as a canary.  If it fails, skip this sink.
     struct : public Src {
-        Error draw(SkCanvas*) const override { return ""; }
+        Error draw(SkCanvas* c) const override {
+            c->drawRect(SkRect::MakeWH(1,1), SkPaint());
+            return "";
+        }
         SkISize size() const override { return SkISize::Make(16, 16); }
-        Name name() const override { return "noop"; }
-    } noop;
+        Name name() const override { return "justOneRect"; }
+    } justOneRect;
 
     SkBitmap bitmap;
     SkDynamicMemoryWStream stream;
     SkString log;
-    Error err = sink->draw(noop, &bitmap, &stream, &log);
+    Error err = sink->draw(justOneRect, &bitmap, &stream, &log);
     if (err.isFatal()) {
         SkDebugf("Could not run %s: %s\n", tag, err.c_str());
         exit(1);
     }
 
-    Tagged<Sink>& ts = gSinks.push_back();
+    SinkType type = kRaster_SinkType;
+    if (sink->enclave() == kGPU_Enclave) { type = kGPU_SinkType; }
+    if (stream.bytesWritten() > 0) { type = kVector_SinkType; }
+
+    TaggedSink& ts = gSinks.push_back();
     ts.reset(sink.detach());
     ts.tag = tag;
+    ts.type = type;
 }
 
 static bool gpu_supported() {
@@ -477,22 +490,28 @@
 // The finest-grained unit of work we can run: draw a single Src into a single Sink,
 // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream.
 struct Task {
-    Task(const Tagged<Src>& src, const Tagged<Sink>& sink) : src(src), sink(sink) {}
-    const Tagged<Src>&  src;
-    const Tagged<Sink>& sink;
+    Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {}
+    const TaggedSrc&  src;
+    const TaggedSink& sink;
 
     static void Run(Task* task) {
         SkString name = task->src->name();
-        SkString note;
+
+        // We'll skip drawing this Src/Sink pair if:
+        //   - the Src vetoes the Sink;
+        //   - this Src / Sink combination is on the blacklist;
+        //   - it's a dry run.
+        SkString note(task->src->veto(task->sink.type) ? " (veto)" : "");
         SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag,
                                                  task->src.options, name.c_str());
         if (!whyBlacklisted.isEmpty()) {
             note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
         }
+
         SkString log;
         WallTimer timer;
         timer.start();
-        if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) {
+        if (!FLAGS_dryRun && note.isEmpty()) {
             SkBitmap bitmap;
             SkDynamicMemoryWStream stream;
             if (FLAGS_pre_log) {
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index fd13313..cbf7a0b 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -71,14 +71,14 @@
     , fScale(scale)
 {}
 
-Error CodecSrc::draw(SkCanvas* canvas) const {
-    SkImageInfo canvasInfo;
-    if (NULL == canvas->peekPixels(&canvasInfo, NULL)) {
-        // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferred decode to
-        // let the GPU handle it.
-        return Error::Nonfatal("No need to test decoding to non-raster backend.");
-    }
+bool CodecSrc::veto(SinkType type) const {
+    // No need to test decoding to non-raster backend.
+    // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferred decode to
+    // let the GPU handle it.
+    return type != kRaster_SinkType;
+}
 
+Error CodecSrc::draw(SkCanvas* canvas) const {
     SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
     if (!encoded) {
         return SkStringPrintf("Couldn't read %s.", fPath.c_str());
@@ -90,7 +90,7 @@
 
     // Choose the color type to decode to
     SkImageInfo decodeInfo = codec->getInfo();
-    SkColorType canvasColorType = canvasInfo.colorType();
+    SkColorType canvasColorType = canvas->imageInfo().colorType();
     switch (fDstColorType) {
         case kIndex8_Always_DstColorType:
             decodeInfo = codec->getInfo().makeColorType(kIndex_8_SkColorType);
@@ -459,18 +459,18 @@
 
 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {}
 
-Error ImageSrc::draw(SkCanvas* canvas) const {
-    SkImageInfo canvasInfo;
-    if (NULL == canvas->peekPixels(&canvasInfo, NULL)) {
-        // TODO: Instead, use lazy decoding to allow the GPU to handle cases like YUV.
-        return Error::Nonfatal("No need to test decoding to non-raster backend.");
-    }
+bool ImageSrc::veto(SinkType type) const {
+    // No need to test decoding to non-raster backend.
+    // TODO: Instead, use lazy decoding to allow the GPU to handle cases like YUV.
+    return type != kRaster_SinkType;
+}
 
+Error ImageSrc::draw(SkCanvas* canvas) const {
     SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
     if (!encoded) {
         return SkStringPrintf("Couldn't read %s.", fPath.c_str());
     }
-    const SkColorType dstColorType = canvasInfo.colorType();
+    const SkColorType dstColorType = canvas->imageInfo().colorType();
     if (fDivisor == 0) {
         // Decode the full image.
         SkBitmap bitmap;
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index b80c7c9..3b180ea 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -53,6 +53,8 @@
     bool     fFatal;
 };
 
+enum SinkType { kGPU_SinkType, kVector_SinkType, kRaster_SinkType };
+
 struct Src {
     // All Srcs must be thread safe.
     virtual ~Src() {}
@@ -60,6 +62,7 @@
     virtual SkISize size() const = 0;
     virtual Name name() const = 0;
     virtual void modifyGrContextOptions(GrContextOptions* options) const {}
+    virtual bool veto(SinkType) const { return false; }
 };
 
 struct Sink {
@@ -111,6 +114,7 @@
     Error draw(SkCanvas*) const override;
     SkISize size() const override;
     Name name() const override;
+    bool veto(SinkType) const override;
 private:
     Path                   fPath;
     Mode                   fMode;
@@ -128,6 +132,7 @@
     Error draw(SkCanvas*) const override;
     SkISize size() const override;
     Name name() const override;
+    bool veto(SinkType) const override;
 private:
     Path fPath;
     const int  fDivisor;
diff --git a/tools/dm_flags.json b/tools/dm_flags.json
index dabaf11..5854967 100644
--- a/tools/dm_flags.json
+++ b/tools/dm_flags.json
@@ -20,14 +20,6 @@
     "gm", 
     "image", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -178,14 +170,6 @@
     "--threads", 
     "0", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -309,14 +293,6 @@
     "--threads", 
     "0", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -438,14 +414,6 @@
     "tests", 
     "gm", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -568,14 +536,6 @@
     "tests", 
     "gm", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -694,14 +654,6 @@
     "gm", 
     "image", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -834,14 +786,6 @@
     "gm", 
     "image", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -972,14 +916,6 @@
     "gm", 
     "image", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -1133,14 +1069,6 @@
     "tests", 
     "gm", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
@@ -1294,14 +1222,6 @@
     "tests", 
     "gm", 
     "--blacklist", 
-    "msaa", 
-    "image", 
-    "_", 
-    "_", 
-    "gpu", 
-    "_", 
-    "_", 
-    "PANO_20121023_214540.jpg", 
     "_", 
     "image", 
     "decode", 
diff --git a/tools/dm_flags.py b/tools/dm_flags.py
index 93102cd..40673c7 100755
--- a/tools/dm_flags.py
+++ b/tools/dm_flags.py
@@ -81,13 +81,6 @@
 
   blacklist = []
 
-  # We do not draw image sources on msaa anyway, so avoid the creation of
-  # large canvases. skbug.com/4045
-  blacklist.extend('msaa image _ _'.split(' '))
-
-  # This image is too large to be a texture for many GPUs.
-  blacklist.extend('gpu _ _ PANO_20121023_214540.jpg'.split(' '))
-
   # Several of the newest version bmps fail on SkImageDecoder
   blacklist.extend('_ image decode pal8os2v2.bmp'.split(' '))
   blacklist.extend('_ image decode pal8v4.bmp'.split(' '))