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 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 match(FLAGS_blacklist[i+2], srcOptions) && | 769 match(FLAGS_blacklist[i+2], srcOptions) && |
770 match(FLAGS_blacklist[i+3], name)) { | 770 match(FLAGS_blacklist[i+3], name)) { |
771 return SkStringPrintf("%s %s %s %s", | 771 return SkStringPrintf("%s %s %s %s", |
772 FLAGS_blacklist[i+0], FLAGS_blacklist[i+1], | 772 FLAGS_blacklist[i+0], FLAGS_blacklist[i+1], |
773 FLAGS_blacklist[i+2], FLAGS_blacklist[i+3]); | 773 FLAGS_blacklist[i+2], FLAGS_blacklist[i+3]); |
774 } | 774 } |
775 } | 775 } |
776 return ""; | 776 return ""; |
777 } | 777 } |
778 | 778 |
| 779 // Even when a Task Sink reports to be non-threadsafe (e.g. GPU), we know things
like |
| 780 // .png encoding are definitely thread safe. This lets us offload that work to
CPU threads. |
| 781 static SkTaskGroup gDefinitelyThreadSafeWork; |
| 782 |
779 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, | 783 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, |
780 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. | 784 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. |
781 struct Task { | 785 struct Task { |
782 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {} | 786 Task(const TaggedSrc& src, const TaggedSink& sink) : src(src), sink(sink) {} |
783 const TaggedSrc& src; | 787 const TaggedSrc& src; |
784 const TaggedSink& sink; | 788 const TaggedSink& sink; |
785 | 789 |
786 static void Run(Task* task) { | 790 static void Run(Task* task) { |
787 SkString name = task->src->name(); | 791 SkString name = task->src->name(); |
788 | 792 |
(...skipping 27 matching lines...) Expand all Loading... |
816 task->src.options.c_str(), | 820 task->src.options.c_str(), |
817 name.c_str(), | 821 name.c_str(), |
818 err.c_str())); | 822 err.c_str())); |
819 } else { | 823 } else { |
820 note.appendf(" (skipped: %s)", err.c_str()); | 824 note.appendf(" (skipped: %s)", err.c_str()); |
821 } | 825 } |
822 done(elapsed, task->sink.tag.c_str(), task->src.tag, task->src.o
ptions, | 826 done(elapsed, task->sink.tag.c_str(), task->src.tag, task->src.o
ptions, |
823 name, note, log); | 827 name, note, log); |
824 return; | 828 return; |
825 } | 829 } |
826 SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream()); | |
827 | 830 |
828 SkString md5; | 831 // We're likely switching threads here, so we must capture by value,
[=] or [foo,bar]. |
829 if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) { | 832 SkStreamAsset* data = stream.detachAsStream(); |
830 SkMD5 hash; | 833 gDefinitelyThreadSafeWork.add([task,name,bitmap,data]{ |
831 if (data->getLength()) { | 834 SkAutoTDelete<SkStreamAsset> ownedData(data); |
832 hash.writeStream(data, data->getLength()); | 835 |
833 data->rewind(); | 836 // Why doesn't the copy constructor do this when we have pre-loc
ked pixels? |
834 } else { | 837 bitmap.lockPixels(); |
835 // If we're BGRA (Linux, Windows), swizzle over to RGBA (Mac
, Android). | 838 |
836 // This helps eliminate multiple 0-pixel-diff hashes on gold
.skia.org. | 839 SkString md5; |
837 // (Android's general slow speed breaks the tie arbitrarily
in RGBA's favor.) | 840 if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) { |
838 // We might consider promoting 565 to RGBA too. | 841 SkMD5 hash; |
839 if (bitmap.colorType() == kBGRA_8888_SkColorType) { | 842 if (data->getLength()) { |
840 SkBitmap swizzle; | 843 hash.writeStream(data, data->getLength()); |
841 SkAssertResult(bitmap.copyTo(&swizzle, kRGBA_8888_SkColo
rType)); | 844 data->rewind(); |
842 hash.write(swizzle.getPixels(), swizzle.getSize()); | |
843 } else { | 845 } else { |
844 hash.write(bitmap.getPixels(), bitmap.getSize()); | 846 // If we're BGRA (Linux, Windows), swizzle over to RGBA
(Mac, Android). |
| 847 // This helps eliminate multiple 0-pixel-diff hashes on
gold.skia.org. |
| 848 // (Android's general slow speed breaks the tie arbitrar
ily in RGBA's favor.) |
| 849 // We might consider promoting 565 to RGBA too. |
| 850 if (bitmap.colorType() == kBGRA_8888_SkColorType) { |
| 851 SkBitmap swizzle; |
| 852 SkAssertResult(bitmap.copyTo(&swizzle, kRGBA_8888_Sk
ColorType)); |
| 853 hash.write(swizzle.getPixels(), swizzle.getSize()); |
| 854 } else { |
| 855 hash.write(bitmap.getPixels(), bitmap.getSize()); |
| 856 } |
| 857 } |
| 858 SkMD5::Digest digest; |
| 859 hash.finish(digest); |
| 860 for (int i = 0; i < 16; i++) { |
| 861 md5.appendf("%02x", digest.data[i]); |
845 } | 862 } |
846 } | 863 } |
847 SkMD5::Digest digest; | 864 |
848 hash.finish(digest); | 865 if (!FLAGS_readPath.isEmpty() && |
849 for (int i = 0; i < 16; i++) { | 866 !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c
_str(), |
850 md5.appendf("%02x", digest.data[i]); | 867 task->src.options.c_str(), name, md5)))
{ |
| 868 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", |
| 869 md5.c_str(), |
| 870 task->sink.tag.c_str(), |
| 871 task->src.tag.c_str(), |
| 872 task->src.options.c_str(), |
| 873 name.c_str(), |
| 874 FLAGS_readPath[0])); |
851 } | 875 } |
852 } | |
853 | 876 |
854 if (!FLAGS_readPath.isEmpty() && | 877 if (!FLAGS_writePath.isEmpty()) { |
855 !gGold.contains(Gold(task->sink.tag.c_str(), task->src.tag.c_str
(), | 878 const char* ext = task->sink->fileExtension(); |
856 task->src.options.c_str(), name, md5))) { | 879 if (data->getLength()) { |
857 fail(SkStringPrintf("%s not found for %s %s %s %s in %s", | 880 WriteToDisk(*task, md5, ext, data, data->getLength(), nu
llptr); |
858 md5.c_str(), | 881 SkASSERT(bitmap.drawsNothing()); |
859 task->sink.tag.c_str(), | 882 } else if (!bitmap.drawsNothing()) { |
860 task->src.tag.c_str(), | 883 WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap); |
861 task->src.options.c_str(), | 884 } |
862 name.c_str(), | |
863 FLAGS_readPath[0])); | |
864 } | |
865 | |
866 if (!FLAGS_writePath.isEmpty()) { | |
867 const char* ext = task->sink->fileExtension(); | |
868 if (data->getLength()) { | |
869 WriteToDisk(*task, md5, ext, data, data->getLength(), nullpt
r); | |
870 SkASSERT(bitmap.drawsNothing()); | |
871 } else if (!bitmap.drawsNothing()) { | |
872 WriteToDisk(*task, md5, ext, nullptr, 0, &bitmap); | |
873 } | 885 } |
874 } | 886 }); |
875 } | 887 } |
876 done(now_ms()-timerStart, task->sink.tag.c_str(), task->src.tag.c_str(),
task->src.options.c_str(), | 888 done(now_ms()-timerStart, task->sink.tag.c_str(), task->src.tag.c_str(),
task->src.options.c_str(), |
877 name, note, log); | 889 name, note, log); |
878 } | 890 } |
879 | 891 |
880 static void WriteToDisk(const Task& task, | 892 static void WriteToDisk(const Task& task, |
881 SkString md5, | 893 SkString md5, |
882 const char* ext, | 894 const char* ext, |
883 SkStream* data, size_t len, | 895 SkStream* data, size_t len, |
884 const SkBitmap* bitmap) { | 896 const SkBitmap* bitmap) { |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 break; | 1115 break; |
1104 case kGPU_Enclave: | 1116 case kGPU_Enclave: |
1105 tg.add([currentEnclave](){ run_enclave_and_gpu_tests(currentEncl
ave); }); | 1117 tg.add([currentEnclave](){ run_enclave_and_gpu_tests(currentEncl
ave); }); |
1106 break; | 1118 break; |
1107 default: | 1119 default: |
1108 tg.add([currentEnclave](){ run_enclave(currentEnclave); }); | 1120 tg.add([currentEnclave](){ run_enclave(currentEnclave); }); |
1109 break; | 1121 break; |
1110 } | 1122 } |
1111 } | 1123 } |
1112 tg.wait(); | 1124 tg.wait(); |
| 1125 gDefinitelyThreadSafeWork.wait(); |
| 1126 |
1113 // At this point we're back in single-threaded land. | 1127 // At this point we're back in single-threaded land. |
1114 sk_tool_utils::release_portable_typefaces(); | 1128 sk_tool_utils::release_portable_typefaces(); |
1115 | 1129 |
1116 if (FLAGS_verbose && gNoteTally.count() > 0) { | 1130 if (FLAGS_verbose && gNoteTally.count() > 0) { |
1117 SkDebugf("\nNote tally:\n"); | 1131 SkDebugf("\nNote tally:\n"); |
1118 gNoteTally.foreach([](const SkString& note, int* tally) { | 1132 gNoteTally.foreach([](const SkString& note, int* tally) { |
1119 SkDebugf("%dx\t%s\n", *tally, note.c_str()); | 1133 SkDebugf("%dx\t%s\n", *tally, note.c_str()); |
1120 }); | 1134 }); |
1121 } | 1135 } |
1122 | 1136 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 Reporter* reporter, | 1238 Reporter* reporter, |
1225 GrContextFactory* fac
tory); | 1239 GrContextFactory* fac
tory); |
1226 } // namespace skiatest | 1240 } // namespace skiatest |
1227 | 1241 |
1228 #if !defined(SK_BUILD_FOR_IOS) | 1242 #if !defined(SK_BUILD_FOR_IOS) |
1229 int main(int argc, char** argv) { | 1243 int main(int argc, char** argv) { |
1230 SkCommandLineFlags::Parse(argc, argv); | 1244 SkCommandLineFlags::Parse(argc, argv); |
1231 return dm_main(); | 1245 return dm_main(); |
1232 } | 1246 } |
1233 #endif | 1247 #endif |
OLD | NEW |