| /* |
| * 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/auto_mem.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/optional.h" |
| #include "cobalt/browser/memory_settings/auto_mem_settings.h" |
| #include "cobalt/browser/memory_settings/calculations.h" |
| #include "cobalt/browser/memory_settings/test_common.h" |
| #include "cobalt/browser/switches.h" |
| #include "cobalt/math/size.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace cobalt { |
| namespace browser { |
| namespace memory_settings { |
| namespace { |
| |
| const math::Size kResolution1080p(1920, 1080); |
| |
| // Represents what the cobalt engine can scale down to under a default |
| // environment. |
| const int64_t kSmallEngineCpuMemorySize = 130 * 1024 * 1024; |
| |
| const int64_t kSmallEngineGpuMemorySize = 68 * 1024 * 1024; |
| |
| #define EXPECT_MEMORY_SETTING(SETTING, SOURCE, MEMORY_TYPE, VALUE) \ |
| EXPECT_EQ(VALUE, SETTING->value()) << " failure for " << SETTING->name(); \ |
| EXPECT_EQ(MEMORY_TYPE, SETTING->memory_type()) << "failure for " \ |
| << SETTING->memory_type(); \ |
| EXPECT_EQ(SOURCE, SETTING->source_type()) << " failure for " \ |
| << SETTING->name(); |
| |
| AutoMemSettings EmptyCommandLine() { |
| return AutoMemSettings(AutoMemSettings::kTypeCommandLine); |
| } |
| |
| scoped_ptr<AutoMem> CreateDefaultAutoMem() { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| scoped_ptr<AutoMem> auto_mem( |
| new AutoMem(kResolution1080p, EmptyCommandLine(), build_settings)); |
| return auto_mem.Pass(); |
| } |
| |
| } // namespace. |
| |
| // Tests the expectation that the command-line overrides will be applied. |
| // Settings which are enabled/disabled when blitter is enabled/disabled are |
| // also tested. |
| TEST(AutoMem, CommandLineOverrides) { |
| // Load up command line settings of command lines. |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| command_line_settings.cobalt_image_cache_size_in_bytes = 1234; |
| command_line_settings.javascript_garbage_collection_threshold_in_bytes = 2345; |
| command_line_settings.skia_cache_size_in_bytes = 3456; |
| command_line_settings.skia_texture_atlas_dimensions = |
| TextureDimensions(1234, 5678, 2); |
| command_line_settings.software_surface_cache_size_in_bytes = 4567; |
| command_line_settings.offscreen_target_cache_size_in_bytes = 5678; |
| |
| for (int i = 0; i <= 1; ++i) { |
| AutoMemSettings build_settings = GetDefaultBuildSettings(); |
| build_settings.has_blitter = (i == 0); |
| |
| AutoMem auto_mem(kResolution1080p, command_line_settings, build_settings); |
| |
| // image_cache_size_in_bytes and javascript_gc_threshold_in_bytes settings |
| // ignore the blitter type. |
| EXPECT_MEMORY_SETTING(auto_mem.image_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, MemorySetting::kGPU, 1234); |
| |
| EXPECT_MEMORY_SETTING(auto_mem.javascript_gc_threshold_in_bytes(), |
| MemorySetting::kCmdLine, MemorySetting::kCPU, 2345); |
| |
| if (auto_mem.offscreen_target_cache_size_in_bytes()->valid()) { |
| EXPECT_MEMORY_SETTING(auto_mem.offscreen_target_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, MemorySetting::kGPU, 5678); |
| } |
| |
| // Certain features are only available for the blitter, and some features |
| // are disabled, vice versa. |
| if (build_settings.has_blitter) { |
| // When blitter is active then skia_atlas_texture_dimensions are |
| // not applicable because this is an OpenGl egl feature. |
| EXPECT_MEMORY_SETTING( |
| auto_mem.skia_atlas_texture_dimensions(), MemorySetting::kCmdLine, |
| MemorySetting::kNotApplicable, TextureDimensions(0, 0, 0)); |
| // Skia cache is also an egl-only feature, which is not applicable |
| // for blitter. |
| EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, |
| MemorySetting::kNotApplicable, 0); |
| |
| EXPECT_MEMORY_SETTING(auto_mem.software_surface_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, MemorySetting::kCPU, 4567); |
| } else { |
| // Skia atlas is an egl-only feature and therefore enabled. |
| EXPECT_MEMORY_SETTING(auto_mem.skia_atlas_texture_dimensions(), |
| MemorySetting::kCmdLine, MemorySetting::kGPU, |
| TextureDimensions(1234, 5678, 2)); |
| |
| // Skia cache is an egl-only feature therefore it is enabled for egl. |
| EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, MemorySetting::kGPU, 3456); |
| |
| // Software surface cache is a blitter-only feature, therefore disabled |
| // in egl. |
| EXPECT_MEMORY_SETTING(auto_mem.software_surface_cache_size_in_bytes(), |
| MemorySetting::kCmdLine, |
| MemorySetting::kNotApplicable, 0); |
| } |
| } |
| } |
| |
| // Tests the expectation that if the command line specifies that the variable |
| // is "autoset" that the builtin setting is overriden. |
| TEST(AutoMem, CommandLineSpecifiesAutoset) { |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| command_line_settings.cobalt_image_cache_size_in_bytes = -1; |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| build_settings.cobalt_image_cache_size_in_bytes = 1234; |
| |
| AutoMem auto_mem(kResolution1080p, command_line_settings, build_settings); |
| |
| EXPECT_MEMORY_SETTING(auto_mem.image_cache_size_in_bytes(), |
| MemorySetting::kAutoSet, MemorySetting::kGPU, |
| CalculateImageCacheSize(kResolution1080p)); |
| } |
| |
| // Tests that skia atlas texture will be bind to the built in value, iff it has |
| // been set. |
| TEST(AutoMem, SkiaGlyphAtlasTextureSize) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild); |
| |
| build_settings_with_default.skia_texture_atlas_dimensions = |
| TextureDimensions(1234, 5678, 2); |
| |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| AutoMem auto_mem_with_default(kResolution1080p, EmptyCommandLine(), |
| build_settings_with_default); |
| |
| // Expect that when the skia_atlas_texture_dimensions is specified in the |
| // build settings that it will bind to the auto-set value (computed from |
| // CalculateSkiaGlyphAtlasTextureSize(...)). |
| EXPECT_MEMORY_SETTING(auto_mem.skia_atlas_texture_dimensions(), |
| MemorySetting::kAutoSet, MemorySetting::kGPU, |
| CalculateSkiaGlyphAtlasTextureSize(kResolution1080p)); |
| |
| // Expect that when the skia_atlas_texture_dimensions is specified in the |
| // build settings that it will bind to the final value. |
| EXPECT_MEMORY_SETTING(auto_mem_with_default.skia_atlas_texture_dimensions(), |
| MemorySetting::kBuildSetting, MemorySetting::kGPU, |
| TextureDimensions(1234, 5678, 2)); |
| } |
| |
| // Tests that software surface cache will be bind to the built in value, iff |
| // it has been set. |
| TEST(AutoMem, SoftwareSurfaceCacheSizeInBytes) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild); |
| // Enable the setting by enabling the blitter. |
| build_settings.has_blitter = true; |
| build_settings_with_default.has_blitter = true; |
| build_settings_with_default.software_surface_cache_size_in_bytes = 1234; |
| |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| AutoMem auto_mem_with_surface_cache(kResolution1080p, EmptyCommandLine(), |
| build_settings_with_default); |
| |
| // Expect that when the software_surface_cache_size_in_bytes is specified in |
| // the/ build settings that it will bind to the auto-set value (computed from |
| // CalculateSoftwareSurfaceCacheSizeInBytes(...)). |
| EXPECT_MEMORY_SETTING( |
| auto_mem.software_surface_cache_size_in_bytes(), MemorySetting::kAutoSet, |
| MemorySetting::kCPU, |
| CalculateSoftwareSurfaceCacheSizeInBytes(kResolution1080p)); |
| |
| EXPECT_MEMORY_SETTING( |
| auto_mem_with_surface_cache.software_surface_cache_size_in_bytes(), |
| MemorySetting::kBuildSetting, MemorySetting::kCPU, 1234); |
| } |
| |
| // Tests that skia cache will be bind to the built in value, iff |
| // it has been set. |
| TEST(AutoMem, SkiaCacheSizeInBytes) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| AutoMemSettings build_settings_with_default(AutoMemSettings::kTypeBuild); |
| build_settings_with_default.skia_cache_size_in_bytes = 1234; |
| |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| AutoMem auto_mem_with_skia_cache(kResolution1080p, EmptyCommandLine(), |
| build_settings_with_default); |
| |
| EXPECT_MEMORY_SETTING(auto_mem.skia_cache_size_in_bytes(), |
| MemorySetting::kAutoSet, MemorySetting::kGPU, |
| CalculateSkiaCacheSize(kResolution1080p)); |
| |
| EXPECT_MEMORY_SETTING(auto_mem_with_skia_cache.skia_cache_size_in_bytes(), |
| MemorySetting::kBuildSetting, MemorySetting::kGPU, |
| 1234); |
| } |
| |
| TEST(AutoMem, AllMemorySettingsAreOrderedByName) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| |
| std::vector<const MemorySetting*> settings = auto_mem.AllMemorySettings(); |
| |
| for (size_t i = 1; i < settings.size(); ++i) { |
| ASSERT_LT(settings[i-1]->name(), settings[i]->name()); |
| } |
| } |
| |
| // Tests the expectation that constraining the CPU memory to kSmallEngineSize |
| // will result in AutoMem reducing to the expected memory footprint. |
| TEST(AutoMem, ConstrainedCPUEnvironment) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| build_settings.max_cpu_in_bytes = kSmallEngineCpuMemorySize; |
| |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| |
| const int64_t cpu_memory_consumption = |
| auto_mem.SumAllMemoryOfType(MemorySetting::kCPU); |
| EXPECT_LE(cpu_memory_consumption, kSmallEngineCpuMemorySize); |
| } |
| |
| // Tests the expectation that constraining the GPU memory will result |
| // in AutoMem reducing the the memory footprint. |
| TEST(AutoMem, ConstrainedGPUEnvironment) { |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| build_settings.max_gpu_in_bytes = 57 * 1024 * 1024; |
| AutoMem auto_mem(kResolution1080p, EmptyCommandLine(), build_settings); |
| |
| std::vector<const MemorySetting*> settings = auto_mem.AllMemorySettings(); |
| const int64_t gpu_memory_consumption = |
| SumMemoryConsumption(MemorySetting::kGPU, settings); |
| EXPECT_LE(gpu_memory_consumption, *build_settings.max_gpu_in_bytes); |
| } |
| |
| // Tests the expectation that constraining the CPU memory to 40MB will result |
| // in AutoMem reducing the the memory footprint. |
| TEST(AutoMem, ExplicitReducedCPUMemoryConsumption) { |
| // STEP ONE: Get the "natural" size of the engine at the default test |
| // settings. |
| scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem(); |
| |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024; |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings, |
| build_settings); |
| |
| EXPECT_EQ(5 * 1024 * 1024, |
| reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value()); |
| |
| const int64_t original_memory_consumption = |
| default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU); |
| const int64_t reduced_memory_consumption = |
| reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU); |
| |
| EXPECT_LE(5 * 1024 * 1024, |
| original_memory_consumption - reduced_memory_consumption); |
| } |
| |
| // Tests the expectation that constraining the CPU memory to 40MB will result |
| // in AutoMem reducing the the memory footprint. |
| TEST(AutoMem, ExplicitReducedGPUMemoryConsumption) { |
| // STEP ONE: Get the "natural" size of the engine at the default test |
| // settings. |
| scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem(); |
| |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| command_line_settings.reduce_gpu_memory_by = 5 * 1024 * 1024; |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings, |
| build_settings); |
| EXPECT_EQ(5 * 1024 * 1024, |
| reduced_cpu_memory_auto_mem.reduced_gpu_bytes_->value()); |
| |
| const int64_t original_memory_consumption = |
| default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU); |
| const int64_t reduced_memory_consumption = |
| reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kGPU); |
| |
| EXPECT_LE(5 * 1024 * 1024, |
| original_memory_consumption - reduced_memory_consumption); |
| } |
| |
| // Tests the expectation that the max cpu value is ignored when reducing |
| // memory. |
| TEST(AutoMem, MaxCpuIsIgnoredDuringExplicitMemoryReduction) { |
| // STEP ONE: Get the "natural" size of the engine at the default test |
| // settings. |
| scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem(); |
| |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| command_line_settings.reduce_cpu_memory_by = 5 * 1024 * 1024; |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| build_settings.max_cpu_in_bytes = 1; |
| AutoMem reduced_cpu_memory_auto_mem(kResolution1080p, command_line_settings, |
| build_settings); |
| |
| EXPECT_EQ(5 * 1024 * 1024, |
| reduced_cpu_memory_auto_mem.reduced_cpu_bytes_->value()); |
| |
| const int64_t original_memory_consumption = |
| default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU); |
| const int64_t reduced_memory_consumption = |
| reduced_cpu_memory_auto_mem.SumAllMemoryOfType(MemorySetting::kCPU); |
| |
| // Max_cpu_in_bytes specifies one byte of memory, but reduce must override |
| // this for this test to pass. |
| EXPECT_LE(5 * 1024 * 1024, |
| original_memory_consumption - reduced_memory_consumption); |
| } |
| |
| // Tests the expectation that the constrainer will not run on cpu memory if |
| // --reduce_cpu_memory_by is set to 0. |
| TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceCPUCommand) { |
| // STEP ONE: Get the "natural" size of the engine at the default test |
| // settings. |
| scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem(); |
| |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will |
| // override the max_cpu_in_bytes setting. |
| build_settings.max_cpu_in_bytes = 1; |
| command_line_settings.reduce_cpu_memory_by = 0; |
| |
| AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings, |
| build_settings); |
| |
| const int64_t original_memory_consumption = |
| default_auto_mem->SumAllMemoryOfType(MemorySetting::kCPU); |
| const int64_t new_memory_consumption = |
| auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU); |
| |
| // Max_cpu_in_bytes specifies one byte of memory, but reduce must override |
| // this for this test to pass. |
| EXPECT_EQ(original_memory_consumption, new_memory_consumption); |
| } |
| |
| // Tests the expectation that the constrainer will not run on gpu memory if |
| // --reduce_gpu_memory_by is set to 0. |
| TEST(AutoMem, MaxCpuIsIgnoredWithZeroValueReduceGPUCommand) { |
| // STEP ONE: Get the "natural" size of the engine at the default test |
| // settings. |
| scoped_ptr<AutoMem> default_auto_mem = CreateDefaultAutoMem(); |
| |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "0" will |
| // override the max_cpu_in_bytes setting. |
| build_settings.max_gpu_in_bytes = 1; |
| command_line_settings.reduce_gpu_memory_by = 0; |
| |
| AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings, |
| build_settings); |
| |
| const int64_t original_memory_consumption = |
| default_auto_mem->SumAllMemoryOfType(MemorySetting::kGPU); |
| const int64_t new_memory_consumption = |
| auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU); |
| |
| // Max_gpu_in_bytes specifies one byte of memory, but reduce must override |
| // this for this test to pass. |
| EXPECT_EQ(original_memory_consumption, new_memory_consumption); |
| } |
| |
| // Tests the expectation that if --reduce_cpu_memory_by is set to -1 that it |
| // will be effectively disabled and --max_cpu_bytes be used as the memory |
| // reduction means. |
| TEST(AutoMem, MaxCpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) { |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1" |
| // passed to the command line will cause max_cpu_in_bytes to be the |
| // dominating memory reduction mechanism. |
| build_settings.max_cpu_in_bytes = kSmallEngineGpuMemorySize; |
| command_line_settings.reduce_cpu_memory_by = -1; |
| |
| AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings, |
| build_settings); |
| const int64_t memory_consumption = |
| auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kCPU); |
| // Max_cpu_in_bytes specifies one byte of memory, but reduce must override |
| // this for this test to pass. |
| EXPECT_LE(memory_consumption, kSmallEngineCpuMemorySize); |
| } |
| |
| // Tests the expectation that if --reduce_gpu_memory_by is set to -1 that it |
| // will be effectively disabled and --max_gpu_bytes be used as the memory |
| // reduction means. |
| TEST(AutoMem, MaxGpuIsEnabledWhenReduceCpuMemoryIsExplicitlyDisabled) { |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| // Max memory is 1-byte. We expect that the kReduceCpuMemoryBy = "-1" |
| // passed to the command line will cause max_cpu_in_bytes to be the |
| // dominating memory reduction mechanism. |
| build_settings.max_gpu_in_bytes = kSmallEngineGpuMemorySize; |
| command_line_settings.reduce_gpu_memory_by = -1; |
| |
| AutoMem auto_mem_no_reduce_cpu(kResolution1080p, command_line_settings, |
| build_settings); |
| const int64_t memory_consumption = |
| auto_mem_no_reduce_cpu.SumAllMemoryOfType(MemorySetting::kGPU); |
| // Max_cpu_in_bytes specifies one byte of memory, but reduce must override |
| // this for this test to pass. |
| EXPECT_LE(memory_consumption, kSmallEngineGpuMemorySize); |
| } |
| |
| // Tests that if the gpu memory could not be queried then the resulting |
| // max_gpu_bytes will not be valid. |
| TEST(AutoMem, NoDefaultGpuMemory) { |
| AutoMemSettings command_line_settings(AutoMemSettings::kTypeCommandLine); |
| AutoMemSettings build_settings(AutoMemSettings::kTypeBuild); |
| |
| AutoMem auto_mem(kResolution1080p, command_line_settings, |
| build_settings); |
| |
| EXPECT_FALSE(auto_mem.max_gpu_bytes()->valid()); |
| } |
| |
| } // namespace memory_settings |
| } // namespace browser |
| } // namespace cobalt |
| |
| #undef EXPECT_MEMORY_SETTING |