Commit 1c320598 authored by Miguel Casas's avatar Miguel Casas Committed by Commit Bot

blink image_decode_bench: use more Chromium stuff

This CL refactors image_decode_bench:
- Rewrites function ReadFile() to use base::FilePath etc.
- Configures the Logging and changes fprintf/stderr to LOG()
 statements, and exit()s into LOG_ASSERT().
- Names the constant kDefaultDecodeTimes.
- s/DecodeError/PrintErrorAndExit/ to clarify what it does.
- Changes uses of CurrentTimeTicks() with base::ElapsedTimer,
 and uses TimeDelta ISO double to count the elapsed time.
- Uses perf_test::PrintResult to add info about the image
 (size and #pixels), when a new parameter (-v / -verbose)
 is specified after the current two parameters, file and
 #iterations; output is e.g.:
*RESULT decode_time /usr/local/google/home/mcasas/Pictures/4.webp: 100 times 790528 pixels (1024x772)= 66.27827 ms/sample

Bug: 889898
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ic0a66d2aa3d2f08b13c8af99aed31e61d7246dec
Reviewed-on: https://chromium-review.googlesource.com/c/1225653
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarLeon Scroggins <scroggo@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#598803}
parent 7f08809a
...@@ -1865,6 +1865,7 @@ jumbo_source_set("blink_platform_unittests_sources") { ...@@ -1865,6 +1865,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
} }
executable("image_decode_bench") { executable("image_decode_bench") {
testonly = true
visibility = [] # Allow re-assignment of list. visibility = [] # Allow re-assignment of list.
visibility = [ "*" ] visibility = [ "*" ]
...@@ -1874,7 +1875,9 @@ executable("image_decode_bench") { ...@@ -1874,7 +1875,9 @@ executable("image_decode_bench") {
deps = [ deps = [
":platform", ":platform",
"//base",
"//mojo/core/embedder", "//mojo/core/embedder",
"//testing/perf",
"//third_party/blink/renderer/platform/wtf", "//third_party/blink/renderer/platform/wtf",
] ]
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// clocks to measure image decode time. Basic usage: // clocks to measure image decode time. Basic usage:
// //
// % ninja -C out/Release image_decode_bench && // % ninja -C out/Release image_decode_bench &&
// ./out/Release/image_decode_bench file [iterations] // ./out/Release/image_decode_bench file [iterations [-v,-verbose]]
// //
// TODO(noel): Consider adding md5 checksum support to WTF. Use it to compute // TODO(noel): Consider adding md5 checksum support to WTF. Use it to compute
// the decoded image frame md5 and output that value. // the decoded image frame md5 and output that value.
...@@ -19,9 +19,13 @@ ...@@ -19,9 +19,13 @@
#include <fstream> #include <fstream>
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
#include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/embedder.h"
#include "testing/perf/perf_test.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h" #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/shared_buffer.h"
...@@ -32,34 +36,14 @@ namespace blink { ...@@ -32,34 +36,14 @@ namespace blink {
namespace { namespace {
scoped_refptr<SharedBuffer> ReadFile(const char* name) { constexpr size_t kDefaultDecodeTimes = 1;
std::ifstream file(name, std::ios::in | std::ios::binary);
if (!file) {
fprintf(stderr, "Cannot open file %s\n", name);
exit(2);
}
file.seekg(0, std::ios::end);
std::streampos file_size = file.tellg();
file.seekg(0, std::ios::beg);
if (!file || file_size <= 0) {
fprintf(stderr, "Error seeking file %s\n", name);
exit(2);
}
if (file_size > std::numeric_limits<wtf_size_t>::max()) { scoped_refptr<SharedBuffer> ReadFile(const char* name) {
fprintf(stderr, "File size too large %s\n", name); std::string file_contents;
exit(2); const auto file_path = base::FilePath(name);
} if (!base::ReadFileToString(file_path, &file_contents))
PLOG(FATAL) << "file name: " << name;
Vector<char> buffer(static_cast<wtf_size_t>(file_size)); return SharedBuffer::Create(file_contents.data(), file_contents.size());
if (!file.read(buffer.data(), file_size)) {
fprintf(stderr, "Error reading file %s\n", name);
exit(2);
}
return SharedBuffer::AdoptVector(buffer);
} }
struct ImageMeta { struct ImageMeta {
...@@ -67,66 +51,64 @@ struct ImageMeta { ...@@ -67,66 +51,64 @@ struct ImageMeta {
int width; int width;
int height; int height;
int frames; int frames;
// Cumulative time in seconds to decode all frames.
double time;
}; };
void DecodeFailure(ImageMeta* image) { void PrintErrorAndExit(ImageMeta* image) {
fprintf(stderr, "Failed to decode image %s\n", image->name); LOG_ASSERT(false) << "Failed to decode image " << image->name;
exit(3);
} }
void DecodeImageData(SharedBuffer* data, ImageMeta* image) { base::TimeDelta DecodeImageData(SharedBuffer* data, ImageMeta* image) {
const bool data_complete = true; constexpr bool data_complete = true;
std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create( std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
data, data_complete, ImageDecoder::kAlphaPremultiplied, data, data_complete, ImageDecoder::kAlphaPremultiplied,
ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()); ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore());
auto start = CurrentTimeTicks(); base::ElapsedTimer timer;
bool all_data_received = true; bool all_data_received = true;
decoder->SetData(data, all_data_received); decoder->SetData(data, all_data_received);
size_t frame_count = decoder->FrameCount(); size_t frame_count = decoder->FrameCount();
for (size_t index = 0; index < frame_count; ++index) { for (size_t index = 0; index < frame_count; ++index) {
if (!decoder->DecodeFrameBufferAtIndex(index)) if (!decoder->DecodeFrameBufferAtIndex(index))
DecodeFailure(image); PrintErrorAndExit(image);
} }
image->time += (CurrentTimeTicks() - start).InSecondsF(); const auto elapsed_time = timer.Elapsed();
if (!frame_count || decoder->Failed()) if (!frame_count || decoder->Failed())
DecodeFailure(image); PrintErrorAndExit(image);
image->width = decoder->Size().Width(); image->width = decoder->Size().Width();
image->height = decoder->Size().Height(); image->height = decoder->Size().Height();
image->frames = frame_count; image->frames = frame_count;
return elapsed_time;
} }
} // namespace } // namespace
int ImageDecodeBenchMain(int argc, char* argv[]) { void ImageDecodeBenchMain(int argc, char* argv[]) {
base::CommandLine::Init(argc, argv); base::CommandLine::Init(argc, argv);
const char* program = argv[0]; const char* program = argv[0];
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s file [iterations]\n", program); LOG(INFO) << "Usage: " << program << " file [iterations [-v,-verbose]]";
exit(1); exit(1);
} }
// Control bench decode iterations. // Control bench decode iterations.
size_t decode_iterations = kDefaultDecodeTimes;
size_t decode_iterations = 1; bool verbose_mode = false;
if (argc >= 3) { if (argc >= 3) {
char* end = nullptr; char* end = nullptr;
decode_iterations = strtol(argv[2], &end, 10); decode_iterations = strtol(argv[2], &end, 10);
if (*end != '\0' || !decode_iterations) { if (*end != '\0' || !decode_iterations) {
fprintf(stderr, LOG_ASSERT(false) << "Second argument should be number of iterations. "
"Second argument should be number of iterations. " << "The default is 1. You supplied " << argv[2];
"The default is 1. You supplied %s\n",
argv[2]);
exit(1);
} }
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
DCHECK(cmd_line);
verbose_mode = cmd_line->HasSwitch("v") || cmd_line->HasSwitch("verbose");
} }
std::unique_ptr<Platform> platform = std::make_unique<Platform>(); std::unique_ptr<Platform> platform = std::make_unique<Platform>();
...@@ -134,25 +116,26 @@ int ImageDecodeBenchMain(int argc, char* argv[]) { ...@@ -134,25 +116,26 @@ int ImageDecodeBenchMain(int argc, char* argv[]) {
// Read entire file content into |data| (a contiguous block of memory) then // Read entire file content into |data| (a contiguous block of memory) then
// decode it to verify the image and record its ImageMeta data. // decode it to verify the image and record its ImageMeta data.
ImageMeta image = {.name = argv[1]};
ImageMeta image = {argv[1], 0, 0, 0, 0};
scoped_refptr<SharedBuffer> data = ReadFile(argv[1]); scoped_refptr<SharedBuffer> data = ReadFile(argv[1]);
DecodeImageData(data.get(), &image); DecodeImageData(data.get(), &image);
// Image decode bench for decode_iterations. // Image decode bench for |decode_iterations|.
base::TimeDelta total_time;
double total_time = 0.0; for (size_t i = 0; i < decode_iterations; ++i)
for (size_t i = 0; i < decode_iterations; ++i) { total_time += DecodeImageData(data.get(), &image);
image.time = 0.0;
DecodeImageData(data.get(), &image); if (verbose_mode) {
total_time += image.time; perf_test::PrintResult(
"decode_time ", argv[1],
base::StringPrintf("%zu times %d pixels (%dx%d)", decode_iterations,
image.width * image.height, image.width,
image.height),
total_time.InMillisecondsF() / decode_iterations, "ms/sample", true);
} else {
printf("%f %f\n", total_time.InSecondsF(),
total_time.InSecondsF() / decode_iterations);
} }
// Results to stdout.
double average_time = total_time / decode_iterations;
printf("%f %f\n", total_time, average_time);
return 0;
} }
} // namespace blink } // namespace blink
...@@ -160,5 +143,8 @@ int ImageDecodeBenchMain(int argc, char* argv[]) { ...@@ -160,5 +143,8 @@ int ImageDecodeBenchMain(int argc, char* argv[]) {
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
base::MessageLoop message_loop; base::MessageLoop message_loop;
mojo::core::Init(); mojo::core::Init();
return blink::ImageDecodeBenchMain(argc, argv); base::CommandLine::Init(argc, argv);
LOG_ASSERT(logging::InitLogging(logging::LoggingSettings()));
blink::ImageDecodeBenchMain(argc, argv);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment