|
5 | 5 | * found in the LICENSE file. |
6 | 6 | */ |
7 | 7 |
|
| 8 | +#include <set> |
8 | 9 | #include <string> |
9 | 10 | #include <emscripten.h> |
10 | 11 | #include <emscripten/bind.h> |
@@ -71,6 +72,12 @@ static sk_sp<GrDirectContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE cont |
71 | 72 | return dContext; |
72 | 73 | } |
73 | 74 |
|
| 75 | +static std::set<std::string> gKnownDigests; |
| 76 | + |
| 77 | +static void LoadKnownDigest(std::string md5) { |
| 78 | + gKnownDigests.insert(md5); |
| 79 | +} |
| 80 | + |
74 | 81 | /** |
75 | 82 | * Runs the given GM and returns a JS object. If the GM was successful, the object will have the |
76 | 83 | * following properties: |
@@ -140,31 +147,36 @@ static JSObject RunGM(sk_sp<GrDirectContext> ctx, std::string name) { |
140 | 147 | md5.appendf("%02x", digest.data[i]); |
141 | 148 | } |
142 | 149 |
|
143 | | - // We do not need to include the keys because they are optional - they are not read by Gold. |
144 | | - CommandLineFlags::StringArray empty; |
145 | | - SkDynamicMemoryWStream stream; |
146 | | - // TODO(kjlubick) make emission of PNGs optional and make it so we can check the hash against |
147 | | - // the list of known digests to not emit it. This will hopefully speed tests up. |
148 | | - hashAndEncode->encodePNG(&stream, md5.c_str(), empty, empty); |
149 | | - |
150 | | - auto data = stream.detachAsData(); |
151 | | - |
152 | | - // This is the cleanest way to create a new Uint8Array with a copy of the data that is not |
153 | | - // in the WASM heap. kjlubick tried returning a pointer inside an SkData, but that lead to some |
154 | | - // use after free issues. By making the copy using the JS transliteration, we don't risk the |
155 | | - // SkData object being cleaned up before we make the copy. |
156 | | - Uint8Array pngData = emscripten::val( |
157 | | - // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-views |
158 | | - typed_memory_view(data->size(), data->bytes()) |
159 | | - ).call<Uint8Array>("slice"); // slice with no args makes a copy of the memory view. |
160 | | - |
161 | | - result.set("png", pngData); |
| 150 | + auto ok = gKnownDigests.find(md5.c_str()); |
| 151 | + if (ok == gKnownDigests.end()) { |
| 152 | + // We only need to decode the image if it is "interesting", that is, we have not written it |
| 153 | + // before to disk and uploaded it to gold. |
| 154 | + SkDynamicMemoryWStream stream; |
| 155 | + // We do not need to include the keys because they are optional - they are not read by Gold. |
| 156 | + CommandLineFlags::StringArray empty; |
| 157 | + hashAndEncode->encodePNG(&stream, md5.c_str(), empty, empty); |
| 158 | + |
| 159 | + auto data = stream.detachAsData(); |
| 160 | + |
| 161 | + // This is the cleanest way to create a new Uint8Array with a copy of the data that is not |
| 162 | + // in the WASM heap. kjlubick tried returning a pointer inside an SkData, but that lead to |
| 163 | + // some use after free issues. By making the copy using the JS transliteration, we don't |
| 164 | + // risk the SkData object being cleaned up before we make the copy. |
| 165 | + Uint8Array pngData = emscripten::val( |
| 166 | + // https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-views |
| 167 | + typed_memory_view(data->size(), data->bytes()) |
| 168 | + ).call<Uint8Array>("slice"); // slice with no args makes a copy of the memory view. |
| 169 | + |
| 170 | + result.set("png", pngData); |
| 171 | + gKnownDigests.emplace(md5.c_str()); |
| 172 | + } |
162 | 173 | result.set("hash", md5.c_str()); |
163 | 174 | return result; |
164 | 175 | } |
165 | 176 |
|
166 | 177 | EMSCRIPTEN_BINDINGS(GMs) { |
167 | 178 | function("ListGMs", &ListGMs); |
| 179 | + function("LoadKnownDigest", &LoadKnownDigest); |
168 | 180 | function("MakeGrContext", &MakeGrContext); |
169 | 181 | function("RunGM", &RunGM); |
170 | 182 |
|
|
0 commit comments