OLD | NEW |
1 #include "CrashHandler.h" | 1 #include "CrashHandler.h" |
2 #include "DMJsonWriter.h" | 2 #include "DMJsonWriter.h" |
3 #include "DMSrcSink.h" | 3 #include "DMSrcSink.h" |
4 #include "OverwriteLine.h" | 4 #include "OverwriteLine.h" |
5 #include "ProcStats.h" | 5 #include "ProcStats.h" |
6 #include "SkBBHFactory.h" | 6 #include "SkBBHFactory.h" |
7 #include "SkCommonFlags.h" | 7 #include "SkCommonFlags.h" |
8 #include "SkForceLinking.h" | 8 #include "SkForceLinking.h" |
9 #include "SkGraphics.h" | 9 #include "SkGraphics.h" |
10 #include "SkMD5.h" | 10 #include "SkMD5.h" |
11 #include "SkOSFile.h" | 11 #include "SkOSFile.h" |
12 #include "SkTaskGroup.h" | 12 #include "SkTaskGroup.h" |
13 #include "Test.h" | 13 #include "Test.h" |
14 #include "Timer.h" | 14 #include "Timer.h" |
15 | 15 |
16 DEFINE_bool(tests, true, "Run tests?"); | 16 DEFINE_bool(tests, true, "Run tests?"); |
17 DEFINE_string(images, "resources", "Images to decode."); | 17 DEFINE_string(images, "resources", "Images to decode."); |
18 //DEFINE_string(src, "gm skp image subset", "Source types to test."); | 18 //DEFINE_string(src, "gm skp image subset", "Source types to test."); |
19 DEFINE_string(src, "gm skp", "Source types to test. TEMPORARILY DISABLED"); | 19 DEFINE_string(src, "gm skp", "Source types to test. TEMPORARILY DISABLED"); |
20 DEFINE_bool(nameByHash, false, | 20 DEFINE_bool(nameByHash, false, |
21 "If true, write to FLAGS_writePath[0]/<hash>.png instead of " | 21 "If true, write to FLAGS_writePath[0]/<hash>.png instead of " |
22 "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); | 22 "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); |
23 DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests."); | 23 DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests."); |
24 DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1", | 24 DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1", |
25 "Matrix to apply when using 'matrix' in config."); | 25 "Matrix to apply when using 'matrix' in config."); |
| 26 DEFINE_bool(gpu_threading, false, "Allow GPU work to run on multiple threads?"); |
26 | 27 |
27 __SK_FORCE_IMAGE_DECODER_LINKING; | 28 __SK_FORCE_IMAGE_DECODER_LINKING; |
28 using namespace DM; | 29 using namespace DM; |
29 | 30 |
30 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 31 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
31 | 32 |
32 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); | 33 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); |
33 static SkTArray<SkString> gFailures; | 34 static SkTArray<SkString> gFailures; |
34 | 35 |
35 static void fail(ImplicitString err) { | 36 static void fail(ImplicitString err) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 #if SK_SUPPORT_GPU | 132 #if SK_SUPPORT_GPU |
132 return FLAGS_gpu; | 133 return FLAGS_gpu; |
133 #else | 134 #else |
134 return false; | 135 return false; |
135 #endif | 136 #endif |
136 } | 137 } |
137 | 138 |
138 static Sink* create_sink(const char* tag) { | 139 static Sink* create_sink(const char* tag) { |
139 #define SINK(t, sink, ...) if (0 == strcmp(t, tag)) { return new sink(__VA_ARGS_
_); } | 140 #define SINK(t, sink, ...) if (0 == strcmp(t, tag)) { return new sink(__VA_ARGS_
_); } |
140 if (gpu_supported()) { | 141 if (gpu_supported()) { |
| 142 typedef GrContextFactory Gr; |
141 const GrGLStandard api = get_gpu_api(); | 143 const GrGLStandard api = get_gpu_api(); |
142 SINK("gpunull", GPUSink, GrContextFactory::kNull_GLContextType, api
, 0, false); | 144 SINK("gpunull", GPUSink, Gr::kNull_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
143 SINK("gpudebug", GPUSink, GrContextFactory::kDebug_GLContextType, api
, 0, false); | 145 SINK("gpudebug", GPUSink, Gr::kDebug_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
144 SINK("gpu", GPUSink, GrContextFactory::kNative_GLContextType, api
, 0, false); | 146 SINK("gpu", GPUSink, Gr::kNative_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
145 SINK("gpudft", GPUSink, GrContextFactory::kNative_GLContextType, api
, 0, true); | 147 SINK("gpudft", GPUSink, Gr::kNative_GLContextType, api, 0, true, F
LAGS_gpu_threading); |
146 SINK("msaa4", GPUSink, GrContextFactory::kNative_GLContextType, api
, 4, false); | 148 SINK("msaa4", GPUSink, Gr::kNative_GLContextType, api, 4, false, F
LAGS_gpu_threading); |
147 SINK("msaa16", GPUSink, GrContextFactory::kNative_GLContextType, api
, 16, false); | 149 SINK("msaa16", GPUSink, Gr::kNative_GLContextType, api, 16, false, F
LAGS_gpu_threading); |
148 SINK("nvprmsaa4", GPUSink, GrContextFactory::kNVPR_GLContextType, api
, 4, false); | 150 SINK("nvprmsaa4", GPUSink, Gr::kNVPR_GLContextType, api, 4, false, F
LAGS_gpu_threading); |
149 SINK("nvprmsaa16", GPUSink, GrContextFactory::kNVPR_GLContextType, api
, 16, false); | 151 SINK("nvprmsaa16", GPUSink, Gr::kNVPR_GLContextType, api, 16, false, F
LAGS_gpu_threading); |
150 #if SK_ANGLE | 152 #if SK_ANGLE |
151 SINK("angle", GPUSink, GrContextFactory::kANGLE_GLContextType, api
, 0, false); | 153 SINK("angle", GPUSink, Gr::kANGLE_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
152 #endif | 154 #endif |
153 #if SK_MESA | 155 #if SK_MESA |
154 SINK("mesa", GPUSink, GrContextFactory::kMESA_GLContextType, api
, 0, false); | 156 SINK("mesa", GPUSink, Gr::kMESA_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
155 #endif | 157 #endif |
156 } | 158 } |
157 | 159 |
158 if (FLAGS_cpu) { | 160 if (FLAGS_cpu) { |
159 SINK("565", RasterSink, kRGB_565_SkColorType); | 161 SINK("565", RasterSink, kRGB_565_SkColorType); |
160 SINK("8888", RasterSink, kN32_SkColorType); | 162 SINK("8888", RasterSink, kN32_SkColorType); |
161 // TODO(mtklein): reenable once skiagold can handle .pdf uploads. | 163 // TODO(mtklein): reenable once skiagold can handle .pdf uploads. |
162 //SINK("pdf", PDFSink); | 164 //SINK("pdf", PDFSink); |
163 } | 165 } |
164 #undef SINK | 166 #undef SINK |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE { | 340 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE { |
339 SkString s; | 341 SkString s; |
340 failure.getFailureString(&s); | 342 failure.getFailureString(&s); |
341 fail(s); | 343 fail(s); |
342 JsonWriter::AddTestFailure(failure); | 344 JsonWriter::AddTestFailure(failure); |
343 } | 345 } |
344 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_pathOpsExtended; } | 346 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_pathOpsExtended; } |
345 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } | 347 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
346 } gTestReporter; | 348 } gTestReporter; |
347 | 349 |
348 static SkTArray<SkAutoTDelete<skiatest::Test>, kMemcpyOK> gTests; | 350 static SkTArray<SkAutoTDelete<skiatest::Test>, kMemcpyOK> gCPUTests, gGPUTests; |
349 | 351 |
350 static void gather_tests() { | 352 static void gather_tests() { |
351 if (!FLAGS_tests) { | 353 if (!FLAGS_tests) { |
352 return; | 354 return; |
353 } | 355 } |
354 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { | 356 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { |
355 SkAutoTDelete<skiatest::Test> test(r->factory()(NULL)); | 357 SkAutoTDelete<skiatest::Test> test(r->factory()(NULL)); |
356 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { | 358 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { |
357 continue; | 359 continue; |
358 } | 360 } |
359 if (test->isGPUTest() /*&& !gpu_supported()*/) { // TEMPORARILY DISABLE
D | 361 |
360 continue; | 362 test->setReporter(&gTestReporter); |
| 363 if (test->isGPUTest() && gpu_supported()) { |
| 364 gGPUTests.push_back().reset(test.detach()); |
| 365 } else if (!test->isGPUTest() && FLAGS_cpu) { |
| 366 gCPUTests.push_back().reset(test.detach()); |
361 } | 367 } |
362 if (!test->isGPUTest() && !FLAGS_cpu) { | |
363 continue; | |
364 } | |
365 test->setReporter(&gTestReporter); | |
366 gTests.push_back().reset(test.detach()); | |
367 } | 368 } |
368 } | 369 } |
369 | 370 |
370 static void run_test(SkAutoTDelete<skiatest::Test>* t) { | 371 static void run_test(SkAutoTDelete<skiatest::Test>* t) { |
371 WallTimer timer; | 372 WallTimer timer; |
372 timer.start(); | 373 timer.start(); |
373 skiatest::Test* test = t->get(); | 374 skiatest::Test* test = t->get(); |
374 if (!FLAGS_dryRun) { | 375 if (!FLAGS_dryRun) { |
375 GrContextFactory grFactory; | 376 test->setGrContextFactory(GetThreadLocalGrContextFactory()); |
376 test->setGrContextFactory(&grFactory); | |
377 test->run(); | 377 test->run(); |
378 if (!test->passed()) { | 378 if (!test->passed()) { |
379 fail(SkStringPrintf("test %s failed", test->getName())); | 379 fail(SkStringPrintf("test %s failed", test->getName())); |
380 } | 380 } |
381 } | 381 } |
382 timer.end(); | 382 timer.end(); |
383 done(timer.fWall, "unit", "test", test->getName()); | 383 done(timer.fWall, "unit", "test", test->getName()); |
384 } | 384 } |
385 | 385 |
386 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 386 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
387 | 387 |
388 int dm_main(); | 388 int dm_main(); |
389 int dm_main() { | 389 int dm_main() { |
390 SetupCrashHandler(); | 390 SetupCrashHandler(); |
391 SkAutoGraphics ag; | 391 SkAutoGraphics ag; |
392 SkTaskGroup::Enabler enabled(FLAGS_threads); | 392 SkTaskGroup::Enabler enabled(FLAGS_threads); |
393 | 393 |
394 gather_srcs(); | 394 gather_srcs(); |
395 gather_sinks(); | 395 gather_sinks(); |
396 gather_tests(); | 396 gather_tests(); |
397 | 397 |
398 gPending = gSrcs.count() * gSinks.count() + gTests.count(); | 398 gPending = gSrcs.count() * gSinks.count() + gCPUTests.count() + gGPUTests.co
unt(); |
399 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", | 399 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", |
400 gSrcs.count(), gSinks.count(), gTests.count(), gPending); | 400 gSrcs.count(), gSinks.count(), gCPUTests.count() + gGPUTests.count(
), gPending); |
401 | 401 |
402 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, | 402 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, |
403 // but Sinks that identify as part of a particular enclave run serially on a
single thread. | 403 // but Sinks that identify as part of a particular enclave run serially on a
single thread. |
404 // Tests run on any thread, with a separate GrContextFactory for each GPU te
st. | 404 // CPU tests run on any thread. GPU tests depend on --gpu_threading. |
405 SkTArray<Task> enclaves[kNumEnclaves]; | 405 SkTArray<Task> enclaves[kNumEnclaves]; |
406 for (int j = 0; j < gSinks.count(); j++) { | 406 for (int j = 0; j < gSinks.count(); j++) { |
407 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; | 407 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; |
408 for (int i = 0; i < gSrcs.count(); i++) { | 408 for (int i = 0; i < gSrcs.count(); i++) { |
409 tasks.push_back(Task(gSrcs[i], gSinks[j])); | 409 tasks.push_back(Task(gSrcs[i], gSinks[j])); |
410 } | 410 } |
411 } | 411 } |
412 | 412 |
413 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); | 413 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); |
414 SkTaskGroup tg; | 414 SkTaskGroup tg; |
415 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); | 415 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); |
416 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); | 416 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); |
417 tg.batch( run_test, gTests.begin(), gTests.count()); | 417 tg.batch( run_test, gCPUTests.begin(), gCPUTests.count()); |
| 418 if (FLAGS_gpu_threading) { |
| 419 tg.batch(run_test, gGPUTests.begin(), gGPUTests.count()); |
| 420 } else { |
| 421 for (int i = 0; i < gGPUTests.count(); i++) { |
| 422 run_test(&gGPUTests[i]); |
| 423 } |
| 424 } |
418 tg.wait(); | 425 tg.wait(); |
419 | 426 |
420 // At this point we're back in single-threaded land. | 427 // At this point we're back in single-threaded land. |
421 | 428 |
422 if (!FLAGS_verbose) { | 429 if (!FLAGS_verbose) { |
423 SkDebugf("\n"); | 430 SkDebugf("\n"); |
424 } | 431 } |
425 | 432 |
426 JsonWriter::DumpJson(); | 433 JsonWriter::DumpJson(); |
427 | 434 |
(...skipping 11 matching lines...) Expand all Loading... |
439 } | 446 } |
440 return 0; | 447 return 0; |
441 } | 448 } |
442 | 449 |
443 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 450 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
444 int main(int argc, char** argv) { | 451 int main(int argc, char** argv) { |
445 SkCommandLineFlags::Parse(argc, argv); | 452 SkCommandLineFlags::Parse(argc, argv); |
446 return dm_main(); | 453 return dm_main(); |
447 } | 454 } |
448 #endif | 455 #endif |
OLD | NEW |