blob: 87555984bc581d43caa74a95d7ead4065fc7d5d5 [file] [log] [blame]
mtklein@google.comd36522d2013-10-16 13:02:15 +00001// Main binary for DM.
2// For a high-level overview, please see dm/README.
3
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +00004#include "SkBenchmark.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +00005#include "SkCommandLineFlags.h"
6#include "SkForceLinking.h"
7#include "SkGraphics.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +00008#include "SkPicture.h"
rmistry@google.comd6bab022013-12-02 13:50:38 +00009#include "SkString.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000010#include "Test.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000011#include "gm.h"
12
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000013#include "DMBenchTask.h"
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000014#include "DMCpuGMTask.h"
15#include "DMGpuGMTask.h"
commit-bot@chromium.org787227d2014-03-26 21:26:15 +000016#include "DMGpuSupport.h"
mtklein30bf3e22014-06-03 13:57:14 -070017#include "DMPDFTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000018#include "DMReporter.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000019#include "DMSKPTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000020#include "DMTask.h"
21#include "DMTaskRunner.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000022#include "DMTestTask.h"
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000023#include "DMWriteTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000024
mtklein30bf3e22014-06-03 13:57:14 -070025#ifdef SK_BUILD_POPPLER
26# include "SkPDFRasterizer.h"
27# define RASTERIZE_PDF_PROC SkPopplerRasterizePDF
28#else
29# define RASTERIZE_PDF_PROC NULL
30#endif
31
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000032#include <ctype.h>
mtklein@google.comd36522d2013-10-16 13:02:15 +000033
34using skiagm::GM;
35using skiagm::GMRegistry;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000036using skiatest::Test;
37using skiatest::TestRegistry;
mtklein@google.comd36522d2013-10-16 13:02:15 +000038
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000039DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000040DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
commit-bot@chromium.orga267d412014-05-16 18:27:11 +000041#ifdef SK_BUILD_JSON_WRITER
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000042DEFINE_string2(expectations, r, "",
43 "If a directory, compare generated images against images under this path. "
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000044 "If a file, compare generated images against JSON expectations at this path."
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000045);
commit-bot@chromium.orga267d412014-05-16 18:27:11 +000046#else
47DEFINE_string2(expectations, r, "",
48 "If a directory, compare generated images against images under this path. "
49);
50#endif
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000051DEFINE_string2(resources, i, "resources", "Path to resources directory.");
mtklein@google.comd36522d2013-10-16 13:02:15 +000052DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
53 "Multiple matches may be separated by spaces.\n"
54 "~ causes a matching GM to always be skipped\n"
55 "^ requires the start of the GM to match\n"
56 "$ requires the end of the GM to match\n"
57 "^ and $ requires an exact match\n"
58 "If a GM does not match any list entry,\n"
59 "it is skipped unless some list entry starts with ~");
mtklein30bf3e22014-06-03 13:57:14 -070060DEFINE_string(config, "565 8888 pdf gpu nonrendering",
61 "Options: 565 8888 pdf gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 "
62 "gpunull gpudebug angle mesa");
63DEFINE_bool(dryRun, false,
64 "Just print the tests that would be run, without actually running them.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000065DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000066DEFINE_string(skps, "", "Directory to read skps from.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000067
68DEFINE_bool(gms, true, "Run GMs?");
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000069DEFINE_bool(benches, true, "Run benches? Does not run GMs-as-benches.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000070DEFINE_bool(tests, true, "Run tests?");
mtklein@google.comd36522d2013-10-16 13:02:15 +000071
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +000072DECLARE_bool(verbose);
73
mtklein@google.comd36522d2013-10-16 13:02:15 +000074__SK_FORCE_IMAGE_DECODER_LINKING;
75
mtklein@google.comd36522d2013-10-16 13:02:15 +000076// "FooBar" -> "foobar". Obviously, ASCII only.
77static SkString lowercase(SkString s) {
78 for (size_t i = 0; i < s.size(); i++) {
79 s[i] = tolower(s[i]);
80 }
81 return s;
82}
83
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000084static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
commit-bot@chromium.orgb6401862014-03-12 14:46:31 +000085static const GrContextFactory::GLContextType nvpr = GrContextFactory::kNVPR_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000086static const GrContextFactory::GLContextType null = GrContextFactory::kNull_GLContextType;
87static const GrContextFactory::GLContextType debug = GrContextFactory::kDebug_GLContextType;
88static const GrContextFactory::GLContextType angle =
89#if SK_ANGLE
90GrContextFactory::kANGLE_GLContextType;
91#else
92native;
93#endif
94static const GrContextFactory::GLContextType mesa =
95#if SK_MESA
bsalomon@google.com9dccafa2014-05-02 14:43:12 +000096GrContextFactory::kMESA_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000097#else
98native;
99#endif
100
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000101static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
102 const SkTArray<SkString>& configs,
103 const DM::Expectations& expectations,
104 DM::Reporter* reporter,
105 DM::TaskRunner* tasks) {
mtkleine4d3e602014-06-06 09:28:43 -0700106#define START(name, type, ...) \
107 if (lowercase(configs[j]).equals(name)) { \
108 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, gms[i], ## __VA_ARGS__))); \
mtklein@google.comd36522d2013-10-16 13:02:15 +0000109 }
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000110 for (int i = 0; i < gms.count(); i++) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000111 for (int j = 0; j < configs.count(); j++) {
mtkleine4d3e602014-06-06 09:28:43 -0700112 START("565", CpuGMTask, expectations, kRGB_565_SkColorType);
113 START("8888", CpuGMTask, expectations, kN32_SkColorType);
114 START("gpu", GpuGMTask, expectations, native, 0);
115 START("msaa4", GpuGMTask, expectations, native, 4);
116 START("msaa16", GpuGMTask, expectations, native, 16);
117 START("nvprmsaa4", GpuGMTask, expectations, nvpr, 4);
118 START("nvprmsaa16", GpuGMTask, expectations, nvpr, 16);
119 START("gpunull", GpuGMTask, expectations, null, 0);
120 START("gpudebug", GpuGMTask, expectations, debug, 0);
121 START("angle", GpuGMTask, expectations, angle, 0);
122 START("mesa", GpuGMTask, expectations, mesa, 0);
mtklein30bf3e22014-06-03 13:57:14 -0700123 START("pdf", PDFTask, RASTERIZE_PDF_PROC);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000124 }
125 }
126#undef START
127}
128
129static void kick_off_benches(const SkTDArray<BenchRegistry::Factory>& benches,
130 const SkTArray<SkString>& configs,
131 DM::Reporter* reporter,
132 DM::TaskRunner* tasks) {
133#define START(name, type, ...) \
134 if (lowercase(configs[j]).equals(name)) { \
135 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, benches[i], ## __VA_ARGS__))); \
136 }
137 for (int i = 0; i < benches.count(); i++) {
138 for (int j = 0; j < configs.count(); j++) {
139 START("nonrendering", NonRenderingBenchTask);
140 START("565", CpuBenchTask, kRGB_565_SkColorType);
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000141 START("8888", CpuBenchTask, kN32_SkColorType);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000142 START("gpu", GpuBenchTask, native, 0);
143 START("msaa4", GpuBenchTask, native, 4);
144 START("msaa16", GpuBenchTask, native, 16);
commit-bot@chromium.orgb6401862014-03-12 14:46:31 +0000145 START("nvprmsaa4", GpuBenchTask, nvpr, 4);
146 START("nvprmsaa16", GpuBenchTask, nvpr, 16);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000147 START("gpunull", GpuBenchTask, null, 0);
148 START("gpudebug", GpuBenchTask, debug, 0);
149 START("angle", GpuBenchTask, angle, 0);
150 START("mesa", GpuBenchTask, mesa, 0);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000151 }
152 }
153#undef START
154}
155
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000156static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
157 DM::Reporter* reporter,
158 DM::TaskRunner* tasks) {
159 for (int i = 0; i < tests.count(); i++) {
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000160 SkAutoTDelete<Test> test(tests[i](NULL));
161 if (test->isGPUTest()) {
162 tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i])));
163 } else {
164 tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i])));
165 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000166 }
167}
168
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000169static void kick_off_skps(DM::Reporter* reporter, DM::TaskRunner* tasks) {
170 if (FLAGS_skps.isEmpty()) {
171 return;
172 }
173
174 SkOSFile::Iter it(FLAGS_skps[0], ".skp");
175 SkString filename;
176 while (it.next(&filename)) {
177 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
178 continue;
179 }
180
181 const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str());
182
183 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path.c_str()));
184 if (stream.get() == NULL) {
185 SkDebugf("Could not read %s.\n", path.c_str());
186 exit(1);
187 }
188 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get()));
189 if (pic.get() == NULL) {
190 SkDebugf("Could not read %s as an SkPicture.\n", path.c_str());
191 exit(1);
192 }
193
mtkleine4d3e602014-06-06 09:28:43 -0700194 tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic->clone(), filename)));
195 tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic->clone(), filename,
196 RASTERIZE_PDF_PROC)));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000197 }
198}
199
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000200static void report_failures(const SkTArray<SkString>& failures) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000201 if (failures.count() == 0) {
202 return;
203 }
204
205 SkDebugf("Failures:\n");
206 for (int i = 0; i < failures.count(); i++) {
207 SkDebugf(" %s\n", failures[i].c_str());
208 }
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000209 SkDebugf("%d failures.\n", failures.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000210}
211
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000212template <typename T, typename Registry>
213static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
214 for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
215 SkAutoTDelete<T> forName(reg->factory()(NULL));
216 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, forName->getName())) {
217 *out->append() = reg->factory();
218 }
219 }
220}
221
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000222int tool_main(int argc, char** argv);
223int tool_main(int argc, char** argv) {
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000224 SkAutoGraphics ag;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000225 SkCommandLineFlags::Parse(argc, argv);
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +0000226
227 if (FLAGS_dryRun) {
228 FLAGS_verbose = true;
229 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000230#if SK_ENABLE_INST_COUNT
231 gPrintInstCount = FLAGS_leaks;
232#endif
mtklein@google.comd36522d2013-10-16 13:02:15 +0000233 GM::SetResourcePath(FLAGS_resources[0]);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000234 SkBenchmark::SetResourcePath(FLAGS_resources[0]);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000235 Test::SetResourcePath(FLAGS_resources[0]);
236
mtklein@google.comd36522d2013-10-16 13:02:15 +0000237 SkTArray<SkString> configs;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000238 for (int i = 0; i < FLAGS_config.count(); i++) {
239 SkStrSplit(FLAGS_config[i], ", ", &configs);
240 }
241
mtklein@google.comd36522d2013-10-16 13:02:15 +0000242 SkTDArray<GMRegistry::Factory> gms;
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000243 SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000244 if (FLAGS_gms) {
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000245 append_matching_factories<GM>(GMRegistry::Head(), &gms);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000246
247 if (FLAGS_expectations.count() > 0) {
248 const char* path = FLAGS_expectations[0];
249 if (sk_isdir(path)) {
250 expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
251 } else {
commit-bot@chromium.org120c9992014-05-16 18:11:51 +0000252#ifdef SK_BUILD_JSON_WRITER
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000253 expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
commit-bot@chromium.org120c9992014-05-16 18:11:51 +0000254#endif
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000255 }
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000256 }
mtklein@google.comd36522d2013-10-16 13:02:15 +0000257 }
258
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000259 SkTDArray<BenchRegistry::Factory> benches;
260 if (FLAGS_benches) {
261 append_matching_factories<SkBenchmark>(BenchRegistry::Head(), &benches);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000262 }
263
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000264 SkTDArray<TestRegistry::Factory> tests;
265 if (FLAGS_tests) {
266 append_matching_factories<Test>(TestRegistry::Head(), &tests);
267 }
268
269 SkDebugf("(%d GMs, %d benches) x %d configs, %d tests\n",
270 gms.count(), benches.count(), configs.count(), tests.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000271 DM::Reporter reporter;
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000272 DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000273 kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000274 kick_off_benches(benches, configs, &reporter, &tasks);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000275 kick_off_tests(tests, &reporter, &tasks);
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000276 kick_off_skps(&reporter, &tasks);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000277 tasks.wait();
278
mtklein@google.comd36522d2013-10-16 13:02:15 +0000279 SkDebugf("\n");
mtklein@google.comd36522d2013-10-16 13:02:15 +0000280
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000281 SkTArray<SkString> failures;
282 reporter.getFailures(&failures);
283 report_failures(failures);
284 return failures.count() > 0;
mtklein@google.comd36522d2013-10-16 13:02:15 +0000285}
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000286
287#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
288int main(int argc, char** argv) {
289 return tool_main(argc, argv);
290}
291#endif