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 packetSize
) |
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 (!packetSize) { |
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> packetData = SharedBuffer::create(); |
| 288 unsigned position = 0; |
| 289 while (true) { |
| 290 const char* packet; |
| 291 unsigned length = data->getSomeData(packet, position); |
| 292 |
| 293 length = std::min(static_cast<size_t>(length), packetSize); |
| 294 packetData->append(packet, length); |
| 295 position += length; |
| 296 |
| 297 bool allDataReceived = position == data->size(); |
| 298 decoder->setData(packetData.get(), allDataReceived); |
| 299 |
| 300 int frameCount = decoder->frameCount(); |
| 301 for (int i = 0; i < frameCount; ++i) { |
| 302 if (!decoder->frameBufferAtIndex(i)) |
| 303 break; |
| 304 } |
| 305 |
| 306 if (allDataReceived || decoder->failed()) |
| 307 break; |
286 } | 308 } |
287 | 309 |
288 return !decoder->failed(); | 310 return !decoder->failed(); |
289 } | 311 } |
290 | 312 |
291 int main(int argc, char* argv[]) | 313 int main(int argc, char* argv[]) |
292 { | 314 { |
293 char* name = argv[0]; | 315 char* name = argv[0]; |
294 | 316 |
295 // If the platform supports color correction, allow it to be controlled. | 317 // If the platform supports color correction, allow it to be controlled. |
296 | 318 |
297 bool applyColorCorrection = false; | 319 bool applyColorCorrection = false; |
298 | 320 |
299 #if USE(QCMSLIB) | 321 #if USE(QCMSLIB) |
300 if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0) | 322 if (argc >= 2 && strcmp(argv[1], "--color-correct") == 0) |
301 applyColorCorrection = (--argc, ++argv, true); | 323 applyColorCorrection = (--argc, ++argv, true); |
302 | 324 |
303 if (argc < 2) { | 325 if (argc < 2) { |
304 fprintf(stderr, "Usage: %s [--color-correct] file [iterations]\n", name)
; | 326 fprintf(stderr, "Usage: %s [--color-correct] file [iterations] [packetSi
ze]\n", name); |
305 exit(1); | 327 exit(1); |
306 } | 328 } |
307 #else | 329 #else |
308 if (argc < 2) { | 330 if (argc < 2) { |
309 fprintf(stderr, "Usage: %s file [iterations]\n", name); | 331 fprintf(stderr, "Usage: %s file [iterations] [packetSize]\n", name); |
310 exit(1); | 332 exit(1); |
311 } | 333 } |
312 #endif | 334 #endif |
313 | 335 |
314 // Control decode bench iterations. | 336 // Control decode bench iterations and packet size. |
315 | 337 |
316 size_t iterations = 1; | 338 size_t iterations = 1; |
317 if (argc >= 3) { | 339 if (argc >= 3) { |
318 char* end = 0; | 340 char* end = 0; |
319 iterations = strtol(argv[2], &end, 10); | 341 iterations = strtol(argv[2], &end, 10); |
320 if (*end != '\0' || !iterations) { | 342 if (*end != '\0' || !iterations) { |
321 fprintf(stderr, "Second argument should be number of iterations. " | 343 fprintf(stderr, "Second argument should be number of iterations. " |
322 "The default is 1. You supplied %s\n", argv[2]); | 344 "The default is 1. You supplied %s\n", argv[2]); |
323 exit(1); | 345 exit(1); |
324 } | 346 } |
325 } | 347 } |
326 | 348 |
| 349 size_t packetSize = 0; |
| 350 if (argc >= 4) { |
| 351 char* end = 0; |
| 352 packetSize = strtol(argv[3], &end, 10); |
| 353 if (*end != '\0') { |
| 354 fprintf(stderr, "Third argument should be packet size. Default is " |
| 355 "0, meaning to decode the entire image in one packet. You " |
| 356 "supplied %s\n", argv[3]); |
| 357 exit(1); |
| 358 } |
| 359 } |
| 360 |
327 // Create a web platform without V8. | 361 // Create a web platform without V8. |
328 | 362 |
329 class WebPlatform : public blink::Platform { | 363 class WebPlatform : public blink::Platform { |
330 public: | 364 public: |
331 const unsigned char* getTraceCategoryEnabledFlag(const char*) override | 365 const unsigned char* getTraceCategoryEnabledFlag(const char*) override |
332 { | 366 { |
333 return reinterpret_cast<const unsigned char *>("nope-none-nada"); | 367 return reinterpret_cast<const unsigned char *>("nope-none-nada"); |
334 } | 368 } |
335 | 369 |
336 void cryptographicallyRandomValues(unsigned char*, size_t) override | 370 void cryptographicallyRandomValues(unsigned char*, size_t) override |
(...skipping 16 matching lines...) Expand all Loading... |
353 #endif | 387 #endif |
354 | 388 |
355 // Read entire file content to data. | 389 // Read entire file content to data. |
356 | 390 |
357 RefPtr<SharedBuffer> data = readFile(argv[1]); | 391 RefPtr<SharedBuffer> data = readFile(argv[1]); |
358 if (!data.get() || !data->size()) { | 392 if (!data.get() || !data->size()) { |
359 fprintf(stderr, "Error reading image data from [%s]\n", argv[1]); | 393 fprintf(stderr, "Error reading image data from [%s]\n", argv[1]); |
360 exit(2); | 394 exit(2); |
361 } | 395 } |
362 | 396 |
| 397 // Consolidate the SharedBuffer data segments into one, contiguous block of
memory. |
| 398 data->data(); |
| 399 |
363 // Image decode bench for iterations. | 400 // Image decode bench for iterations. |
364 | 401 |
365 double totalTime = 0.0; | 402 double totalTime = 0.0; |
366 | 403 |
367 for (size_t i = 0; i < iterations; ++i) { | 404 for (size_t i = 0; i < iterations; ++i) { |
368 double startTime = getCurrentTime(); | 405 double startTime = getCurrentTime(); |
369 bool decoded = decodeImageData(data.get(), applyColorCorrection); | 406 bool decoded = decodeImageData(data.get(), applyColorCorrection, packetS
ize); |
370 double elapsedTime = getCurrentTime() - startTime; | 407 double elapsedTime = getCurrentTime() - startTime; |
371 totalTime += elapsedTime; | 408 totalTime += elapsedTime; |
372 if (!decoded) { | 409 if (!decoded) { |
373 fprintf(stderr, "Image decode failed [%s]\n", argv[1]); | 410 fprintf(stderr, "Image decode failed [%s]\n", argv[1]); |
374 exit(3); | 411 exit(3); |
375 } | 412 } |
376 } | 413 } |
377 | 414 |
378 // Results to stdout. | 415 // Results to stdout. |
379 | 416 |
380 double averageTime = totalTime / static_cast<double>(iterations); | 417 double averageTime = totalTime / static_cast<double>(iterations); |
381 printf("%f %f\n", totalTime, averageTime); | 418 printf("%f %f\n", totalTime, averageTime); |
382 return 0; | 419 return 0; |
383 } | 420 } |
OLD | NEW |