blob: 7a26e5aaf2e1982e648e71d334ff27aaf736f989 [file]
// 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