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 #if defined(OS_CHROMEOS)
28 const size_t kNumFeatures
= 14;
30 const size_t kNumFeatures
= 13;
32 const GpuFeatureInfo
GetGpuFeatureInfo(size_t index
) {
33 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
34 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
36 const GpuFeatureInfo kGpuFeatureInfo
[] = {
39 manager
->IsFeatureBlacklisted(
40 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS
),
41 command_line
.HasSwitch(switches::kDisableAccelerated2dCanvas
) ||
42 !GpuDataManagerImpl::GetInstance()->
43 GetGPUInfo().SupportsAccelerated2dCanvas(),
44 "Accelerated 2D canvas is unavailable: either disabled at the command"
45 " line or not supported by the current system.",
50 manager
->IsFeatureBlacklisted(
51 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
),
52 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
),
53 "Accelerated compositing has been disabled, either via about:flags or"
54 " command line. This adversely affects performance of all hardware"
55 " accelerated features.",
60 manager
->IsFeatureBlacklisted(
61 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
) ||
62 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS
),
63 command_line
.HasSwitch(switches::kDisableAcceleratedLayers
),
64 "Accelerated layers have been disabled at the command line.",
69 manager
->IsFeatureBlacklisted(
70 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
) ||
71 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS
),
72 command_line
.HasSwitch(cc::switches::kDisableThreadedAnimation
) ||
73 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
) ||
74 command_line
.HasSwitch(switches::kDisableAcceleratedLayers
),
75 "Accelerated CSS animation has been disabled at the command line.",
80 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL
),
81 command_line
.HasSwitch(switches::kDisableExperimentalWebGL
),
82 "WebGL has been disabled, either via about:flags or command line.",
87 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING
),
88 command_line
.HasSwitch(switches::kDisableGLMultisampling
),
89 "Multisampling has been disabled, either via about:flags or command"
95 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D
),
96 command_line
.HasSwitch(switches::kDisableFlash3d
),
97 "Using 3d in flash has been disabled, either via about:flags or"
103 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D
),
104 command_line
.HasSwitch(switches::kDisableFlashStage3d
),
105 "Using Stage3d in Flash has been disabled, either via about:flags or"
110 "flash_stage3d_baseline",
111 manager
->IsFeatureBlacklisted(
112 gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE
) ||
113 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D
),
114 command_line
.HasSwitch(switches::kDisableFlashStage3d
),
115 "Using Stage3d Baseline profile in Flash has been disabled, either"
116 " via about:flags or command line.",
121 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING
),
122 command_line
.HasSwitch(switches::kDisableImageTransportSurface
),
123 "Sharing textures between processes has been disabled, either via"
124 " about:flags or command line.",
129 manager
->IsFeatureBlacklisted(
130 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE
),
131 command_line
.HasSwitch(switches::kDisableAcceleratedVideoDecode
),
132 "Accelerated video decode has been disabled, either via about:flags"
138 manager
->IsFeatureBlacklisted(
139 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO
),
140 command_line
.HasSwitch(switches::kDisableAcceleratedVideo
) ||
141 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
),
142 "Accelerated video presentation has been disabled, either via"
143 " about:flags or command line.",
146 #if defined(OS_CHROMEOS)
149 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING
),
150 command_line
.HasSwitch(switches::kDisablePanelFitting
),
151 "Panel fitting has been disabled, either via about:flags or command"
157 "force_compositing_mode",
158 manager
->IsFeatureBlacklisted(
159 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
) &&
160 !IsForceCompositingModeEnabled(),
161 !IsForceCompositingModeEnabled() &&
162 !manager
->IsFeatureBlacklisted(
163 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
),
164 "Force compositing mode is off, either disabled at the command"
165 " line or not supported by the current system.",
169 return kGpuFeatureInfo
[index
];
172 bool CanDoAcceleratedCompositing() {
173 const GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
175 // Don't use force compositing mode if gpu access has been blocked or
176 // accelerated compositing is blacklisted.
177 if (!manager
->GpuAccessAllowed(NULL
) ||
178 manager
->IsFeatureBlacklisted(
179 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
))
182 // Check for SwiftShader.
183 if (manager
->ShouldUseSwiftShader())
186 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
187 if (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
))
193 bool IsForceCompositingModeBlacklisted() {
194 return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
195 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
);
200 bool IsThreadedCompositingEnabled() {
201 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
203 // Command line switches take precedence over blacklist.
204 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
) ||
205 command_line
.HasSwitch(switches::kDisableThreadedCompositing
)) {
207 } else if (command_line
.HasSwitch(switches::kEnableThreadedCompositing
)) {
211 #if defined(USE_AURA)
212 // We always want threaded compositing on Aura.
216 if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
219 #if defined(OS_MACOSX) || defined(OS_WIN)
220 // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
221 // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
222 // false before this hits on unsupported Win/Mac versions.
229 bool IsForceCompositingModeEnabled() {
230 // Force compositing mode is a subset of threaded compositing mode.
231 if (IsThreadedCompositingEnabled())
234 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
236 // Command line switches take precedence over blacklisting.
237 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
))
239 else if (command_line
.HasSwitch(switches::kForceCompositingMode
))
242 if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
245 #if defined(OS_MACOSX) || defined(OS_WIN)
246 // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
247 // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
248 // false before this hits on unsupported Win/Mac versions.
255 bool IsDelegatedRendererEnabled() {
256 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
257 bool enabled
= false;
259 #if defined(USE_AURA)
265 enabled
|= command_line
.HasSwitch(switches::kEnableDelegatedRenderer
);
266 enabled
&= !command_line
.HasSwitch(switches::kDisableDelegatedRenderer
);
268 // Needs compositing, and thread.
270 (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
272 LOG(ERROR
) << "Disabling delegated-rendering because it needs "
273 << "force-compositing-mode and threaded-compositing.";
279 bool IsDeadlineSchedulingEnabled() {
280 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
282 // Default to enabled.
286 enabled
|= command_line
.HasSwitch(switches::kEnableDeadlineScheduling
);
287 enabled
&= !command_line
.HasSwitch(switches::kDisableDeadlineScheduling
);
292 base::Value
* GetFeatureStatus() {
293 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
294 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
295 std::string gpu_access_blocked_reason
;
296 bool gpu_access_blocked
=
297 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
299 base::DictionaryValue
* feature_status_dict
= new base::DictionaryValue();
301 for (size_t i
= 0; i
< kNumFeatures
; ++i
) {
302 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
);
303 // force_compositing_mode status is part of the compositing status.
304 if (gpu_feature_info
.name
== "force_compositing_mode")
308 if (gpu_feature_info
.disabled
) {
310 if (gpu_feature_info
.name
== "css_animation") {
311 status
+= "_software_animated";
312 } else if (gpu_feature_info
.name
== "raster") {
313 if (cc::switches::IsImplSidePaintingEnabled())
314 status
+= "_software_multithreaded";
316 status
+= "_software";
318 if (gpu_feature_info
.fallback_to_software
)
319 status
+= "_software";
323 } else if (manager
->ShouldUseSwiftShader()) {
324 status
= "unavailable_software";
325 } else if (gpu_feature_info
.blocked
||
326 gpu_access_blocked
) {
327 status
= "unavailable";
328 if (gpu_feature_info
.fallback_to_software
)
329 status
+= "_software";
334 if (gpu_feature_info
.name
== "webgl" &&
335 (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
) ||
336 manager
->IsFeatureBlacklisted(
337 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
)))
338 status
+= "_readback";
339 bool has_thread
= IsThreadedCompositingEnabled();
340 if (gpu_feature_info
.name
== "compositing") {
341 bool force_compositing
= IsForceCompositingModeEnabled();
342 if (force_compositing
)
345 status
+= "_threaded";
347 if (gpu_feature_info
.name
== "css_animation") {
349 status
= "accelerated_threaded";
351 status
= "accelerated";
354 // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
355 if (gpu_feature_info
.name
== "raster" &&
356 cc::switches::IsImplSidePaintingEnabled()) {
357 status
= "disabled_software_multithreaded";
359 feature_status_dict
->SetString(
360 gpu_feature_info
.name
.c_str(), status
.c_str());
362 return feature_status_dict
;
365 base::Value
* GetProblems() {
366 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
367 std::string gpu_access_blocked_reason
;
368 bool gpu_access_blocked
=
369 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
371 base::ListValue
* problem_list
= new base::ListValue();
372 manager
->GetBlacklistReasons(problem_list
);
374 if (gpu_access_blocked
) {
375 base::DictionaryValue
* problem
= new base::DictionaryValue();
376 problem
->SetString("description",
377 "GPU process was unable to boot: " + gpu_access_blocked_reason
);
378 problem
->Set("crBugs", new base::ListValue());
379 problem
->Set("webkitBugs", new base::ListValue());
380 problem_list
->Insert(0, problem
);
383 for (size_t i
= 0; i
< kNumFeatures
; ++i
) {
384 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
);
385 if (gpu_feature_info
.disabled
) {
386 base::DictionaryValue
* problem
= new base::DictionaryValue();
388 "description", gpu_feature_info
.disabled_description
);
389 problem
->Set("crBugs", new base::ListValue());
390 problem
->Set("webkitBugs", new base::ListValue());
391 problem_list
->Append(problem
);
397 base::Value
* GetDriverBugWorkarounds() {
398 base::ListValue
* workaround_list
= new base::ListValue();
399 GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list
);
400 return workaround_list
;
403 } // namespace content