Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / content / browser / gpu / compositor_util.cc
blob55fcfdd389f84229b3925edcc220c26f2f9e013e
1 // Copyright (c) 2012 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.
5 #include "content/browser/gpu/compositor_util.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/sys_info.h"
12 #include "build/build_config.h"
13 #include "cc/base/math_util.h"
14 #include "cc/base/switches.h"
15 #include "content/browser/gpu/gpu_data_manager_impl.h"
16 #include "content/public/common/content_switches.h"
17 #include "gpu/config/gpu_feature_type.h"
19 namespace content {
21 namespace {
23 static bool IsGpuRasterizationBlacklisted() {
24 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
25 return manager->IsFeatureBlacklisted(
26 gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION);
29 const char* kGpuCompositingFeatureName = "gpu_compositing";
30 const char* kWebGLFeatureName = "webgl";
31 const char* kRasterizationFeatureName = "rasterization";
32 const char* kMultipleRasterThreadsFeatureName = "multiple_raster_threads";
34 const int kMinRasterThreads = 1;
35 const int kMaxRasterThreads = 4;
37 const int kMinMSAASampleCount = 0;
39 struct GpuFeatureInfo {
40 std::string name;
41 bool blocked;
42 bool disabled;
43 std::string disabled_description;
44 bool fallback_to_software;
47 const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
48 const base::CommandLine& command_line =
49 *base::CommandLine::ForCurrentProcess();
50 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
52 const GpuFeatureInfo kGpuFeatureInfo[] = {
54 "2d_canvas",
55 manager->IsFeatureBlacklisted(
56 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
57 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
58 !GpuDataManagerImpl::GetInstance()->
59 GetGPUInfo().SupportsAccelerated2dCanvas(),
60 "Accelerated 2D canvas is unavailable: either disabled at the command"
61 " line or not supported by the current system.",
62 true
65 kGpuCompositingFeatureName,
66 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING),
67 command_line.HasSwitch(switches::kDisableGpuCompositing),
68 "Gpu compositing has been disabled, either via about:flags or"
69 " command line. The browser will fall back to software compositing"
70 " and hardware acceleration will be unavailable.",
71 true
74 kWebGLFeatureName,
75 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
76 command_line.HasSwitch(switches::kDisableExperimentalWebGL),
77 "WebGL has been disabled, either via about:flags or command line.",
78 false
81 "flash_3d",
82 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
83 command_line.HasSwitch(switches::kDisableFlash3d),
84 "Using 3d in flash has been disabled, either via about:flags or"
85 " command line.",
86 true
89 "flash_stage3d",
90 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
91 command_line.HasSwitch(switches::kDisableFlashStage3d),
92 "Using Stage3d in Flash has been disabled, either via about:flags or"
93 " command line.",
94 true
97 "flash_stage3d_baseline",
98 manager->IsFeatureBlacklisted(
99 gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
100 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
101 command_line.HasSwitch(switches::kDisableFlashStage3d),
102 "Using Stage3d Baseline profile in Flash has been disabled, either"
103 " via about:flags or command line.",
104 true
107 "video_decode",
108 manager->IsFeatureBlacklisted(
109 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
110 command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
111 "Accelerated video decode has been disabled, either via about:flags"
112 " or command line.",
113 true
115 #if defined(ENABLE_WEBRTC)
117 "video_encode",
118 manager->IsFeatureBlacklisted(
119 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
120 command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
121 "Accelerated video encode has been disabled, either via about:flags"
122 " or command line.",
123 true
125 #endif
126 #if defined(OS_CHROMEOS)
128 "panel_fitting",
129 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
130 command_line.HasSwitch(switches::kDisablePanelFitting),
131 "Panel fitting has been disabled, either via about:flags or command"
132 " line.",
133 false
135 #endif
137 kRasterizationFeatureName,
138 IsGpuRasterizationBlacklisted() &&
139 !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled(),
140 !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled() &&
141 !IsGpuRasterizationBlacklisted(),
142 "Accelerated rasterization has been disabled, either via about:flags"
143 " or command line.",
144 true
147 kMultipleRasterThreadsFeatureName,
148 false,
149 NumberOfRendererRasterThreads() == 1,
150 "Raster is using a single thread.",
151 false
154 DCHECK(index < arraysize(kGpuFeatureInfo));
155 *eof = (index == arraysize(kGpuFeatureInfo) - 1);
156 return kGpuFeatureInfo[index];
159 } // namespace
161 bool IsPropertyTreeVerificationEnabled() {
162 const base::CommandLine& command_line =
163 *base::CommandLine::ForCurrentProcess();
164 return command_line.HasSwitch(cc::switches::kEnablePropertyTreeVerification);
167 bool IsDelegatedRendererEnabled() {
168 const base::CommandLine& command_line =
169 *base::CommandLine::ForCurrentProcess();
170 bool enabled = false;
172 #if defined(USE_AURA) || defined(OS_MACOSX)
173 // Enable on Aura and Mac.
174 enabled = true;
175 #endif
177 // Flags override.
178 enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
179 enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
180 return enabled;
183 int NumberOfRendererRasterThreads() {
184 int num_processors = base::SysInfo::NumberOfProcessors();
186 #if defined(OS_ANDROID)
187 // Android may report 6 to 8 CPUs for big.LITTLE configurations.
188 // Limit the number of raster threads based on maximum of 4 big cores.
189 num_processors = std::min(num_processors, 4);
190 #endif
192 int num_raster_threads = num_processors / 2;
194 // Async uploads is used when neither zero-copy nor one-copy is enabled and
195 // it uses its own thread, so reduce the number of raster threads when async
196 // uploads is in use.
197 bool async_uploads_is_used =
198 !IsZeroCopyUploadEnabled() && !IsOneCopyUploadEnabled();
199 if (async_uploads_is_used)
200 --num_raster_threads;
202 #if defined(OS_ANDROID)
203 // Limit the number of raster threads to 1 on Android.
204 // TODO(reveman): Remove this when we have a better mechanims to prevent
205 // pre-paint raster work from slowing down non-raster work. crbug.com/504515
206 num_raster_threads = 1;
207 #endif
209 const base::CommandLine& command_line =
210 *base::CommandLine::ForCurrentProcess();
212 if (command_line.HasSwitch(switches::kNumRasterThreads)) {
213 std::string string_value = command_line.GetSwitchValueASCII(
214 switches::kNumRasterThreads);
215 if (!base::StringToInt(string_value, &num_raster_threads)) {
216 DLOG(WARNING) << "Failed to parse switch " <<
217 switches::kNumRasterThreads << ": " << string_value;
221 return cc::MathUtil::ClampToRange(num_raster_threads, kMinRasterThreads,
222 kMaxRasterThreads);
225 bool IsOneCopyUploadEnabled() {
226 if (IsZeroCopyUploadEnabled())
227 return false;
229 const base::CommandLine& command_line =
230 *base::CommandLine::ForCurrentProcess();
231 if (command_line.HasSwitch(switches::kEnableOneCopy))
232 return true;
233 if (command_line.HasSwitch(switches::kDisableOneCopy))
234 return false;
236 #if defined(OS_ANDROID)
237 return false;
238 #endif
239 return true;
242 bool IsZeroCopyUploadEnabled() {
243 const base::CommandLine& command_line =
244 *base::CommandLine::ForCurrentProcess();
245 // Single-threaded mode in the renderer process (for layout tests) is
246 // synchronous, which depends on tiles being ready to draw when raster is
247 // complete. Therefore, it must use one of zero copy, software raster, or
248 // GPU raster. So we force zero-copy on for the case where software/GPU raster
249 // is not used.
250 // TODO(reveman): One-copy can work with sync compositing: crbug.com/490295.
251 if (command_line.HasSwitch(switches::kDisableThreadedCompositing))
252 return true;
253 return command_line.HasSwitch(switches::kEnableZeroCopy);
256 bool IsGpuRasterizationEnabled() {
257 const base::CommandLine& command_line =
258 *base::CommandLine::ForCurrentProcess();
260 if (command_line.HasSwitch(switches::kDisableGpuRasterization))
261 return false;
262 else if (command_line.HasSwitch(switches::kEnableGpuRasterization))
263 return true;
265 if (IsGpuRasterizationBlacklisted()) {
266 return false;
269 #if defined(OS_ANDROID)
270 return true;
271 #endif
273 // explicitly disable GPU rasterization on all non-android devices until we
274 // have full test coverage.
275 return false;
278 bool IsForceGpuRasterizationEnabled() {
279 const base::CommandLine& command_line =
280 *base::CommandLine::ForCurrentProcess();
281 return command_line.HasSwitch(switches::kForceGpuRasterization);
284 bool UseSurfacesEnabled() {
285 #if defined(OS_ANDROID)
286 return false;
287 #endif
288 bool enabled = false;
289 #if defined(USE_AURA) || defined(OS_MACOSX)
290 enabled = true;
291 #endif
293 const base::CommandLine& command_line =
294 *base::CommandLine::ForCurrentProcess();
296 // Flags override.
297 enabled |= command_line.HasSwitch(switches::kUseSurfaces);
298 enabled &= !command_line.HasSwitch(switches::kDisableSurfaces);
299 return enabled;
302 int GpuRasterizationMSAASampleCount() {
303 const base::CommandLine& command_line =
304 *base::CommandLine::ForCurrentProcess();
306 if (!command_line.HasSwitch(switches::kGpuRasterizationMSAASampleCount))
307 #if defined(OS_ANDROID)
308 return 4;
309 #else
310 return 8;
311 #endif
312 std::string string_value = command_line.GetSwitchValueASCII(
313 switches::kGpuRasterizationMSAASampleCount);
314 int msaa_sample_count = 0;
315 if (base::StringToInt(string_value, &msaa_sample_count) &&
316 msaa_sample_count >= kMinMSAASampleCount) {
317 return msaa_sample_count;
318 } else {
319 DLOG(WARNING) << "Failed to parse switch "
320 << switches::kGpuRasterizationMSAASampleCount << ": "
321 << string_value;
322 return 0;
326 base::DictionaryValue* GetFeatureStatus() {
327 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
328 std::string gpu_access_blocked_reason;
329 bool gpu_access_blocked =
330 !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
332 base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
334 bool eof = false;
335 for (size_t i = 0; !eof; ++i) {
336 const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
337 std::string status;
338 if (gpu_feature_info.disabled) {
339 status = "disabled";
340 if (gpu_feature_info.fallback_to_software)
341 status += "_software";
342 else
343 status += "_off";
344 } else if (gpu_feature_info.blocked ||
345 gpu_access_blocked) {
346 status = "unavailable";
347 if (gpu_feature_info.fallback_to_software)
348 status += "_software";
349 else
350 status += "_off";
351 } else {
352 status = "enabled";
353 if (gpu_feature_info.name == kWebGLFeatureName &&
354 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
355 status += "_readback";
356 if (gpu_feature_info.name == kRasterizationFeatureName) {
357 if (IsForceGpuRasterizationEnabled())
358 status += "_force";
360 if (gpu_feature_info.name == kMultipleRasterThreadsFeatureName) {
361 const base::CommandLine& command_line =
362 *base::CommandLine::ForCurrentProcess();
363 if (command_line.HasSwitch(switches::kNumRasterThreads))
364 status += "_force";
366 if (gpu_feature_info.name == kMultipleRasterThreadsFeatureName)
367 status += "_on";
369 if (gpu_feature_info.name == kWebGLFeatureName &&
370 (gpu_feature_info.blocked || gpu_access_blocked) &&
371 manager->ShouldUseSwiftShader()) {
372 status = "unavailable_software";
375 feature_status_dict->SetString(
376 gpu_feature_info.name.c_str(), status.c_str());
378 return feature_status_dict;
381 base::Value* GetProblems() {
382 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
383 std::string gpu_access_blocked_reason;
384 bool gpu_access_blocked =
385 !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
387 base::ListValue* problem_list = new base::ListValue();
388 manager->GetBlacklistReasons(problem_list);
390 if (gpu_access_blocked) {
391 base::DictionaryValue* problem = new base::DictionaryValue();
392 problem->SetString("description",
393 "GPU process was unable to boot: " + gpu_access_blocked_reason);
394 problem->Set("crBugs", new base::ListValue());
395 problem->Set("webkitBugs", new base::ListValue());
396 base::ListValue* disabled_features = new base::ListValue();
397 disabled_features->AppendString("all");
398 problem->Set("affectedGpuSettings", disabled_features);
399 problem->SetString("tag", "disabledFeatures");
400 problem_list->Insert(0, problem);
403 bool eof = false;
404 for (size_t i = 0; !eof; ++i) {
405 const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
406 if (gpu_feature_info.disabled) {
407 base::DictionaryValue* problem = new base::DictionaryValue();
408 problem->SetString(
409 "description", gpu_feature_info.disabled_description);
410 problem->Set("crBugs", new base::ListValue());
411 problem->Set("webkitBugs", new base::ListValue());
412 base::ListValue* disabled_features = new base::ListValue();
413 disabled_features->AppendString(gpu_feature_info.name);
414 problem->Set("affectedGpuSettings", disabled_features);
415 problem->SetString("tag", "disabledFeatures");
416 problem_list->Append(problem);
419 return problem_list;
422 std::vector<std::string> GetDriverBugWorkarounds() {
423 return GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds();
426 } // namespace content