| OLD | NEW |
| 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 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 } | 576 } |
| 577 } | 577 } |
| 578 | 578 |
| 579 SkTArray<SkString> images; | 579 SkTArray<SkString> images; |
| 580 if (!CollectImages(&images)) { | 580 if (!CollectImages(&images)) { |
| 581 return false; | 581 return false; |
| 582 } | 582 } |
| 583 | 583 |
| 584 for (auto image : images) { | 584 for (auto image : images) { |
| 585 push_codec_srcs(image); | 585 push_codec_srcs(image); |
| 586 const char* ext = ""; | 586 const char* ext = strrchr(image.c_str(), '.'); |
| 587 int index = image.findLastOf('.'); | 587 if (ext && brd_supported(ext+1)) { |
| 588 if (index >= 0 && (size_t) ++index < image.size()) { | |
| 589 ext = &image.c_str()[index]; | |
| 590 } | |
| 591 if (brd_supported(ext)) { | |
| 592 push_brd_srcs(image); | 588 push_brd_srcs(image); |
| 593 } | 589 } |
| 594 } | 590 } |
| 595 | 591 |
| 596 return true; | 592 return true; |
| 597 } | 593 } |
| 598 | 594 |
| 599 static void push_sink(const SkCommandLineConfig& config, Sink* s) { | 595 static void push_sink(const SkCommandLineConfig& config, Sink* s) { |
| 600 SkAutoTDelete<Sink> sink(s); | 596 SkAutoTDelete<Sink> sink(s); |
| 601 | 597 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 // .png encoding are definitely thread safe. This lets us offload that work to
CPU threads. | 831 // .png encoding are definitely thread safe. This lets us offload that work to
CPU threads. |
| 836 static SkTaskGroup gDefinitelyThreadSafeWork; | 832 static SkTaskGroup gDefinitelyThreadSafeWork; |
| 837 | 833 |
| 838 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, | 834 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, |
| 839 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. | 835 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. |
| 840 struct Task { | 836 struct Task { |
| 841 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {} | 837 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {} |
| 842 const TaggedSrc& src; | 838 const TaggedSrc& src; |
| 843 const TaggedSink& sink; | 839 const TaggedSink& sink; |
| 844 | 840 |
| 845 static void Run(Task* task) { | 841 static void Run(const Task& task) { |
| 846 SkString name = task->src->name(); | 842 SkString name = task.src->name(); |
| 847 | 843 |
| 848 // We'll skip drawing this Src/Sink pair if: | 844 // We'll skip drawing this Src/Sink pair if: |
| 849 // - the Src vetoes the Sink; | 845 // - the Src vetoes the Sink; |
| 850 // - this Src / Sink combination is on the blacklist; | 846 // - this Src / Sink combination is on the blacklist; |
| 851 // - it's a dry run. | 847 // - it's a dry run. |
| 852 SkString note(task->src->veto(task->sink->flags()) ? " (veto)" : ""); | 848 SkString note(task.src->veto(task.sink->flags()) ? " (veto)" : ""); |
| 853 SkString whyBlacklisted = is_blacklisted(task->sink.tag.c_str(), task->s
rc.tag.c_str(), | 849 SkString whyBlacklisted = is_blacklisted(task.sink.tag.c_str(), task.src
.tag.c_str(), |
| 854 task->src.options.c_str(), name
.c_str()); | 850 task.src.options.c_str(), name.
c_str()); |
| 855 if (!whyBlacklisted.isEmpty()) { | 851 if (!whyBlacklisted.isEmpty()) { |
| 856 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); | 852 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); |
| 857 } | 853 } |
| 858 | 854 |
| 859 SkString log; | 855 SkString log; |
| 860 auto timerStart = now_ms(); | 856 auto timerStart = now_ms(); |
| 861 if (!FLAGS_dryRun && note.isEmpty()) { | 857 if (!FLAGS_dryRun && note.isEmpty()) { |
| 862 SkBitmap bitmap; | 858 SkBitmap bitmap; |
| 863 SkDynamicMemoryWStream stream; | 859 SkDynamicMemoryWStream stream; |
| 864 if (FLAGS_pre_log) { | 860 if (FLAGS_pre_log) { |
| 865 SkDebugf("\nRunning %s->%s", name.c_str(), task->sink.tag.c_str(
)); | 861 SkDebugf("\nRunning %s->%s", name.c_str(), task.sink.tag.c_str()
); |
| 866 } | 862 } |
| 867 start(task->sink.tag.c_str(), task->src.tag, task->src.options, name
.c_str()); | 863 start(task.sink.tag.c_str(), task.src.tag, task.src.options, name.c_
str()); |
| 868 Error err = task->sink->draw(*task->src, &bitmap, &stream, &log); | 864 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log); |
| 869 if (!err.isEmpty()) { | 865 if (!err.isEmpty()) { |
| 870 if (err.isFatal()) { | 866 if (err.isFatal()) { |
| 871 fail(SkStringPrintf("%s %s %s %s: %s", | 867 fail(SkStringPrintf("%s %s %s %s: %s", |
| 872 task->sink.tag.c_str(), | 868 task.sink.tag.c_str(), |
| 873 task->src.tag.c_str(), | 869 task.src.tag.c_str(), |
| 874 task->src.options.c_str(), | 870 task.src.options.c_str(), |
| 875 name.c_str(), | 871 name.c_str(), |
| 876 err.c_str())); | 872 err.c_str())); |
| 877 } else { | 873 } else { |
| 878 note.appendf(" (skipped: %s)", err.c_str()); | 874 note.appendf(" (skipped: %s)", err.c_str()); |
| 879 auto elapsed = now_ms() - timerStart; | 875 auto elapsed = now_ms() - timerStart; |
| 880 done(elapsed, task->sink.tag.c_str(), task->src.tag, task->s
rc.options, | 876 done(elapsed, task.sink.tag.c_str(), task.src.tag, task.src.
options, |
| 881 name, note, log); | 877 name, note, log); |
| 882 return; | 878 return; |
| 883 } | 879 } |
| 884 } | 880 } |
| 885 | 881 |
| 886 // We're likely switching threads here, so we must capture by value,
[=] or [foo,bar]. | 882 // We're likely switching threads here, so we must capture by value,
[=] or [foo,bar]. |
| 887 SkStreamAsset* data = stream.detachAsStream(); | 883 SkStreamAsset* data = stream.detachAsStream(); |
| 888 gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{ | 884 gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{ |
| 889 SkAutoTDelete<SkStreamAsset> ownedData(data); | 885 SkAutoTDelete<SkStreamAsset> ownedData(data); |
| 890 | 886 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 911 } | 907 } |
| 912 } | 908 } |
| 913 SkMD5::Digest digest; | 909 SkMD5::Digest digest; |
| 914 hash.finish(digest); | 910 hash.finish(digest); |
| 915 for (int i = 0; i < 16; i++) { | 911 for (int i = 0; i < 16; i++) { |
| 916 md5.appendf("%02x", digest.data[i]); | 912 md5.appendf("%02x", digest.data[i]); |
| 917 } | 913 } |
| 918 } | 914 } |
| 919 | 915 |
| 920 if (!FLAGS_readPath.isEmpty() && | 916 if (!FLAGS_readPath.isEmpty() && |
| 921 !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c
_str(), | 917 !gGold.contains(Gold(task.sink.tag.c_str(), task.src.tag.c_s
tr(), |
| 922 task->src.options.c_str(), name, md5)))
{ | 918 task.src.options.c_str(), name, md5)))
{ |
| 923 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", | 919 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", |
| 924 md5.c_str(), | 920 md5.c_str(), |
| 925 task->sink.tag.c_str(), | 921 task.sink.tag.c_str(), |
| 926 task->src.tag.c_str(), | 922 task.src.tag.c_str(), |
| 927 task->src.options.c_str(), | 923 task.src.options.c_str(), |
| 928 name.c_str(), | 924 name.c_str(), |
| 929 FLAGS_readPath[0])); | 925 FLAGS_readPath[0])); |
| 930 } | 926 } |
| 931 | 927 |
| 932 if (!FLAGS_writePath.isEmpty()) { | 928 if (!FLAGS_writePath.isEmpty()) { |
| 933 const char* ext = task->sink->fileExtension(); | 929 const char* ext = task.sink->fileExtension(); |
| 934 if (data->getLength()) { | 930 if (data->getLength()) { |
| 935 WriteToDisk(*task, md5, ext, data, data->getLength(), nu
llptr); | 931 WriteToDisk(task, md5, ext, data, data->getLength(), nul
lptr); |
| 936 SkASSERT(bitmap.drawsNothing()); | 932 SkASSERT(bitmap.drawsNothing()); |
| 937 } else if (!bitmap.drawsNothing()) { | 933 } else if (!bitmap.drawsNothing()) { |
| 938 WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap); | 934 WriteToDisk(task, md5, ext, nullptr, 0, &bitmap); |
| 939 } | 935 } |
| 940 } | 936 } |
| 941 }); | 937 }); |
| 942 } | 938 } |
| 943 auto elapsed = now_ms() - timerStart; | 939 auto elapsed = now_ms() - timerStart; |
| 944 done(elapsed, task->sink.tag.c_str(), task->src.tag.c_str(), task->src.o
ptions.c_str(), | 940 done(elapsed, task.sink.tag.c_str(), task.src.tag.c_str(), task.src.opti
ons.c_str(), |
| 945 name, note, log); | 941 name, note, log); |
| 946 } | 942 } |
| 947 | 943 |
| 948 static void WriteToDisk(const Task& task, | 944 static void WriteToDisk(const Task& task, |
| 949 SkString md5, | 945 SkString md5, |
| 950 const char* ext, | 946 const char* ext, |
| 951 SkStream* data, size_t len, | 947 SkStream* data, size_t len, |
| 952 const SkBitmap* bitmap) { | 948 const SkBitmap* bitmap) { |
| 953 JsonWriter::BitmapResult result; | 949 JsonWriter::BitmapResult result; |
| 954 result.name = task.src->name(); | 950 result.name = task.src->name(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 return; | 1001 return; |
| 1006 } | 1002 } |
| 1007 if (!file.writeStream(data, len)) { | 1003 if (!file.writeStream(data, len)) { |
| 1008 fail(SkStringPrintf("Can't write to %s.\n", path.c_str())); | 1004 fail(SkStringPrintf("Can't write to %s.\n", path.c_str())); |
| 1009 return; | 1005 return; |
| 1010 } | 1006 } |
| 1011 } | 1007 } |
| 1012 } | 1008 } |
| 1013 }; | 1009 }; |
| 1014 | 1010 |
| 1015 // Run all tasks in the same enclave serially on the same thread. | |
| 1016 // They can't possibly run concurrently with each other. | |
| 1017 static void run_enclave(SkTArray<Task>* tasks) { | |
| 1018 for (int i = 0; i < tasks->count(); i++) { | |
| 1019 Task::Run(tasks->begin() + i); | |
| 1020 } | |
| 1021 } | |
| 1022 | |
| 1023 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1011 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 1024 | 1012 |
| 1025 // Unit tests don't fit so well into the Src/Sink model, so we give them special
treatment. | 1013 // Unit tests don't fit so well into the Src/Sink model, so we give them special
treatment. |
| 1026 | 1014 |
| 1027 static SkTDArray<skiatest::Test> gThreadedTests, gGPUTests; | 1015 static SkTDArray<skiatest::Test> gParallelTests, gSerialTests; |
| 1028 | 1016 |
| 1029 static void gather_tests() { | 1017 static void gather_tests() { |
| 1030 if (!FLAGS_src.contains("tests")) { | 1018 if (!FLAGS_src.contains("tests")) { |
| 1031 return; | 1019 return; |
| 1032 } | 1020 } |
| 1033 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { | 1021 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { |
| 1034 if (!in_shard()) { | 1022 if (!in_shard()) { |
| 1035 continue; | 1023 continue; |
| 1036 } | 1024 } |
| 1037 // Despite its name, factory() is returning a reference to | 1025 // Despite its name, factory() is returning a reference to |
| 1038 // link-time static const POD data. | 1026 // link-time static const POD data. |
| 1039 const skiatest::Test& test = r->factory(); | 1027 const skiatest::Test& test = r->factory(); |
| 1040 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test.name)) { | 1028 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test.name)) { |
| 1041 continue; | 1029 continue; |
| 1042 } | 1030 } |
| 1043 if (test.needsGpu && gpu_supported()) { | 1031 if (test.needsGpu && gpu_supported()) { |
| 1044 (FLAGS_gpu_threading ? gThreadedTests : gGPUTests).push(test); | 1032 (FLAGS_gpu_threading ? gParallelTests : gSerialTests).push(test); |
| 1045 } else if (!test.needsGpu && FLAGS_cpu) { | 1033 } else if (!test.needsGpu && FLAGS_cpu) { |
| 1046 gThreadedTests.push(test); | 1034 gParallelTests.push(test); |
| 1047 } | 1035 } |
| 1048 } | 1036 } |
| 1049 } | 1037 } |
| 1050 | 1038 |
| 1051 static void run_test(skiatest::Test* test) { | 1039 static void run_test(skiatest::Test test) { |
| 1052 struct : public skiatest::Reporter { | 1040 struct : public skiatest::Reporter { |
| 1053 void reportFailed(const skiatest::Failure& failure) override { | 1041 void reportFailed(const skiatest::Failure& failure) override { |
| 1054 fail(failure.toString()); | 1042 fail(failure.toString()); |
| 1055 JsonWriter::AddTestFailure(failure); | 1043 JsonWriter::AddTestFailure(failure); |
| 1056 } | 1044 } |
| 1057 bool allowExtendedTest() const override { | 1045 bool allowExtendedTest() const override { |
| 1058 return FLAGS_pathOpsExtended; | 1046 return FLAGS_pathOpsExtended; |
| 1059 } | 1047 } |
| 1060 bool verbose() const override { return FLAGS_veryVerbose; } | 1048 bool verbose() const override { return FLAGS_veryVerbose; } |
| 1061 } reporter; | 1049 } reporter; |
| 1062 | 1050 |
| 1063 SkString note; | 1051 SkString note; |
| 1064 SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test->name); | 1052 SkString whyBlacklisted = is_blacklisted("_", "tests", "_", test.name); |
| 1065 if (!whyBlacklisted.isEmpty()) { | 1053 if (!whyBlacklisted.isEmpty()) { |
| 1066 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); | 1054 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); |
| 1067 } | 1055 } |
| 1068 | 1056 |
| 1069 auto timerStart = now_ms(); | 1057 auto timerStart = now_ms(); |
| 1070 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { | 1058 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { |
| 1071 start("unit", "test", "", test->name); | 1059 start("unit", "test", "", test.name); |
| 1072 GrContextFactory factory; | 1060 GrContextFactory factory; |
| 1073 if (FLAGS_pre_log) { | 1061 if (FLAGS_pre_log) { |
| 1074 SkDebugf("\nRunning test %s", test->name); | 1062 SkDebugf("\nRunning test %s", test.name); |
| 1075 } | 1063 } |
| 1076 test->proc(&reporter, &factory); | 1064 test.proc(&reporter, &factory); |
| 1077 } | 1065 } |
| 1078 done(now_ms()-timerStart, "unit", "test", "", test->name, note, ""); | 1066 done(now_ms()-timerStart, "unit", "test", "", test.name, note, ""); |
| 1079 } | 1067 } |
| 1080 | 1068 |
| 1081 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 1069 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 1082 | 1070 |
| 1083 // If we're isolating all GPU-bound work to one thread (the default), this funct
ion runs all that. | |
| 1084 static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) { | |
| 1085 run_enclave(tasks); | |
| 1086 for (int i = 0; i < gGPUTests.count(); i++) { | |
| 1087 run_test(&gGPUTests[i]); | |
| 1088 } | |
| 1089 } | |
| 1090 | |
| 1091 // Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've
hung. | 1071 // Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've
hung. |
| 1092 // This prints something every once in a while so that it knows we're still work
ing. | 1072 // This prints something every once in a while so that it knows we're still work
ing. |
| 1093 static void start_keepalive() { | 1073 static void start_keepalive() { |
| 1094 struct Loop { | 1074 struct Loop { |
| 1095 static void forever(void*) { | 1075 static void forever(void*) { |
| 1096 for (;;) { | 1076 for (;;) { |
| 1097 static const int kSec = 300; | 1077 static const int kSec = 300; |
| 1098 #if defined(SK_BUILD_FOR_WIN) | 1078 #if defined(SK_BUILD_FOR_WIN) |
| 1099 Sleep(kSec * 1000); | 1079 Sleep(kSec * 1000); |
| 1100 #else | 1080 #else |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 | 1121 |
| 1142 gather_gold(); | 1122 gather_gold(); |
| 1143 gather_uninteresting_hashes(); | 1123 gather_uninteresting_hashes(); |
| 1144 | 1124 |
| 1145 if (!gather_srcs()) { | 1125 if (!gather_srcs()) { |
| 1146 return 1; | 1126 return 1; |
| 1147 } | 1127 } |
| 1148 gather_sinks(); | 1128 gather_sinks(); |
| 1149 gather_tests(); | 1129 gather_tests(); |
| 1150 | 1130 |
| 1151 gPending = gSrcs.count() * gSinks.count() + gThreadedTests.count() + gGPUTes
ts.count(); | 1131 gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerial
Tests.count(); |
| 1152 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", | 1132 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", |
| 1153 gSrcs.count(), gSinks.count(), gThreadedTests.count() + gGPUTests.c
ount(), gPending); | 1133 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest
s.count(), gPending); |
| 1154 | 1134 |
| 1155 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, | 1135 // Kick off as much parallel work as we can, making note of any serial work
we'll need to do. |
| 1156 // but Sinks that identify as part of a particular enclave run serially on a
single thread. | 1136 SkTaskGroup parallel; |
| 1157 // CPU tests run on any thread. GPU tests depend on --gpu_threading. | 1137 SkTArray<Task> serial; |
| 1158 SkTArray<Task> enclaves[kNumEnclaves]; | 1138 |
| 1159 for (int j = 0; j < gSinks.count(); j++) { | 1139 for (auto& sink : gSinks) |
| 1160 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; | 1140 for (auto& src : gSrcs) { |
| 1161 for (int i = 0; i < gSrcs.count(); i++) { | 1141 Task task(src, sink); |
| 1162 tasks.push_back(Task(gSrcs[i], gSinks[j])); | 1142 if (src->serial() || sink->serial()) { |
| 1143 serial.push_back(task); |
| 1144 } else { |
| 1145 parallel.add([task] { Task::Run(task); }); |
| 1163 } | 1146 } |
| 1164 } | 1147 } |
| 1148 for (auto test : gParallelTests) { |
| 1149 parallel.add([test] { run_test(test); }); |
| 1150 } |
| 1165 | 1151 |
| 1166 SkTaskGroup tg; | 1152 // With the parallel work running, run serial tasks and tests here on main t
hread. |
| 1167 tg.batch(gThreadedTests.count(), [](int i){ run_test(&gThreadedTests[i]); })
; | 1153 for (auto task : serial) { Task::Run(task); } |
| 1168 for (int i = 0; i < kNumEnclaves; i++) { | 1154 for (auto test : gSerialTests) { run_test(test); } |
| 1169 SkTArray<Task>* currentEnclave = &enclaves[i]; | 1155 |
| 1170 switch(i) { | 1156 // Wait for any remaining parallel work to complete (including any spun off
of serial tasks). |
| 1171 case kAnyThread_Enclave: | 1157 parallel.wait(); |
| 1172 tg.batch(currentEnclave->count(), | |
| 1173 [currentEnclave](int j) { Task::Run(&(*currentEnclave)[
j]); }); | |
| 1174 break; | |
| 1175 case kGPU_Enclave: | |
| 1176 tg.add([currentEnclave](){ run_enclave_and_gpu_tests(currentEncl
ave); }); | |
| 1177 break; | |
| 1178 default: | |
| 1179 tg.add([currentEnclave](){ run_enclave(currentEnclave); }); | |
| 1180 break; | |
| 1181 } | |
| 1182 } | |
| 1183 tg.wait(); | |
| 1184 gDefinitelyThreadSafeWork.wait(); | 1158 gDefinitelyThreadSafeWork.wait(); |
| 1185 | 1159 |
| 1186 // At this point we're back in single-threaded land. | 1160 // At this point we're back in single-threaded land. |
| 1187 sk_tool_utils::release_portable_typefaces(); | 1161 sk_tool_utils::release_portable_typefaces(); |
| 1188 | 1162 |
| 1189 if (FLAGS_verbose && gNoteTally.count() > 0) { | 1163 if (FLAGS_verbose && gNoteTally.count() > 0) { |
| 1190 SkDebugf("\nNote tally:\n"); | 1164 SkDebugf("\nNote tally:\n"); |
| 1191 gNoteTally.foreach([](const SkString& note, int* tally) { | 1165 gNoteTally.foreach([](const SkString& note, int* tally) { |
| 1192 SkDebugf("%dx\t%s\n", *tally, note.c_str()); | 1166 SkDebugf("%dx\t%s\n", *tally, note.c_str()); |
| 1193 }); | 1167 }); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 Reporter* reporter, | 1274 Reporter* reporter, |
| 1301 GrContextFactory* fac
tory); | 1275 GrContextFactory* fac
tory); |
| 1302 } // namespace skiatest | 1276 } // namespace skiatest |
| 1303 | 1277 |
| 1304 #if !defined(SK_BUILD_FOR_IOS) | 1278 #if !defined(SK_BUILD_FOR_IOS) |
| 1305 int main(int argc, char** argv) { | 1279 int main(int argc, char** argv) { |
| 1306 SkCommandLineFlags::Parse(argc, argv); | 1280 SkCommandLineFlags::Parse(argc, argv); |
| 1307 return dm_main(); | 1281 return dm_main(); |
| 1308 } | 1282 } |
| 1309 #endif | 1283 #endif |
| OLD | NEW |