blob: 65dea86a65129c10afb0dd8ea9f745473fd10d26 [file] [log] [blame]
// 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