| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/public/browser/gpu_utils.h" |
| |
| #include <string> |
| #include <string_view> |
| |
| #include "base/command_line.h" |
| #include "base/functional/bind.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "build/build_config.h" |
| #include "cc/base/switches.h" |
| #include "components/viz/common/features.h" |
| #include "components/viz/common/switches.h" |
| #include "components/viz/common/viz_utils.h" |
| #include "content/browser/browser_main_loop.h" |
| #include "content/browser/gpu/gpu_process_host.h" |
| #include "content/public/common/content_features.h" |
| #include "content/public/common/content_switches.h" |
| #include "gpu/command_buffer/service/service_utils.h" |
| #include "gpu/config/gpu_finch_features.h" |
| #include "gpu/config/gpu_switches.h" |
| #include "media/base/media_switches.h" |
| #include "media/gpu/buildflags.h" |
| #include "media/media_buildflags.h" |
| #include "third_party/blink/public/common/features.h" |
| #include "ui/gfx/switches.h" |
| #include "ui/gl/gl_features.h" |
| |
| namespace { |
| |
| void KillGpuProcessImpl(content::GpuProcessHost* host) { |
| if (host) { |
| host->ForceShutdown(); |
| } |
| } |
| |
| bool GetUintFromSwitch(const base::CommandLine* command_line, |
| const std::string_view& switch_string, |
| uint32_t* value) { |
| std::string switch_value(command_line->GetSwitchValueASCII(switch_string)); |
| return base::StringToUint(switch_value, value); |
| } |
| |
| } // namespace |
| |
| namespace content { |
| |
| const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() { |
| DCHECK(base::CommandLine::InitializedForCurrentProcess()); |
| const base::CommandLine* command_line = |
| base::CommandLine::ForCurrentProcess(); |
| gpu::GpuPreferences gpu_preferences = |
| gpu::gles2::ParseGpuPreferences(command_line); |
| gpu_preferences.disable_accelerated_video_decode = |
| command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode); |
| gpu_preferences.disable_accelerated_video_encode = |
| command_line->HasSwitch(switches::kDisableAcceleratedVideoEncode); |
| #if BUILDFLAG(IS_WIN) |
| gpu_preferences.enable_low_latency_dxva = |
| !command_line->HasSwitch(switches::kDisableLowLatencyDxva); |
| gpu_preferences.enable_zero_copy_dxgi_video = |
| !command_line->HasSwitch(switches::kDisableZeroCopyDxgiVideo); |
| gpu_preferences.enable_nv12_dxgi_video = |
| !command_line->HasSwitch(switches::kDisableNv12DxgiVideo); |
| #endif |
| gpu_preferences.disable_software_rasterizer = |
| command_line->HasSwitch(switches::kDisableSoftwareRasterizer) || |
| (!features::IsSwiftShaderAllowed(command_line) && |
| !features::IsWARPAllowedByFeature()); |
| gpu_preferences.log_gpu_control_list_decisions = |
| command_line->HasSwitch(switches::kLogGpuControlListDecisions); |
| gpu_preferences.gpu_startup_dialog = |
| command_line->HasSwitch(switches::kGpuStartupDialog); |
| gpu_preferences.disable_gpu_watchdog = |
| command_line->HasSwitch(switches::kDisableGpuWatchdog) || |
| command_line->HasSwitch(switches::kSingleProcess) || |
| command_line->HasSwitch(switches::kInProcessGPU); |
| |
| gpu_preferences.gpu_sandbox_start_early = |
| command_line->HasSwitch(switches::kGpuSandboxStartEarly); |
| |
| gpu_preferences.enable_vulkan_protected_memory = |
| command_line->HasSwitch(switches::kEnableVulkanProtectedMemory); |
| gpu_preferences.disable_vulkan_fallback_to_gl_for_testing = |
| command_line->HasSwitch(switches::kDisableVulkanFallbackToGLForTesting); |
| |
| gpu_preferences.enable_gpu_benchmarking_extension = |
| command_line->HasSwitch(switches::kEnableGpuBenchmarking); |
| |
| gpu_preferences.enable_native_gpu_memory_buffers = |
| command_line->HasSwitch(switches::kEnableNativeGpuMemoryBuffers); |
| |
| #if BUILDFLAG(IS_ANDROID) |
| gpu_preferences.disable_oopr_debug_crash_dump = |
| command_line->HasSwitch(switches::kDisableOoprDebugCrashDump); |
| #endif |
| |
| if (GetUintFromSwitch(command_line, switches::kVulkanHeapMemoryLimitMb, |
| &gpu_preferences.vulkan_heap_memory_limit)) { |
| gpu_preferences.vulkan_heap_memory_limit *= 1024 * 1024; |
| } |
| if (GetUintFromSwitch(command_line, switches::kVulkanSyncCpuMemoryLimitMb, |
| &gpu_preferences.vulkan_sync_cpu_memory_limit)) { |
| gpu_preferences.vulkan_sync_cpu_memory_limit *= 1024 * 1024; |
| } |
| |
| gpu_preferences.force_separate_egl_display_for_webgl_testing = |
| command_line->HasSwitch( |
| switches::kForceSeparateEGLDisplayForWebGLTesting); |
| |
| gpu_preferences.enable_webgpu_experimental_features = |
| command_line->HasSwitch( |
| switches::kEnableExperimentalWebPlatformFeatures) || |
| base::FeatureList::IsEnabled( |
| blink::features::kWebGPUExperimentalFeatures); |
| |
| // Some of these preferences are set or adjusted in |
| // GpuDataManagerImplPrivate::AppendGpuCommandLine. |
| return gpu_preferences; |
| } |
| |
| void KillGpuProcess() { |
| GpuProcessHost::CallOnUI(FROM_HERE, GPU_PROCESS_KIND_SANDBOXED, |
| false /* force_create */, |
| base::BindOnce(&KillGpuProcessImpl)); |
| } |
| |
| gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory() { |
| return BrowserMainLoop::GetInstance()->gpu_channel_establish_factory(); |
| } |
| |
| #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX) |
| void DumpGpuProfilingData(base::OnceClosure callback) { |
| content::GpuProcessHost::CallOnUI( |
| FROM_HERE, content::GPU_PROCESS_KIND_SANDBOXED, false /* force_create */, |
| base::BindOnce( |
| [](base::OnceClosure callback, content::GpuProcessHost* host) { |
| if (host) { |
| host->gpu_service()->WriteClangProfilingProfile( |
| std::move(callback)); |
| } else { |
| LOG(ERROR) << "DumpGpuProfilingData() failed to dump."; |
| std::move(callback).Run(); |
| } |
| }, |
| std::move(callback))); |
| } |
| #endif // BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX) |
| |
| } // namespace content |