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 const char* kGpuCompositingFeatureName
= "gpu_compositing";
20 const char* kWebGLFeatureName
= "webgl";
21 const char* kRasterizationFeatureName
= "rasterization";
23 struct GpuFeatureInfo
{
27 std::string disabled_description
;
28 bool fallback_to_software
;
31 const GpuFeatureInfo
GetGpuFeatureInfo(size_t index
, bool* eof
) {
32 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
33 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
35 const GpuFeatureInfo kGpuFeatureInfo
[] = {
38 manager
->IsFeatureBlacklisted(
39 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS
),
40 command_line
.HasSwitch(switches::kDisableAccelerated2dCanvas
) ||
41 !GpuDataManagerImpl::GetInstance()->
42 GetGPUInfo().SupportsAccelerated2dCanvas(),
43 "Accelerated 2D canvas is unavailable: either disabled at the command"
44 " line or not supported by the current system.",
48 kGpuCompositingFeatureName
,
49 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING
),
51 "Gpu compositing has been disabled, either via about:flags or"
52 " command line. The browser will fall back to software compositing"
53 " and hardware acceleration will be unavailable.",
58 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL
),
59 command_line
.HasSwitch(switches::kDisableExperimentalWebGL
),
60 "WebGL has been disabled, either via about:flags or command line.",
65 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D
),
66 command_line
.HasSwitch(switches::kDisableFlash3d
),
67 "Using 3d in flash has been disabled, either via about:flags or"
73 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D
),
74 command_line
.HasSwitch(switches::kDisableFlashStage3d
),
75 "Using Stage3d in Flash has been disabled, either via about:flags or"
80 "flash_stage3d_baseline",
81 manager
->IsFeatureBlacklisted(
82 gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE
) ||
83 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D
),
84 command_line
.HasSwitch(switches::kDisableFlashStage3d
),
85 "Using Stage3d Baseline profile in Flash has been disabled, either"
86 " via about:flags or command line.",
91 manager
->IsFeatureBlacklisted(
92 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE
),
93 command_line
.HasSwitch(switches::kDisableAcceleratedVideoDecode
),
94 "Accelerated video decode has been disabled, either via about:flags"
98 #if defined(ENABLE_WEBRTC)
101 manager
->IsFeatureBlacklisted(
102 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE
),
103 command_line
.HasSwitch(switches::kDisableWebRtcHWEncoding
),
104 "Accelerated video encode has been disabled, either via about:flags"
109 #if defined(OS_CHROMEOS)
112 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING
),
113 command_line
.HasSwitch(switches::kDisablePanelFitting
),
114 "Panel fitting has been disabled, either via about:flags or command"
120 kRasterizationFeatureName
,
121 manager
->IsFeatureBlacklisted(
122 gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION
) &&
123 !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled(),
124 !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled() &&
125 !manager
->IsFeatureBlacklisted(
126 gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION
),
127 "Accelerated rasterization has not been enabled or"
128 " is not supported by the current system.",
132 DCHECK(index
< arraysize(kGpuFeatureInfo
));
133 *eof
= (index
== arraysize(kGpuFeatureInfo
) - 1);
134 return kGpuFeatureInfo
[index
];
139 bool IsPinchVirtualViewportEnabled() {
140 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
142 // Command line switches take precedence over platform default.
143 if (command_line
.HasSwitch(cc::switches::kDisablePinchVirtualViewport
))
145 if (command_line
.HasSwitch(cc::switches::kEnablePinchVirtualViewport
))
148 #if defined(OS_CHROMEOS)
155 bool IsThreadedCompositingEnabled() {
156 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
158 // Command line switches take precedence over blacklist.
159 if (command_line
.HasSwitch(switches::kDisableThreadedCompositing
))
161 if (command_line
.HasSwitch(switches::kEnableThreadedCompositing
))
164 #if defined(USE_AURA) || defined(OS_MACOSX)
165 // We always want threaded compositing on Aura and Mac (the fallback is a
166 // threaded software compositor).
173 bool IsDelegatedRendererEnabled() {
174 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
175 bool enabled
= false;
177 #if defined(USE_AURA)
183 enabled
|= command_line
.HasSwitch(switches::kEnableDelegatedRenderer
);
184 enabled
&= !command_line
.HasSwitch(switches::kDisableDelegatedRenderer
);
186 // Needs compositing, and thread.
187 if (enabled
&& !IsThreadedCompositingEnabled()) {
189 LOG(ERROR
) << "Disabling delegated-rendering because it needs "
190 << "force-compositing-mode and threaded-compositing.";
196 bool IsImplSidePaintingEnabled() {
197 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
199 if (command_line
.HasSwitch(switches::kDisableImplSidePainting
))
201 else if (command_line
.HasSwitch(switches::kEnableImplSidePainting
))
203 else if (command_line
.HasSwitch(
204 switches::kEnableBleedingEdgeRenderingFastPaths
))
207 #if defined(OS_MACOSX)
210 return IsThreadedCompositingEnabled();
214 bool IsGpuRasterizationEnabled() {
215 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
217 if (!IsImplSidePaintingEnabled())
220 if (command_line
.HasSwitch(switches::kDisableGpuRasterization
))
222 else if (command_line
.HasSwitch(switches::kEnableGpuRasterization
))
225 if (GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
226 gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION
)) {
233 bool IsForceGpuRasterizationEnabled() {
234 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
236 if (!IsImplSidePaintingEnabled())
239 return command_line
.HasSwitch(switches::kForceGpuRasterization
);
242 base::Value
* GetFeatureStatus() {
243 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
244 std::string gpu_access_blocked_reason
;
245 bool gpu_access_blocked
=
246 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
248 base::DictionaryValue
* feature_status_dict
= new base::DictionaryValue();
251 for (size_t i
= 0; !eof
; ++i
) {
252 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
, &eof
);
254 if (gpu_feature_info
.disabled
) {
256 if (gpu_feature_info
.name
== kRasterizationFeatureName
) {
257 if (IsImplSidePaintingEnabled())
258 status
+= "_software_multithreaded";
260 status
+= "_software";
262 if (gpu_feature_info
.fallback_to_software
)
263 status
+= "_software";
267 } else if (manager
->ShouldUseSwiftShader()) {
268 status
= "unavailable_software";
269 } else if (gpu_feature_info
.blocked
||
270 gpu_access_blocked
) {
271 status
= "unavailable";
272 if (gpu_feature_info
.fallback_to_software
)
273 status
+= "_software";
278 if (gpu_feature_info
.name
== kWebGLFeatureName
&&
279 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING
))
280 status
+= "_readback";
281 if (gpu_feature_info
.name
== kRasterizationFeatureName
) {
282 if (IsForceGpuRasterizationEnabled())
286 if (gpu_feature_info
.name
== kGpuCompositingFeatureName
) {
287 if (IsThreadedCompositingEnabled())
288 status
+= "_threaded";
290 feature_status_dict
->SetString(
291 gpu_feature_info
.name
.c_str(), status
.c_str());
293 return feature_status_dict
;
296 base::Value
* GetProblems() {
297 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
298 std::string gpu_access_blocked_reason
;
299 bool gpu_access_blocked
=
300 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
302 base::ListValue
* problem_list
= new base::ListValue();
303 manager
->GetBlacklistReasons(problem_list
);
305 if (gpu_access_blocked
) {
306 base::DictionaryValue
* problem
= new base::DictionaryValue();
307 problem
->SetString("description",
308 "GPU process was unable to boot: " + gpu_access_blocked_reason
);
309 problem
->Set("crBugs", new base::ListValue());
310 problem
->Set("webkitBugs", new base::ListValue());
311 base::ListValue
* disabled_features
= new base::ListValue();
312 disabled_features
->AppendString("all");
313 problem
->Set("affectedGpuSettings", disabled_features
);
314 problem
->SetString("tag", "disabledFeatures");
315 problem_list
->Insert(0, problem
);
319 for (size_t i
= 0; !eof
; ++i
) {
320 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
, &eof
);
321 if (gpu_feature_info
.disabled
) {
322 base::DictionaryValue
* problem
= new base::DictionaryValue();
324 "description", gpu_feature_info
.disabled_description
);
325 problem
->Set("crBugs", new base::ListValue());
326 problem
->Set("webkitBugs", new base::ListValue());
327 base::ListValue
* disabled_features
= new base::ListValue();
328 disabled_features
->AppendString(gpu_feature_info
.name
);
329 problem
->Set("affectedGpuSettings", disabled_features
);
330 problem
->SetString("tag", "disabledFeatures");
331 problem_list
->Append(problem
);
337 base::Value
* GetDriverBugWorkarounds() {
338 base::ListValue
* workaround_list
= new base::ListValue();
339 GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list
);
340 return workaround_list
;
343 } // namespace content