Commit 3e84fc80 authored by Sean Gilhuly's avatar Sean Gilhuly Committed by Commit Bot

Add GPU modes for Vulkan and Metal

Split GpuMode::HARDWARE_ACCELERATED into HARDWARE_GL, HARDWARE_VULKAN,
and HARDWARE_METAL. Then, during GpuDataManagerImpl initialization, add
GL to the |fallback_modes_| stack, followed by Vulkan or Metal if they
are enabled.

GL can still be used in the Vulkan and Metal modes, but disable Vulkan
and Metal when the GPU is not running in that mode. This way, the first
GPU fallback will still leave hardware acceleration available.

Note that this doesn't check what Vulkan or Metal are being used for.
For instance, with the flag --use-vulkan=native, Vulkan will be
initialized, but Skia GL will still be used for compositing without the
flag --enable-features=Vulkan. In this case, the first fallback will
disable Vulkan anyway, and the second will disable GL.

Bug: 1005383
Change-Id: I2cc46b4861f325883f8324bde541410440764c3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1976827
Commit-Queue: Sean Gilhuly <sgilhuly@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734192}
parent a88c0271
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/config/gpu_blocklist.h" #include "gpu/config/gpu_blocklist.h"
#include "gpu/config/gpu_driver_bug_list.h" #include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/config/gpu_driver_bug_workaround_type.h"
...@@ -51,6 +52,7 @@ ...@@ -51,6 +52,7 @@
#include "gpu/ipc/common/memory_stats.h" #include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h" #include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/ipc/host/shader_disk_cache.h" #include "gpu/ipc/host/shader_disk_cache.h"
#include "gpu/vulkan/buildflags.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#include "ui/gfx/switches.h" #include "ui/gfx/switches.h"
...@@ -275,14 +277,45 @@ void RequestVideoMemoryUsageStats( ...@@ -275,14 +277,45 @@ void RequestVideoMemoryUsageStats(
// Determines if SwiftShader is available as a fallback for WebGL. // Determines if SwiftShader is available as a fallback for WebGL.
bool SwiftShaderAllowed() { bool SwiftShaderAllowed() {
#if !BUILDFLAG(ENABLE_SWIFTSHADER) #if BUILDFLAG(ENABLE_SWIFTSHADER)
return false;
#else
return !base::CommandLine::ForCurrentProcess()->HasSwitch( return !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableSoftwareRasterizer); switches::kDisableSoftwareRasterizer);
#else
return false;
#endif #endif
} }
// These functions are never called on the Fuchsia path. Leave them undefined to
// fix a compiler warning.
#if !defined(OS_FUCHSIA)
// Determines if Vulkan is available for the GPU process.
bool VulkanAllowed() {
#if BUILDFLAG(ENABLE_VULKAN)
// Vulkan will be enabled if certain flags are present.
// --enable-features=Vulkan will cause Vulkan to be used for compositing and
// rasterization. --use-vulkan by itself will initialize Vulkan so that it can
// be used for other purposes, such as WebGPU.
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
gpu::GrContextType gr_context_type = gpu::gles2::ParseGrContextType();
gpu::VulkanImplementationName use_vulkan =
gpu::gles2::ParseVulkanImplementationName(command_line, gr_context_type);
return use_vulkan != gpu::VulkanImplementationName::kNone;
#else
return false;
#endif
}
// Determines if Metal is available for the GPU process.
bool MetalAllowed() {
#if defined(OS_MACOSX)
return base::FeatureList::IsEnabled(features::kMetal);
#else
return false;
#endif
}
#endif // !OS_FUCHSIA
// These values are logged to UMA. Entries should not be renumbered and numeric // These values are logged to UMA. Entries should not be renumbered and numeric
// values should never be reused. Please keep in sync with "CompositingMode" in // values should never be reused. Please keep in sync with "CompositingMode" in
// src/tools/metrics/histograms/enums.xml. // src/tools/metrics/histograms/enums.xml.
...@@ -361,14 +394,18 @@ void GpuDataManagerImplPrivate::InitializeGpuModes() { ...@@ -361,14 +394,18 @@ void GpuDataManagerImplPrivate::InitializeGpuModes() {
// embedder. Falling back to SW compositing in that case is not supported. // embedder. Falling back to SW compositing in that case is not supported.
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
fallback_modes_.clear(); fallback_modes_.clear();
#endif fallback_modes_.push_back(gpu::GpuMode::HARDWARE_VULKAN);
#else
fallback_modes_.push_back(gpu::GpuMode::HARDWARE_GL);
// TODO(sgilhuly): Add a way to differentiate between using hardware GL and if (VulkanAllowed())
// hardware Vulkan. fallback_modes_.push_back(gpu::GpuMode::HARDWARE_VULKAN);
fallback_modes_.push_back(gpu::GpuMode::HARDWARE_ACCELERATED); if (MetalAllowed())
fallback_modes_.push_back(gpu::GpuMode::HARDWARE_METAL);
#endif // OS_FUCHSIA
} }
GoToNextGpuMode(/*is_fallback=*/false); FallBackToNextGpuMode();
} }
void GpuDataManagerImplPrivate::BlacklistWebGLForTesting() { void GpuDataManagerImplPrivate::BlacklistWebGLForTesting() {
...@@ -396,7 +433,9 @@ gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const { ...@@ -396,7 +433,9 @@ gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const {
bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const { bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {
switch (gpu_mode_) { switch (gpu_mode_) {
case gpu::GpuMode::HARDWARE_ACCELERATED: case gpu::GpuMode::HARDWARE_GL:
case gpu::GpuMode::HARDWARE_METAL:
case gpu::GpuMode::HARDWARE_VULKAN:
return true; return true;
case gpu::GpuMode::SWIFTSHADER: case gpu::GpuMode::SWIFTSHADER:
DCHECK(SwiftShaderAllowed()); DCHECK(SwiftShaderAllowed());
...@@ -411,10 +450,10 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const { ...@@ -411,10 +450,10 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {
if (base::CommandLine::ForCurrentProcess()->HasSwitch( if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpu)) switches::kDisableGpu))
*reason += "through commandline switch --disable-gpu."; *reason += "through commandline switch --disable-gpu.";
else if (hardware_disabled_by_fallback_) else if (hardware_disabled_explicitly_)
*reason += "due to frequent crashes.";
else
*reason += "in chrome://settings."; *reason += "in chrome://settings.";
else
*reason += "due to frequent crashes.";
} }
} }
return false; return false;
...@@ -678,6 +717,19 @@ void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo( ...@@ -678,6 +717,19 @@ void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo(
const base::Optional<gpu::GpuFeatureInfo>& const base::Optional<gpu::GpuFeatureInfo>&
gpu_feature_info_for_hardware_gpu) { gpu_feature_info_for_hardware_gpu) {
gpu_feature_info_ = gpu_feature_info; gpu_feature_info_ = gpu_feature_info;
// If Vulkan initialization fails, the GPU process can silently fallback to
// GL. Update the GPU mode for this case.
#if !defined(OS_FUCHSIA)
if (gpu_mode_ == gpu::GpuMode::HARDWARE_VULKAN &&
gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_VULKAN] !=
gpu::GpuFeatureStatus::kGpuFeatureStatusEnabled) {
// TODO(sgilhuly): The GpuMode in GpuProcessHost will still be
// HARDWARE_VULKAN. This isn't a big issue right now because both GPU modes
// report to the same histogram. The first fallback will occur after 4
// crashes, instead of 3.
FallBackToNextGpuMode();
}
#endif // !OS_FUCHSIA
if (!gpu_feature_info_for_hardware_gpu_.IsInitialized()) { if (!gpu_feature_info_for_hardware_gpu_.IsInitialized()) {
if (gpu_feature_info_for_hardware_gpu.has_value()) { if (gpu_feature_info_for_hardware_gpu.has_value()) {
DCHECK(gpu_feature_info_for_hardware_gpu->IsInitialized()); DCHECK(gpu_feature_info_for_hardware_gpu->IsInitialized());
...@@ -712,8 +764,7 @@ gpu::GpuExtraInfo GpuDataManagerImplPrivate::GetGpuExtraInfo() const { ...@@ -712,8 +764,7 @@ gpu::GpuExtraInfo GpuDataManagerImplPrivate::GetGpuExtraInfo() const {
} }
bool GpuDataManagerImplPrivate::IsGpuCompositingDisabled() const { bool GpuDataManagerImplPrivate::IsGpuCompositingDisabled() const {
return disable_gpu_compositing_ || return disable_gpu_compositing_ || !HardwareAccelerationEnabled();
gpu_mode_ != gpu::GpuMode::HARDWARE_ACCELERATED;
} }
void GpuDataManagerImplPrivate::SetGpuCompositingDisabled() { void GpuDataManagerImplPrivate::SetGpuCompositingDisabled() {
...@@ -739,7 +790,9 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine( ...@@ -739,7 +790,9 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
std::string use_gl; std::string use_gl;
switch (gpu_mode_) { switch (gpu_mode_) {
case gpu::GpuMode::HARDWARE_ACCELERATED: case gpu::GpuMode::HARDWARE_GL:
case gpu::GpuMode::HARDWARE_METAL:
case gpu::GpuMode::HARDWARE_VULKAN:
use_gl = browser_command_line->GetSwitchValueASCII(switches::kUseGL); use_gl = browser_command_line->GetSwitchValueASCII(switches::kUseGL);
break; break;
case gpu::GpuMode::SWIFTSHADER: case gpu::GpuMode::SWIFTSHADER:
...@@ -810,15 +863,31 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences( ...@@ -810,15 +863,31 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences(
->GetPlatformProperties() ->GetPlatformProperties()
.message_pump_type_for_gpu; .message_pump_type_for_gpu;
#endif #endif
#if defined(OS_MACOSX)
if (gpu_mode_ != gpu::GpuMode::HARDWARE_METAL)
gpu_preferences->enable_metal = false;
#elif BUILDFLAG(ENABLE_VULKAN)
if (gpu_mode_ != gpu::GpuMode::HARDWARE_VULKAN)
gpu_preferences->use_vulkan = gpu::VulkanImplementationName::kNone;
#endif
} }
void GpuDataManagerImplPrivate::DisableHardwareAcceleration() { void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
if (gpu_mode_ == gpu::GpuMode::HARDWARE_ACCELERATED) hardware_disabled_explicitly_ = true;
GoToNextGpuMode(/*is_fallback=*/false); while (HardwareAccelerationEnabled())
FallBackToNextGpuMode();
} }
bool GpuDataManagerImplPrivate::HardwareAccelerationEnabled() const { bool GpuDataManagerImplPrivate::HardwareAccelerationEnabled() const {
return gpu_mode_ == gpu::GpuMode::HARDWARE_ACCELERATED; switch (gpu_mode_) {
case gpu::GpuMode::HARDWARE_GL:
case gpu::GpuMode::HARDWARE_METAL:
case gpu::GpuMode::HARDWARE_VULKAN:
return true;
default:
return false;
}
} }
void GpuDataManagerImplPrivate::OnGpuBlocked() { void GpuDataManagerImplPrivate::OnGpuBlocked() {
...@@ -1065,10 +1134,6 @@ gpu::GpuMode GpuDataManagerImplPrivate::GetGpuMode() const { ...@@ -1065,10 +1134,6 @@ gpu::GpuMode GpuDataManagerImplPrivate::GetGpuMode() const {
} }
void GpuDataManagerImplPrivate::FallBackToNextGpuMode() { void GpuDataManagerImplPrivate::FallBackToNextGpuMode() {
GoToNextGpuMode(/*is_fallback=*/true);
}
void GpuDataManagerImplPrivate::GoToNextGpuMode(bool is_fallback) {
if (fallback_modes_.empty()) { if (fallback_modes_.empty()) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
FatalGpuProcessLaunchFailureOnBackground(); FatalGpuProcessLaunchFailureOnBackground();
...@@ -1076,20 +1141,12 @@ void GpuDataManagerImplPrivate::GoToNextGpuMode(bool is_fallback) { ...@@ -1076,20 +1141,12 @@ void GpuDataManagerImplPrivate::GoToNextGpuMode(bool is_fallback) {
IntentionallyCrashBrowserForUnusableGpuProcess(); IntentionallyCrashBrowserForUnusableGpuProcess();
} }
if (is_fallback && gpu_mode_ == gpu::GpuMode::HARDWARE_ACCELERATED)
hardware_disabled_by_fallback_ = true;
gpu_mode_ = fallback_modes_.back(); gpu_mode_ = fallback_modes_.back();
fallback_modes_.pop_back(); fallback_modes_.pop_back();
switch (gpu_mode_) { DCHECK_NE(gpu_mode_, gpu::GpuMode::UNKNOWN);
case gpu::GpuMode::HARDWARE_ACCELERATED: if (gpu_mode_ == gpu::GpuMode::DISPLAY_COMPOSITOR ||
case gpu::GpuMode::SWIFTSHADER: gpu_mode_ == gpu::GpuMode::DISABLED) {
break; OnGpuBlocked();
case gpu::GpuMode::DISPLAY_COMPOSITOR:
case gpu::GpuMode::DISABLED:
OnGpuBlocked();
break;
case gpu::GpuMode::UNKNOWN:
NOTREACHED();
} }
} }
......
...@@ -191,8 +191,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { ...@@ -191,8 +191,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void RequestDxDiagNodeData(); void RequestDxDiagNodeData();
void RequestGpuSupportedRuntimeVersion(bool delayed); void RequestGpuSupportedRuntimeVersion(bool delayed);
void GoToNextGpuMode(bool is_fallback);
void RecordCompositingMode(); void RecordCompositingMode();
GpuDataManagerImpl* const owner_; GpuDataManagerImpl* const owner_;
...@@ -229,8 +227,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate { ...@@ -229,8 +227,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// Order of gpu process fallback states, used as a stack. // Order of gpu process fallback states, used as a stack.
std::vector<gpu::GpuMode> fallback_modes_; std::vector<gpu::GpuMode> fallback_modes_;
// Used to tell if the gpu was disabled due to process crashes. // Used to tell if the gpu was disabled by an explicit call to
bool hardware_disabled_by_fallback_ = false; // DisableHardwareAcceleration(), rather than by fallback.
bool hardware_disabled_explicitly_ = false;
// We disable histogram stuff in testing, especially in unit tests because // We disable histogram stuff in testing, especially in unit tests because
// they cause random failures. // they cause random failures.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -15,7 +16,9 @@ ...@@ -15,7 +16,9 @@
#include "content/browser/gpu/gpu_data_manager_testing_entry_enums_autogen.h" #include "content/browser/gpu/gpu_data_manager_testing_entry_enums_autogen.h"
#include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_feature_type.h" #include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_info.h" #include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_switches.h" #include "gpu/config/gpu_switches.h"
#include "gpu/ipc/common/memory_stats.h" #include "gpu/ipc/common/memory_stats.h"
...@@ -54,7 +57,7 @@ static GURL GetDomain2ForTesting() { ...@@ -54,7 +57,7 @@ static GURL GetDomain2ForTesting() {
return GURL("http://bar.com/"); return GURL("http://bar.com/");
} }
} // namespace anonymous } // namespace
class GpuDataManagerImplPrivateTest : public testing::Test { class GpuDataManagerImplPrivateTest : public testing::Test {
public: public:
...@@ -256,7 +259,7 @@ TEST_F(GpuDataManagerImplPrivateTest, UnblockThisDomainFrom3DAPIs) { ...@@ -256,7 +259,7 @@ TEST_F(GpuDataManagerImplPrivateTest, UnblockThisDomainFrom3DAPIs) {
#if !defined(OS_FUCHSIA) #if !defined(OS_FUCHSIA)
TEST_F(GpuDataManagerImplPrivateTest, FallbackToSwiftShader) { TEST_F(GpuDataManagerImplPrivateTest, FallbackToSwiftShader) {
ScopedGpuDataManagerImplPrivate manager; ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_ACCELERATED, manager->GetGpuMode()); EXPECT_EQ(gpu::GpuMode::HARDWARE_GL, manager->GetGpuMode());
manager->FallBackToNextGpuMode(); manager->FallBackToNextGpuMode();
EXPECT_EQ(gpu::GpuMode::SWIFTSHADER, manager->GetGpuMode()); EXPECT_EQ(gpu::GpuMode::SWIFTSHADER, manager->GetGpuMode());
...@@ -266,7 +269,7 @@ TEST_F(GpuDataManagerImplPrivateTest, FallbackWithSwiftShaderDisabled) { ...@@ -266,7 +269,7 @@ TEST_F(GpuDataManagerImplPrivateTest, FallbackWithSwiftShaderDisabled) {
base::CommandLine::ForCurrentProcess()->AppendSwitch( base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableSoftwareRasterizer); switches::kDisableSoftwareRasterizer);
ScopedGpuDataManagerImplPrivate manager; ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_ACCELERATED, manager->GetGpuMode()); EXPECT_EQ(gpu::GpuMode::HARDWARE_GL, manager->GetGpuMode());
manager->FallBackToNextGpuMode(); manager->FallBackToNextGpuMode();
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -285,4 +288,71 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuStartsWithGpuDisabled) { ...@@ -285,4 +288,71 @@ TEST_F(GpuDataManagerImplPrivateTest, GpuStartsWithGpuDisabled) {
} }
#endif // !OS_ANDROID && !OS_CHROMEOS #endif // !OS_ANDROID && !OS_CHROMEOS
#if defined(OS_MACOSX)
TEST_F(GpuDataManagerImplPrivateTest, FallbackFromMetalToGL) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kMetal);
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_METAL, manager->GetGpuMode());
manager->FallBackToNextGpuMode();
EXPECT_EQ(gpu::GpuMode::HARDWARE_GL, manager->GetGpuMode());
}
#endif // OS_MACOSX
#if BUILDFLAG(ENABLE_VULKAN)
TEST_F(GpuDataManagerImplPrivateTest, GpuStartsWithUseVulkanFlag) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kUseVulkan, switches::kVulkanImplementationNameNative);
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_VULKAN, manager->GetGpuMode());
}
TEST_F(GpuDataManagerImplPrivateTest, GpuStartsWithVulkanFeatureFlag) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kVulkan);
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_VULKAN, manager->GetGpuMode());
}
// Don't run these tests on Fuchsia, which doesn't support falling back from
// Vulkan.
#if !defined(OS_FUCHSIA)
TEST_F(GpuDataManagerImplPrivateTest, FallbackFromVulkanToGL) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kVulkan);
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_VULKAN, manager->GetGpuMode());
manager->FallBackToNextGpuMode();
EXPECT_EQ(gpu::GpuMode::HARDWARE_GL, manager->GetGpuMode());
}
TEST_F(GpuDataManagerImplPrivateTest, VulkanInitializationFails) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kVulkan);
ScopedGpuDataManagerImplPrivate manager;
EXPECT_EQ(gpu::GpuMode::HARDWARE_VULKAN, manager->GetGpuMode());
// Simulate GPU process initialization completing with Vulkan unavailable.
gpu::GpuFeatureInfo gpu_feature_info;
for (auto& status : gpu_feature_info.status_values)
status = gpu::GpuFeatureStatus::kGpuFeatureStatusEnabled;
gpu_feature_info.status_values[gpu::GpuFeatureType::GPU_FEATURE_TYPE_VULKAN] =
gpu::GpuFeatureStatus::kGpuFeatureStatusDisabled;
manager->UpdateGpuFeatureInfo(gpu_feature_info, base::nullopt);
// GpuDataManager should update its mode to be GL.
EXPECT_EQ(gpu::GpuMode::HARDWARE_GL, manager->GetGpuMode());
// The first fallback should go to SwiftShader on platforms where fallback to
// software is allowed.
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
manager->FallBackToNextGpuMode();
EXPECT_EQ(gpu::GpuMode::SWIFTSHADER, manager->GetGpuMode());
#endif // !OS_ANDROID && !OS_CHROMEOS
}
#endif // !OS_FUCHSIA
#endif // BUILDFLAG(ENABLE_VULKAN)
} // namespace content } // namespace content
...@@ -123,7 +123,10 @@ constexpr char kProcessLifetimeEventsDisplayCompositor[] = ...@@ -123,7 +123,10 @@ constexpr char kProcessLifetimeEventsDisplayCompositor[] =
// Returns the UMA histogram name for the given GPU mode. // Returns the UMA histogram name for the given GPU mode.
const char* GetProcessLifetimeUmaName(gpu::GpuMode gpu_mode) { const char* GetProcessLifetimeUmaName(gpu::GpuMode gpu_mode) {
switch (gpu_mode) { switch (gpu_mode) {
case gpu::GpuMode::HARDWARE_ACCELERATED: // TODO(sgilhuly): Add separate histograms for the different hardware modes.
case gpu::GpuMode::HARDWARE_GL:
case gpu::GpuMode::HARDWARE_METAL:
case gpu::GpuMode::HARDWARE_VULKAN:
return kProcessLifetimeEventsHardwareAccelerated; return kProcessLifetimeEventsHardwareAccelerated;
case gpu::GpuMode::SWIFTSHADER: case gpu::GpuMode::SWIFTSHADER:
return kProcessLifetimeEventsSwiftShader; return kProcessLifetimeEventsSwiftShader;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/gpu_switches.h"
...@@ -159,37 +160,11 @@ GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) { ...@@ -159,37 +160,11 @@ GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) {
command_line->HasSwitch(switches::kIgnoreGpuBlacklist); command_line->HasSwitch(switches::kIgnoreGpuBlacklist);
gpu_preferences.enable_webgpu = gpu_preferences.enable_webgpu =
command_line->HasSwitch(switches::kEnableUnsafeWebGPU); command_line->HasSwitch(switches::kEnableUnsafeWebGPU);
if (command_line->HasSwitch(switches::kUseVulkan)) { gpu_preferences.gr_context_type = ParseGrContextType();
auto value = command_line->GetSwitchValueASCII(switches::kUseVulkan); gpu_preferences.use_vulkan = ParseVulkanImplementationName(
if (value.empty() || value == switches::kVulkanImplementationNameNative) { command_line, gpu_preferences.gr_context_type);
gpu_preferences.use_vulkan = VulkanImplementationName::kForcedNative;
} else if (value == switches::kVulkanImplementationNameSwiftshader) {
gpu_preferences.use_vulkan = VulkanImplementationName::kSwiftshader;
} else {
gpu_preferences.use_vulkan = VulkanImplementationName::kNone;
}
}
gpu_preferences.disable_vulkan_surface = gpu_preferences.disable_vulkan_surface =
command_line->HasSwitch(switches::kDisableVulkanSurface); command_line->HasSwitch(switches::kDisableVulkanSurface);
#if defined(OS_MACOSX)
gpu_preferences.gr_context_type =
base::FeatureList::IsEnabled(features::kMetal) ? GrContextType::kMetal
: GrContextType::kGL;
#else
gpu_preferences.gr_context_type =
base::FeatureList::IsEnabled(features::kVulkan) ? GrContextType::kVulkan
: GrContextType::kGL;
#endif
#if BUILDFLAG(SKIA_USE_DAWN)
if (base::FeatureList::IsEnabled(features::kSkiaDawn))
gpu_preferences.gr_context_type = GrContextType::kDawn;
#endif
if (gpu_preferences.gr_context_type == GrContextType::kVulkan &&
gpu_preferences.use_vulkan == gpu::VulkanImplementationName::kNone) {
// If gpu_preferences.use_vulkan is not set from --use-vulkan, the native
// vulkan implementation will be used by default.
gpu_preferences.use_vulkan = gpu::VulkanImplementationName::kNative;
}
gpu_preferences.enable_gpu_blocked_time_metric = gpu_preferences.enable_gpu_blocked_time_metric =
command_line->HasSwitch(switches::kEnableGpuBlockedTime); command_line->HasSwitch(switches::kEnableGpuBlockedTime);
...@@ -197,5 +172,38 @@ GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) { ...@@ -197,5 +172,38 @@ GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) {
return gpu_preferences; return gpu_preferences;
} }
GrContextType ParseGrContextType() {
#if BUILDFLAG(SKIA_USE_DAWN)
if (base::FeatureList::IsEnabled(features::kSkiaDawn))
return GrContextType::kDawn;
#endif
#if defined(OS_MACOSX)
return base::FeatureList::IsEnabled(features::kMetal) ? GrContextType::kMetal
: GrContextType::kGL;
#else
return base::FeatureList::IsEnabled(features::kVulkan)
? GrContextType::kVulkan
: GrContextType::kGL;
#endif
}
VulkanImplementationName ParseVulkanImplementationName(
const base::CommandLine* command_line,
GrContextType gr_context_type) {
if (command_line->HasSwitch(switches::kUseVulkan)) {
auto value = command_line->GetSwitchValueASCII(switches::kUseVulkan);
if (value.empty() || value == switches::kVulkanImplementationNameNative) {
return VulkanImplementationName::kForcedNative;
} else if (value == switches::kVulkanImplementationNameSwiftshader) {
return VulkanImplementationName::kSwiftshader;
}
}
// If the vulkan implementation is not set from --use-vulkan, the native
// vulkan implementation will be used by default.
return gr_context_type == GrContextType::kVulkan
? VulkanImplementationName::kNative
: VulkanImplementationName::kNone;
}
} // namespace gles2 } // namespace gles2
} // namespace gpu } // namespace gpu
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#define GPU_COMMAND_BUFFER_SERVICE_SERVICE_UTILS_H_ #define GPU_COMMAND_BUFFER_SERVICE_SERVICE_UTILS_H_
#include "base/command_line.h" #include "base/command_line.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/gpu_gles2_export.h" #include "gpu/gpu_gles2_export.h"
#include "ui/gl/gl_context.h" #include "ui/gl/gl_context.h"
namespace gpu { namespace gpu {
struct ContextCreationAttribs; struct ContextCreationAttribs;
struct GpuPreferences;
namespace gles2 { namespace gles2 {
class ContextGroup; class ContextGroup;
...@@ -34,6 +34,17 @@ GPU_GLES2_EXPORT bool PassthroughCommandDecoderSupported(); ...@@ -34,6 +34,17 @@ GPU_GLES2_EXPORT bool PassthroughCommandDecoderSupported();
GPU_GLES2_EXPORT GpuPreferences GPU_GLES2_EXPORT GpuPreferences
ParseGpuPreferences(const base::CommandLine* command_line); ParseGpuPreferences(const base::CommandLine* command_line);
// Determine which Skia GrContext backend will be used for GPU compositing and
// rasterization (if enabled) by checking the feature flags for Vulkan and
// Metal. If they are not enabled, default to GL.
GPU_GLES2_EXPORT GrContextType ParseGrContextType();
// Parse the value of --use-vulkan from the command line. If unspecified and
// a Vulkan GrContext is going to be used, default to the native implementation.
GPU_GLES2_EXPORT VulkanImplementationName
ParseVulkanImplementationName(const base::CommandLine* command_line,
GrContextType gr_context_type);
} // namespace gles2 } // namespace gles2
} // namespace gpu } // namespace gpu
......
...@@ -10,8 +10,12 @@ namespace gpu { ...@@ -10,8 +10,12 @@ namespace gpu {
// What the GPU process is running for. // What the GPU process is running for.
enum class GpuMode { enum class GpuMode {
UNKNOWN, UNKNOWN,
// The GPU process is running with hardare acceleration. // The GPU process is running with hardware acceleration, using only GL.
HARDWARE_ACCELERATED, HARDWARE_GL,
// The GPU process is running with hardware acceleration, using Metal and GL.
HARDWARE_METAL,
// The GPU process is running with hardware acceleration, using Vulkan and GL.
HARDWARE_VULKAN,
// The GPU process is running for SwiftShader WebGL. // The GPU process is running for SwiftShader WebGL.
SWIFTSHADER, SWIFTSHADER,
// The GPU process is running for the display compositor (OOP-D only). // The GPU process is running for the display compositor (OOP-D only).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment