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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 SkStrSplit((const char*)data->data(), "\n", &hashes); | 168 SkStrSplit((const char*)data->data(), "\n", &hashes); |
| 169 for (const SkString& hash : hashes) { | 169 for (const SkString& hash : hashes) { |
| 170 gUninterestingHashes.add(hash); | 170 gUninterestingHashes.add(hash); |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 175 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
| 176 | 176 |
| 177 struct TaggedSrc : public SkAutoTDelete<Src> { | 177 struct TaggedSrc : public SkAutoTDelete<Src> { |
| 178 const char* tag; | 178 ImplicitString tag; |
| 179 const char* options; | 179 ImplicitString options; |
| 180 }; | 180 }; |
| 181 | 181 |
| 182 struct TaggedSink : public SkAutoTDelete<Sink> { | 182 struct TaggedSink : public SkAutoTDelete<Sink> { |
| 183 const char* tag; | 183 const char* tag; |
| 184 }; | 184 }; |
| 185 | 185 |
| 186 static const bool kMemcpyOK = true; | 186 static const bool kMemcpyOK = true; |
| 187 | 187 |
| 188 static SkTArray<TaggedSrc, kMemcpyOK> gSrcs; | 188 static SkTArray<TaggedSrc, kMemcpyOK> gSrcs; |
| 189 static SkTArray<TaggedSink, kMemcpyOK> gSinks; | 189 static SkTArray<TaggedSink, kMemcpyOK> gSinks; |
| 190 | 190 |
| 191 static bool in_shard() { | 191 static bool in_shard() { |
| 192 static int N = 0; | 192 static int N = 0; |
| 193 return N++ % FLAGS_shards == FLAGS_shard; | 193 return N++ % FLAGS_shards == FLAGS_shard; |
| 194 } | 194 } |
| 195 | 195 |
| 196 static void push_src(const char* tag, const char* options, Src* s) { | 196 static void push_src(ImplicitString tag, ImplicitString options, Src* s) { |
| 197 SkAutoTDelete<Src> src(s); | 197 SkAutoTDelete<Src> src(s); |
| 198 if (in_shard() && | 198 if (in_shard() && |
| 199 FLAGS_src.contains(tag) && | 199 FLAGS_src.contains(tag.c_str()) && |
| 200 !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) { | 200 !SkCommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) { |
| 201 TaggedSrc& s = gSrcs.push_back(); | 201 TaggedSrc& s = gSrcs.push_back(); |
| 202 s.reset(src.detach()); | 202 s.reset(src.detach()); |
| 203 s.tag = tag; | 203 s.tag = tag; |
| 204 s.options = options; | 204 s.options = options; |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp e dstColorType, | |
| 209 float scale) { | |
| 210 SkString folder; | |
| 211 switch (mode) { | |
| 212 case CodecSrc::kCodec_Mode: | |
| 213 folder.append("codec"); | |
| 214 break; | |
| 215 case CodecSrc::kScaledCodec_Mode: | |
| 216 folder.append("scaled_codec"); | |
| 217 break; | |
| 218 case CodecSrc::kScanline_Mode: | |
| 219 folder.append("scanline"); | |
| 220 break; | |
| 221 case CodecSrc::kScanline_Subset_Mode: | |
| 222 folder.append("scanline_subset"); | |
| 223 break; | |
| 224 case CodecSrc::kStripe_Mode: | |
| 225 folder.append("stripe"); | |
| 226 break; | |
| 227 case CodecSrc::kSubset_Mode: | |
| 228 folder.append("subset"); | |
| 229 break; | |
| 230 } | |
| 231 | |
| 232 switch (dstColorType) { | |
| 233 case CodecSrc::kGrayscale_Always_DstColorType: | |
| 234 folder.append("_kGray8"); | |
| 235 break; | |
| 236 case CodecSrc::kIndex8_Always_DstColorType: | |
| 237 folder.append("_kIndex8"); | |
| 238 break; | |
| 239 default: | |
| 240 break; | |
| 241 } | |
| 242 | |
| 243 if (1.0f != scale) { | |
| 244 folder.appendf("_%.3f", scale); | |
| 245 } | |
| 246 | |
| 247 CodecSrc* src = new CodecSrc(path, mode, dstColorType, scale); | |
| 248 push_src(SkString("image"), folder, src); | |
|
scroggo
2015/09/01 21:41:22
It seems like if this takes an ImplicitString, thi
msarett
2015/09/01 21:51:32
You are correct. I have fixed this.
| |
| 249 } | |
| 250 | |
| 208 static void push_codec_srcs(Path path) { | 251 static void push_codec_srcs(Path path) { |
| 209 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); | 252 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); |
| 210 if (!encoded) { | 253 if (!encoded) { |
| 211 SkDebugf("Couldn't read %s.", path.c_str()); | 254 SkDebugf("Couldn't read %s.", path.c_str()); |
| 212 return; | 255 return; |
| 213 } | 256 } |
| 214 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 257 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 215 if (nullptr == codec.get()) { | 258 if (nullptr == codec.get()) { |
| 216 SkDebugf("Couldn't create codec for %s.", path.c_str()); | 259 SkDebugf("Couldn't create codec for %s.", path.c_str()); |
| 217 return; | 260 return; |
| 218 } | 261 } |
| 219 | 262 |
| 220 // Choose scales for scaling tests. | 263 // Choose scales for scaling tests. |
| 221 // TODO (msarett): Add more scaling tests as we implement more flexible scal ing. | |
| 222 // TODO (msarett): Implement scaling tests for SkImageDecoder in order to co mpare with these | 264 // TODO (msarett): Implement scaling tests for SkImageDecoder in order to co mpare with these |
| 223 // tests. SkImageDecoder supports downscales by integer fac tors. | 265 // tests. SkImageDecoder supports downscales by integer fac tors. |
| 224 // SkJpegCodec natively supports scaling to: 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 | 266 // SkJpegCodec natively supports scaling to: 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 |
| 225 // 0.1, 0.16, 0.2 etc allow us to test SkScaledCodec with sampleSize 10, 6, 5, etc | 267 // 0.1, 0.16, 0.2 etc allow us to test SkScaledCodec with sampleSize 10, 6, 5, etc |
| 226 // 0.4, 0.7 etc allow to test what happens when the client requests a scale that | 268 // 0.4, 0.7 etc allow to test what happens when the client requests a scale that |
| 227 // does not exactly match a sampleSize or native scaling capability | 269 // does not exactly match a sampleSize or native scaling capability |
| 228 const float scales[] = { 0.1f, 0.125f, 0.166f, 0.2f, 0.25f, 0.333f, 0.375f, 0.4f, 0.5f, 0.6f, | 270 const float scales[] = { 0.1f, 0.125f, 0.166f, 0.2f, 0.25f, 0.333f, 0.375f, 0.4f, 0.5f, 0.6f, |
| 229 0.625f, 0.750f, 0.8f, 0.875f, 1.0f }; | 271 0.625f, 0.750f, 0.8f, 0.875f, 1.0f }; |
| 230 | 272 |
| 273 const CodecSrc::Mode modes[] = { CodecSrc::kCodec_Mode, CodecSrc::kScaledCod ec_Mode, | |
| 274 CodecSrc::kScanline_Mode, CodecSrc::kScanline_Subset_Mode, CodecSrc: :kStripe_Mode, | |
| 275 CodecSrc::kSubset_Mode }; | |
| 276 | |
| 277 const CodecSrc::DstColorType colorTypes[] = { CodecSrc::kGetFromCanvas_DstCo lorType, | |
| 278 CodecSrc::kGrayscale_Always_DstColorType, CodecSrc::kIndex8_Always_D stColorType }; | |
| 279 | |
| 231 for (float scale : scales) { | 280 for (float scale : scales) { |
| 232 if (scale != 1.0f && (path.endsWith(".webp") || path.endsWith(".WEBP"))) { | 281 if (scale != 1.0f && (path.endsWith(".webp") || path.endsWith(".WEBP"))) { |
| 233 // FIXME: skbug.com/4038 Scaling webp seems to leave some pixels uni nitialized/ | 282 // FIXME: skbug.com/4038 Scaling webp seems to leave some pixels uni nitialized/ |
| 234 // compute their colors based on uninitialized values. | 283 // compute their colors based on uninitialized values. |
| 235 continue; | 284 continue; |
| 236 } | 285 } |
| 237 // Build additional test cases for images that decode natively to non-ca nvas types | 286 |
| 238 switch(codec->getInfo().colorType()) { | 287 for (CodecSrc::Mode mode : modes) { |
| 239 case kGray_8_SkColorType: | 288 for (CodecSrc::DstColorType colorType : colorTypes) { |
| 240 push_src("image", "codec_kGray8", new CodecSrc(path, CodecSrc::k Normal_Mode, | 289 push_codec_src(path, mode, colorType, scale); |
| 241 CodecSrc::kGrayscale_Always_DstColorType, scale)); | 290 } |
| 242 push_src("image", "scanline_kGray8", new CodecSrc(path, CodecSrc ::kScanline_Mode, | |
| 243 CodecSrc::kGrayscale_Always_DstColorType, scale)); | |
| 244 push_src("image", "scanline_subset_kGray8", new CodecSrc(path, | |
| 245 CodecSrc::kScanline_Subset_Mode, CodecSrc::kGrayscale_Al ways_DstColorType, | |
| 246 scale)); | |
| 247 push_src("image", "stripe_kGray8", new CodecSrc(path, CodecSrc:: kStripe_Mode, | |
| 248 CodecSrc::kGrayscale_Always_DstColorType, scale)); | |
| 249 // Intentional fall through | |
| 250 // FIXME: Is this a long term solution for testing wbmps decodes to kIndex8? | |
| 251 // Further discussion on this topic is at skbug.com/3683 | |
| 252 case kIndex_8_SkColorType: | |
| 253 push_src("image", "codec_kIndex8", new CodecSrc(path, CodecSrc:: kNormal_Mode, | |
| 254 CodecSrc::kIndex8_Always_DstColorType, scale)); | |
| 255 push_src("image", "scanline_kIndex8", new CodecSrc(path, CodecSr c::kScanline_Mode, | |
| 256 CodecSrc::kIndex8_Always_DstColorType, scale)); | |
| 257 push_src("image", "scanline_subset_kIndex8", new CodecSrc(path, | |
| 258 CodecSrc::kScanline_Subset_Mode, CodecSrc::kIndex8_Alway s_DstColorType, | |
| 259 scale)); | |
| 260 push_src("image", "stripe_kIndex8", new CodecSrc(path, CodecSrc: :kStripe_Mode, | |
| 261 CodecSrc::kIndex8_Always_DstColorType, scale)); | |
| 262 break; | |
| 263 default: | |
| 264 // Do nothing | |
| 265 break; | |
| 266 } | 291 } |
| 267 | |
| 268 // Decode all images to the canvas color type | |
| 269 push_src("image", "codec", new CodecSrc(path, CodecSrc::kNormal_Mode, | |
| 270 CodecSrc::kGetFromCanvas_DstColorType, scale)); | |
| 271 push_src("image", "scanline", new CodecSrc(path, CodecSrc::kScanline_Mod e, | |
| 272 CodecSrc::kGetFromCanvas_DstColorType, scale)); | |
| 273 push_src("image", "scanline_subset", new CodecSrc(path, CodecSrc::kScanl ine_Subset_Mode, | |
| 274 CodecSrc::kGetFromCanvas_DstColorType, scale)); | |
| 275 push_src("image", "stripe", new CodecSrc(path, CodecSrc::kStripe_Mode, | |
| 276 CodecSrc::kGetFromCanvas_DstColorType, scale)); | |
| 277 // Note: The only codec which supports subsets natively is SkWebpCodec, which will never | |
| 278 // report kIndex_8 or kGray_8, so there is no need to test kSubset_mode with those color | |
| 279 // types specifically requested. | |
| 280 push_src("image", "codec_subset", new CodecSrc(path, CodecSrc::kSubset_M ode, | |
| 281 CodecSrc::kGetFromCanvas_DstColorType, scale)); | |
| 282 } | 292 } |
| 283 } | 293 } |
| 284 | 294 |
| 285 static bool codec_supported(const char* ext) { | 295 static bool codec_supported(const char* ext) { |
| 286 // FIXME: Once other versions of SkCodec are available, we can add them to t his | 296 // FIXME: Once other versions of SkCodec are available, we can add them to t his |
| 287 // list (and eventually we can remove this check once they are all supported ). | 297 // list (and eventually we can remove this check once they are all supported ). |
| 288 static const char* const exts[] = { | 298 static const char* const exts[] = { |
| 289 "bmp", "gif", "jpg", "jpeg", "png", "ico", "wbmp", "webp", | 299 "bmp", "gif", "jpg", "jpeg", "png", "ico", "wbmp", "webp", |
| 290 "BMP", "GIF", "JPG", "JPEG", "PNG", "ICO", "WBMP", "WEBP", | 300 "BMP", "GIF", "JPG", "JPEG", "PNG", "ICO", "WBMP", "WEBP", |
| 291 }; | 301 }; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 const TaggedSink& sink; | 578 const TaggedSink& sink; |
| 569 | 579 |
| 570 static void Run(Task* task) { | 580 static void Run(Task* task) { |
| 571 SkString name = task->src->name(); | 581 SkString name = task->src->name(); |
| 572 | 582 |
| 573 // We'll skip drawing this Src/Sink pair if: | 583 // We'll skip drawing this Src/Sink pair if: |
| 574 // - the Src vetoes the Sink; | 584 // - the Src vetoes the Sink; |
| 575 // - this Src / Sink combination is on the blacklist; | 585 // - this Src / Sink combination is on the blacklist; |
| 576 // - it's a dry run. | 586 // - it's a dry run. |
| 577 SkString note(task->src->veto(task->sink->flags()) ? " (veto)" : ""); | 587 SkString note(task->src->veto(task->sink->flags()) ? " (veto)" : ""); |
| 578 SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag, | 588 SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag.c _str(), |
| 579 task->src.options, name.c_str() ); | 589 task->src.options.c_str(), name .c_str()); |
| 580 if (!whyBlacklisted.isEmpty()) { | 590 if (!whyBlacklisted.isEmpty()) { |
| 581 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); | 591 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); |
| 582 } | 592 } |
| 583 | 593 |
| 584 SkString log; | 594 SkString log; |
| 585 WallTimer timer; | 595 WallTimer timer; |
| 586 timer.start(); | 596 timer.start(); |
| 587 if (!FLAGS_dryRun && note.isEmpty()) { | 597 if (!FLAGS_dryRun && note.isEmpty()) { |
| 588 SkBitmap bitmap; | 598 SkBitmap bitmap; |
| 589 SkDynamicMemoryWStream stream; | 599 SkDynamicMemoryWStream stream; |
| 590 if (FLAGS_pre_log) { | 600 if (FLAGS_pre_log) { |
| 591 SkDebugf("\nRunning %s->%s", name.c_str(), task->sink.tag); | 601 SkDebugf("\nRunning %s->%s", name.c_str(), task->sink.tag); |
| 592 } | 602 } |
| 593 start(task->sink.tag, task->src.tag, task->src.options, name.c_str() ); | 603 start(task->sink.tag, task->src.tag, task->src.options, name.c_str() ); |
| 594 Error err = task->sink->draw(*task->src, &bitmap, &stream, &log); | 604 Error err = task->sink->draw(*task->src, &bitmap, &stream, &log); |
| 595 if (!err.isEmpty()) { | 605 if (!err.isEmpty()) { |
| 596 timer.end(); | 606 timer.end(); |
| 597 if (err.isFatal()) { | 607 if (err.isFatal()) { |
| 598 fail(SkStringPrintf("%s %s %s %s: %s", | 608 fail(SkStringPrintf("%s %s %s %s: %s", |
| 599 task->sink.tag, | 609 task->sink.tag, |
| 600 task->src.tag, | 610 task->src.tag.c_str(), |
| 601 task->src.options, | 611 task->src.options.c_str(), |
| 602 name.c_str(), | 612 name.c_str(), |
| 603 err.c_str())); | 613 err.c_str())); |
| 604 } else { | 614 } else { |
| 605 note.appendf(" (skipped: %s)", err.c_str()); | 615 note.appendf(" (skipped: %s)", err.c_str()); |
| 606 } | 616 } |
| 607 done(timer.fWall, task->sink.tag, task->src.tag, task->src.optio ns, | 617 done(timer.fWall, task->sink.tag, task->src.tag, task->src.optio ns, |
| 608 name, note, log); | 618 name, note, log); |
| 609 return; | 619 return; |
| 610 } | 620 } |
| 611 SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream()); | 621 SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream()); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 630 } | 640 } |
| 631 } | 641 } |
| 632 SkMD5::Digest digest; | 642 SkMD5::Digest digest; |
| 633 hash.finish(digest); | 643 hash.finish(digest); |
| 634 for (int i = 0; i < 16; i++) { | 644 for (int i = 0; i < 16; i++) { |
| 635 md5.appendf("%02x", digest.data[i]); | 645 md5.appendf("%02x", digest.data[i]); |
| 636 } | 646 } |
| 637 } | 647 } |
| 638 | 648 |
| 639 if (!FLAGS_readPath.isEmpty() && | 649 if (!FLAGS_readPath.isEmpty() && |
| 640 !gGold.contains(Gold(task->sink.tag, task->src.tag, | 650 !gGold.contains(Gold(task->sink.tag, task->src.tag.c_str(), |
| 641 task->src.options, name, md5))) { | 651 task->src.options.c_str(), name, md5))) { |
| 642 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", | 652 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", |
| 643 md5.c_str(), | 653 md5.c_str(), |
| 644 task->sink.tag, | 654 task->sink.tag, |
| 645 task->src.tag, | 655 task->src.tag.c_str(), |
| 646 task->src.options, | 656 task->src.options.c_str(), |
| 647 name.c_str(), | 657 name.c_str(), |
| 648 FLAGS_readPath[0])); | 658 FLAGS_readPath[0])); |
| 649 } | 659 } |
| 650 | 660 |
| 651 if (!FLAGS_writePath.isEmpty()) { | 661 if (!FLAGS_writePath.isEmpty()) { |
| 652 const char* ext = task->sink->fileExtension(); | 662 const char* ext = task->sink->fileExtension(); |
| 653 if (data->getLength()) { | 663 if (data->getLength()) { |
| 654 WriteToDisk(*task, md5, ext, data, data->getLength(), nullpt r); | 664 WriteToDisk(*task, md5, ext, data, data->getLength(), nullpt r); |
| 655 SkASSERT(bitmap.drawsNothing()); | 665 SkASSERT(bitmap.drawsNothing()); |
| 656 } else if (!bitmap.drawsNothing()) { | 666 } else if (!bitmap.drawsNothing()) { |
| 657 WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap); | 667 WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap); |
| 658 } | 668 } |
| 659 } | 669 } |
| 660 } | 670 } |
| 661 timer.end(); | 671 timer.end(); |
| 662 done(timer.fWall, task->sink.tag, task->src.tag, task->src.options, name , note, log); | 672 done(timer.fWall, task->sink.tag, task->src.tag.c_str(), task->src.optio ns.c_str(), name, |
| 673 note, log); | |
| 663 } | 674 } |
| 664 | 675 |
| 665 static void WriteToDisk(const Task& task, | 676 static void WriteToDisk(const Task& task, |
| 666 SkString md5, | 677 SkString md5, |
| 667 const char* ext, | 678 const char* ext, |
| 668 SkStream* data, size_t len, | 679 SkStream* data, size_t len, |
| 669 const SkBitmap* bitmap) { | 680 const SkBitmap* bitmap) { |
| 670 JsonWriter::BitmapResult result; | 681 JsonWriter::BitmapResult result; |
| 671 result.name = task.src->name(); | 682 result.name = task.src->name(); |
| 672 result.config = task.sink.tag; | 683 result.config = task.sink.tag; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 692 if (FLAGS_nameByHash) { | 703 if (FLAGS_nameByHash) { |
| 693 path = SkOSPath::Join(dir, result.md5.c_str()); | 704 path = SkOSPath::Join(dir, result.md5.c_str()); |
| 694 path.append("."); | 705 path.append("."); |
| 695 path.append(ext); | 706 path.append(ext); |
| 696 if (sk_exists(path.c_str())) { | 707 if (sk_exists(path.c_str())) { |
| 697 return; // Content-addressed. If it exists already, we're done . | 708 return; // Content-addressed. If it exists already, we're done . |
| 698 } | 709 } |
| 699 } else { | 710 } else { |
| 700 path = SkOSPath::Join(dir, task.sink.tag); | 711 path = SkOSPath::Join(dir, task.sink.tag); |
| 701 sk_mkdir(path.c_str()); | 712 sk_mkdir(path.c_str()); |
| 702 path = SkOSPath::Join(path.c_str(), task.src.tag); | 713 path = SkOSPath::Join(path.c_str(), task.src.tag.c_str()); |
| 703 sk_mkdir(path.c_str()); | 714 sk_mkdir(path.c_str()); |
| 704 if (strcmp(task.src.options, "") != 0) { | 715 if (strcmp(task.src.options.c_str(), "") != 0) { |
| 705 path = SkOSPath::Join(path.c_str(), task.src.options); | 716 path = SkOSPath::Join(path.c_str(), task.src.options.c_str()); |
| 706 sk_mkdir(path.c_str()); | 717 sk_mkdir(path.c_str()); |
| 707 } | 718 } |
| 708 path = SkOSPath::Join(path.c_str(), task.src->name().c_str()); | 719 path = SkOSPath::Join(path.c_str(), task.src->name().c_str()); |
| 709 path.append("."); | 720 path.append("."); |
| 710 path.append(ext); | 721 path.append(ext); |
| 711 } | 722 } |
| 712 | 723 |
| 713 if (bitmap) { | 724 if (bitmap) { |
| 714 if (!dump_png(*bitmap, path.c_str(), result.md5.c_str())) { | 725 if (!dump_png(*bitmap, path.c_str(), result.md5.c_str())) { |
| 715 fail(SkStringPrintf("Can't encode PNG to %s.\n", path.c_str())); | 726 fail(SkStringPrintf("Can't encode PNG to %s.\n", path.c_str())); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 913 } | 924 } |
| 914 return 0; | 925 return 0; |
| 915 } | 926 } |
| 916 | 927 |
| 917 #if !defined(SK_BUILD_FOR_IOS) | 928 #if !defined(SK_BUILD_FOR_IOS) |
| 918 int main(int argc, char** argv) { | 929 int main(int argc, char** argv) { |
| 919 SkCommandLineFlags::Parse(argc, argv); | 930 SkCommandLineFlags::Parse(argc, argv); |
| 920 return dm_main(); | 931 return dm_main(); |
| 921 } | 932 } |
| 922 #endif | 933 #endif |
| OLD | NEW |