blob: 2be37942dd659e3e2145d5c7a229069ac7647a50 [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"
mtklein1d0f1642014-09-08 08:05:18 -07009#include "SkOSFile.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000010#include "SkPicture.h"
rmistry@google.comd6bab022013-12-02 13:50:38 +000011#include "SkString.h"
mtklein406654b2014-09-03 15:34:37 -070012#include "SkTaskGroup.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000013#include "Test.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000014#include "gm.h"
Cary Clark992c7b02014-07-31 08:58:44 -040015#include "sk_tool_utils.h"
16#include "sk_tool_utils_flags.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000017
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +000018#include "DMCpuGMTask.h"
19#include "DMGpuGMTask.h"
commit-bot@chromium.org787227d2014-03-26 21:26:15 +000020#include "DMGpuSupport.h"
mtklein30bf3e22014-06-03 13:57:14 -070021#include "DMPDFTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000022#include "DMReporter.h"
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +000023#include "DMSKPTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000024#include "DMTask.h"
25#include "DMTaskRunner.h"
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000026#include "DMTestTask.h"
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000027#include "DMWriteTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000028
mtklein30bf3e22014-06-03 13:57:14 -070029#ifdef SK_BUILD_POPPLER
30# include "SkPDFRasterizer.h"
31# define RASTERIZE_PDF_PROC SkPopplerRasterizePDF
32#else
33# define RASTERIZE_PDF_PROC NULL
34#endif
35
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000036#include <ctype.h>
mtklein@google.comd36522d2013-10-16 13:02:15 +000037
38using skiagm::GM;
39using skiagm::GMRegistry;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000040using skiatest::Test;
41using skiatest::TestRegistry;
mtklein@google.comd36522d2013-10-16 13:02:15 +000042
kkinnunen80549fc2014-06-30 06:36:31 -070043static const char kGpuAPINameGL[] = "gl";
44static const char kGpuAPINameGLES[] = "gles";
45
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000046DEFINE_string2(expectations, r, "",
47 "If a directory, compare generated images against images under this path. "
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000048 "If a file, compare generated images against JSON expectations at this path."
commit-bot@chromium.org120c9992014-05-16 18:11:51 +000049);
caryclark17f0b6d2014-07-22 10:15:34 -070050
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000051DEFINE_bool(gms, true, "Run GMs?");
52DEFINE_bool(tests, true, "Run tests?");
Cary Clark992c7b02014-07-31 08:58:44 -040053DEFINE_bool(reportUsedChars, false, "Output test font construction data to be pasted into"
54 " create_test_font.cpp.");
mtklein@google.comd36522d2013-10-16 13:02:15 +000055
56__SK_FORCE_IMAGE_DECODER_LINKING;
57
mtklein@google.comd36522d2013-10-16 13:02:15 +000058// "FooBar" -> "foobar". Obviously, ASCII only.
59static SkString lowercase(SkString s) {
60 for (size_t i = 0; i < s.size(); i++) {
61 s[i] = tolower(s[i]);
62 }
63 return s;
64}
65
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000066static const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
mtklein60c77072014-08-14 10:36:55 -070067static const GrContextFactory::GLContextType nvpr = GrContextFactory::kNVPR_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000068static const GrContextFactory::GLContextType null = GrContextFactory::kNull_GLContextType;
69static const GrContextFactory::GLContextType debug = GrContextFactory::kDebug_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000070#if SK_ANGLE
mtklein60c77072014-08-14 10:36:55 -070071static const GrContextFactory::GLContextType angle = GrContextFactory::kANGLE_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000072#endif
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000073#if SK_MESA
mtklein60c77072014-08-14 10:36:55 -070074static const GrContextFactory::GLContextType mesa = GrContextFactory::kMESA_GLContextType;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000075#endif
76
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000077static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
78 const SkTArray<SkString>& configs,
kkinnunen80549fc2014-06-30 06:36:31 -070079 GrGLStandard gpuAPI,
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +000080 const DM::Expectations& expectations,
81 DM::Reporter* reporter,
82 DM::TaskRunner* tasks) {
mtkleine4d3e602014-06-06 09:28:43 -070083#define START(name, type, ...) \
84 if (lowercase(configs[j]).equals(name)) { \
85 tasks->add(SkNEW_ARGS(DM::type, (name, reporter, tasks, gms[i], ## __VA_ARGS__))); \
mtklein@google.comd36522d2013-10-16 13:02:15 +000086 }
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +000087 for (int i = 0; i < gms.count(); i++) {
mtklein@google.comd36522d2013-10-16 13:02:15 +000088 for (int j = 0; j < configs.count(); j++) {
kkinnunen80549fc2014-06-30 06:36:31 -070089
mtkleine4d3e602014-06-06 09:28:43 -070090 START("565", CpuGMTask, expectations, kRGB_565_SkColorType);
91 START("8888", CpuGMTask, expectations, kN32_SkColorType);
kkinnunen80549fc2014-06-30 06:36:31 -070092 START("gpu", GpuGMTask, expectations, native, gpuAPI, 0);
93 START("msaa4", GpuGMTask, expectations, native, gpuAPI, 4);
94 START("msaa16", GpuGMTask, expectations, native, gpuAPI, 16);
95 START("nvprmsaa4", GpuGMTask, expectations, nvpr, gpuAPI, 4);
96 START("nvprmsaa16", GpuGMTask, expectations, nvpr, gpuAPI, 16);
97 START("gpunull", GpuGMTask, expectations, null, gpuAPI, 0);
98 START("gpudebug", GpuGMTask, expectations, debug, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -070099#if SK_ANGLE
kkinnunen80549fc2014-06-30 06:36:31 -0700100 START("angle", GpuGMTask, expectations, angle, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -0700101#endif
102#if SK_MESA
kkinnunen80549fc2014-06-30 06:36:31 -0700103 START("mesa", GpuGMTask, expectations, mesa, gpuAPI, 0);
mtklein60c77072014-08-14 10:36:55 -0700104#endif
mtklein30bf3e22014-06-03 13:57:14 -0700105 START("pdf", PDFTask, RASTERIZE_PDF_PROC);
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000106 }
107 }
108#undef START
109}
110
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000111static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
112 DM::Reporter* reporter,
113 DM::TaskRunner* tasks) {
114 for (int i = 0; i < tests.count(); i++) {
commit-bot@chromium.orgef57b7e2014-02-28 20:31:31 +0000115 SkAutoTDelete<Test> test(tests[i](NULL));
116 if (test->isGPUTest()) {
117 tasks->add(SkNEW_ARGS(DM::GpuTestTask, (reporter, tasks, tests[i])));
118 } else {
119 tasks->add(SkNEW_ARGS(DM::CpuTestTask, (reporter, tasks, tests[i])));
120 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000121 }
122}
123
halcanarya98683b2014-07-28 07:21:24 -0700124static void find_skps(SkTArray<SkString>* skps) {
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000125 if (FLAGS_skps.isEmpty()) {
126 return;
127 }
128
129 SkOSFile::Iter it(FLAGS_skps[0], ".skp");
130 SkString filename;
131 while (it.next(&filename)) {
halcanarya98683b2014-07-28 07:21:24 -0700132 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, filename.c_str())) {
tfarinaa8e2e152014-07-28 19:26:58 -0700133 skps->push_back(SkOSPath::Join(FLAGS_skps[0], filename.c_str()));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000134 }
halcanarya98683b2014-07-28 07:21:24 -0700135 }
136}
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000137
halcanarya98683b2014-07-28 07:21:24 -0700138static void kick_off_skps(const SkTArray<SkString>& skps,
139 DM::Reporter* reporter, DM::TaskRunner* tasks) {
140 for (int i = 0; i < skps.count(); ++i) {
141 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(skps[i].c_str()));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000142 if (stream.get() == NULL) {
halcanarya98683b2014-07-28 07:21:24 -0700143 SkDebugf("Could not read %s.\n", skps[i].c_str());
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000144 exit(1);
145 }
mtklein72ebb9f2014-08-07 14:27:03 -0700146 SkAutoTUnref<SkPicture> pic(
147 SkPicture::CreateFromStream(stream.get(), &sk_tools::LazyDecodeBitmap));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000148 if (pic.get() == NULL) {
halcanarya98683b2014-07-28 07:21:24 -0700149 SkDebugf("Could not read %s as an SkPicture.\n", skps[i].c_str());
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000150 exit(1);
151 }
152
tfarinaa8e2e152014-07-28 19:26:58 -0700153 SkString filename = SkOSPath::Basename(skps[i].c_str());
mtkleind3e474e2014-06-27 12:34:44 -0700154 tasks->add(SkNEW_ARGS(DM::SKPTask, (reporter, tasks, pic, filename)));
155 tasks->add(SkNEW_ARGS(DM::PDFTask, (reporter, tasks, pic, filename,
mtkleine4d3e602014-06-06 09:28:43 -0700156 RASTERIZE_PDF_PROC)));
commit-bot@chromium.org90b5a2a2014-05-14 17:55:32 +0000157 }
158}
159
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000160static void report_failures(const SkTArray<SkString>& failures) {
mtklein@google.comd36522d2013-10-16 13:02:15 +0000161 if (failures.count() == 0) {
162 return;
163 }
164
165 SkDebugf("Failures:\n");
166 for (int i = 0; i < failures.count(); i++) {
167 SkDebugf(" %s\n", failures[i].c_str());
168 }
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000169 SkDebugf("%d failures.\n", failures.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000170}
171
kkinnunen80549fc2014-06-30 06:36:31 -0700172static GrGLStandard get_gl_standard() {
173 if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
174 return kGL_GrGLStandard;
175 }
176 if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
177 return kGLES_GrGLStandard;
178 }
179 return kNone_GrGLStandard;
180}
181
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000182template <typename T, typename Registry>
183static void append_matching_factories(Registry* head, SkTDArray<typename Registry::Factory>* out) {
184 for (const Registry* reg = head; reg != NULL; reg = reg->next()) {
185 SkAutoTDelete<T> forName(reg->factory()(NULL));
186 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, forName->getName())) {
187 *out->append() = reg->factory();
188 }
189 }
190}
191
caryclark17f0b6d2014-07-22 10:15:34 -0700192int dm_main();
193int dm_main() {
mtklein30e6e2a2014-06-18 11:44:15 -0700194 SetupCrashHandler();
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000195 SkAutoGraphics ag;
mtklein406654b2014-09-03 15:34:37 -0700196 SkTaskGroup::Enabler enabled(FLAGS_threads);
commit-bot@chromium.orga65e2fd2014-05-30 17:23:31 +0000197
198 if (FLAGS_dryRun) {
199 FLAGS_verbose = true;
200 }
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000201#if SK_ENABLE_INST_COUNT
202 gPrintInstCount = FLAGS_leaks;
203#endif
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000204
mtklein@google.comd36522d2013-10-16 13:02:15 +0000205 SkTArray<SkString> configs;
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000206 for (int i = 0; i < FLAGS_config.count(); i++) {
207 SkStrSplit(FLAGS_config[i], ", ", &configs);
208 }
209
kkinnunen80549fc2014-06-30 06:36:31 -0700210 GrGLStandard gpuAPI = get_gl_standard();
211
mtklein1d0f1642014-09-08 08:05:18 -0700212 SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::Expectations));
213 if (FLAGS_expectations.count() > 0) {
214 expectations.reset(DM::WriteTask::Expectations::Create(FLAGS_expectations[0]));
215 if (!expectations.get()) {
216 return 1;
217 }
218 }
219
mtklein@google.comd36522d2013-10-16 13:02:15 +0000220 SkTDArray<GMRegistry::Factory> gms;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000221 if (FLAGS_gms) {
commit-bot@chromium.org38aeb0f2014-02-26 23:01:57 +0000222 append_matching_factories<GM>(GMRegistry::Head(), &gms);
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;
mtklein406654b2014-09-03 15:34:37 -0700236
237 DM::TaskRunner tasks;
commit-bot@chromium.org0dc5bd12014-02-26 16:31:22 +0000238 kick_off_tests(tests, &reporter, &tasks);
mtklein36ea6c82014-08-05 07:19:46 -0700239 kick_off_gms(gms, configs, gpuAPI, *expectations, &reporter, &tasks);
halcanarya98683b2014-07-28 07:21:24 -0700240 kick_off_skps(skps, &reporter, &tasks);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000241 tasks.wait();
242
mtklein1d0f1642014-09-08 08:05:18 -0700243 DM::WriteTask::DumpJson();
244
mtklein@google.comd36522d2013-10-16 13:02:15 +0000245 SkDebugf("\n");
Cary Clark992c7b02014-07-31 08:58:44 -0400246#ifdef SK_DEBUG
247 if (FLAGS_portableFonts && FLAGS_reportUsedChars) {
248 sk_tool_utils::report_used_chars();
249 }
250#endif
mtklein92007582014-08-01 07:46:52 -0700251
commit-bot@chromium.org39e8d932014-05-29 20:14:48 +0000252 SkTArray<SkString> failures;
253 reporter.getFailures(&failures);
254 report_failures(failures);
255 return failures.count() > 0;
mtklein@google.comd36522d2013-10-16 13:02:15 +0000256}
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000257
258#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
259int main(int argc, char** argv) {
caryclark17f0b6d2014-07-22 10:15:34 -0700260 SkCommandLineFlags::Parse(argc, argv);
261 return dm_main();
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000262}
263#endif