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