Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "CrashHandler.h" | 8 #include "CrashHandler.h" |
| 9 #include "DMJsonWriter.h" | 9 #include "DMJsonWriter.h" |
| 10 #include "DMSrcSink.h" | 10 #include "DMSrcSink.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 "this list, no image is written for that result."); | 66 "this list, no image is written for that result."); |
| 67 | 67 |
| 68 DEFINE_int32(shards, 1, "We're splitting source data into this many shards."); | 68 DEFINE_int32(shards, 1, "We're splitting source data into this many shards."); |
| 69 DEFINE_int32(shard, 0, "Which shard do I run?"); | 69 DEFINE_int32(shard, 0, "Which shard do I run?"); |
| 70 DEFINE_bool(simpleCodec, false, "Only decode images to native scale"); | 70 DEFINE_bool(simpleCodec, false, "Only decode images to native scale"); |
| 71 | 71 |
| 72 using namespace DM; | 72 using namespace DM; |
| 73 | 73 |
| 74 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 74 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
| 75 | 75 |
| 76 static const SkMSec kStartMs = SkTime::GetMSecs(); | |
| 77 | |
| 78 static FILE* gVLog; | |
| 79 | |
| 80 template <typename... Args> | |
| 81 static void vlog(const char* fmt, Args&&... args) { | |
| 82 if (gVLog) { | |
| 83 fprintf(gVLog, "%s\t", HumanizeMs(SkTime::GetMSecs() - kStartMs).c_str() ); | |
| 84 fprintf(gVLog, fmt, args...); | |
| 85 fflush(gVLog); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 template <typename... Args> | |
| 90 static void info(const char* fmt, Args&&... args) { | |
| 91 vlog(fmt, args...); | |
| 92 FLAGS_quiet || printf(fmt, args...); | |
|
hal.canary
2016/03/08 15:09:34
nit: We never use this syntax.
if (!FLAGS_quie
mtklein
2016/03/08 15:15:55
Done.
| |
| 93 } | |
| 94 static void info(const char* fmt) { | |
| 95 FLAGS_quiet || printf("%s", fmt); // Clang warns printf(fmt) is insecure. | |
| 96 } | |
| 97 | |
| 76 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); | 98 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); |
| 77 static SkTArray<SkString> gFailures; | 99 static SkTArray<SkString> gFailures; |
| 78 | 100 |
| 79 static void fail(const SkString& err) { | 101 static void fail(const SkString& err) { |
| 80 SkAutoMutexAcquire lock(gFailuresMutex); | 102 SkAutoMutexAcquire lock(gFailuresMutex); |
| 81 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); | 103 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); |
| 82 gFailures.push_back(err); | 104 gFailures.push_back(err); |
| 83 } | 105 } |
| 84 | 106 |
| 85 | 107 |
| 86 // We use a spinlock to make locking this in a signal handler _somewhat_ safe. | 108 // We use a spinlock to make locking this in a signal handler _somewhat_ safe. |
| 87 static SkSpinlock gMutex; | 109 static SkSpinlock gMutex; |
| 88 static int32_t gPending; | 110 static int32_t gPending; |
| 89 static SkTArray<SkString> gRunning; | 111 static SkTArray<SkString> gRunning; |
| 90 | 112 |
| 91 static void done(const char* config, const char* src, const char* srcOptions, co nst char* name) { | 113 static void done(const char* config, const char* src, const char* srcOptions, co nst char* name) { |
| 92 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); | 114 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); |
| 115 vlog("done %s\n", id.c_str()); | |
| 93 int pending; | 116 int pending; |
| 94 { | 117 { |
| 95 SkAutoTAcquire<SkSpinlock> lock(gMutex); | 118 SkAutoTAcquire<SkSpinlock> lock(gMutex); |
| 96 for (int i = 0; i < gRunning.count(); i++) { | 119 for (int i = 0; i < gRunning.count(); i++) { |
| 97 if (gRunning[i] == id) { | 120 if (gRunning[i] == id) { |
| 98 gRunning.removeShuffle(i); | 121 gRunning.removeShuffle(i); |
| 99 break; | 122 break; |
| 100 } | 123 } |
| 101 } | 124 } |
| 102 pending = --gPending; | 125 pending = --gPending; |
| 103 } | 126 } |
| 104 // We write our dm.json file every once in a while in case we crash. | 127 // We write our dm.json file every once in a while in case we crash. |
| 105 // Notice this also handles the final dm.json when pending == 0. | 128 // Notice this also handles the final dm.json when pending == 0. |
| 106 if (pending % 500 == 0) { | 129 if (pending % 500 == 0) { |
| 107 JsonWriter::DumpJson(); | 130 JsonWriter::DumpJson(); |
| 108 } | 131 } |
| 109 } | 132 } |
| 110 | 133 |
| 111 static void start(const char* config, const char* src, const char* srcOptions, c onst char* name) { | 134 static void start(const char* config, const char* src, const char* srcOptions, c onst char* name) { |
| 112 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); | 135 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name); |
| 136 vlog("start %s\n", id.c_str()); | |
| 113 SkAutoTAcquire<SkSpinlock> lock(gMutex); | 137 SkAutoTAcquire<SkSpinlock> lock(gMutex); |
| 114 gRunning.push_back(id); | 138 gRunning.push_back(id); |
| 115 } | 139 } |
| 116 | 140 |
| 117 static void print_status() { | 141 static void print_status() { |
| 118 static SkMSec start_ms = SkTime::GetMSecs(); | |
| 119 | |
| 120 int curr = sk_tools::getCurrResidentSetSizeMB(), | 142 int curr = sk_tools::getCurrResidentSetSizeMB(), |
| 121 peak = sk_tools::getMaxResidentSetSizeMB(); | 143 peak = sk_tools::getMaxResidentSetSizeMB(); |
| 122 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - start_ms); | 144 SkString elapsed = HumanizeMs(SkTime::GetMSecs() - kStartMs); |
| 123 | 145 |
| 124 SkAutoTAcquire<SkSpinlock> lock(gMutex); | 146 SkAutoTAcquire<SkSpinlock> lock(gMutex); |
| 125 SkDebugf("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n", | 147 info("\n%s elapsed, %d active, %d queued, %dMB RAM, %dMB peak\n", |
| 126 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), cur r, peak); | 148 elapsed.c_str(), gRunning.count(), gPending - gRunning.count(), curr, p eak); |
| 127 for (auto& task : gRunning) { | 149 for (auto& task : gRunning) { |
| 128 SkDebugf("\t%s\n", task.c_str()); | 150 info("\t%s\n", task.c_str()); |
| 129 } | 151 } |
| 130 } | 152 } |
| 131 | 153 |
| 132 // Yo dawg, I heard you like signals so I caught a signal in your | 154 // Yo dawg, I heard you like signals so I caught a signal in your |
| 133 // signal handler so you can handle signals while you handle signals. | 155 // signal handler so you can handle signals while you handle signals. |
| 134 // Let's not get into that situation. Only print if we're the first ones to get a crash signal. | 156 // Let's not get into that situation. Only print if we're the first ones to get a crash signal. |
| 135 static std::atomic<bool> in_signal_handler{false}; | 157 static std::atomic<bool> in_signal_handler{false}; |
| 136 | 158 |
| 137 #if defined(SK_BUILD_FOR_WIN32) | 159 #if defined(SK_BUILD_FOR_WIN32) |
| 138 static LONG WINAPI handler(EXCEPTION_POINTERS* e) { | 160 static LONG WINAPI handler(EXCEPTION_POINTERS* e) { |
| 139 static const struct { | 161 static const struct { |
| 140 const char* name; | 162 const char* name; |
| 141 DWORD code; | 163 DWORD code; |
| 142 } kExceptions[] = { | 164 } kExceptions[] = { |
| 143 #define _(E) {#E, E} | 165 #define _(E) {#E, E} |
| 144 _(EXCEPTION_ACCESS_VIOLATION), | 166 _(EXCEPTION_ACCESS_VIOLATION), |
| 145 _(EXCEPTION_BREAKPOINT), | 167 _(EXCEPTION_BREAKPOINT), |
| 146 _(EXCEPTION_INT_DIVIDE_BY_ZERO), | 168 _(EXCEPTION_INT_DIVIDE_BY_ZERO), |
| 147 _(EXCEPTION_STACK_OVERFLOW), | 169 _(EXCEPTION_STACK_OVERFLOW), |
| 148 // TODO: more? | 170 // TODO: more? |
| 149 #undef _ | 171 #undef _ |
| 150 }; | 172 }; |
| 151 | 173 |
| 152 if (!in_signal_handler.exchange(true)) { | 174 if (!in_signal_handler.exchange(true)) { |
| 153 const DWORD code = e->ExceptionRecord->ExceptionCode; | 175 const DWORD code = e->ExceptionRecord->ExceptionCode; |
| 154 SkDebugf("\nCaught exception %u", code); | 176 info("\nCaught exception %u", code); |
| 155 for (const auto& exception : kExceptions) { | 177 for (const auto& exception : kExceptions) { |
| 156 if (exception.code == code) { | 178 if (exception.code == code) { |
| 157 SkDebugf(" %s", exception.name); | 179 info(" %s", exception.name); |
| 158 } | 180 } |
| 159 } | 181 } |
| 160 SkDebugf("\n"); | 182 info("\n"); |
| 161 print_status(); | 183 print_status(); |
| 162 } | 184 } |
| 163 // Execute default exception handler... hopefully, exit. | 185 // Execute default exception handler... hopefully, exit. |
| 164 return EXCEPTION_EXECUTE_HANDLER; | 186 return EXCEPTION_EXECUTE_HANDLER; |
| 165 } | 187 } |
| 166 static void setup_crash_handler() { SetUnhandledExceptionFilter(handler); } | 188 static void setup_crash_handler() { SetUnhandledExceptionFilter(handler); } |
| 167 | 189 |
| 168 #elif !defined(SK_BUILD_FOR_ANDROID) | 190 #elif !defined(SK_BUILD_FOR_ANDROID) |
| 169 #include <execinfo.h> | 191 #include <execinfo.h> |
| 170 #include <signal.h> | 192 #include <signal.h> |
| 171 #include <stdlib.h> | 193 #include <stdlib.h> |
| 172 | 194 |
| 173 static void setup_crash_handler() { | 195 static void setup_crash_handler() { |
| 174 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; | 196 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; |
| 175 for (int sig : kSignals) { | 197 for (int sig : kSignals) { |
| 176 signal(sig, [](int sig) { | 198 signal(sig, [](int sig) { |
| 177 if (!in_signal_handler.exchange(true)) { | 199 if (!in_signal_handler.exchange(true)) { |
| 178 SkAutoTAcquire<SkSpinlock> lock(gMutex); | 200 SkAutoTAcquire<SkSpinlock> lock(gMutex); |
| 179 SkDebugf("\nCaught signal %d [%s], was running:\n", sig, str signal(sig)); | 201 info("\nCaught signal %d [%s], was running:\n", sig, strsign al(sig)); |
| 180 for (auto& task : gRunning) { | 202 for (auto& task : gRunning) { |
| 181 SkDebugf("\t%s\n", task.c_str()); | 203 info("\t%s\n", task.c_str()); |
| 182 } | 204 } |
| 183 | 205 |
| 184 void* stack[64]; | 206 void* stack[64]; |
| 185 int count = backtrace(stack, SK_ARRAY_COUNT(stack)); | 207 int count = backtrace(stack, SK_ARRAY_COUNT(stack)); |
| 186 char** symbols = backtrace_symbols(stack, count); | 208 char** symbols = backtrace_symbols(stack, count); |
| 187 SkDebugf("\nStack trace:\n"); | 209 info("\nStack trace:\n"); |
| 188 for (int i = 0; i < count; i++) { | 210 for (int i = 0; i < count; i++) { |
| 189 SkDebugf(" %s\n", symbols[i]); | 211 info(" %s\n", symbols[i]); |
| 190 } | 212 } |
| 191 } | 213 } |
| 192 _Exit(sig); | 214 _Exit(sig); |
| 193 }); | 215 }); |
| 194 } | 216 } |
| 195 } | 217 } |
| 196 | 218 |
| 197 #else // Android | 219 #else // Android |
| 198 static void setup_crash_handler() {} | 220 static void setup_crash_handler() {} |
| 199 #endif | 221 #endif |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 } | 257 } |
| 236 | 258 |
| 237 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 259 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
| 238 | 260 |
| 239 static SkTHashSet<SkString> gUninterestingHashes; | 261 static SkTHashSet<SkString> gUninterestingHashes; |
| 240 | 262 |
| 241 static void gather_uninteresting_hashes() { | 263 static void gather_uninteresting_hashes() { |
| 242 if (!FLAGS_uninterestingHashesFile.isEmpty()) { | 264 if (!FLAGS_uninterestingHashesFile.isEmpty()) { |
| 243 SkAutoTUnref<SkData> data(SkData::NewFromFileName(FLAGS_uninterestingHas hesFile[0])); | 265 SkAutoTUnref<SkData> data(SkData::NewFromFileName(FLAGS_uninterestingHas hesFile[0])); |
| 244 if (!data) { | 266 if (!data) { |
| 245 SkDebugf("WARNING: unable to read uninteresting hashes from %s\n", | 267 info("WARNING: unable to read uninteresting hashes from %s\n", |
| 246 FLAGS_uninterestingHashesFile[0]); | 268 FLAGS_uninterestingHashesFile[0]); |
| 247 return; | 269 return; |
| 248 } | 270 } |
| 249 SkTArray<SkString> hashes; | 271 SkTArray<SkString> hashes; |
| 250 SkStrSplit((const char*)data->data(), "\n", &hashes); | 272 SkStrSplit((const char*)data->data(), "\n", &hashes); |
| 251 for (const SkString& hash : hashes) { | 273 for (const SkString& hash : hashes) { |
| 252 gUninterestingHashes.add(hash); | 274 gUninterestingHashes.add(hash); |
| 253 } | 275 } |
| 254 SkDebugf("FYI: loaded %d distinct uninteresting hashes from %d lines\n", | 276 info("FYI: loaded %d distinct uninteresting hashes from %d lines\n", |
| 255 gUninterestingHashes.count(), hashes.count()); | 277 gUninterestingHashes.count(), hashes.count()); |
| 256 } | 278 } |
| 257 } | 279 } |
| 258 | 280 |
| 259 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 281 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
| 260 | 282 |
| 261 struct TaggedSrc : public SkAutoTDelete<Src> { | 283 struct TaggedSrc : public SkAutoTDelete<Src> { |
| 262 SkString tag; | 284 SkString tag; |
| 263 SkString options; | 285 SkString options; |
| 264 }; | 286 }; |
| 265 | 287 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 folder.appendf("_%.3f", 1.0f / (float) sampleSize); | 418 folder.appendf("_%.3f", 1.0f / (float) sampleSize); |
| 397 } | 419 } |
| 398 | 420 |
| 399 AndroidCodecSrc* src = new AndroidCodecSrc(path, mode, dstColorType, dstAlph aType, sampleSize); | 421 AndroidCodecSrc* src = new AndroidCodecSrc(path, mode, dstColorType, dstAlph aType, sampleSize); |
| 400 push_src("image", folder, src); | 422 push_src("image", folder, src); |
| 401 } | 423 } |
| 402 | 424 |
| 403 static void push_codec_srcs(Path path) { | 425 static void push_codec_srcs(Path path) { |
| 404 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); | 426 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); |
| 405 if (!encoded) { | 427 if (!encoded) { |
| 406 SkDebugf("Couldn't read %s.", path.c_str()); | 428 info("Couldn't read %s.", path.c_str()); |
| 407 return; | 429 return; |
| 408 } | 430 } |
| 409 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 431 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 410 if (nullptr == codec.get()) { | 432 if (nullptr == codec.get()) { |
| 411 SkDebugf("Couldn't create codec for %s.", path.c_str()); | 433 info("Couldn't create codec for %s.", path.c_str()); |
| 412 return; | 434 return; |
| 413 } | 435 } |
| 414 | 436 |
| 415 // Native Scales | 437 // Native Scales |
| 416 // SkJpegCodec natively supports scaling to: 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 | 438 // SkJpegCodec natively supports scaling to: 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 |
| 417 const float nativeScales[] = { 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.750f, 0.875f, 1.0f }; | 439 const float nativeScales[] = { 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.750f, 0.875f, 1.0f }; |
| 418 | 440 |
| 419 SkTArray<CodecSrc::Mode> nativeModes; | 441 SkTArray<CodecSrc::Mode> nativeModes; |
| 420 nativeModes.push_back(CodecSrc::kCodec_Mode); | 442 nativeModes.push_back(CodecSrc::kCodec_Mode); |
| 421 nativeModes.push_back(CodecSrc::kCodecZeroInit_Mode); | 443 nativeModes.push_back(CodecSrc::kCodecZeroInit_Mode); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 } | 719 } |
| 698 SkISize size() const override { return SkISize::Make(16, 16); } | 720 SkISize size() const override { return SkISize::Make(16, 16); } |
| 699 Name name() const override { return "justOneRect"; } | 721 Name name() const override { return "justOneRect"; } |
| 700 } justOneRect; | 722 } justOneRect; |
| 701 | 723 |
| 702 SkBitmap bitmap; | 724 SkBitmap bitmap; |
| 703 SkDynamicMemoryWStream stream; | 725 SkDynamicMemoryWStream stream; |
| 704 SkString log; | 726 SkString log; |
| 705 Error err = sink->draw(justOneRect, &bitmap, &stream, &log); | 727 Error err = sink->draw(justOneRect, &bitmap, &stream, &log); |
| 706 if (err.isFatal()) { | 728 if (err.isFatal()) { |
| 707 SkDebugf("Could not run %s: %s\n", config.getTag().c_str(), err.c_str()) ; | 729 info("Could not run %s: %s\n", config.getTag().c_str(), err.c_str()); |
| 708 exit(1); | 730 exit(1); |
| 709 } | 731 } |
| 710 | 732 |
| 711 TaggedSink& ts = gSinks.push_back(); | 733 TaggedSink& ts = gSinks.push_back(); |
| 712 ts.reset(sink.detach()); | 734 ts.reset(sink.detach()); |
| 713 ts.tag = config.getTag(); | 735 ts.tag = config.getTag(); |
| 714 } | 736 } |
| 715 | 737 |
| 716 static bool gpu_supported() { | 738 static bool gpu_supported() { |
| 717 #if SK_SUPPORT_GPU | 739 #if SK_SUPPORT_GPU |
| 718 return FLAGS_gpu; | 740 return FLAGS_gpu; |
| 719 #else | 741 #else |
| 720 return false; | 742 return false; |
| 721 #endif | 743 #endif |
| 722 } | 744 } |
| 723 | 745 |
| 724 static Sink* create_sink(const SkCommandLineConfig* config) { | 746 static Sink* create_sink(const SkCommandLineConfig* config) { |
| 725 #if SK_SUPPORT_GPU | 747 #if SK_SUPPORT_GPU |
| 726 if (gpu_supported()) { | 748 if (gpu_supported()) { |
| 727 if (const SkCommandLineConfigGpu* gpuConfig = config->asConfigGpu()) { | 749 if (const SkCommandLineConfigGpu* gpuConfig = config->asConfigGpu()) { |
| 728 GrContextFactory::GLContextType contextType = gpuConfig->getContextT ype(); | 750 GrContextFactory::GLContextType contextType = gpuConfig->getContextT ype(); |
| 729 GrContextFactory::GLContextOptions contextOptions = | 751 GrContextFactory::GLContextOptions contextOptions = |
| 730 GrContextFactory::kNone_GLContextOptions; | 752 GrContextFactory::kNone_GLContextOptions; |
| 731 if (gpuConfig->getUseNVPR()) { | 753 if (gpuConfig->getUseNVPR()) { |
| 732 contextOptions = static_cast<GrContextFactory::GLContextOptions> ( | 754 contextOptions = static_cast<GrContextFactory::GLContextOptions> ( |
| 733 contextOptions | GrContextFactory::kEnableNVPR_GLContextOpti ons); | 755 contextOptions | GrContextFactory::kEnableNVPR_GLContextOpti ons); |
| 734 } | 756 } |
| 735 GrContextFactory testFactory; | 757 GrContextFactory testFactory; |
| 736 if (!testFactory.get(contextType, contextOptions)) { | 758 if (!testFactory.get(contextType, contextOptions)) { |
| 737 SkDebugf("WARNING: can not create GPU context for config '%s'. " | 759 info("WARNING: can not create GPU context for config '%s'. " |
| 738 "GM tests will be skipped.\n", gpuConfig->getTag().c_st r()); | 760 "GM tests will be skipped.\n", gpuConfig->getTag().c_str()) ; |
| 739 return nullptr; | 761 return nullptr; |
| 740 } | 762 } |
| 741 return new GPUSink(contextType, contextOptions, gpuConfig->getSample s(), | 763 return new GPUSink(contextType, contextOptions, gpuConfig->getSample s(), |
| 742 gpuConfig->getUseDIText(), FLAGS_gpu_threading); | 764 gpuConfig->getUseDIText(), FLAGS_gpu_threading); |
| 743 } | 765 } |
| 744 } | 766 } |
| 745 #endif | 767 #endif |
| 746 | 768 |
| 747 #define SINK(t, sink, ...) if (config->getBackend().equals(t)) { return new sink (__VA_ARGS__); } | 769 #define SINK(t, sink, ...) if (config->getBackend().equals(t)) { return new sink (__VA_ARGS__); } |
| 748 | 770 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 798 return nullptr; | 820 return nullptr; |
| 799 } | 821 } |
| 800 | 822 |
| 801 static void gather_sinks() { | 823 static void gather_sinks() { |
| 802 SkCommandLineConfigArray configs; | 824 SkCommandLineConfigArray configs; |
| 803 ParseConfigs(FLAGS_config, &configs); | 825 ParseConfigs(FLAGS_config, &configs); |
| 804 for (int i = 0; i < configs.count(); i++) { | 826 for (int i = 0; i < configs.count(); i++) { |
| 805 const SkCommandLineConfig& config = *configs[i]; | 827 const SkCommandLineConfig& config = *configs[i]; |
| 806 Sink* sink = create_sink(&config); | 828 Sink* sink = create_sink(&config); |
| 807 if (sink == nullptr) { | 829 if (sink == nullptr) { |
| 808 SkDebugf("Skipping config %s: Don't understand '%s'.\n", config.getT ag().c_str(), | 830 info("Skipping config %s: Don't understand '%s'.\n", config.getTag() .c_str(), |
| 809 config.getTag().c_str()); | 831 config.getTag().c_str()); |
| 810 continue; | 832 continue; |
| 811 } | 833 } |
| 812 | 834 |
| 813 const SkTArray<SkString>& parts = config.getViaParts(); | 835 const SkTArray<SkString>& parts = config.getViaParts(); |
| 814 for (int j = parts.count(); j-- > 0;) { | 836 for (int j = parts.count(); j-- > 0;) { |
| 815 const SkString& part = parts[j]; | 837 const SkString& part = parts[j]; |
| 816 Sink* next = create_via(part, sink); | 838 Sink* next = create_via(part, sink); |
| 817 if (next == nullptr) { | 839 if (next == nullptr) { |
| 818 SkDebugf("Skipping config %s: Don't understand '%s'.\n", config. getTag().c_str(), | 840 info("Skipping config %s: Don't understand '%s'.\n", config.getT ag().c_str(), |
| 819 part.c_str()); | 841 part.c_str()); |
| 820 delete sink; | 842 delete sink; |
| 821 sink = nullptr; | 843 sink = nullptr; |
| 822 break; | 844 break; |
| 823 } | 845 } |
| 824 sink = next; | 846 sink = next; |
| 825 } | 847 } |
| 826 if (sink) { | 848 if (sink) { |
| 827 push_sink(config, sink); | 849 push_sink(config, sink); |
| 828 } | 850 } |
| 829 } | 851 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 SkString name = task.src->name(); | 1003 SkString name = task.src->name(); |
| 982 | 1004 |
| 983 SkString log; | 1005 SkString log; |
| 984 if (!FLAGS_dryRun) { | 1006 if (!FLAGS_dryRun) { |
| 985 SkBitmap bitmap; | 1007 SkBitmap bitmap; |
| 986 SkDynamicMemoryWStream stream; | 1008 SkDynamicMemoryWStream stream; |
| 987 start(task.sink.tag.c_str(), task.src.tag.c_str(), | 1009 start(task.sink.tag.c_str(), task.src.tag.c_str(), |
| 988 task.src.options.c_str(), name.c_str()); | 1010 task.src.options.c_str(), name.c_str()); |
| 989 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log); | 1011 Error err = task.sink->draw(*task.src, &bitmap, &stream, &log); |
| 990 if (!log.isEmpty()) { | 1012 if (!log.isEmpty()) { |
| 991 SkDebugf("%s %s %s %s:\n%s\n", task.sink.tag.c_str() | 1013 info("%s %s %s %s:\n%s\n", task.sink.tag.c_str() |
| 992 , task.src.tag.c_str() | 1014 , task.src.tag.c_str() |
| 993 , task.src.options.c_str() | 1015 , task.src.options.c_str() |
| 994 , name.c_str() | 1016 , name.c_str() |
| 995 , log.c_str()); | 1017 , log.c_str()); |
| 996 } | 1018 } |
| 997 if (!err.isEmpty()) { | 1019 if (!err.isEmpty()) { |
| 998 if (err.isFatal()) { | 1020 if (err.isFatal()) { |
| 999 fail(SkStringPrintf("%s %s %s %s: %s", | 1021 fail(SkStringPrintf("%s %s %s %s: %s", |
| 1000 task.sink.tag.c_str(), | 1022 task.sink.tag.c_str(), |
| 1001 task.src.tag.c_str(), | 1023 task.src.tag.c_str(), |
| 1002 task.src.options.c_str(), | 1024 task.src.options.c_str(), |
| 1003 name.c_str(), | 1025 name.c_str(), |
| 1004 err.c_str())); | 1026 err.c_str())); |
| 1005 } else { | 1027 } else { |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1221 } | 1243 } |
| 1222 | 1244 |
| 1223 #undef PORTABLE_FONT_PREFIX | 1245 #undef PORTABLE_FONT_PREFIX |
| 1224 | 1246 |
| 1225 extern SkTypeface* (*gCreateTypefaceDelegate)(const char [], SkTypeface::Style ) ; | 1247 extern SkTypeface* (*gCreateTypefaceDelegate)(const char [], SkTypeface::Style ) ; |
| 1226 | 1248 |
| 1227 int dm_main(); | 1249 int dm_main(); |
| 1228 int dm_main() { | 1250 int dm_main() { |
| 1229 setup_crash_handler(); | 1251 setup_crash_handler(); |
| 1230 | 1252 |
| 1253 if (FLAGS_verbose && !FLAGS_writePath.isEmpty()) { | |
| 1254 sk_mkdir(FLAGS_writePath[0]); | |
| 1255 gVLog = freopen(SkOSPath::Join(FLAGS_writePath[0], "verbose.log").c_str( ), "w", stderr); | |
| 1256 } | |
| 1257 | |
| 1231 JsonWriter::DumpJson(); // It's handy for the bots to assume this is ~never missing. | 1258 JsonWriter::DumpJson(); // It's handy for the bots to assume this is ~never missing. |
| 1232 SkAutoGraphics ag; | 1259 SkAutoGraphics ag; |
| 1233 SkTaskGroup::Enabler enabled(FLAGS_threads); | 1260 SkTaskGroup::Enabler enabled(FLAGS_threads); |
| 1234 gCreateTypefaceDelegate = &create_from_name; | 1261 gCreateTypefaceDelegate = &create_from_name; |
| 1235 | 1262 |
| 1236 { | 1263 { |
| 1237 SkString testResourcePath = GetResourcePath("color_wheel.png"); | 1264 SkString testResourcePath = GetResourcePath("color_wheel.png"); |
| 1238 SkFILEStream testResource(testResourcePath.c_str()); | 1265 SkFILEStream testResource(testResourcePath.c_str()); |
| 1239 if (!testResource.isValid()) { | 1266 if (!testResource.isValid()) { |
| 1240 SkDebugf("Some resources are missing. Do you need to set --resource Path?\n"); | 1267 info("Some resources are missing. Do you need to set --resourcePath ?\n"); |
| 1241 } | 1268 } |
| 1242 } | 1269 } |
| 1243 gather_gold(); | 1270 gather_gold(); |
| 1244 gather_uninteresting_hashes(); | 1271 gather_uninteresting_hashes(); |
| 1245 | 1272 |
| 1246 if (!gather_srcs()) { | 1273 if (!gather_srcs()) { |
| 1247 return 1; | 1274 return 1; |
| 1248 } | 1275 } |
| 1249 gather_sinks(); | 1276 gather_sinks(); |
| 1250 gather_tests(); | 1277 gather_tests(); |
| 1251 | 1278 |
| 1252 gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerial Tests.count(); | 1279 gPending = gSrcs.count() * gSinks.count() + gParallelTests.count() + gSerial Tests.count(); |
| 1253 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks", | 1280 info("%d srcs * %d sinks + %d tests == %d tasks", |
| 1254 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTest s.count(), gPending); | 1281 gSrcs.count(), gSinks.count(), gParallelTests.count() + gSerialTests.co unt(), gPending); |
| 1255 SkAutoTDelete<SkThread> statusThread(start_status_thread()); | 1282 SkAutoTDelete<SkThread> statusThread(start_status_thread()); |
| 1256 | 1283 |
| 1257 // Kick off as much parallel work as we can, making note of any serial work we'll need to do. | 1284 // Kick off as much parallel work as we can, making note of any serial work we'll need to do. |
| 1258 SkTaskGroup parallel; | 1285 SkTaskGroup parallel; |
| 1259 SkTArray<Task> serial; | 1286 SkTArray<Task> serial; |
| 1260 | 1287 |
| 1261 for (auto& sink : gSinks) | 1288 for (auto& sink : gSinks) |
| 1262 for (auto& src : gSrcs) { | 1289 for (auto& src : gSrcs) { |
| 1263 if (src->veto(sink->flags()) || | 1290 if (src->veto(sink->flags()) || |
| 1264 is_blacklisted(sink.tag.c_str(), src.tag.c_str(), | 1291 is_blacklisted(sink.tag.c_str(), src.tag.c_str(), |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1289 | 1316 |
| 1290 // We'd better have run everything. | 1317 // We'd better have run everything. |
| 1291 SkASSERT(gPending == 0); | 1318 SkASSERT(gPending == 0); |
| 1292 // Make sure we've flushed all our results to disk. | 1319 // Make sure we've flushed all our results to disk. |
| 1293 JsonWriter::DumpJson(); | 1320 JsonWriter::DumpJson(); |
| 1294 | 1321 |
| 1295 // At this point we're back in single-threaded land. | 1322 // At this point we're back in single-threaded land. |
| 1296 sk_tool_utils::release_portable_typefaces(); | 1323 sk_tool_utils::release_portable_typefaces(); |
| 1297 | 1324 |
| 1298 if (gFailures.count() > 0) { | 1325 if (gFailures.count() > 0) { |
| 1299 SkDebugf("Failures:\n"); | 1326 info("Failures:\n"); |
| 1300 for (int i = 0; i < gFailures.count(); i++) { | 1327 for (int i = 0; i < gFailures.count(); i++) { |
| 1301 SkDebugf("\t%s\n", gFailures[i].c_str()); | 1328 info("\t%s\n", gFailures[i].c_str()); |
| 1302 } | 1329 } |
| 1303 SkDebugf("%d failures\n", gFailures.count()); | 1330 info("%d failures\n", gFailures.count()); |
| 1304 return 1; | 1331 return 1; |
| 1305 } | 1332 } |
| 1306 | 1333 |
| 1307 #ifdef SK_PDF_IMAGE_STATS | 1334 #ifdef SK_PDF_IMAGE_STATS |
| 1308 SkPDFImageDumpStats(); | 1335 SkPDFImageDumpStats(); |
| 1309 #endif // SK_PDF_IMAGE_STATS | 1336 #endif // SK_PDF_IMAGE_STATS |
| 1310 | 1337 |
| 1311 print_status(); | 1338 print_status(); |
| 1312 SkDebugf("Finished!\n"); | 1339 info("Finished!\n"); |
| 1313 return 0; | 1340 return 0; |
| 1314 } | 1341 } |
| 1315 | 1342 |
| 1316 // TODO: currently many GPU tests are declared outside SK_SUPPORT_GPU guards. | 1343 // TODO: currently many GPU tests are declared outside SK_SUPPORT_GPU guards. |
| 1317 // Thus we export the empty RunWithGPUTestContexts when SK_SUPPORT_GPU=0. | 1344 // Thus we export the empty RunWithGPUTestContexts when SK_SUPPORT_GPU=0. |
| 1318 namespace skiatest { | 1345 namespace skiatest { |
| 1319 namespace { | 1346 namespace { |
| 1320 typedef void(*TestWithGrContext)(skiatest::Reporter*, GrContext*); | 1347 typedef void(*TestWithGrContext)(skiatest::Reporter*, GrContext*); |
| 1321 typedef void(*TestWithGrContextAndGLContext)(skiatest::Reporter*, GrContext*, Sk GLContext*); | 1348 typedef void(*TestWithGrContextAndGLContext)(skiatest::Reporter*, GrContext*, Sk GLContext*); |
| 1322 #if SK_SUPPORT_GPU | 1349 #if SK_SUPPORT_GPU |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1400 Reporter* reporter, | 1427 Reporter* reporter, |
| 1401 GrContextFactory* fac tory); | 1428 GrContextFactory* fac tory); |
| 1402 } // namespace skiatest | 1429 } // namespace skiatest |
| 1403 | 1430 |
| 1404 #if !defined(SK_BUILD_FOR_IOS) | 1431 #if !defined(SK_BUILD_FOR_IOS) |
| 1405 int main(int argc, char** argv) { | 1432 int main(int argc, char** argv) { |
| 1406 SkCommandLineFlags::Parse(argc, argv); | 1433 SkCommandLineFlags::Parse(argc, argv); |
| 1407 return dm_main(); | 1434 return dm_main(); |
| 1408 } | 1435 } |
| 1409 #endif | 1436 #endif |
| OLD | NEW |