Add --uninterestingHashesFile to DM

The file is expected to contain a list of strings. If the hash for
any result is in this file, don't write an image for it.

BUG=skia:3521

Review URL: https://codereview.chromium.org/1059363002
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 256014e..3ad8226 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -42,6 +42,10 @@
 
 DEFINE_string2(readPath, r, "", "If set check for equality with golden results in this directory.");
 
+DEFINE_string(uninterestingHashesFile, "",
+        "File containing a list of uninteresting hashes. If a result hashes to something in "
+        "this list, no image is written for that result.");
+
 __SK_FORCE_IMAGE_DECODER_LINKING;
 using namespace DM;
 
@@ -137,6 +141,21 @@
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
+static SkTHashSet<SkString> gUninterestingHashes;
+
+static void gather_uninteresting_hashes() {
+    if (!FLAGS_uninterestingHashesFile.isEmpty()) {
+        SkAutoTUnref<SkData> data(SkData::NewFromFileName(FLAGS_uninterestingHashesFile[0]));
+        SkTArray<SkString> hashes;
+        SkStrSplit((const char*)data->data(), "\n", &hashes);
+        for (const SkString& hash : hashes) {
+            gUninterestingHashes.add(hash);
+        }
+    }
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
 template <typename T>
 struct Tagged : public SkAutoTDelete<T> {
   const char* tag;
@@ -435,7 +454,7 @@
                                     FLAGS_readPath[0]));
             }
 
-            if (!FLAGS_writePath.isEmpty()) {
+            if (!FLAGS_writePath.isEmpty() && !gUninterestingHashes.contains(md5)) {
                 const char* ext = task->sink->fileExtension();
                 if (data->getLength()) {
                     WriteToDisk(*task, md5, ext, data, data->getLength(), NULL);
@@ -625,6 +644,7 @@
     start_keepalive();
 
     gather_gold();
+    gather_uninteresting_hashes();
 
     gather_srcs();
     gather_sinks();