| // Copyright 2026 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gpu/command_buffer/service/service_utils.h" |
| |
| #include "base/memory/memory_pressure_listener.h" |
| #include "base/memory_coordinator/utils.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "build/build_config.h" |
| #include "gpu/config/gpu_finch_features.h" |
| #include "gpu/config/gpu_switches.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace gpu { |
| namespace { |
| |
| constexpr size_t kMaxCacheSize = 1024u; |
| |
| TEST(ServiceUtilsTest, UpdateShaderCacheSizeOnMemoryLimit_NonAggressive) { |
| base::test::ScopedFeatureList feature_list; |
| feature_list.InitAndDisableFeature(features::kAggressiveShaderCacheLimits); |
| |
| // None (100%) |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 100), |
| kMaxCacheSize); |
| |
| // Moderate (50%) -> 25% of max size |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 50), |
| kMaxCacheSize / 4); |
| |
| // Critical (0%) -> 0 |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 0), 0u); |
| |
| // Intermediate (75%) -> 56.25% of max size (quadratically) |
| // 1024 * (0.75 * 0.75) = 1024 * 0.5625 = 576 |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 75), 576u); |
| } |
| |
| TEST(ServiceUtilsTest, UpdateShaderCacheSizeOnMemoryLimit_Aggressive) { |
| base::test::ScopedFeatureList feature_list; |
| feature_list.InitAndEnableFeature(features::kAggressiveShaderCacheLimits); |
| |
| #if BUILDFLAG(IS_ANDROID) |
| // Android ignores all pressure. |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 100), |
| kMaxCacheSize); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 50), |
| kMaxCacheSize); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 0), |
| kMaxCacheSize); |
| #else |
| // Non-Android desktop: |
| // Ignore limits above Moderate (50%). |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 100), |
| kMaxCacheSize); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 75), |
| kMaxCacheSize); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 50), |
| kMaxCacheSize); |
| |
| // Interpolate between Moderate (50%) and Critical (0%). |
| // 25% -> t = (50 - 25)/50 = 0.5. lerp(1.0, 0.25, 0.5) = 0.625. |
| // 1024 * 0.625 = 640. |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 25), 640u); |
| |
| // Critical (0%) -> 25% of max size |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryLimit(kMaxCacheSize, 0), |
| kMaxCacheSize / 4); |
| #endif |
| } |
| |
| TEST(ServiceUtilsTest, UpdateShaderCacheSizeOnMemoryPressure) { |
| base::test::ScopedFeatureList feature_list; |
| feature_list.InitAndDisableFeature(features::kAggressiveShaderCacheLimits); |
| |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryPressure( |
| kMaxCacheSize, base::MEMORY_PRESSURE_LEVEL_NONE), |
| kMaxCacheSize); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryPressure( |
| kMaxCacheSize, base::MEMORY_PRESSURE_LEVEL_MODERATE), |
| kMaxCacheSize / 4); |
| EXPECT_EQ(UpdateShaderCacheSizeOnMemoryPressure( |
| kMaxCacheSize, base::MEMORY_PRESSURE_LEVEL_CRITICAL), |
| 0u); |
| } |
| |
| TEST(ServiceUtilsTest, ParseGpuPreferencesIgnoreGpuBlocklist) { |
| { // No switch. |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| GpuPreferences prefs = gles2::ParseGpuPreferences(&command_line); |
| EXPECT_FALSE(prefs.ignore_gpu_blocklist); |
| EXPECT_TRUE(prefs.ignored_gpu_blocklist_entries.empty()); |
| } |
| |
| { // Switch without parameters. |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitch(switches::kIgnoreGpuBlocklist); |
| GpuPreferences prefs = gles2::ParseGpuPreferences(&command_line); |
| EXPECT_TRUE(prefs.ignore_gpu_blocklist); |
| EXPECT_TRUE(prefs.ignored_gpu_blocklist_entries.empty()); |
| } |
| |
| { // Switch with valid parameters. |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kIgnoreGpuBlocklist, "1,2,3"); |
| GpuPreferences prefs = gles2::ParseGpuPreferences(&command_line); |
| EXPECT_FALSE(prefs.ignore_gpu_blocklist); |
| EXPECT_EQ(3u, prefs.ignored_gpu_blocklist_entries.size()); |
| EXPECT_EQ(1u, prefs.ignored_gpu_blocklist_entries[0]); |
| EXPECT_EQ(2u, prefs.ignored_gpu_blocklist_entries[1]); |
| EXPECT_EQ(3u, prefs.ignored_gpu_blocklist_entries[2]); |
| } |
| |
| { // Switch with invalid parameters. |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kIgnoreGpuBlocklist, "1,a,3"); |
| GpuPreferences prefs = gles2::ParseGpuPreferences(&command_line); |
| EXPECT_FALSE(prefs.ignore_gpu_blocklist); |
| EXPECT_TRUE(prefs.ignored_gpu_blocklist_entries.empty()); |
| } |
| |
| { // Switch with empty string (same as no parameters). |
| base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| command_line.AppendSwitchASCII(switches::kIgnoreGpuBlocklist, ""); |
| GpuPreferences prefs = gles2::ParseGpuPreferences(&command_line); |
| EXPECT_TRUE(prefs.ignore_gpu_blocklist); |
| EXPECT_TRUE(prefs.ignored_gpu_blocklist_entries.empty()); |
| } |
| } |
| |
| } // namespace |
| } // namespace gpu |