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