| /* |
| * 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/memory_settings.h" |
| |
| #include <algorithm> |
| #include <locale> |
| #include <string> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "base/stringprintf.h" |
| #include "cobalt/browser/memory_settings/constants.h" |
| #include "cobalt/browser/switches.h" |
| #include "cobalt/math/linear_interpolator.h" |
| |
| namespace cobalt { |
| namespace browser { |
| namespace memory_settings { |
| |
| void MemorySetting::set_memory_scaling_function(ScalingFunction function) { |
| memory_scaling_function_ = function; |
| } |
| |
| double MemorySetting::ComputeAbsoluteMemoryScale( |
| double requested_memory_scale) const { |
| if (memory_scaling_function_.is_null()) { |
| return 1.0; |
| } else { |
| return memory_scaling_function_.Run(requested_memory_scale); |
| } |
| } |
| |
| MemorySetting::MemorySetting(ClassType type, const std::string& name) |
| : class_type_(type), |
| name_(name), |
| source_type_(kUnset), |
| memory_type_(kCPU) {} |
| |
| IntSetting::IntSetting(const std::string& name) |
| : MemorySetting(kInt, name), value_() {} |
| |
| std::string IntSetting::ValueToString() const { |
| std::stringstream ss; |
| ss << value(); |
| return ss.str(); |
| } |
| |
| int64_t IntSetting::MemoryConsumption() const { return value(); } |
| |
| void IntSetting::ScaleMemory(double memory_scale) { |
| DCHECK_LE(0.0, memory_scale); |
| DCHECK_LE(memory_scale, 1.0); |
| |
| const int64_t new_value = static_cast<int64_t>(value() * memory_scale); |
| set_value(MemorySetting::kAutosetConstrained, new_value); |
| } |
| |
| DimensionSetting::DimensionSetting(const std::string& name) |
| : MemorySetting(kDimensions, name) {} |
| |
| std::string DimensionSetting::ValueToString() const { |
| std::stringstream ss; |
| TextureDimensions value_data = value(); |
| ss << value_data.width() << "x" << value_data.height() << "x" |
| << value_data.bytes_per_pixel(); |
| return ss.str(); |
| } |
| |
| int64_t DimensionSetting::MemoryConsumption() const { |
| return value().TotalBytes(); |
| } |
| |
| SkiaGlyphAtlasTextureSetting::SkiaGlyphAtlasTextureSetting() |
| : DimensionSetting(switches::kSkiaTextureAtlasDimensions) { |
| set_memory_scaling_function(MakeSkiaGlyphAtlasMemoryScaler()); |
| } |
| |
| void SkiaGlyphAtlasTextureSetting::ScaleMemory(double memory_scale) { |
| DCHECK_LE(0.0, memory_scale); |
| DCHECK_LE(memory_scale, 1.0); |
| |
| if (!valid()) { |
| return; |
| } |
| const size_t number_of_reductions = NumberOfReductions(memory_scale); |
| if (number_of_reductions == 0) { |
| return; |
| } |
| |
| TextureDimensions texture_dims = value(); |
| DCHECK_LT(0, texture_dims.width()); |
| DCHECK_LT(0, texture_dims.height()); |
| |
| for (size_t i = 0; i < number_of_reductions; ++i) { |
| if (texture_dims.width() <= 1 && texture_dims.height() <=1) { |
| break; |
| } |
| if (texture_dims.width() > texture_dims.height()) { |
| texture_dims.set_width(texture_dims.width() / 2); |
| } else { |
| texture_dims.set_height(texture_dims.height() / 2); |
| } |
| } |
| |
| set_value(MemorySetting::kAutosetConstrained, texture_dims); |
| } |
| |
| size_t SkiaGlyphAtlasTextureSetting::NumberOfReductions( |
| double reduction_factor) { |
| size_t num_of_reductions = 0; |
| while (reduction_factor <= 0.5f) { |
| ++num_of_reductions; |
| reduction_factor *= 2.0; |
| } |
| return num_of_reductions; |
| } |
| |
| JavaScriptGcThresholdSetting::JavaScriptGcThresholdSetting() |
| : IntSetting(switches::kJavaScriptGcThresholdInBytes) { |
| } |
| |
| void JavaScriptGcThresholdSetting::PostInit() { |
| const int64_t normal_memory_consumption = MemoryConsumption(); |
| const int64_t min_memory_consumption = |
| std::min<int64_t>(normal_memory_consumption, 1 * 1024 * 1024); |
| |
| ScalingFunction function = |
| MakeJavaScriptGCScaler(min_memory_consumption, |
| normal_memory_consumption); |
| set_memory_scaling_function(function); |
| } |
| |
| int64_t SumMemoryConsumption( |
| base::optional<MemorySetting::MemoryType> memory_type_filter, |
| const std::vector<const MemorySetting*>& memory_settings) { |
| int64_t sum = 0; |
| for (size_t i = 0; i < memory_settings.size(); ++i) { |
| const MemorySetting* setting = memory_settings[i]; |
| if (!memory_type_filter || memory_type_filter == setting->memory_type()) { |
| sum += setting->MemoryConsumption(); |
| } |
| } |
| return sum; |
| } |
| |
| int64_t SumMemoryConsumption( |
| base::optional<MemorySetting::MemoryType> memory_type_filter, |
| const std::vector<MemorySetting*>& memory_settings) { |
| const std::vector<const MemorySetting*> const_vector( |
| memory_settings.begin(), memory_settings.end()); |
| return SumMemoryConsumption(memory_type_filter, const_vector); |
| } |
| |
| } // namespace memory_settings |
| } // namespace browser |
| } // namespace cobalt |