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"
136 #if defined(ENABLE_WEBRTC)
139 manager
->IsFeatureBlacklisted(
140 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE
),
141 command_line
.HasSwitch(switches::kDisableWebRtcHWEncoding
),
142 "Accelerated video encode has been disabled, either via about:flags"
149 manager
->IsFeatureBlacklisted(
150 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO
),
151 command_line
.HasSwitch(switches::kDisableAcceleratedVideo
) ||
152 command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
),
153 "Accelerated video presentation has been disabled, either via"
154 " about:flags or command line.",
157 #if defined(OS_CHROMEOS)
160 manager
->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING
),
161 command_line
.HasSwitch(switches::kDisablePanelFitting
),
162 "Panel fitting has been disabled, either via about:flags or command"
168 "force_compositing_mode",
169 manager
->IsFeatureBlacklisted(
170 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
) &&
171 !IsForceCompositingModeEnabled(),
172 !IsForceCompositingModeEnabled() &&
173 !manager
->IsFeatureBlacklisted(
174 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
),
175 "Force compositing mode is off, either disabled at the command"
176 " line or not supported by the current system.",
180 return kGpuFeatureInfo
[index
];
183 bool CanDoAcceleratedCompositing() {
184 const GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
186 // Don't use force compositing mode if gpu access has been blocked or
187 // accelerated compositing is blacklisted.
188 if (!manager
->GpuAccessAllowed(NULL
) ||
189 manager
->IsFeatureBlacklisted(
190 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
))
193 // Check for SwiftShader.
194 if (manager
->ShouldUseSwiftShader())
197 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
198 if (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
))
204 bool IsForceCompositingModeBlacklisted() {
205 return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
206 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE
);
211 bool IsThreadedCompositingEnabled() {
212 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
214 // Command line switches take precedence over blacklist.
215 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
) ||
216 command_line
.HasSwitch(switches::kDisableThreadedCompositing
)) {
218 } else if (command_line
.HasSwitch(switches::kEnableThreadedCompositing
)) {
222 #if defined(USE_AURA) || defined(OS_MACOSX)
223 // We always want threaded compositing on Aura and Mac (the fallback is a
224 // threaded software compositor).
228 if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
232 // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
233 // The blacklist check above takes care of returning false before this hits
234 // on unsupported Win versions.
241 bool IsForceCompositingModeEnabled() {
242 // Force compositing mode is a subset of threaded compositing mode.
243 if (IsThreadedCompositingEnabled())
246 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
248 // Command line switches take precedence over blacklisting.
249 if (command_line
.HasSwitch(switches::kDisableForceCompositingMode
))
251 else if (command_line
.HasSwitch(switches::kForceCompositingMode
))
254 if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
257 #if defined(OS_MACOSX) || defined(OS_WIN)
258 // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
259 // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
260 // false before this hits on unsupported Win/Mac versions.
267 bool IsDelegatedRendererEnabled() {
268 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
269 bool enabled
= false;
271 #if defined(USE_AURA)
277 enabled
|= command_line
.HasSwitch(switches::kEnableDelegatedRenderer
);
278 enabled
&= !command_line
.HasSwitch(switches::kDisableDelegatedRenderer
);
280 // Needs compositing, and thread.
282 (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
284 LOG(ERROR
) << "Disabling delegated-rendering because it needs "
285 << "force-compositing-mode and threaded-compositing.";
291 bool IsDeadlineSchedulingEnabled() {
292 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
294 // Default to enabled.
298 enabled
|= command_line
.HasSwitch(switches::kEnableDeadlineScheduling
);
299 enabled
&= !command_line
.HasSwitch(switches::kDisableDeadlineScheduling
);
304 base::Value
* GetFeatureStatus() {
305 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
306 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
307 std::string gpu_access_blocked_reason
;
308 bool gpu_access_blocked
=
309 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
311 base::DictionaryValue
* feature_status_dict
= new base::DictionaryValue();
313 for (size_t i
= 0; i
< kNumFeatures
; ++i
) {
314 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
);
315 // force_compositing_mode status is part of the compositing status.
316 if (gpu_feature_info
.name
== "force_compositing_mode")
320 if (gpu_feature_info
.disabled
) {
322 if (gpu_feature_info
.name
== "css_animation") {
323 status
+= "_software_animated";
324 } else if (gpu_feature_info
.name
== "raster") {
325 if (cc::switches::IsImplSidePaintingEnabled())
326 status
+= "_software_multithreaded";
328 status
+= "_software";
330 if (gpu_feature_info
.fallback_to_software
)
331 status
+= "_software";
335 } else if (manager
->ShouldUseSwiftShader()) {
336 status
= "unavailable_software";
337 } else if (gpu_feature_info
.blocked
||
338 gpu_access_blocked
) {
339 status
= "unavailable";
340 if (gpu_feature_info
.fallback_to_software
)
341 status
+= "_software";
346 if (gpu_feature_info
.name
== "webgl" &&
347 (command_line
.HasSwitch(switches::kDisableAcceleratedCompositing
) ||
348 manager
->IsFeatureBlacklisted(
349 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING
)))
350 status
+= "_readback";
351 bool has_thread
= IsThreadedCompositingEnabled();
352 if (gpu_feature_info
.name
== "compositing") {
353 bool force_compositing
= IsForceCompositingModeEnabled();
354 if (force_compositing
)
357 status
+= "_threaded";
359 if (gpu_feature_info
.name
== "css_animation") {
361 status
= "accelerated_threaded";
363 status
= "accelerated";
366 // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
367 if (gpu_feature_info
.name
== "raster" &&
368 cc::switches::IsImplSidePaintingEnabled()) {
369 status
= "disabled_software_multithreaded";
371 feature_status_dict
->SetString(
372 gpu_feature_info
.name
.c_str(), status
.c_str());
374 return feature_status_dict
;
377 base::Value
* GetProblems() {
378 GpuDataManagerImpl
* manager
= GpuDataManagerImpl::GetInstance();
379 std::string gpu_access_blocked_reason
;
380 bool gpu_access_blocked
=
381 !manager
->GpuAccessAllowed(&gpu_access_blocked_reason
);
383 base::ListValue
* problem_list
= new base::ListValue();
384 manager
->GetBlacklistReasons(problem_list
);
386 if (gpu_access_blocked
) {
387 base::DictionaryValue
* problem
= new base::DictionaryValue();
388 problem
->SetString("description",
389 "GPU process was unable to boot: " + gpu_access_blocked_reason
);
390 problem
->Set("crBugs", new base::ListValue());
391 problem
->Set("webkitBugs", new base::ListValue());
392 problem_list
->Insert(0, problem
);
395 for (size_t i
= 0; i
< kNumFeatures
; ++i
) {
396 const GpuFeatureInfo gpu_feature_info
= GetGpuFeatureInfo(i
);
397 if (gpu_feature_info
.disabled
) {
398 base::DictionaryValue
* problem
= new base::DictionaryValue();
400 "description", gpu_feature_info
.disabled_description
);
401 problem
->Set("crBugs", new base::ListValue());
402 problem
->Set("webkitBugs", new base::ListValue());
403 problem_list
->Append(problem
);
409 base::Value
* GetDriverBugWorkarounds() {
410 base::ListValue
* workaround_list
= new base::ListValue();
411 GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list
);
412 return workaround_list
;
415 } // namespace content