Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(635)

Side by Side Diff: dm/DM.cpp

Issue 1727363004: trim DM fat (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "CrashHandler.h" 8 #include "CrashHandler.h"
9 #include "DMJsonWriter.h" 9 #include "DMJsonWriter.h"
10 #include "DMSrcSink.h" 10 #include "DMSrcSink.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 "this list, no image is written for that result."); 64 "this list, no image is written for that result.");
65 65
66 DEFINE_int32(shards, 1, "We're splitting source data into this many shards."); 66 DEFINE_int32(shards, 1, "We're splitting source data into this many shards.");
67 DEFINE_int32(shard, 0, "Which shard do I run?"); 67 DEFINE_int32(shard, 0, "Which shard do I run?");
68 68
69 __SK_FORCE_IMAGE_DECODER_LINKING; 69 __SK_FORCE_IMAGE_DECODER_LINKING;
70 using namespace DM; 70 using namespace DM;
71 71
72 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 72 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
73 73
74 static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
75
76 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); 74 SK_DECLARE_STATIC_MUTEX(gFailuresMutex);
77 static SkTArray<SkString> gFailures; 75 static SkTArray<SkString> gFailures;
78 76
79 static void fail(ImplicitString err) { 77 static void fail(const SkString& err) {
80 SkAutoMutexAcquire lock(gFailuresMutex); 78 SkAutoMutexAcquire lock(gFailuresMutex);
81 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); 79 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str());
82 gFailures.push_back(err); 80 gFailures.push_back(err);
83 } 81 }
84 82
85 83
86 // We use a spinlock to make locking this in a signal handler _somewhat_ safe. 84 // We use a spinlock to make locking this in a signal handler _somewhat_ safe.
87 SK_DECLARE_STATIC_SPINLOCK(gMutex); 85 SK_DECLARE_STATIC_SPINLOCK(gMutex);
88 static int32_t gPending; 86 static int32_t gPending;
89 static SkTArray<SkString> gRunning; 87 static SkTArray<SkString> gRunning;
90 static SkTHashMap<SkString, int> gNoteTally;
91 88
92 static void done(double ms, 89 static void done(const char* config, const char* src, const char* srcOptions, co nst char* name) {
93 ImplicitString config, ImplicitString src, ImplicitString srcOp tions, 90 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
94 ImplicitString name, ImplicitString note, ImplicitString log) {
95 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(),
96 srcOptions.c_str(), name.c_str() );
97 int pending; 91 int pending;
98 { 92 {
99 SkAutoTAcquire<SkPODSpinlock> lock(gMutex); 93 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
100 for (int i = 0; i < gRunning.count(); i++) { 94 for (int i = 0; i < gRunning.count(); i++) {
101 if (gRunning[i] == id) { 95 if (gRunning[i] == id) {
102 gRunning.removeShuffle(i); 96 gRunning.removeShuffle(i);
103 break; 97 break;
104 } 98 }
105 } 99 }
106 if (!note.isEmpty()) {
107 if (int* tally = gNoteTally.find(note)) {
108 *tally += 1;
109 } else {
110 gNoteTally.set(note, 1);
111 }
112 }
113 pending = --gPending; 100 pending = --gPending;
114 } 101 }
115 // We write our dm.json file every once in a while in case we crash. 102 // We write our dm.json file every once in a while in case we crash.
116 // Notice this also handles the final dm.json when pending == 0. 103 // Notice this also handles the final dm.json when pending == 0.
117 if (pending % 500 == 0) { 104 if (pending % 500 == 0) {
118 JsonWriter::DumpJson(); 105 JsonWriter::DumpJson();
119 } 106 }
120 } 107 }
121 108
122 static void start(ImplicitString config, ImplicitString src, 109 static void start(const char* config, const char* src, const char* srcOptions, c onst char* name) {
123 ImplicitString srcOptions, ImplicitString name) { 110 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
124 SkString id = SkStringPrintf("%s %s %s %s", config.c_str(), src.c_str(),
125 srcOptions.c_str(), name.c_str() );
126 SkAutoTAcquire<SkPODSpinlock> lock(gMutex); 111 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
127 gRunning.push_back(id); 112 gRunning.push_back(id);
128 } 113 }
129 114
130 static void print_status() { 115 static void print_status() {
131 static SkMSec start_ms = SkTime::GetMSecs(); 116 static SkMSec start_ms = SkTime::GetMSecs();
132 117
133 int curr = sk_tools::getCurrResidentSetSizeMB(), 118 int curr = sk_tools::getCurrResidentSetSizeMB(),
134 peak = sk_tools::getMaxResidentSetSizeMB(); 119 peak = sk_tools::getMaxResidentSetSizeMB();
135 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms); 120 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms);
(...skipping 22 matching lines...) Expand all
158 print_status(); 143 print_status();
159 }); 144 });
160 } 145 }
161 } 146 }
162 #endif 147 #endif
163 148
164 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 149 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
165 150
166 struct Gold : public SkString { 151 struct Gold : public SkString {
167 Gold() : SkString("") {} 152 Gold() : SkString("") {}
168 Gold(ImplicitString sink, ImplicitString src, ImplicitString srcOptions, 153 Gold(const SkString& sink, const SkString& src,
169 ImplicitString name, ImplicitString md5) 154 const SkString& srcOptions, const SkString& name,
155 const SkString& md5)
170 : SkString("") { 156 : SkString("") {
171 this->append(sink); 157 this->append(sink);
172 this->append(src); 158 this->append(src);
173 this->append(srcOptions); 159 this->append(srcOptions);
174 this->append(name); 160 this->append(name);
175 this->append(md5); 161 this->append(md5);
176 } 162 }
177 struct Hash { 163 struct Hash {
178 uint32_t operator()(const Gold& g) const { 164 uint32_t operator()(const Gold& g) const {
179 return SkGoodHash()((const SkString&)g); 165 return SkGoodHash()((const SkString&)g);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 gUninterestingHashes.add(hash); 200 gUninterestingHashes.add(hash);
215 } 201 }
216 SkDebugf("FYI: loaded %d distinct uninteresting hashes from %d lines\n", 202 SkDebugf("FYI: loaded %d distinct uninteresting hashes from %d lines\n",
217 gUninterestingHashes.count(), hashes.count()); 203 gUninterestingHashes.count(), hashes.count());
218 } 204 }
219 } 205 }
220 206
221 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 207 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
222 208
223 struct TaggedSrc : public SkAutoTDelete<Src> { 209 struct TaggedSrc : public SkAutoTDelete<Src> {
224 ImplicitString tag; 210 SkString tag;
225 ImplicitString options; 211 SkString options;
226 }; 212 };
227 213
228 struct TaggedSink : public SkAutoTDelete<Sink> { 214 struct TaggedSink : public SkAutoTDelete<Sink> {
229 SkString tag; 215 SkString tag;
230 }; 216 };
231 217
232 static const bool kMemcpyOK = true; 218 static const bool kMemcpyOK = true;
233 219
234 static SkTArray<TaggedSrc, kMemcpyOK> gSrcs; 220 static SkTArray<TaggedSrc, kMemcpyOK> gSrcs;
235 static SkTArray<TaggedSink, kMemcpyOK> gSinks; 221 static SkTArray<TaggedSink, kMemcpyOK> gSinks;
236 222
237 static bool in_shard() { 223 static bool in_shard() {
238 static int N = 0; 224 static int N = 0;
239 return N++ % FLAGS_shards == FLAGS_shard; 225 return N++ % FLAGS_shards == FLAGS_shard;
240 } 226 }
241 227
242 static void push_src(ImplicitString tag, ImplicitString options, Src* s) { 228 static void push_src(const char* tag, ImplicitString options, Src* s) {
243 SkAutoTDelete<Src> src(s); 229 SkAutoTDelete<Src> src(s);
244 if (in_shard() && 230 if (in_shard() &&
245 FLAGS_src.contains(tag.c_str()) && 231 FLAGS_src.contains(tag) &&
246 !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) { 232 !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) {
247 TaggedSrc& s = gSrcs.push_back(); 233 TaggedSrc& s = gSrcs.push_back();
248 s.reset(src.detach()); 234 s.reset(src.detach());
249 s.tag = tag; 235 s.tag = tag;
250 s.options = options; 236 s.options = options;
251 } 237 }
252 } 238 }
253 239
254 static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp e dstColorType, 240 static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp e dstColorType,
255 SkAlphaType dstAlphaType, float scale) { 241 SkAlphaType dstAlphaType, float scale) {
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 835
850 png_destroy_write_struct(&png, &info); 836 png_destroy_write_struct(&png, &info);
851 fclose(f); 837 fclose(f);
852 return true; 838 return true;
853 } 839 }
854 840
855 static bool match(const char* needle, const char* haystack) { 841 static bool match(const char* needle, const char* haystack) {
856 return 0 == strcmp("_", needle) || nullptr != strstr(haystack, needle); 842 return 0 == strcmp("_", needle) || nullptr != strstr(haystack, needle);
857 } 843 }
858 844
859 static ImplicitString is_blacklisted(const char* sink, const char* src, 845 static bool is_blacklisted(const char* sink, const char* src,
860 const char* srcOptions, const char* name) { 846 const char* srcOptions, const char* name) {
861 for (int i = 0; i < FLAGS_blacklist.count() - 3; i += 4) { 847 for (int i = 0; i < FLAGS_blacklist.count() - 3; i += 4) {
862 if (match(FLAGS_blacklist[i+0], sink) && 848 if (match(FLAGS_blacklist[i+0], sink) &&
863 match(FLAGS_blacklist[i+1], src) && 849 match(FLAGS_blacklist[i+1], src) &&
864 match(FLAGS_blacklist[i+2], srcOptions) && 850 match(FLAGS_blacklist[i+2], srcOptions) &&
865 match(FLAGS_blacklist[i+3], name)) { 851 match(FLAGS_blacklist[i+3], name)) {
866 return SkStringPrintf("%s %s %s %s", 852 return true;
867 FLAGS_blacklist[i+0], FLAGS_blacklist[i+1],
868 FLAGS_blacklist[i+2], FLAGS_blacklist[i+3]);
869 } 853 }
870 } 854 }
871 return ""; 855 return false;
872 } 856 }
873 857
874 // Even when a Task Sink reports to be non-threadsafe (e.g. GPU), we know things like 858 // Even when a Task Sink reports to be non-threadsafe (e.g. GPU), we know things like
875 // .png encoding are definitely thread safe. This lets us offload that work to CPU threads. 859 // .png encoding are definitely thread safe. This lets us offload that work to CPU threads.
876 static SkTaskGroup gDefinitelyThreadSafeWork; 860 static SkTaskGroup gDefinitelyThreadSafeWork;
877 861
878 // The finest-grained unit of work we can run: draw a single Src into a single S ink, 862 // The finest-grained unit of work we can run: draw a single Src into a single S ink,
879 // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream. 863 // report any errors, and perhaps write out the output: a .png of the bitmap, or a raw stream.
880 struct Task { 864 struct Task {
881 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {} 865 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {}
882 const TaggedSrc& src; 866 const TaggedSrc& src;
883 const TaggedSink& sink; 867 const TaggedSink& sink;
884 868
885 static void Run(const Task& task) { 869 static void Run(const Task& task) {
886 SkString name = task.src->name(); 870 SkString name = task.src->name();
887 871
888 // We'll skip drawing this Src/Sink pair if:
889 // - the Src vetoes the Sink;
890 // - this Src / Sink combination is on the blacklist;
891 // - it's a dry run.
892 SkString note(task.src->veto(task.sink->flags()) ? " (veto)" : "");
893 SkString whyBlacklisted = is_blacklisted(task.sink.tag.c_str(), task.src .tag.c_str(),
894 task.src.options.c_str(), name. c_str());
895 if (!whyBlacklisted.isEmpty()) {
896 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
897 }
898
899 SkString log; 872 SkString log;
900 auto timerStart = now_ms(); 873 if (!FLAGS_dryRun) {
901 if (!FLAGS_dryRun && note.isEmpty()) {
902 SkBitmap bitmap; 874 SkBitmap bitmap;
903 SkDynamicMemoryWStream stream; 875 SkDynamicMemoryWStream stream;
904 start(task.sink.tag.c_str(), task.src.tag, task.src.options, name.c_ str()); 876 start(task.sink.tag.c_str(), task.src.tag.c_str(),
877 task.src.options.c_str(), name.c_str());
905 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log); 878 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log);
906 if (!err.isEmpty()) { 879 if (!err.isEmpty()) {
907 if (err.isFatal()) { 880 if (err.isFatal()) {
908 fail(SkStringPrintf("%s %s %s %s: %s", 881 fail(SkStringPrintf("%s %s %s %s: %s",
909 task.sink.tag.c_str(), 882 task.sink.tag.c_str(),
910 task.src.tag.c_str(), 883 task.src.tag.c_str(),
911 task.src.options.c_str(), 884 task.src.options.c_str(),
912 name.c_str(), 885 name.c_str(),
913 err.c_str())); 886 err.c_str()));
914 } else { 887 } else {
915 note.appendf(" (skipped: %s)", err.c_str()); 888 done(task.sink.tag.c_str(), task.src.tag.c_str(),
916 auto elapsed = now_ms() - timerStart; 889 task.src.options.c_str(), name.c_str());
917 done(elapsed, task.sink.tag.c_str(), task.src.tag, task.src. options,
918 name, note, log);
919 return; 890 return;
920 } 891 }
921 } 892 }
922 893
923 // We're likely switching threads here, so we must capture by value, [=] or [foo,bar]. 894 // We're likely switching threads here, so we must capture by value, [=] or [foo,bar].
924 SkStreamAsset* data = stream.detachAsStream(); 895 SkStreamAsset* data = stream.detachAsStream();
925 gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{ 896 gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{
926 SkAutoTDelete<SkStreamAsset> ownedData(data); 897 SkAutoTDelete<SkStreamAsset> ownedData(data);
927 898
928 // Why doesn't the copy constructor do this when we have pre-loc ked pixels? 899 // Why doesn't the copy constructor do this when we have pre-loc ked pixels?
(...skipping 19 matching lines...) Expand all
948 } 919 }
949 } 920 }
950 SkMD5::Digest digest; 921 SkMD5::Digest digest;
951 hash.finish(digest); 922 hash.finish(digest);
952 for (int i = 0; i < 16; i++) { 923 for (int i = 0; i < 16; i++) {
953 md5.appendf("%02x", digest.data[i]); 924 md5.appendf("%02x", digest.data[i]);
954 } 925 }
955 } 926 }
956 927
957 if (!FLAGS_readPath.isEmpty() && 928 if (!FLAGS_readPath.isEmpty() &&
958 !gGold.contains(Gold(task.sink.tag.c_str(), task.src.tag.c_s tr(), 929 !gGold.contains(Gold(task.sink.tag, task.src.tag,
959 task.src.options.c_str(), name, md5))) { 930 task.src.options, name, md5))) {
960 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", 931 fail(SkStringPrintf("%s not found for %s %s %s %s in %s",
961 md5.c_str(), 932 md5.c_str(),
962 task.sink.tag.c_str(), 933 task.sink.tag.c_str(),
963 task.src.tag.c_str(), 934 task.src.tag.c_str(),
964 task.src.options.c_str(), 935 task.src.options.c_str(),
965 name.c_str(), 936 name.c_str(),
966 FLAGS_readPath[0])); 937 FLAGS_readPath[0]));
967 } 938 }
968 939
969 if (!FLAGS_writePath.isEmpty()) { 940 if (!FLAGS_writePath.isEmpty()) {
970 const char* ext = task.sink->fileExtension(); 941 const char* ext = task.sink->fileExtension();
971 if (data->getLength()) { 942 if (data->getLength()) {
972 WriteToDisk(task, md5, ext, data, data->getLength(), nul lptr); 943 WriteToDisk(task, md5, ext, data, data->getLength(), nul lptr);
973 SkASSERT(bitmap.drawsNothing()); 944 SkASSERT(bitmap.drawsNothing());
974 } else if (!bitmap.drawsNothing()) { 945 } else if (!bitmap.drawsNothing()) {
975 WriteToDisk(task, md5, ext, nullptr, 0, &bitmap); 946 WriteToDisk(task, md5, ext, nullptr, 0, &bitmap);
976 } 947 }
977 } 948 }
978 }); 949 });
979 } 950 }
980 auto elapsed = now_ms() - timerStart; 951 done(task.sink.tag.c_str(), task.src.tag.c_str(), task.src.options.c_str (), name.c_str());
981 done(elapsed, task.sink.tag.c_str(), task.src.tag.c_str(), task.src.opti ons.c_str(),
982 name, note, log);
983 } 952 }
984 953
985 static void WriteToDisk(const Task& task, 954 static void WriteToDisk(const Task& task,
986 SkString md5, 955 SkString md5,
987 const char* ext, 956 const char* ext,
988 SkStream* data, size_t len, 957 SkStream* data, size_t len,
989 const SkBitmap* bitmap) { 958 const SkBitmap* bitmap) {
990 JsonWriter::BitmapResult result; 959 JsonWriter::BitmapResult result;
991 result.name = task.src->name(); 960 result.name = task.src->name();
992 result.config = task.sink.tag.c_str(); 961 result.config = task.sink.tag;
993 result.sourceType = task.src.tag; 962 result.sourceType = task.src.tag;
994 result.sourceOptions = task.src.options; 963 result.sourceOptions = task.src.options;
995 result.ext = ext; 964 result.ext = ext;
996 result.md5 = md5; 965 result.md5 = md5;
997 JsonWriter::AddBitmapResult(result); 966 JsonWriter::AddBitmapResult(result);
998 967
999 // If an MD5 is uninteresting, we want it noted in the JSON file, 968 // If an MD5 is uninteresting, we want it noted in the JSON file,
1000 // but don't want to dump it out as a .png (or whatever ext is). 969 // but don't want to dump it out as a .png (or whatever ext is).
1001 if (gUninterestingHashes.contains(md5)) { 970 if (gUninterestingHashes.contains(md5)) {
1002 return; 971 return;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 void reportFailed(const skiatest::Failure& failure) override { 1051 void reportFailed(const skiatest::Failure& failure) override {
1083 fail(failure.toString()); 1052 fail(failure.toString());
1084 JsonWriter::AddTestFailure(failure); 1053 JsonWriter::AddTestFailure(failure);
1085 } 1054 }
1086 bool allowExtendedTest() const override { 1055 bool allowExtendedTest() const override {
1087 return FLAGS_pathOpsExtended; 1056 return FLAGS_pathOpsExtended;
1088 } 1057 }
1089 bool verbose() const override { return FLAGS_veryVerbose; } 1058 bool verbose() const override { return FLAGS_veryVerbose; }
1090 } reporter; 1059 } reporter;
1091 1060
1092 SkString note; 1061 if (!FLAGS_dryRun && !is_blacklisted("_", "tests", "_", test.name)) {
1093 SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test.name);
1094 if (!whyBlacklisted.isEmpty()) {
1095 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str());
1096 }
1097
1098 auto timerStart = now_ms();
1099 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) {
1100 start("unit", "test", "", test.name); 1062 start("unit", "test", "", test.name);
1101 GrContextFactory factory; 1063 GrContextFactory factory;
1102 test.proc(&reporter, &factory); 1064 test.proc(&reporter, &factory);
1103 } 1065 }
1104 done(now_ms()-timerStart, "unit", "test", "", test.name, note, ""); 1066 done("unit", "test", "", test.name);
1105 } 1067 }
1106 1068
1107 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ 1069 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/
1108 1070
1109 DEFINE_int32(status_sec, 15, "Print status this often (and if we crash)."); 1071 DEFINE_int32(status_sec, 15, "Print status this often (and if we crash).");
1110 1072
1111 SkThread* start_status_thread() { 1073 SkThread* start_status_thread() {
1112 auto thread = new SkThread([] (void*) { 1074 auto thread = new SkThread([] (void*) {
1113 for (;;) { 1075 for (;;) {
1114 print_status(); 1076 print_status();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks", 1128 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks",
1167 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest s.count(), gPending); 1129 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest s.count(), gPending);
1168 SkAutoTDelete<SkThread> statusThread(start_status_thread()); 1130 SkAutoTDelete<SkThread> statusThread(start_status_thread());
1169 1131
1170 // Kick off as much parallel work as we can, making note of any serial work we'll need to do. 1132 // Kick off as much parallel work as we can, making note of any serial work we'll need to do.
1171 SkTaskGroup parallel; 1133 SkTaskGroup parallel;
1172 SkTArray<Task> serial; 1134 SkTArray<Task> serial;
1173 1135
1174 for (auto& sink : gSinks) 1136 for (auto& sink : gSinks)
1175 for (auto& src : gSrcs) { 1137 for (auto& src : gSrcs) {
1138 if (src->veto(sink->flags()) ||
1139 is_blacklisted(sink.tag.c_str(), src.tag.c_str(),
1140 src.options.c_str(), src->name().c_str())) {
1141 SkAutoTAcquire<SkPODSpinlock> lock(gMutex);
1142 gPending--;
1143 continue;
1144 }
1145
1176 Task task(src, sink); 1146 Task task(src, sink);
1177 if (src->serial() || sink->serial()) { 1147 if (src->serial() || sink->serial()) {
1178 serial.push_back(task); 1148 serial.push_back(task);
1179 } else { 1149 } else {
1180 parallel.add([task] { Task::Run(task); }); 1150 parallel.add([task] { Task::Run(task); });
1181 } 1151 }
1182 } 1152 }
1183 for (auto test : gParallelTests) { 1153 for (auto test : gParallelTests) {
1184 parallel.add([test] { run_test(test); }); 1154 parallel.add([test] { run_test(test); });
1185 } 1155 }
1186 1156
1187 // With the parallel work running, run serial tasks and tests here on main t hread. 1157 // With the parallel work running, run serial tasks and tests here on main t hread.
1188 for (auto task : serial) { Task::Run(task); } 1158 for (auto task : serial) { Task::Run(task); }
1189 for (auto test : gSerialTests) { run_test(test); } 1159 for (auto test : gSerialTests) { run_test(test); }
1190 1160
1191 // Wait for any remaining parallel work to complete (including any spun off of serial tasks). 1161 // Wait for any remaining parallel work to complete (including any spun off of serial tasks).
1192 parallel.wait(); 1162 parallel.wait();
1193 gDefinitelyThreadSafeWork.wait(); 1163 gDefinitelyThreadSafeWork.wait();
1194 1164
1195 // We'd better have run everything. 1165 // We'd better have run everything.
1196 SkASSERT(gPending == 0); 1166 SkASSERT(gPending == 0);
1197 1167
1198 // At this point we're back in single-threaded land. 1168 // At this point we're back in single-threaded land.
1199 sk_tool_utils::release_portable_typefaces(); 1169 sk_tool_utils::release_portable_typefaces();
1200 1170
1201 if (FLAGS_verbose && gNoteTally.count() > 0) {
1202 SkDebugf("\nNote tally:\n");
1203 gNoteTally.foreach([](const SkString& note, int* tally) {
1204 SkDebugf("%dx\t%s\n", *tally, note.c_str());
1205 });
1206 }
1207
1208 SkDebugf("\n");
1209 if (gFailures.count() > 0) { 1171 if (gFailures.count() > 0) {
1210 SkDebugf("Failures:\n"); 1172 SkDebugf("Failures:\n");
1211 for (int i = 0; i < gFailures.count(); i++) { 1173 for (int i = 0; i < gFailures.count(); i++) {
1212 SkDebugf("\t%s\n", gFailures[i].c_str()); 1174 SkDebugf("\t%s\n", gFailures[i].c_str());
1213 } 1175 }
1214 SkDebugf("%d failures\n", gFailures.count()); 1176 SkDebugf("%d failures\n", gFailures.count());
1215 return 1; 1177 return 1;
1216 } 1178 }
1217 1179
1218 #ifdef SK_PDF_IMAGE_STATS 1180 #ifdef SK_PDF_IMAGE_STATS
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 Reporter* reporter, 1273 Reporter* reporter,
1312 GrContextFactory* fac tory); 1274 GrContextFactory* fac tory);
1313 } // namespace skiatest 1275 } // namespace skiatest
1314 1276
1315 #if !defined(SK_BUILD_FOR_IOS) 1277 #if !defined(SK_BUILD_FOR_IOS)
1316 int main(int argc, char** argv) { 1278 int main(int argc, char** argv) {
1317 SkCommandLineFlags::Parse(argc, argv); 1279 SkCommandLineFlags::Parse(argc, argv);
1318 return dm_main(); 1280 return dm_main();
1319 } 1281 }
1320 #endif 1282 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698