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 "build/build_config.h"
10 #include "cc/base/switches.h"
11 #include "content/browser/gpu/gpu_data_manager_impl.h"
12 #include "content/public/common/content_switches.h"
13 #include "gpu/config/gpu_feature_type.h"
19 struct GpuFeatureInfo
{
23 std::string disabled_description
;
24 bool fallback_to_software
;
27 const GpuFeatureInfo
GetGpuFeatureInfo(size_t index
, bool* eof
) {
28 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
29 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
31 const GpuFeatureInfo kGpuFeatureInfo
[] = {
34 manager
->IsFeatureBlacklisted(
35 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS
),
36 command_line
.HasSwitch(switches::kDisableAccelerated2dCanvas
) ||
37 !GpuDataManagerImpl::GetInstance()->
38 GetGPUInfo().SupportsAccelerated2dCanvas(),
39 "Accelerated 2D canvas is unavailable: either disabled at the command"
40 " line or not supported by the current system.",
45 manager
->IsFeatureBlacklisted(
46 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
),
47 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
),
48 "Accelerated compositing has been disabled, either via about:flags or"
49 " command line. This adversely affects performance of all hardware"
50 " accelerated features.",
55 manager
->IsFeatureBlacklisted(
56 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
) ||
57 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS
),
58 command_line
.HasSwitch(switches::kDisableAcceleratedLayers
),
59 "Accelerated layers have been disabled at the command line.",
64 manager
->IsFeatureBlacklisted(
65 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
) ||
66 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS
),
67 command_line
.HasSwitch(cc::switches::kDisableThreadedAnimation
) ||
68 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
) ||
69 command_line
.HasSwitch(switches::kDisableAcceleratedLayers
),
70 "Accelerated CSS animation has been disabled at the command line.",
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.",
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"
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"
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.",
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"
115 #if defined(ENABLE_WEBRTC)
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"
128 manager
->IsFeatureBlacklisted(
129 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO
),
130 command_line
.HasSwitch(switches::kDisableAcceleratedVideo
) ||
131 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
),
132 "Accelerated video presentation has been disabled, either via"
133 " about:flags or command line.",
136 #if defined(OS_CHROMEOS)
139 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING
),
140 command_line
.HasSwitch(switches::kDisablePanelFitting
),
141 "Panel fitting has been disabled, either via about:flags or command"
147 "force_compositing_mode",
148 manager
->IsFeatureBlacklisted(
149 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
) &&
150 !IsForceCompositingModeEnabled(),
151 !IsForceCompositingModeEnabled() &&
152 !manager
->IsFeatureBlacklisted(
153 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
),
154 "Force compositing mode is off, either disabled at the command"
155 " line or not supported by the current system.",
159 DCHECK(index
< arraysize(kGpuFeatureInfo
));
160 *eof
= (index
== arraysize(kGpuFeatureInfo
) - 1);
161 return kGpuFeatureInfo
[index
];
164 bool CanDoAcceleratedCompositing() {
165 const GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
167 // Don't use force compositing mode if gpu access has been blocked or
168 // accelerated compositing is blacklisted.
169 if (!manager
->GpuAccessAllowed(NULL
) ||
170 manager
->IsFeatureBlacklisted(
171 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
))
174 // Check for SwiftShader.
175 if (manager
->ShouldUseSwiftShader())
178 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
179 if (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
))
185 bool IsForceCompositingModeBlacklisted() {
186 return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
187 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
);
192 bool IsThreadedCompositingEnabled() {
193 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
195 // Command line switches take precedence over blacklist.
196 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
) ||
197 command_line
.HasSwitch(switches::kDisableThreadedCompositing
))
199 if (command_line
.HasSwitch(switches::kEnableThreadedCompositing
))
202 #if defined(USE_AURA) || defined(OS_MACOSX)
203 // We always want threaded compositing on Aura and Mac (the fallback is a
204 // threaded software compositor).
211 bool IsForceCompositingModeEnabled() {
212 // Force compositing mode is a subset of threaded compositing mode.
213 if (IsThreadedCompositingEnabled())
216 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
218 // Command line switches take precedence over blacklisting.
219 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
))
221 if (command_line
.HasSwitch(switches::kForceCompositingMode
))
224 if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
227 #if defined(OS_MACOSX) || defined(OS_WIN)
228 // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
229 // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
230 // false before this hits on unsupported Win/Mac versions.
237 bool IsDelegatedRendererEnabled() {
238 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
239 bool enabled
= false;
241 #if defined(USE_AURA)
247 enabled
|= command_line
.HasSwitch(switches::kEnableDelegatedRenderer
);
248 enabled
&= !command_line
.HasSwitch(switches::kDisableDelegatedRenderer
);
250 // Needs compositing, and thread.
252 (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
254 LOG(ERROR
) << "Disabling delegated-rendering because it needs "
255 << "force-compositing-mode and threaded-compositing.";
261 bool IsImplSidePaintingEnabled() {
262 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
264 if (command_line
.HasSwitch(switches::kDisableImplSidePainting
))
266 else if (command_line
.HasSwitch(switches::kEnableImplSidePainting
))
269 #if defined(OS_ANDROID)
276 base::Value
* GetFeatureStatus() {
277 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
278 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
279 std::string gpu_access_blocked_reason
;
280 bool gpu_access_blocked
=
281 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
283 base::DictionaryValue
* feature_status_dict
= new base::DictionaryValue();
286 for (size_t i
= 0; !eof
; ++i
) {
287 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
, &eof
);
288 // force_compositing_mode status is part of the compositing status.
289 if (gpu_feature_info
.name
== "force_compositing_mode")
293 if (gpu_feature_info
.disabled
) {
295 if (gpu_feature_info
.name
== "css_animation") {
296 status
+= "_software_animated";
297 } else if (gpu_feature_info
.name
== "raster") {
298 if (IsImplSidePaintingEnabled())
299 status
+= "_software_multithreaded";
301 status
+= "_software";
303 if (gpu_feature_info
.fallback_to_software
)
304 status
+= "_software";
308 } else if (manager
->ShouldUseSwiftShader()) {
309 status
= "unavailable_software";
310 } else if (gpu_feature_info
.blocked
||
311 gpu_access_blocked
) {
312 status
= "unavailable";
313 if (gpu_feature_info
.fallback_to_software
)
314 status
+= "_software";
319 if (gpu_feature_info
.name
== "webgl" &&
320 (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
) ||
321 manager
->IsFeatureBlacklisted(
322 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
)))
323 status
+= "_readback";
324 bool has_thread
= IsThreadedCompositingEnabled();
325 if (gpu_feature_info
.name
== "compositing") {
326 bool force_compositing
= IsForceCompositingModeEnabled();
327 if (force_compositing
)
330 status
+= "_threaded";
332 if (gpu_feature_info
.name
== "css_animation") {
334 status
= "accelerated_threaded";
336 status
= "accelerated";
339 // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
340 if (gpu_feature_info
.name
== "raster" && IsImplSidePaintingEnabled())
341 status
= "disabled_software_multithreaded";
342 feature_status_dict
->SetString(
343 gpu_feature_info
.name
.c_str(), status
.c_str());
345 return feature_status_dict
;
348 base::Value
* GetProblems() {
349 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
350 std::string gpu_access_blocked_reason
;
351 bool gpu_access_blocked
=
352 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
354 base::ListValue
* problem_list
= new base::ListValue();
355 manager
->GetBlacklistReasons(problem_list
);
357 if (gpu_access_blocked
) {
358 base::DictionaryValue
* problem
= new base::DictionaryValue();
359 problem
->SetString("description",
360 "GPU process was unable to boot: " + gpu_access_blocked_reason
);
361 problem
->Set("crBugs", new base::ListValue());
362 problem
->Set("webkitBugs", new base::ListValue());
363 base::ListValue
* disabled_features
= new base::ListValue();
364 disabled_features
->AppendString("all");
365 problem
->Set("affectedGpuSettings", disabled_features
);
366 problem
->SetString("tag", "disabledFeatures");
367 problem_list
->Insert(0, problem
);
371 for (size_t i
= 0; !eof
; ++i
) {
372 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
, &eof
);
373 if (gpu_feature_info
.disabled
) {
374 base::DictionaryValue
* problem
= new base::DictionaryValue();
376 "description", gpu_feature_info
.disabled_description
);
377 problem
->Set("crBugs", new base::ListValue());
378 problem
->Set("webkitBugs", new base::ListValue());
379 base::ListValue
* disabled_features
= new base::ListValue();
380 disabled_features
->AppendString(gpu_feature_info
.name
);
381 problem
->Set("affectedGpuSettings", disabled_features
);
382 problem
->SetString("tag", "disabledFeatures");
383 problem_list
->Append(problem
);
389 base::Value
* GetDriverBugWorkarounds() {
390 base::ListValue
* workaround_list
= new base::ListValue();
391 GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list
);
392 return workaround_list
;
395 } // namespace content