blob: afe75734e981724c4d07238c5ad2cdb8b3a638b9 [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
tfarinaf168b862014-06-19 12:32:29 -07004#include "Benchmark.h"
5#include "CrashHandler.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +00006#include "SkCommandLineFlags.h"
7#include "SkForceLinking.h"
8#include "SkGraphics.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +00009#include "SkPicture.h"
rmistry@google.comd6bab022013-12-02 13:50:38 +000010#include "SkString.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000011#include "Test.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000012#include "gm.h"
13
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000014#include "DMBenchTask.h"
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000015#include "DMCpuGMTask.h"
16#include "DMGpuGMTask.h"
commit-bot@chromium.org787227d2014-03-26 21:26:15 +000017#include "DMGpuSupport.h"
mtklein30bf3e22014-06-03 13:57:14 -070018#include "DMPDFTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000019#include "DMReporter.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000020#include "DMSKPTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000021#include "DMTask.h"
22#include "DMTaskRunner.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000023#include "DMTestTask.h"
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000024#include "DMWriteTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000025
mtklein30bf3e22014-06-03 13:57:14 -070026#ifdef SK_BUILD_POPPLER
27# include "SkPDFRasterizer.h"
28# define RASTERIZE_PDF_PROC SkPopplerRasterizePDF
29#else
30# define RASTERIZE_PDF_PROC NULL
31#endif
32
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000033#include <ctype.h>
mtklein@google.comd36522d2013-10-16 13:02:15 +000034
35using skiagm::GM;
36using skiagm::GMRegistry;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000037using skiatest::Test;
38using skiatest::TestRegistry;
mtklein@google.comd36522d2013-10-16 13:02:15 +000039
kkinnunen80549fc2014-06-30 06:36:31 -070040static const char kGpuAPINameGL[] = "gl";
41static const char kGpuAPINameGLES[] = "gles";
42
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000043DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000044DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
kkinnunen80549fc2014-06-30 06:36:31 -070045DEFINE_string(gpuAPI, "", "Force use of specific gpu API. Using \"gl\" "
46 "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
47 "Defaults to empty string, which selects the API native to the "
48 "system.");
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000049DEFINE_string2(expectations, r, "",
50 "If a directory, compare generated images against images under this path. "
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000051 "If a file, compare generated images against JSON expectations at this path."
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000052);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000053DEFINE_string2(resources, i, "resources", "Path to resources directory.");
mtklein@google.comd36522d2013-10-16 13:02:15 +000054DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
55 "Multiple matches may be separated by spaces.\n"
56 "~ causes a matching GM to always be skipped\n"
57 "^ requires the start of the GM to match\n"
58 "$ requires the end of the GM to match\n"
59 "^ and $ requires an exact match\n"
60 "If a GM does not match any list entry,\n"
61 "it is skipped unless some list entry starts with ~");
mtklein30bf3e22014-06-03 13:57:14 -070062DEFINE_string(config, "565 8888 pdf gpu nonrendering",
63 "Options: 565 8888 pdf gpu nonrendering msaa4 msaa16 nvprmsaa4 nvprmsaa16 "
64 "gpunull gpudebug angle mesa");
65DEFINE_bool(dryRun, false,
66 "Just print the tests that would be run, without actually running them.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000067DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000068DEFINE_string(skps, "", "Directory to read skps from.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000069
70DEFINE_bool(gms, true, "Run GMs?");
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000071DEFINE_bool(benches, true, "Run benches? Does not run GMs-as-benches.");
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000072DEFINE_bool(tests, true, "Run tests?");
mtklein@google.comd36522d2013-10-16 13:02:15 +000073
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +000074DECLARE_bool(verbose);
75
mtklein@google.comd36522d2013-10-16 13:02:15 +000076__SK_FORCE_IMAGE_DECODER_LINKING;
77
mtklein@google.comd36522d2013-10-16 13:02:15 +000078// "FooBar" -> "foobar". Obviously, ASCII only.
79static SkString lowercase(SkString s) {
80 for (size_t i = 0; i < s.size(); i++) {
81 s[i] = tolower(s[i]);
82 }
83 return s;
84}
85
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000086static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
commit-bot@chromium.orgb6401862014-03-12 14:46:31 +000087static const GrContextFactory::GLContextType nvpr = GrContextFactory::kNVPR_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000088static const GrContextFactory::GLContextType null = GrContextFactory::kNull_GLContextType;
89static const GrContextFactory::GLContextType debug = GrContextFactory::kDebug_GLContextType;
90static const GrContextFactory::GLContextType angle =
91#if SK_ANGLE
92GrContextFactory::kANGLE_GLContextType;
93#else
94native;
95#endif
96static const GrContextFactory::GLContextType mesa =
97#if SK_MESA
bsalomon@google.com9dccafa2014-05-02 14:43:12 +000098GrContextFactory::kMESA_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000099#else
100native;
101#endif
102
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000103static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
104 const SkTArray<SkString>& configs,
kkinnunen80549fc2014-06-30 06:36:31 -0700105 GrGLStandard gpuAPI,
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000106 const DM::Expectations& expectations,
107 DM::Reporter* reporter,
108 DM::TaskRunner* tasks) {
mtkleine4d3e602014-06-06 09:28:43 -0700109#define START(name, type, ...) \
110 if (lowercase(configs[j]).equals(name)) { \
111 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, gms[i], ## __VA_ARGS__))); \
mtklein@google.comd36522d2013-10-16 13:02:15 +0000112 }
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000113 for (int i = 0; i < gms.count(); i++) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000114 for (int j = 0; j < configs.count(); j++) {
kkinnunen80549fc2014-06-30 06:36:31 -0700115
mtkleine4d3e602014-06-06 09:28:43 -0700116 START("565", CpuGMTask, expectations, kRGB_565_SkColorType);
117 START("8888", CpuGMTask, expectations, kN32_SkColorType);
kkinnunen80549fc2014-06-30 06:36:31 -0700118 START("gpu", GpuGMTask, expectations, native, gpuAPI, 0);
119 START("msaa4", GpuGMTask, expectations, native, gpuAPI, 4);
120 START("msaa16", GpuGMTask, expectations, native, gpuAPI, 16);
121 START("nvprmsaa4", GpuGMTask, expectations, nvpr, gpuAPI, 4);
122 START("nvprmsaa16", GpuGMTask, expectations, nvpr, gpuAPI, 16);
123 START("gpunull", GpuGMTask, expectations, null, gpuAPI, 0);
124 START("gpudebug", GpuGMTask, expectations, debug, gpuAPI, 0);
125 START("angle", GpuGMTask, expectations, angle, gpuAPI, 0);
126 START("mesa", GpuGMTask, expectations, mesa, gpuAPI, 0);
mtklein30bf3e22014-06-03 13:57:14 -0700127 START("pdf", PDFTask, RASTERIZE_PDF_PROC);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000128 }
129 }
130#undef START
131}
132
133static void kick_off_benches(const SkTDArray<BenchRegistry::Factory>& benches,
134 const SkTArray<SkString>& configs,
kkinnunen80549fc2014-06-30 06:36:31 -0700135 GrGLStandard gpuAPI,
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000136 DM::Reporter* reporter,
137 DM::TaskRunner* tasks) {
138#define START(name, type, ...) \
139 if (lowercase(configs[j]).equals(name)) { \
140 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, benches[i], ## __VA_ARGS__))); \
141 }
142 for (int i = 0; i < benches.count(); i++) {
143 for (int j = 0; j < configs.count(); j++) {
144 START("nonrendering", NonRenderingBenchTask);
145 START("565", CpuBenchTask, kRGB_565_SkColorType);
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000146 START("8888", CpuBenchTask, kN32_SkColorType);
kkinnunen80549fc2014-06-30 06:36:31 -0700147 START("gpu", GpuBenchTask, native, gpuAPI, 0);
148 START("msaa4", GpuBenchTask, native, gpuAPI, 4);
149 START("msaa16", GpuBenchTask, native, gpuAPI, 16);
150 START("nvprmsaa4", GpuBenchTask, nvpr, gpuAPI, 4);
151 START("nvprmsaa16", GpuBenchTask, nvpr, gpuAPI, 16);
152 START("gpunull", GpuBenchTask, null, gpuAPI, 0);
153 START("gpudebug", GpuBenchTask, debug, gpuAPI, 0);
154 START("angle", GpuBenchTask, angle, gpuAPI, 0);
155 START("mesa", GpuBenchTask, mesa, gpuAPI, 0);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000156 }
157 }
158#undef START
159}
160
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000161static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
162 DM::Reporter* reporter,
163 DM::TaskRunner* tasks) {
164 for (int i = 0; i < tests.count(); i++) {
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000165 SkAutoTDelete<Test> test(tests[i](NULL));
166 if (test->isGPUTest()) {
167 tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i])));
168 } else {
169 tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i])));
170 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000171 }
172}
173
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000174static void kick_off_skps(DM::Reporter* reporter, DM::TaskRunner* tasks) {
175 if (FLAGS_skps.isEmpty()) {
176 return;
177 }
178
179 SkOSFile::Iter it(FLAGS_skps[0], ".skp");
180 SkString filename;
181 while (it.next(&filename)) {
182 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
183 continue;
184 }
185
186 const SkString path = SkOSPath::SkPathJoin(FLAGS_skps[0], filename.c_str());
187
188 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path.c_str()));
189 if (stream.get() == NULL) {
190 SkDebugf("Could not read %s.\n", path.c_str());
191 exit(1);
192 }
193 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get()));
194 if (pic.get() == NULL) {
195 SkDebugf("Could not read %s as an SkPicture.\n", path.c_str());
196 exit(1);
197 }
198
mtkleind3e474e2014-06-27 12:34:44 -0700199 tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic, filename)));
200 tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic, filename,
mtkleine4d3e602014-06-06 09:28:43 -0700201 RASTERIZE_PDF_PROC)));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000202 }
203}
204
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000205static void report_failures(const SkTArray<SkString>& failures) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000206 if (failures.count() == 0) {
207 return;
208 }
209
210 SkDebugf("Failures:\n");
211 for (int i = 0; i < failures.count(); i++) {
212 SkDebugf(" %s\n", failures[i].c_str());
213 }
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000214 SkDebugf("%d failures.\n", failures.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000215}
216
kkinnunen80549fc2014-06-30 06:36:31 -0700217static GrGLStandard get_gl_standard() {
218 if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
219 return kGL_GrGLStandard;
220 }
221 if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
222 return kGLES_GrGLStandard;
223 }
224 return kNone_GrGLStandard;
225}
226
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000227template <typename T, typename Registry>
228static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
229 for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
230 SkAutoTDelete<T> forName(reg->factory()(NULL));
231 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, forName->getName())) {
232 *out->append() = reg->factory();
233 }
234 }
235}
236
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000237int tool_main(int argc, char** argv);
238int tool_main(int argc, char** argv) {
mtklein30e6e2a2014-06-18 11:44:15 -0700239 SetupCrashHandler();
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000240 SkAutoGraphics ag;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000241 SkCommandLineFlags::Parse(argc, argv);
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +0000242
243 if (FLAGS_dryRun) {
244 FLAGS_verbose = true;
245 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000246#if SK_ENABLE_INST_COUNT
247 gPrintInstCount = FLAGS_leaks;
248#endif
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000249
mtklein@google.comd36522d2013-10-16 13:02:15 +0000250 SkTArray<SkString> configs;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000251 for (int i = 0; i < FLAGS_config.count(); i++) {
252 SkStrSplit(FLAGS_config[i], ", ", &configs);
253 }
254
kkinnunen80549fc2014-06-30 06:36:31 -0700255 GrGLStandard gpuAPI = get_gl_standard();
256
mtklein@google.comd36522d2013-10-16 13:02:15 +0000257 SkTDArray<GMRegistry::Factory> gms;
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000258 SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000259 if (FLAGS_gms) {
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000260 append_matching_factories<GM>(GMRegistry::Head(), &gms);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000261
262 if (FLAGS_expectations.count() > 0) {
263 const char* path = FLAGS_expectations[0];
264 if (sk_isdir(path)) {
265 expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
266 } else {
267 expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
268 }
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000269 }
mtklein@google.comd36522d2013-10-16 13:02:15 +0000270 }
271
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000272 SkTDArray<BenchRegistry::Factory> benches;
273 if (FLAGS_benches) {
tfarinaf168b862014-06-19 12:32:29 -0700274 append_matching_factories<Benchmark>(BenchRegistry::Head(), &benches);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000275 }
276
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000277 SkTDArray<TestRegistry::Factory> tests;
278 if (FLAGS_tests) {
279 append_matching_factories<Test>(TestRegistry::Head(), &tests);
280 }
281
282 SkDebugf("(%d GMs, %d benches) x %d configs, %d tests\n",
283 gms.count(), benches.count(), configs.count(), tests.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000284 DM::Reporter reporter;
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000285 DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
kkinnunen80549fc2014-06-30 06:36:31 -0700286 kick_off_gms(gms, configs, gpuAPI, *expectations, &reporter, &tasks);
287 kick_off_benches(benches, configs, gpuAPI, &reporter, &tasks);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000288 kick_off_tests(tests, &reporter, &tasks);
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000289 kick_off_skps(&reporter, &tasks);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000290 tasks.wait();
291
mtklein@google.comd36522d2013-10-16 13:02:15 +0000292 SkDebugf("\n");
mtklein@google.comd36522d2013-10-16 13:02:15 +0000293
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000294 SkTArray<SkString> failures;
295 reporter.getFailures(&failures);
296 report_failures(failures);
297 return failures.count() > 0;
mtklein@google.comd36522d2013-10-16 13:02:15 +0000298}
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000299
300#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
301int main(int argc, char** argv) {
302 return tool_main(argc, argv);
303}
304#endif