blob: 09f0ce8f268cd0b15e0cd16a3012fd4e19148741 [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 "CrashHandler.h"
mtklein72ebb9f2014-08-07 14:27:03 -07005#include "LazyDecodeBitmap.h"
caryclark17f0b6d2014-07-22 10:15:34 -07006#include "SkCommonFlags.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +00007#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"
Cary Clark992c7b02014-07-31 08:58:44 -040013#include "sk_tool_utils.h"
14#include "sk_tool_utils_flags.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000015
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000016#include "DMCpuGMTask.h"
17#include "DMGpuGMTask.h"
commit-bot@chromium.org787227d2014-03-26 21:26:15 +000018#include "DMGpuSupport.h"
mtklein30bf3e22014-06-03 13:57:14 -070019#include "DMPDFTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000020#include "DMReporter.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000021#include "DMSKPTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000022#include "DMTask.h"
23#include "DMTaskRunner.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000024#include "DMTestTask.h"
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000025#include "DMWriteTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000026
mtklein30bf3e22014-06-03 13:57:14 -070027#ifdef SK_BUILD_POPPLER
28# include "SkPDFRasterizer.h"
29# define RASTERIZE_PDF_PROC SkPopplerRasterizePDF
30#else
31# define RASTERIZE_PDF_PROC NULL
32#endif
33
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000034#include <ctype.h>
mtklein@google.comd36522d2013-10-16 13:02:15 +000035
36using skiagm::GM;
37using skiagm::GMRegistry;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000038using skiatest::Test;
39using skiatest::TestRegistry;
mtklein@google.comd36522d2013-10-16 13:02:15 +000040
kkinnunen80549fc2014-06-30 06:36:31 -070041static const char kGpuAPINameGL[] = "gl";
42static const char kGpuAPINameGLES[] = "gles";
43
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000044DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000045DEFINE_string2(expectations, r, "",
46 "If a directory, compare generated images against images under this path. "
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000047 "If a file, compare generated images against JSON expectations at this path."
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000048);
caryclark17f0b6d2014-07-22 10:15:34 -070049
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000050DEFINE_bool(gms, true, "Run GMs?");
51DEFINE_bool(tests, true, "Run tests?");
Cary Clark992c7b02014-07-31 08:58:44 -040052DEFINE_bool(reportUsedChars, false, "Output test font construction data to be pasted into"
53 " create_test_font.cpp.");
mtklein@google.comd36522d2013-10-16 13:02:15 +000054
55__SK_FORCE_IMAGE_DECODER_LINKING;
56
mtklein@google.comd36522d2013-10-16 13:02:15 +000057// "FooBar" -> "foobar". Obviously, ASCII only.
58static SkString lowercase(SkString s) {
59 for (size_t i = 0; i < s.size(); i++) {
60 s[i] = tolower(s[i]);
61 }
62 return s;
63}
64
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000065static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
mtklein60c77072014-08-14 10:36:55 -070066static const GrContextFactory::GLContextType nvpr = GrContextFactory::kNVPR_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000067static const GrContextFactory::GLContextType null = GrContextFactory::kNull_GLContextType;
68static const GrContextFactory::GLContextType debug = GrContextFactory::kDebug_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000069#if SK_ANGLE
mtklein60c77072014-08-14 10:36:55 -070070static const GrContextFactory::GLContextType angle = GrContextFactory::kANGLE_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000071#endif
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000072#if SK_MESA
mtklein60c77072014-08-14 10:36:55 -070073static const GrContextFactory::GLContextType mesa = GrContextFactory::kMESA_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000074#endif
75
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000076static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
77 const SkTArray<SkString>& configs,
kkinnunen80549fc2014-06-30 06:36:31 -070078 GrGLStandard gpuAPI,
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000079 const DM::Expectations& expectations,
80 DM::Reporter* reporter,
81 DM::TaskRunner* tasks) {
mtkleine4d3e602014-06-06 09:28:43 -070082#define START(name, type, ...) \
83 if (lowercase(configs[j]).equals(name)) { \
84 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, gms[i], ## __VA_ARGS__))); \
mtklein@google.comd36522d2013-10-16 13:02:15 +000085 }
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000086 for (int i = 0; i < gms.count(); i++) {
mtklein@google.comd36522d2013-10-16 13:02:15 +000087 for (int j = 0; j < configs.count(); j++) {
kkinnunen80549fc2014-06-30 06:36:31 -070088
mtkleine4d3e602014-06-06 09:28:43 -070089 START("565", CpuGMTask, expectations, kRGB_565_SkColorType);
90 START("8888", CpuGMTask, expectations, kN32_SkColorType);
kkinnunen80549fc2014-06-30 06:36:31 -070091 START("gpu", GpuGMTask, expectations, native, gpuAPI, 0);
92 START("msaa4", GpuGMTask, expectations, native, gpuAPI, 4);
93 START("msaa16", GpuGMTask, expectations, native, gpuAPI, 16);
94 START("nvprmsaa4", GpuGMTask, expectations, nvpr, gpuAPI, 4);
95 START("nvprmsaa16", GpuGMTask, expectations, nvpr, gpuAPI, 16);
96 START("gpunull", GpuGMTask, expectations, null, gpuAPI, 0);
97 START("gpudebug", GpuGMTask, expectations, debug, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -070098#if SK_ANGLE
kkinnunen80549fc2014-06-30 06:36:31 -070099 START("angle", GpuGMTask, expectations, angle, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -0700100#endif
101#if SK_MESA
kkinnunen80549fc2014-06-30 06:36:31 -0700102 START("mesa", GpuGMTask, expectations, mesa, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -0700103#endif
mtklein30bf3e22014-06-03 13:57:14 -0700104 START("pdf", PDFTask, RASTERIZE_PDF_PROC);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000105 }
106 }
107#undef START
108}
109
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000110static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
111 DM::Reporter* reporter,
112 DM::TaskRunner* tasks) {
113 for (int i = 0; i < tests.count(); i++) {
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000114 SkAutoTDelete<Test> test(tests[i](NULL));
115 if (test->isGPUTest()) {
116 tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i])));
117 } else {
118 tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i])));
119 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000120 }
121}
122
halcanarya98683b2014-07-28 07:21:24 -0700123static void find_skps(SkTArray<SkString>* skps) {
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000124 if (FLAGS_skps.isEmpty()) {
125 return;
126 }
127
128 SkOSFile::Iter it(FLAGS_skps[0], ".skp");
129 SkString filename;
130 while (it.next(&filename)) {
halcanarya98683b2014-07-28 07:21:24 -0700131 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
tfarinaa8e2e152014-07-28 19:26:58 -0700132 skps->push_back(SkOSPath::Join(FLAGS_skps[0], filename.c_str()));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000133 }
halcanarya98683b2014-07-28 07:21:24 -0700134 }
135}
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000136
halcanarya98683b2014-07-28 07:21:24 -0700137static void kick_off_skps(const SkTArray<SkString>& skps,
138 DM::Reporter* reporter, DM::TaskRunner* tasks) {
139 for (int i = 0; i < skps.count(); ++i) {
140 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(skps[i].c_str()));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000141 if (stream.get() == NULL) {
halcanarya98683b2014-07-28 07:21:24 -0700142 SkDebugf("Could not read %s.\n", skps[i].c_str());
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000143 exit(1);
144 }
mtklein72ebb9f2014-08-07 14:27:03 -0700145 SkAutoTUnref<SkPicture> pic(
146 SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000147 if (pic.get() == NULL) {
halcanarya98683b2014-07-28 07:21:24 -0700148 SkDebugf("Could not read %s as an SkPicture.\n", skps[i].c_str());
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000149 exit(1);
150 }
151
tfarinaa8e2e152014-07-28 19:26:58 -0700152 SkString filename = SkOSPath::Basename(skps[i].c_str());
mtkleind3e474e2014-06-27 12:34:44 -0700153 tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic, filename)));
154 tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic, filename,
mtkleine4d3e602014-06-06 09:28:43 -0700155 RASTERIZE_PDF_PROC)));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000156 }
157}
158
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000159static void report_failures(const SkTArray<SkString>& failures) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000160 if (failures.count() == 0) {
161 return;
162 }
163
164 SkDebugf("Failures:\n");
165 for (int i = 0; i < failures.count(); i++) {
166 SkDebugf(" %s\n", failures[i].c_str());
167 }
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000168 SkDebugf("%d failures.\n", failures.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000169}
170
kkinnunen80549fc2014-06-30 06:36:31 -0700171static GrGLStandard get_gl_standard() {
172 if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
173 return kGL_GrGLStandard;
174 }
175 if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
176 return kGLES_GrGLStandard;
177 }
178 return kNone_GrGLStandard;
179}
180
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000181template <typename T, typename Registry>
182static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
183 for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
184 SkAutoTDelete<T> forName(reg->factory()(NULL));
185 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, forName->getName())) {
186 *out->append() = reg->factory();
187 }
188 }
189}
190
caryclark17f0b6d2014-07-22 10:15:34 -0700191int dm_main();
192int dm_main() {
mtklein30e6e2a2014-06-18 11:44:15 -0700193 SetupCrashHandler();
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000194 SkAutoGraphics ag;
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +0000195
196 if (FLAGS_dryRun) {
197 FLAGS_verbose = true;
198 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000199#if SK_ENABLE_INST_COUNT
200 gPrintInstCount = FLAGS_leaks;
201#endif
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000202
mtklein@google.comd36522d2013-10-16 13:02:15 +0000203 SkTArray<SkString> configs;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000204 for (int i = 0; i < FLAGS_config.count(); i++) {
205 SkStrSplit(FLAGS_config[i], ", ", &configs);
206 }
207
kkinnunen80549fc2014-06-30 06:36:31 -0700208 GrGLStandard gpuAPI = get_gl_standard();
209
mtklein@google.comd36522d2013-10-16 13:02:15 +0000210 SkTDArray<GMRegistry::Factory> gms;
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000211 SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000212 if (FLAGS_gms) {
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000213 append_matching_factories<GM>(GMRegistry::Head(), &gms);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000214
215 if (FLAGS_expectations.count() > 0) {
216 const char* path = FLAGS_expectations[0];
217 if (sk_isdir(path)) {
218 expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
219 } else {
220 expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
221 }
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000222 }
mtklein@google.comd36522d2013-10-16 13:02:15 +0000223 }
224
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000225 SkTDArray<TestRegistry::Factory> tests;
226 if (FLAGS_tests) {
227 append_matching_factories<Test>(TestRegistry::Head(), &tests);
228 }
229
halcanarya98683b2014-07-28 07:21:24 -0700230 SkTArray<SkString> skps;
231 find_skps(&skps);
232
233 SkDebugf("%d GMs x %d configs, %d tests, %d pictures\n",
234 gms.count(), configs.count(), tests.count(), skps.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000235 DM::Reporter reporter;
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000236 DM::TaskRunner tasks(FLAGS_threads, FLAGS_gpuThreads);
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000237 kick_off_tests(tests, &reporter, &tasks);
mtklein36ea6c82014-08-05 07:19:46 -0700238 kick_off_gms(gms, configs, gpuAPI, *expectations, &reporter, &tasks);
halcanarya98683b2014-07-28 07:21:24 -0700239 kick_off_skps(skps, &reporter, &tasks);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000240 tasks.wait();
241
mtklein@google.comd36522d2013-10-16 13:02:15 +0000242 SkDebugf("\n");
Cary Clark992c7b02014-07-31 08:58:44 -0400243#ifdef SK_DEBUG
244 if (FLAGS_portableFonts && FLAGS_reportUsedChars) {
245 sk_tool_utils::report_used_chars();
246 }
247#endif
mtklein92007582014-08-01 07:46:52 -0700248
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000249 SkTArray<SkString> failures;
250 reporter.getFailures(&failures);
251 report_failures(failures);
252 return failures.count() > 0;
mtklein@google.comd36522d2013-10-16 13:02:15 +0000253}
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000254
255#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
256int main(int argc, char** argv) {
caryclark17f0b6d2014-07-22 10:15:34 -0700257 SkCommandLineFlags::Parse(argc, argv);
258 return dm_main();
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000259}
260#endif