OLD | NEW |
1 #include "DMWriteTask.h" | 1 #include "DMWriteTask.h" |
2 | 2 |
3 #include "DMUtil.h" | 3 #include "DMUtil.h" |
4 #include "SkColorPriv.h" | 4 #include "SkColorPriv.h" |
5 #include "SkCommonFlags.h" | 5 #include "SkCommonFlags.h" |
6 #include "SkData.h" | 6 #include "SkData.h" |
7 #include "SkImageEncoder.h" | 7 #include "SkImageEncoder.h" |
8 #include "SkMD5.h" | 8 #include "SkMD5.h" |
9 #include "SkMallocPixelRef.h" | 9 #include "SkMallocPixelRef.h" |
10 #include "SkOSFile.h" | 10 #include "SkOSFile.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 SkASSERT(fData.get()); | 57 SkASSERT(fData.get()); |
58 SkASSERT(fData->unique()); | 58 SkASSERT(fData->unique()); |
59 } | 59 } |
60 | 60 |
61 void WriteTask::makeDirOrFail(SkString dir) { | 61 void WriteTask::makeDirOrFail(SkString dir) { |
62 if (!sk_mkdir(dir.c_str())) { | 62 if (!sk_mkdir(dir.c_str())) { |
63 this->fail(); | 63 this->fail(); |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 static SkStreamAsset* encode_to_png(const SkBitmap& bitmap) { | 67 static SkString get_md5(const void* ptr, size_t len) { |
68 SkDynamicMemoryWStream png; | |
69 if (!SkImageEncoder::EncodeStream(&png, bitmap, SkImageEncoder::kPNG_Type, 1
00)) { | |
70 return NULL; | |
71 } | |
72 png.copyToData()->unref(); // Forces detachAsStream() to be contiguous. | |
73 return png.detachAsStream(); | |
74 } | |
75 | |
76 static SkString get_md5(SkStreamAsset* src) { | |
77 SkMD5 hasher; | 68 SkMD5 hasher; |
78 hasher.write(src->getMemoryBase(), src->getLength()); | 69 hasher.write(ptr, len); |
79 SkMD5::Digest digest; | 70 SkMD5::Digest digest; |
80 hasher.finish(digest); | 71 hasher.finish(digest); |
81 | 72 |
82 SkString md5; | 73 SkString md5; |
83 for (int i = 0; i < 16; i++) { | 74 for (int i = 0; i < 16; i++) { |
84 md5.appendf("%02x", digest.data[i]); | 75 md5.appendf("%02x", digest.data[i]); |
85 } | 76 } |
86 return md5; | 77 return md5; |
87 } | 78 } |
88 | 79 |
89 struct JsonData { | 80 struct JsonData { |
90 SkString name; // E.g. "ninepatch-stretch", "desk-gws_skp" | 81 SkString name; // E.g. "ninepatch-stretch", "desk-gws_skp" |
91 SkString config; // "gpu", "8888" | 82 SkString config; // "gpu", "8888" |
92 SkString sourceType; // "GM", "SKP" | 83 SkString sourceType; // "GM", "SKP" |
93 SkString md5; // In ASCII, so 32 bytes long. | 84 SkString md5; // In ASCII, so 32 bytes long. |
94 }; | 85 }; |
95 SkTArray<JsonData> gJsonData; | 86 SkTArray<JsonData> gJsonData; |
96 SK_DECLARE_STATIC_MUTEX(gJsonDataLock); | 87 SK_DECLARE_STATIC_MUTEX(gJsonDataLock); |
97 | 88 |
98 void WriteTask::draw() { | 89 void WriteTask::draw() { |
99 if (!fData.get()) { | 90 SkString md5; |
100 fData.reset(encode_to_png(fBitmap)); | 91 { |
101 if (!fData.get()) { | 92 SkAutoLockPixels lock(fBitmap); |
102 this->fail("Can't encode to PNG."); | 93 md5 = fData ? get_md5(fData->getMemoryBase(), fData->getLength()) |
103 } | 94 : get_md5(fBitmap.getPixels(), fBitmap.getSize()); |
104 } | 95 } |
105 | 96 |
106 JsonData entry = { fBaseName, fSuffixes[0], fSourceType, get_md5(fData) }; | 97 JsonData entry = { fBaseName, fSuffixes[0], fSourceType, md5 }; |
107 { | 98 { |
108 SkAutoMutexAcquire lock(&gJsonDataLock); | 99 SkAutoMutexAcquire lock(&gJsonDataLock); |
109 gJsonData.push_back(entry); | 100 gJsonData.push_back(entry); |
110 } | 101 } |
111 | 102 |
112 SkString dir(FLAGS_writePath[0]); | 103 SkString dir(FLAGS_writePath[0]); |
113 #if SK_BUILD_FOR_IOS | 104 #if SK_BUILD_FOR_IOS |
114 if (dir.equals("@")) { | 105 if (dir.equals("@")) { |
115 dir.set(FLAGS_resourcePath[0]); | 106 dir.set(FLAGS_resourcePath[0]); |
116 } | 107 } |
117 #endif | 108 #endif |
118 this->makeDirOrFail(dir); | 109 this->makeDirOrFail(dir); |
119 | 110 |
120 SkString path; | 111 SkString path; |
121 if (FLAGS_nameByHash) { | 112 if (FLAGS_nameByHash) { |
122 // Flat directory of hash-named files. | 113 // Flat directory of hash-named files. |
123 path = SkOSPath::Join(dir.c_str(), entry.md5.c_str()); | 114 path = SkOSPath::Join(dir.c_str(), md5.c_str()); |
124 path.append(fExtension); | 115 path.append(fExtension); |
125 // We're content-addressed, so it's possible two threads race to write | 116 // We're content-addressed, so it's possible two threads race to write |
126 // this file. We let the first one win. This also means we won't | 117 // this file. We let the first one win. This also means we won't |
127 // overwrite identical files from previous runs. | 118 // overwrite identical files from previous runs. |
128 if (sk_exists(path.c_str())) { | 119 if (sk_exists(path.c_str())) { |
129 return; | 120 return; |
130 } | 121 } |
131 } else { | 122 } else { |
132 // Nested by mode, config, etc. | 123 // Nested by mode, config, etc. |
133 for (int i = 0; i < fSuffixes.count(); i++) { | 124 for (int i = 0; i < fSuffixes.count(); i++) { |
134 dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str()); | 125 dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str()); |
135 this->makeDirOrFail(dir); | 126 this->makeDirOrFail(dir); |
136 } | 127 } |
137 path = SkOSPath::Join(dir.c_str(), fBaseName.c_str()); | 128 path = SkOSPath::Join(dir.c_str(), fBaseName.c_str()); |
138 path.append(fExtension); | 129 path.append(fExtension); |
139 // The path is unique, so two threads can't both write to the same file. | 130 // The path is unique, so two threads can't both write to the same file. |
140 // If already present we overwrite here, since the content may have chan
ged. | 131 // If already present we overwrite here, since the content may have chan
ged. |
141 } | 132 } |
142 | 133 |
143 SkFILEWStream file(path.c_str()); | 134 SkFILEWStream file(path.c_str()); |
144 if (!file.isValid()) { | 135 if (!file.isValid()) { |
145 return this->fail("Can't open file."); | 136 return this->fail("Can't open file."); |
146 } | 137 } |
147 | 138 |
148 fData->rewind(); | 139 bool ok = fData ? file.writeStream(fData, fData->getLength()) |
149 if (!file.writeStream(fData, fData->getLength())) { | 140 : SkImageEncoder::EncodeStream(&file, fBitmap, SkImageEncode
r::kPNG_Type, 100); |
| 141 if (!ok) { |
150 return this->fail("Can't write to file."); | 142 return this->fail("Can't write to file."); |
151 } | 143 } |
152 } | 144 } |
153 | 145 |
154 SkString WriteTask::name() const { | 146 SkString WriteTask::name() const { |
155 SkString name("writing "); | 147 SkString name("writing "); |
156 for (int i = 0; i < fSuffixes.count(); i++) { | 148 for (int i = 0; i < fSuffixes.count(); i++) { |
157 name.appendf("%s/", fSuffixes[i].c_str()); | 149 name.appendf("%s/", fSuffixes[i].c_str()); |
158 } | 150 } |
159 name.append(fBaseName.c_str()); | 151 name.append(fBaseName.c_str()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 } | 183 } |
192 } | 184 } |
193 | 185 |
194 SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json"); | 186 SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json"); |
195 SkFILEWStream stream(path.c_str()); | 187 SkFILEWStream stream(path.c_str()); |
196 stream.writeText(Json::StyledWriter().write(root).c_str()); | 188 stream.writeText(Json::StyledWriter().write(root).c_str()); |
197 stream.flush(); | 189 stream.flush(); |
198 } | 190 } |
199 | 191 |
200 } // namespace DM | 192 } // namespace DM |
OLD | NEW |