OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifdef WTF | 5 #ifdef WTF |
6 | 6 |
7 Provides a minimal wrapping of the Blink image decoders. Used to perform | 7 Provides a minimal wrapping of the Blink image decoders. Used to perform |
8 a non-threaded, memory-to-memory image decode using micro second accuracy | 8 a non-threaded, memory-to-memory image decode using micro second accuracy |
9 clocks to measure image decode time. Optionally applies color correction | 9 clocks to measure image decode time. Optionally applies color correction |
10 during image decoding on supported platforms (default off). Usage: | 10 during image decoding on supported platforms (default off). Usage: |
11 | 11 |
12 % ninja -C /out/Release image_decode_bench && | 12 % ninja -C /out/Release image_decode_bench && |
13 ./out/Release/image_decode_bench file [iterations] | 13 ./out/Release/image_decode_bench file [iterations] |
14 | 14 |
15 FIXME: Consider adding md5 checksum support to WTF. Use it to compute the | 15 FIXME: Consider adding md5 checksum support to WTF. Use it to compute the |
16 decoded image frame md5 and output that value. | 16 decoded image frame md5 and output that value. |
17 | 17 |
18 FIXME: Consider adding an input data packetization option. Break the input | |
19 into network-sized packets, pump the packets into the image decoder until | |
20 the input data is complete (allDataReceived). This to include any internal | |
21 SharedBuffer costs, such as buffer coalescing, in the reported results. | |
22 | |
23 FIXME: Consider integrating this tool in Chrome telemetry for realz, using | 18 FIXME: Consider integrating this tool in Chrome telemetry for realz, using |
24 the image corpii used to assess Blink image decode performance. Refer to | 19 the image corpii used to assess Blink image decode performance. Refer to |
25 http://crbug.com/398235#c103 and http://crbug.com/258324#c5 | 20 http://crbug.com/398235#c103 and http://crbug.com/258324#c5 |
26 | 21 |
27 #endif | 22 #endif |
28 | 23 |
29 #include "config.h" | 24 #include "config.h" |
30 | 25 |
31 #include "platform/SharedBuffer.h" | 26 #include "platform/SharedBuffer.h" |
32 #include "platform/image-decoders/ImageDecoder.h" | 27 #include "platform/image-decoders/ImageDecoder.h" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 OwnPtr<unsigned char[]> buffer = adoptArrayPtr(new unsigned char[fileSize]); | 258 OwnPtr<unsigned char[]> buffer = adoptArrayPtr(new unsigned char[fileSize]); |
264 if (fileSize != fread(buffer.get(), 1, fileSize, fp)) { | 259 if (fileSize != fread(buffer.get(), 1, fileSize, fp)) { |
265 fprintf(stderr, "Error reading file %s\n", fileName); | 260 fprintf(stderr, "Error reading file %s\n", fileName); |
266 exit(2); | 261 exit(2); |
267 } | 262 } |
268 | 263 |
269 fclose(fp); | 264 fclose(fp); |
270 return SharedBuffer::create(buffer.get(), fileSize); | 265 return SharedBuffer::create(buffer.get(), fileSize); |
271 } | 266 } |
272 | 267 |
273 bool decodeImageData(SharedBuffer* data, bool colorCorrection) | 268 bool decodeImageData(SharedBuffer* data, bool colorCorrection, size_t chunkSize) |
274 { | 269 { |
275 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, | 270 OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, |
276 ImageDecoder::AlphaPremultiplied, colorCorrection ? | 271 ImageDecoder::AlphaPremultiplied, colorCorrection ? |
277 ImageDecoder::GammaAndColorProfileApplied : ImageDecoder::GammaAndCo lorProfileIgnored); | 272 ImageDecoder::GammaAndColorProfileApplied : ImageDecoder::GammaAndCo lorProfileIgnored); |
278 | 273 |
279 bool allDataReceived = true; | 274 if (!chunkSize) { |
280 decoder->setData(data, allDataReceived); | 275 bool allDataReceived = true; |
276 decoder->setData(data, allDataReceived); | |
281 | 277 |
282 int frameCount = decoder->frameCount(); | 278 int frameCount = decoder->frameCount(); |
283 for (int i = 0; i < frameCount; ++i) { | 279 for (int i = 0; i < frameCount; ++i) { |
284 if (!decoder->frameBufferAtIndex(i)) | 280 if (!decoder->frameBufferAtIndex(i)) |
285 return false; | 281 return false; |
282 } | |
283 | |
284 return !decoder->failed(); | |
285 } | |
286 | |
287 RefPtr<SharedBuffer> incrementalData = SharedBuffer::create(); | |
Noel Gordon
2015/09/02 23:29:35
incrementalData -> packetData ?
scroggo
2015/09/03 22:10:26
Done.
| |
288 unsigned position = 0; | |
289 while (true) { | |
290 const char* segment; | |
Noel Gordon
2015/09/02 23:29:35
segment -> packet
scroggo
2015/09/03 22:10:26
Done.
| |
291 unsigned length = data->getSomeData(segment, position); | |
292 | |
293 length = std::min(static_cast<size_t>(length), chunkSize); | |
294 incrementalData->append(segment, length); | |
295 position += length; | |
296 bool allDataReceived = position == data->size(); | |
Noel Gordon
2015/09/02 23:29:35
Space before this line.
scroggo
2015/09/03 22:10:26
Done.
| |
297 decoder->setData(incrementalData.get(), allDataReceived); | |
298 | |
299 int frameCount = decoder->frameCount(); | |
300 for (int i = 0; i < frameCount; ++i) { | |
301 if (!decoder->frameBufferAtIndex(i)) | |
302 break; | |
303 } | |
304 | |
305 if (allDataReceived || decoder->failed()) | |
306 break; | |
286 } | 307 } |
287 | 308 |
288 return !decoder->failed(); | 309 return !decoder->failed(); |
289 } | 310 } |
290 | 311 |
291 int main(int argc, char* argv[]) | 312 int main(int argc, char* argv[]) |
292 { | 313 { |
293 char* name = argv[0]; | 314 char* name = argv[0]; |
294 | 315 |
295 // If the platform supports color correction, allow it to be controlled. | 316 // If the platform supports color correction, allow it to be controlled. |
296 | 317 |
297 bool applyColorCorrection = false; | 318 bool applyColorCorrection = false; |
298 | 319 |
299 #if USE(QCMSLIB) | 320 #if USE(QCMSLIB) |
300 if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0) | 321 if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0) |
301 applyColorCorrection = (--argc, ++argv, true); | 322 applyColorCorrection = (--argc, ++argv, true); |
302 | 323 |
303 if (argc < 2) { | 324 if (argc < 2) { |
304 fprintf(stderr, "Usage: %s [--color-correct] file [iterations]\n", name) ; | 325 fprintf(stderr, "Usage: %s [--color-correct] file [iterations] [chunkSiz e]\n", name); |
305 exit(1); | 326 exit(1); |
306 } | 327 } |
307 #else | 328 #else |
308 if (argc < 2) { | 329 if (argc < 2) { |
309 fprintf(stderr, "Usage: %s file [iterations]\n", name); | 330 fprintf(stderr, "Usage: %s file [iterations] [chunkSize]\n", name); |
310 exit(1); | 331 exit(1); |
311 } | 332 } |
312 #endif | 333 #endif |
313 | 334 |
314 // Control decode bench iterations. | 335 // Control decode bench iterations. |
Noel Gordon
2015/09/02 23:29:35
... iterations and chunkSize.
scroggo
2015/09/03 22:10:26
Done. I've also changed "chunkSize" to "packetSize
| |
315 | 336 |
316 size_t iterations = 1; | 337 size_t iterations = 1; |
317 if (argc >= 3) { | 338 if (argc >= 3) { |
318 char* end = 0; | 339 char* end = 0; |
319 iterations = strtol(argv[2], &end, 10); | 340 iterations = strtol(argv[2], &end, 10); |
320 if (*end != '\0' || !iterations) { | 341 if (*end != '\0' || !iterations) { |
321 fprintf(stderr, "Second argument should be number of iterations. " | 342 fprintf(stderr, "Second argument should be number of iterations. " |
322 "The default is 1. You supplied %s\n", argv[2]); | 343 "The default is 1. You supplied %s\n", argv[2]); |
323 exit(1); | 344 exit(1); |
324 } | 345 } |
325 } | 346 } |
326 | 347 |
348 size_t chunkSize = 0; | |
349 if (argc >= 4) { | |
350 char* end = 0; | |
351 chunkSize = strtol(argv[3], &end, 10); | |
352 if (*end != '\0') { | |
353 fprintf(stderr, "Third argument should be chunk size. Default is " | |
354 "0, meaning to decode the entire image in one chunk. You " | |
355 "supplied %s\n", argv[3]); | |
356 exit(1); | |
357 } | |
358 } | |
359 | |
327 // Create a web platform without V8. | 360 // Create a web platform without V8. |
328 | 361 |
329 class WebPlatform : public blink::Platform { | 362 class WebPlatform : public blink::Platform { |
330 public: | 363 public: |
331 const unsigned char* getTraceCategoryEnabledFlag(const char*) override | 364 const unsigned char* getTraceCategoryEnabledFlag(const char*) override |
332 { | 365 { |
333 return reinterpret_cast<const unsigned char *>("nope-none-nada"); | 366 return reinterpret_cast<const unsigned char *>("nope-none-nada"); |
334 } | 367 } |
335 | 368 |
336 void cryptographicallyRandomValues(unsigned char*, size_t) override | 369 void cryptographicallyRandomValues(unsigned char*, size_t) override |
(...skipping 16 matching lines...) Expand all Loading... | |
353 #endif | 386 #endif |
354 | 387 |
355 // Read entire file content to data. | 388 // Read entire file content to data. |
356 | 389 |
357 RefPtr<SharedBuffer> data = readFile(argv[1]); | 390 RefPtr<SharedBuffer> data = readFile(argv[1]); |
358 if (!data.get() || !data->size()) { | 391 if (!data.get() || !data->size()) { |
359 fprintf(stderr, "Error reading image data from [%s]\n", argv[1]); | 392 fprintf(stderr, "Error reading image data from [%s]\n", argv[1]); |
360 exit(2); | 393 exit(2); |
361 } | 394 } |
362 | 395 |
396 // Merge the buffers. This imitates the MemCache case, where the data is | |
Noel Gordon
2015/09/02 23:29:35
These details about Memcache and packet chunkSize
scroggo
2015/09/03 22:10:26
Done.
| |
397 // consolidated before calling the decoder. This also means that if | |
398 // chunkSize is not zero, each call to SharedBuffer::append will be of size | |
399 // chunkSize (except the last, which may be smaller). | |
400 data->data(); | |
401 | |
363 // Image decode bench for iterations. | 402 // Image decode bench for iterations. |
364 | 403 |
365 double totalTime = 0.0; | 404 double totalTime = 0.0; |
366 | 405 |
367 for (size_t i = 0; i < iterations; ++i) { | 406 for (size_t i = 0; i < iterations; ++i) { |
368 double startTime = getCurrentTime(); | 407 double startTime = getCurrentTime(); |
369 bool decoded = decodeImageData(data.get(), applyColorCorrection); | 408 bool decoded = decodeImageData(data.get(), applyColorCorrection, chunkSi ze); |
370 double elapsedTime = getCurrentTime() - startTime; | 409 double elapsedTime = getCurrentTime() - startTime; |
371 totalTime += elapsedTime; | 410 totalTime += elapsedTime; |
372 if (!decoded) { | 411 if (!decoded) { |
373 fprintf(stderr, "Image decode failed [%s]\n", argv[1]); | 412 fprintf(stderr, "Image decode failed [%s]\n", argv[1]); |
374 exit(3); | 413 exit(3); |
375 } | 414 } |
376 } | 415 } |
377 | 416 |
378 // Results to stdout. | 417 // Results to stdout. |
379 | 418 |
380 double averageTime = totalTime / static_cast<double>(iterations); | 419 double averageTime = totalTime / static_cast<double>(iterations); |
381 printf("%f %f\n", totalTime, averageTime); | 420 printf("%f %f\n", totalTime, averageTime); |
382 return 0; | 421 return 0; |
383 } | 422 } |
OLD | NEW |