1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/public/browser/gpu_utils.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/single_thread_task_runner.h"
12 #include "build/build_config.h"
13 #include "cc/base/switches.h"
14 #include "components/viz/common/features.h"
15 #include "components/viz/common/switches.h"
16 #include "components/viz/common/viz_utils.h"
17 #include "content/browser/browser_main_loop.h"
18 #include "content/browser/gpu/gpu_process_host.h"
19 #include "content/public/common/content_features.h"
20 #include "content/public/common/content_switches.h"
21 #include "gpu/command_buffer/service/gpu_switches.h"
22 #include "gpu/command_buffer/service/service_utils.h"
23 #include "gpu/config/gpu_finch_features.h"
24 #include "gpu/config/gpu_switches.h"
25 #include "media/base/media_switches.h"
26 #include "media/media_buildflags.h"
27 #include "ui/gfx/switches.h"
28
29 namespace {
30
RunTaskOnTaskRunner(scoped_refptr<base::SingleThreadTaskRunner> task_runner,base::OnceClosure callback)31 void RunTaskOnTaskRunner(
32 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
33 base::OnceClosure callback) {
34 task_runner->PostTask(FROM_HERE, std::move(callback));
35 }
36
StopGpuProcessImpl(base::OnceClosure callback,content::GpuProcessHost * host)37 void StopGpuProcessImpl(base::OnceClosure callback,
38 content::GpuProcessHost* host) {
39 if (host)
40 host->gpu_service()->Stop(std::move(callback));
41 else
42 std::move(callback).Run();
43 }
44
KillGpuProcessImpl(content::GpuProcessHost * host)45 void KillGpuProcessImpl(content::GpuProcessHost* host) {
46 if (host) {
47 host->ForceShutdown();
48 }
49 }
50
GetUintFromSwitch(const base::CommandLine * command_line,const base::StringPiece & switch_string,uint32_t * value)51 bool GetUintFromSwitch(const base::CommandLine* command_line,
52 const base::StringPiece& switch_string,
53 uint32_t* value) {
54 std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
55 return base::StringToUint(switch_value, value);
56 }
57
58 } // namespace
59
60 namespace content {
61
ShouldEnableAndroidSurfaceControl(const base::CommandLine & cmd_line)62 bool ShouldEnableAndroidSurfaceControl(const base::CommandLine& cmd_line) {
63 #if !defined(OS_ANDROID)
64 return false;
65 #else
66 if (viz::PreferRGB565ResourcesForDisplay())
67 return false;
68 return features::IsAndroidSurfaceControlEnabled();
69 #endif
70 }
71
GetGpuPreferencesFromCommandLine()72 const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
73 DCHECK(base::CommandLine::InitializedForCurrentProcess());
74 const base::CommandLine* command_line =
75 base::CommandLine::ForCurrentProcess();
76 gpu::GpuPreferences gpu_preferences =
77 gpu::gles2::ParseGpuPreferences(command_line);
78 gpu_preferences.disable_accelerated_video_decode =
79 command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode);
80 gpu_preferences.disable_accelerated_video_encode =
81 command_line->HasSwitch(switches::kDisableAcceleratedVideoEncode);
82 #if defined(OS_WIN)
83 gpu_preferences.enable_low_latency_dxva =
84 !command_line->HasSwitch(switches::kDisableLowLatencyDxva);
85 gpu_preferences.enable_zero_copy_dxgi_video =
86 !command_line->HasSwitch(switches::kDisableZeroCopyDxgiVideo);
87 gpu_preferences.enable_nv12_dxgi_video =
88 !command_line->HasSwitch(switches::kDisableNv12DxgiVideo);
89 #endif
90 gpu_preferences.disable_software_rasterizer =
91 command_line->HasSwitch(switches::kDisableSoftwareRasterizer);
92 gpu_preferences.log_gpu_control_list_decisions =
93 command_line->HasSwitch(switches::kLogGpuControlListDecisions);
94 gpu_preferences.gpu_startup_dialog =
95 command_line->HasSwitch(switches::kGpuStartupDialog);
96 gpu_preferences.disable_gpu_watchdog =
97 command_line->HasSwitch(switches::kDisableGpuWatchdog) ||
98 command_line->HasSwitch(switches::kSingleProcess) ||
99 command_line->HasSwitch(switches::kInProcessGPU);
100 gpu_preferences.gpu_sandbox_start_early =
101 command_line->HasSwitch(switches::kGpuSandboxStartEarly);
102
103 gpu_preferences.enable_oop_rasterization =
104 command_line->HasSwitch(switches::kEnableOopRasterization);
105 gpu_preferences.disable_oop_rasterization =
106 command_line->HasSwitch(switches::kDisableOopRasterization);
107
108 gpu_preferences.enable_oop_rasterization_ddl =
109 base::FeatureList::IsEnabled(features::kOopRasterizationDDL);
110 gpu_preferences.enable_vulkan_protected_memory =
111 command_line->HasSwitch(switches::kEnableVulkanProtectedMemory);
112 gpu_preferences.enforce_vulkan_protected_memory =
113 command_line->HasSwitch(switches::kEnforceVulkanProtectedMemory);
114 gpu_preferences.disable_vulkan_fallback_to_gl_for_testing =
115 command_line->HasSwitch(switches::kDisableVulkanFallbackToGLForTesting);
116
117 #if defined(OS_MAC)
118 gpu_preferences.enable_metal = base::FeatureList::IsEnabled(features::kMetal);
119 #endif
120
121 gpu_preferences.enable_gpu_benchmarking_extension =
122 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking);
123
124 gpu_preferences.enable_android_surface_control =
125 ShouldEnableAndroidSurfaceControl(*command_line);
126
127 gpu_preferences.enable_native_gpu_memory_buffers =
128 command_line->HasSwitch(switches::kEnableNativeGpuMemoryBuffers);
129
130 #if defined(OS_CHROMEOS)
131 gpu_preferences.platform_disallows_chromeos_direct_video_decoder =
132 command_line->HasSwitch(
133 switches::kPlatformDisallowsChromeOSDirectVideoDecoder);
134 #endif
135
136 #if defined(OS_ANDROID)
137 gpu_preferences.disable_oopr_debug_crash_dump =
138 command_line->HasSwitch(switches::kDisableOoprDebugCrashDump);
139 #endif
140
141 if (GetUintFromSwitch(command_line, switches::kVulkanHeapMemoryLimitMb,
142 &gpu_preferences.vulkan_heap_memory_limit)) {
143 gpu_preferences.vulkan_heap_memory_limit *= 1024 * 1024;
144 }
145 if (GetUintFromSwitch(command_line, switches::kVulkanSyncCpuMemoryLimitMb,
146 &gpu_preferences.vulkan_sync_cpu_memory_limit)) {
147 gpu_preferences.vulkan_sync_cpu_memory_limit *= 1024 * 1024;
148 }
149
150 // Some of these preferences are set or adjusted in
151 // GpuDataManagerImplPrivate::AppendGpuCommandLine.
152 return gpu_preferences;
153 }
154
StopGpuProcess(base::OnceClosure callback)155 void StopGpuProcess(base::OnceClosure callback) {
156 GpuProcessHost::CallOnIO(
157 GPU_PROCESS_KIND_SANDBOXED, false /* force_create */,
158 base::BindOnce(&StopGpuProcessImpl,
159 base::BindOnce(RunTaskOnTaskRunner,
160 base::ThreadTaskRunnerHandle::Get(),
161 std::move(callback))));
162 }
163
KillGpuProcess()164 void KillGpuProcess() {
165 GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED, false /* force_create */,
166 base::BindOnce(&KillGpuProcessImpl));
167 }
168
GetGpuChannelEstablishFactory()169 gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory() {
170 return BrowserMainLoop::GetInstance()->gpu_channel_establish_factory();
171 }
172
173 #if BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX)
DumpGpuProfilingData(base::OnceClosure callback)174 void DumpGpuProfilingData(base::OnceClosure callback) {
175 content::GpuProcessHost::CallOnIO(
176 content::GPU_PROCESS_KIND_SANDBOXED, false /* force_create */,
177 base::BindOnce(
178 [](base::OnceClosure callback, content::GpuProcessHost* host) {
179 host->gpu_service()->WriteClangProfilingProfile(
180 std::move(callback));
181 },
182 std::move(callback)));
183 }
184 #endif // BUILDFLAG(CLANG_PROFILING_INSIDE_SANDBOX)
185
186 } // namespace content
187