blob: 62b3efcef662178ac4657f95b126d26b8e2b814a [file] [log] [blame]
/*
* Copyright 2017 Google Inc. 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 "cobalt/browser/memory_settings/pretty_print.h"
#include <algorithm>
#include <string>
#include <vector>
#include "base/string_split.h"
#include "cobalt/browser/memory_settings/memory_settings.h"
#include "cobalt/browser/memory_settings/table_printer.h"
#include "starboard/log.h"
#include "starboard/string.h"
namespace cobalt {
namespace browser {
namespace memory_settings {
namespace {
std::string StringifyMemoryType(const MemorySetting& setting) {
switch (setting.memory_type()) {
case MemorySetting::kCPU: {
return "CPU";
}
case MemorySetting::kGPU: {
return "GPU";
}
case MemorySetting::kNotApplicable: {
return "N/A";
}
}
SB_NOTIMPLEMENTED() << "Unimplemented string for memory type: "
<< setting.memory_type();
return "UNKNOWN";
}
std::string StringifyValue(const MemorySetting* setting) {
if (!setting->valid()) {
return "N/A";
}
return setting->ValueToString();
}
void FillStream(size_t count, const char fill_ch, std::stringstream* ss) {
for (size_t i = 0; i < count; ++i) {
(*ss) << fill_ch;
}
}
} // namespace
std::string GeneratePrettyPrintTable(
bool use_color_ascii,
const std::vector<const MemorySetting*>& settings) {
TablePrinter printer;
if (use_color_ascii) {
printer.set_text_color(TablePrinter::kGreen);
}
std::vector<std::string> header;
header.push_back("SETTING NAME");
header.push_back("VALUE");
header.push_back("");
header.push_back("TYPE");
header.push_back("SOURCE");
printer.AddRow(header);
for (size_t i = 0; i < settings.size(); ++i) {
const MemorySetting* setting = settings[i];
std::vector<std::string> row;
row.push_back(setting->name());
row.push_back(StringifyValue(setting));
if (setting->valid()) {
row.push_back(ToMegabyteString(setting->MemoryConsumption(), 1));
} else {
row.push_back("N/A");
}
row.push_back(StringifyMemoryType(*setting));
row.push_back(StringifySourceType(*setting));
printer.AddRow(row);
}
std::string table_string = printer.ToString();
return table_string;
}
std::string GenerateMemoryTable(bool use_color_ascii,
const IntSetting& total_cpu_memory,
const IntSetting& total_gpu_memory,
int64_t settings_cpu_consumption,
int64_t settings_gpu_consumption) {
TablePrinter printer;
if (use_color_ascii) {
printer.set_text_color(TablePrinter::kGreen);
}
std::vector<std::string> header;
header.push_back("MEMORY");
header.push_back("SOURCE");
header.push_back("TOTAL");
header.push_back("SETTINGS CONSUME");
printer.AddRow(header);
std::vector<std::string> data_row;
data_row.push_back(total_cpu_memory.name());
data_row.push_back(StringifySourceType(total_cpu_memory));
data_row.push_back(ToMegabyteString(total_cpu_memory.value(), 1));
data_row.push_back(ToMegabyteString(settings_cpu_consumption, 1));
printer.AddRow(data_row);
data_row.clear();
data_row.push_back(total_gpu_memory.name());
data_row.push_back(StringifySourceType(total_gpu_memory));
std::string total_gpu_consumption_str;
const bool available_gpu_settings_invalid = (total_gpu_memory.value() <= 0);
if (available_gpu_settings_invalid) {
total_gpu_consumption_str = "<UNKNOWN>";
} else {
total_gpu_consumption_str = ToMegabyteString(total_gpu_memory.value(), 1);
}
data_row.push_back(total_gpu_consumption_str);
data_row.push_back(ToMegabyteString(settings_gpu_consumption, 1));
printer.AddRow(data_row);
data_row.clear();
return printer.ToString();
}
std::string ToMegabyteString(int64_t bytes, int decimal_places) {
float megabytes = bytes / (1024.0f * 1024.0f);
std::stringstream ss_fmt;
// e.g. "%.1f MB"
ss_fmt << "%." << decimal_places << "f MB";
char buff[128];
SbStringFormatF(buff, sizeof(buff), ss_fmt.str().c_str(), megabytes);
// Use 16
return std::string(buff);
}
std::string MakeBorder(const std::string& body, const char border_ch) {
std::vector<std::string> lines;
base::SplitStringDontTrim(body, '\n', &lines);
size_t max_span = 0;
for (size_t i = 0; i < lines.size(); ++i) {
max_span = std::max(max_span, lines[i].size());
}
std::stringstream ss;
ss << "\n\n";
FillStream(max_span + 4, border_ch, &ss);
ss << "\n";
for (size_t i = 0; i < lines.size(); ++i) {
const std::string& line = lines[i];
ss << border_ch << ' ' << line;
FillStream(max_span - line.size() + 1, ' ', &ss);
ss << border_ch;
ss << "\n";
}
FillStream(max_span + 4, border_ch, &ss);
ss << "\n\n";
return ss.str();
}
std::string StringifySourceType(const MemorySetting& setting) {
if (setting.memory_type() == MemorySetting::kNotApplicable) {
return "N/A";
}
switch (setting.source_type()) {
case MemorySetting::kUnset: {
return "Unset";
}
case MemorySetting::kStarboardAPI: {
return "Starboard API";
}
case MemorySetting::kBuildSetting: {
return "Build";
}
case MemorySetting::kCmdLine: {
return "CmdLine";
}
case MemorySetting::kAutoSet: {
return "AutoSet";
}
case MemorySetting::kAutosetConstrained: {
return "AutoSet (Constrained)";
}
}
SB_NOTIMPLEMENTED() << "Unimplemented string for type: "
<< setting.source_type();
return "UNKNOWN";
}
} // namespace memory_settings
} // namespace browser
} // namespace cobalt