blob: ee53e9d99fe20ec6b4cdf1d94abf91537c5a3c17 [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
4#include "GrContext.h"
5#include "GrContextFactory.h"
6#include "SkCommandLineFlags.h"
7#include "SkForceLinking.h"
8#include "SkGraphics.h"
rmistry@google.comd6bab022013-12-02 13:50:38 +00009#include "SkString.h"
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000010#include "Test.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000011#include "gm.h"
12
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000013#include "DMCpuTask.h"
14#include "DMGpuTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000015#include "DMReporter.h"
16#include "DMTask.h"
17#include "DMTaskRunner.h"
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000018#include "DMTestTask.h"
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000019#include "DMWriteTask.h"
mtklein@google.comd36522d2013-10-16 13:02:15 +000020
21#include <string.h>
22
23using skiagm::GM;
24using skiagm::GMRegistry;
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000025using skiatest::Test;
26using skiatest::TestRegistry;
mtklein@google.comd36522d2013-10-16 13:02:15 +000027
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000028DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
commit-bot@chromium.org99589af2013-12-10 14:53:16 +000029DEFINE_string2(expectations, r, "",
30 "If a directory, compare generated images against images under this path. "
31 "If a file, compare generated images against JSON expectations at this path.");
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000032DEFINE_string2(resources, i, "resources", "Path to resources directory.");
mtklein@google.comd36522d2013-10-16 13:02:15 +000033DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
34 "Multiple matches may be separated by spaces.\n"
35 "~ causes a matching GM to always be skipped\n"
36 "^ requires the start of the GM to match\n"
37 "$ requires the end of the GM to match\n"
38 "^ and $ requires an exact match\n"
39 "If a GM does not match any list entry,\n"
40 "it is skipped unless some list entry starts with ~");
commit-bot@chromium.org88e1ec82014-01-09 19:14:57 +000041DEFINE_string(config, "565 8888 gpu",
mtklein@google.comd36522d2013-10-16 13:02:15 +000042 "Options: 565 8888 gpu msaa4 msaa16 gpunull gpudebug angle mesa"); // TODO(mtklein): pdf
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000043DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
44
45DEFINE_bool(gms, true, "Run GMs?");
46DEFINE_bool(tests, true, "Run tests?");
mtklein@google.comd36522d2013-10-16 13:02:15 +000047
48__SK_FORCE_IMAGE_DECODER_LINKING;
49
mtklein@google.comd36522d2013-10-16 13:02:15 +000050// "FooBar" -> "foobar". Obviously, ASCII only.
51static SkString lowercase(SkString s) {
52 for (size_t i = 0; i < s.size(); i++) {
53 s[i] = tolower(s[i]);
54 }
55 return s;
56}
57
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +000058static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
59 const SkTArray<SkString>& configs,
60 const DM::Expectations& expectations,
61 DM::Reporter* reporter,
62 DM::TaskRunner* tasks) {
commit-bot@chromium.org15a14052014-02-16 00:59:25 +000063 const SkColorType _565 = kRGB_565_SkColorType;
64 const SkColorType _8888 = kPMColor_SkColorType;
mtklein@google.comd36522d2013-10-16 13:02:15 +000065 const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
66 const GrContextFactory::GLContextType null = GrContextFactory::kNull_GLContextType;
67 const GrContextFactory::GLContextType debug = GrContextFactory::kDebug_GLContextType;
68 const GrContextFactory::GLContextType angle =
69 #if SK_ANGLE
70 GrContextFactory::kANGLE_GLContextType;
71 #else
72 native;
73 #endif
74 const GrContextFactory::GLContextType mesa =
75 #if SK_MESA
76 GLContextFactory::kMESA_GLContextType;
77 #else
78 native;
79 #endif
80
81 for (int i = 0; i < gms.count(); i++) {
mtklein@google.comd36522d2013-10-16 13:02:15 +000082#define START(name, type, ...) \
83 if (lowercase(configs[j]).equals(name)) { \
84 tasks->add(SkNEW_ARGS(DM::type, \
85 (name, reporter, tasks, expectations, gms[i], __VA_ARGS__))); \
86 }
87 for (int j = 0; j < configs.count(); j++) {
88 START("565", CpuTask, _565);
89 START("8888", CpuTask, _8888);
90 START("gpu", GpuTask, _8888, native, 0);
91 START("msaa4", GpuTask, _8888, native, 4);
92 START("msaa16", GpuTask, _8888, native, 16);
93 START("gpunull", GpuTask, _8888, null, 0);
94 START("gpudebug", GpuTask, _8888, debug, 0);
95 START("angle", GpuTask, _8888, angle, 0);
96 START("mesa", GpuTask, _8888, mesa, 0);
97 //START("pdf", PdfTask, _8888);
98 }
99 }
100#undef START
101}
102
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000103static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
104 DM::Reporter* reporter,
105 DM::TaskRunner* tasks) {
106 for (int i = 0; i < tests.count(); i++) {
107 tasks->add(SkNEW_ARGS(DM::TestTask, (reporter, tasks, tests[i])));
108 }
109}
110
mtklein@google.comd36522d2013-10-16 13:02:15 +0000111static void report_failures(const DM::Reporter& reporter) {
112 SkTArray<SkString> failures;
113 reporter.getFailures(&failures);
114
115 if (failures.count() == 0) {
116 return;
117 }
118
119 SkDebugf("Failures:\n");
120 for (int i = 0; i < failures.count(); i++) {
121 SkDebugf(" %s\n", failures[i].c_str());
122 }
123}
124
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000125int tool_main(int argc, char** argv);
126int tool_main(int argc, char** argv) {
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000127#if SK_ENABLE_INST_COUNT
128 gPrintInstCount = FLAGS_leaks;
129#endif
mtklein@google.comd36522d2013-10-16 13:02:15 +0000130 SkGraphics::Init();
mtklein@google.comd36522d2013-10-16 13:02:15 +0000131 SkCommandLineFlags::Parse(argc, argv);
132 GM::SetResourcePath(FLAGS_resources[0]);
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000133 Test::SetResourcePath(FLAGS_resources[0]);
134
mtklein@google.comd36522d2013-10-16 13:02:15 +0000135 SkTArray<SkString> configs;
mtklein@google.comd36522d2013-10-16 13:02:15 +0000136 SkTDArray<GMRegistry::Factory> gms;
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000137 SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000138
139 if (FLAGS_gms) {
140 for (int i = 0; i < FLAGS_config.count(); i++) {
141 SkStrSplit(FLAGS_config[i], ", ", &configs);
142 }
143
144 for (const GMRegistry* reg = GMRegistry::Head(); reg != NULL; reg = reg->next()) {
145 SkAutoTDelete<GM> gmForName(reg->factory()(NULL));
146 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gmForName->shortName())) {
147 *gms.append() = reg->factory();
148 }
149 }
150
151 if (FLAGS_expectations.count() > 0) {
152 const char* path = FLAGS_expectations[0];
153 if (sk_isdir(path)) {
154 expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
155 } else {
156 expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
157 }
commit-bot@chromium.org99589af2013-12-10 14:53:16 +0000158 }
mtklein@google.comd36522d2013-10-16 13:02:15 +0000159 }
160
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000161 SkTDArray<TestRegistry::Factory> tests;
162 if (FLAGS_tests) {
163 for (const TestRegistry* reg = TestRegistry::Head(); reg != NULL; reg = reg->next()) {
164 SkAutoTDelete<Test> testForName(reg->factory()(NULL));
165 if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, testForName->getName())) {
166 *tests.append() = reg->factory();
167 }
168 }
169 }
170
171 SkDebugf("%d GMs x %d configs, %d tests\n", gms.count(), configs.count(), tests.count());
mtklein@google.comd36522d2013-10-16 13:02:15 +0000172 DM::Reporter reporter;
commit-bot@chromium.org6bd250a2014-02-25 19:32:15 +0000173 DM::TaskRunner tasks(FLAGS_threads);
174 kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
175 kick_off_tests(tests, &reporter, &tasks);
mtklein@google.comd36522d2013-10-16 13:02:15 +0000176 tasks.wait();
177
mtklein@google.comd36522d2013-10-16 13:02:15 +0000178 SkDebugf("\n");
179 report_failures(reporter);
180
181 SkGraphics::Term();
182
183 return reporter.failed() > 0;
184}
commit-bot@chromium.org846872f2013-10-16 18:21:03 +0000185
186#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
187int main(int argc, char** argv) {
188 return tool_main(argc, argv);
189}
190#endif