blob: 63673051f7a638874961f25ae84d46750ad7a601 [file] [log] [blame]
// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <memory>
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/loader/image/image_decoder.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/renderer_module.h"
#include "cobalt/system_window/system_window.h"
#include "cobalt/trace_event/scoped_trace_to_file.h"
namespace cobalt {
namespace loader {
namespace image {
namespace sandbox {
namespace {
const int kViewportWidth = 1920;
const int kViewportHeight = 1080;
using base::FileEnumerator;
using render_tree::ResourceProvider;
using renderer::RendererModule;
using system_window::SystemWindow;
struct ImageDecoderCallback {
void SuccessCallback(const scoped_refptr<loader::image::Image>& value) {
image = value;
}
void LoadCompleteCallback(const base::Optional<std::string>& error) {
if (error) LOG(ERROR) << *error;
}
scoped_refptr<loader::image::Image> image;
};
std::vector<base::FilePath> GetImagePaths(const char* extention) {
base::FilePath image_path;
CHECK(base::PathService::Get(base::DIR_TEST_DATA, &image_path));
image_path = image_path.Append(FILE_PATH_LITERAL("cobalt"))
.Append(FILE_PATH_LITERAL("loader"))
.Append(FILE_PATH_LITERAL("testdata"));
std::vector<base::FilePath> result;
FileEnumerator file_enumerator(image_path, false /* Not recursive */,
FileEnumerator::FILES);
for (base::FilePath next = file_enumerator.Next(); !next.empty();
next = file_enumerator.Next()) {
if (next.Extension() == extention) {
result.push_back(next);
}
}
return result;
}
std::vector<uint8> GetFileContent(const base::FilePath& file_path) {
int64 size;
std::vector<uint8> data;
bool success = base::GetFileSize(file_path, &size);
CHECK(success) << "Could not get file size.";
CHECK_GT(size, 0);
data.resize(static_cast<size_t>(size));
int num_of_bytes = base::ReadFile(
file_path, reinterpret_cast<char*>(&data[0]), static_cast<int>(size));
CHECK_EQ(num_of_bytes, data.size())
<< "Could not read '" << file_path.value() << "'.";
return data;
}
void DecodeImages(ResourceProvider* resource_provider, const char* extension) {
std::vector<base::FilePath> paths = GetImagePaths(extension);
base::TimeDelta total_time;
size_t total_size = 0;
for (size_t i = 0; i < paths.size(); ++i) {
base::NullDebuggerHooks debugger_hooks;
ImageDecoderCallback image_decoder_result;
std::vector<uint8> image_data = GetFileContent(paths[i]);
base::Time start = base::Time::Now();
std::unique_ptr<Decoder> image_decoder(
new ImageDecoder(resource_provider, debugger_hooks,
base::Bind(&ImageDecoderCallback::SuccessCallback,
base::Unretained(&image_decoder_result)),
base::Bind(&ImageDecoderCallback::LoadCompleteCallback,
base::Unretained(&image_decoder_result))));
image_decoder->DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
image_data.size());
image_decoder->Finish();
if (image_decoder_result.image) {
base::TimeDelta decoding_time = base::Time::Now() - start;
total_time += decoding_time;
total_size += image_decoder_result.image->GetEstimatedSizeInBytes();
LOG(INFO) << "Decoding " << paths[i].BaseName().value() << " takes "
<< decoding_time.InMicroseconds() << " microseconds";
}
}
if (total_time.InMicroseconds() != 0) {
LOG(INFO) << "Average decoding speed for type \"" << extension << "\" is "
<< total_size * base::Time::kMicrosecondsPerSecond /
total_time.InMicroseconds()
<< " byte per seconds";
}
}
int SandboxMain(int argc, char** argv) {
cobalt::trace_event::ScopedTraceToFile trace_to_file(
base::FilePath(FILE_PATH_LITERAL("image_decoder_sandbox_trace.json")));
math::Size view_size(kViewportWidth, kViewportHeight);
base::EventDispatcher event_dispatcher;
// Create a system window to use as a render target.
std::unique_ptr<SystemWindow> system_window(
new cobalt::system_window::SystemWindow(&event_dispatcher, view_size));
// Construct a renderer module using default options.
RendererModule::Options renderer_module_options;
RendererModule renderer_module(system_window.get(), renderer_module_options);
// Try to decode all images in the given folder.
ResourceProvider* resource_provider =
renderer_module.pipeline()->GetResourceProvider();
DecodeImages(resource_provider, ".jpg");
DecodeImages(resource_provider, ".png");
DecodeImages(resource_provider, ".webp");
return 0;
}
} // namespace
} // namespace sandbox
} // namespace image
} // namespace loader
} // namespace cobalt
COBALT_WRAP_SIMPLE_MAIN(cobalt::loader::image::sandbox::SandboxMain);