• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/gpu/compositor_util.h"
6 
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"
14 
15 namespace content {
16 
17 namespace {
18 
19 struct GpuFeatureInfo {
20   std::string name;
21   uint32 blocked;
22   bool disabled;
23   std::string disabled_description;
24   bool fallback_to_software;
25 };
26 
27 #if defined(OS_CHROMEOS)
28 const size_t kNumFeatures = 14;
29 #else
30 const size_t kNumFeatures = 13;
31 #endif
GetGpuFeatureInfo(size_t index)32 const GpuFeatureInfo GetGpuFeatureInfo(size_t index) {
33   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
34   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
35 
36   const GpuFeatureInfo kGpuFeatureInfo[] = {
37       {
38           "2d_canvas",
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.",
46           true
47       },
48       {
49           "compositing",
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.",
56           true
57       },
58       {
59           "3d_css",
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.",
65           false
66       },
67       {
68           "css_animation",
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.",
76           true
77       },
78       {
79           "webgl",
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.",
83           false
84       },
85       {
86           "multisampling",
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"
90           " line.",
91           false
92       },
93       {
94           "flash_3d",
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"
98           " command line.",
99           false
100       },
101       {
102           "flash_stage3d",
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"
106           " command line.",
107           false
108       },
109       {
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.",
117           false
118       },
119       {
120           "texture_sharing",
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.",
125           false
126       },
127       {
128           "video_decode",
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"
133           " or command line.",
134           true
135       },
136 #if defined(ENABLE_WEBRTC)
137       {
138           "video_encode",
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"
143           " or command line.",
144           true
145       },
146 #endif
147       {
148           "video",
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.",
155           true
156       },
157 #if defined(OS_CHROMEOS)
158       {
159           "panel_fitting",
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"
163           " line.",
164           false
165       },
166 #endif
167       {
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.",
177           false
178       },
179   };
180   return kGpuFeatureInfo[index];
181 }
182 
CanDoAcceleratedCompositing()183 bool CanDoAcceleratedCompositing() {
184   const GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
185 
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))
191     return false;
192 
193   // Check for SwiftShader.
194   if (manager->ShouldUseSwiftShader())
195     return false;
196 
197   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
198   if (command_line.HasSwitch(switches::kDisableAcceleratedCompositing))
199     return false;
200 
201   return true;
202 }
203 
IsForceCompositingModeBlacklisted()204 bool IsForceCompositingModeBlacklisted() {
205   return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
206       gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
207 }
208 
209 }  // namespace
210 
IsThreadedCompositingEnabled()211 bool IsThreadedCompositingEnabled() {
212   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
213 
214   // Command line switches take precedence over blacklist.
215   if (command_line.HasSwitch(switches::kDisableForceCompositingMode) ||
216       command_line.HasSwitch(switches::kDisableThreadedCompositing)) {
217     return false;
218   } else if (command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
219     return true;
220   }
221 
222 #if defined(USE_AURA)
223   // We always want threaded compositing on Aura.
224   return true;
225 #endif
226 
227   if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
228     return false;
229 
230 #if defined(OS_MACOSX) || defined(OS_WIN)
231   // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
232   // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
233   // false before this hits on unsupported Win/Mac versions.
234   return true;
235 #endif
236 
237   return false;
238 }
239 
IsForceCompositingModeEnabled()240 bool IsForceCompositingModeEnabled() {
241   // Force compositing mode is a subset of threaded compositing mode.
242   if (IsThreadedCompositingEnabled())
243     return true;
244 
245   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
246 
247   // Command line switches take precedence over blacklisting.
248   if (command_line.HasSwitch(switches::kDisableForceCompositingMode))
249     return false;
250   else if (command_line.HasSwitch(switches::kForceCompositingMode))
251     return true;
252 
253   if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
254     return false;
255 
256 #if defined(OS_MACOSX) || defined(OS_WIN)
257   // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
258   // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
259   // false before this hits on unsupported Win/Mac versions.
260   return true;
261 #endif
262 
263   return false;
264 }
265 
IsDelegatedRendererEnabled()266 bool IsDelegatedRendererEnabled() {
267   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
268   bool enabled = false;
269 
270 #if defined(USE_AURA)
271   // Enable on Aura.
272   enabled = true;
273 #endif
274 
275   // Flags override.
276   enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
277   enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
278 
279   // Needs compositing, and thread.
280   if (enabled &&
281       (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
282     enabled = false;
283     LOG(ERROR) << "Disabling delegated-rendering because it needs "
284                << "force-compositing-mode and threaded-compositing.";
285   }
286 
287   return enabled;
288 }
289 
IsDeadlineSchedulingEnabled()290 bool IsDeadlineSchedulingEnabled() {
291   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
292 
293   // Default to enabled.
294   bool enabled = true;
295 
296   // Flags override.
297   enabled |= command_line.HasSwitch(switches::kEnableDeadlineScheduling);
298   enabled &= !command_line.HasSwitch(switches::kDisableDeadlineScheduling);
299 
300   return enabled;
301 }
302 
GetFeatureStatus()303 base::Value* GetFeatureStatus() {
304   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
305   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
306   std::string gpu_access_blocked_reason;
307   bool gpu_access_blocked =
308       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
309 
310   base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
311 
312   for (size_t i = 0; i < kNumFeatures; ++i) {
313     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
314     // force_compositing_mode status is part of the compositing status.
315     if (gpu_feature_info.name == "force_compositing_mode")
316       continue;
317 
318     std::string status;
319     if (gpu_feature_info.disabled) {
320       status = "disabled";
321       if (gpu_feature_info.name == "css_animation") {
322         status += "_software_animated";
323       } else if (gpu_feature_info.name == "raster") {
324         if (cc::switches::IsImplSidePaintingEnabled())
325           status += "_software_multithreaded";
326         else
327           status += "_software";
328       } else {
329         if (gpu_feature_info.fallback_to_software)
330           status += "_software";
331         else
332           status += "_off";
333       }
334     } else if (manager->ShouldUseSwiftShader()) {
335       status = "unavailable_software";
336     } else if (gpu_feature_info.blocked ||
337                gpu_access_blocked) {
338       status = "unavailable";
339       if (gpu_feature_info.fallback_to_software)
340         status += "_software";
341       else
342         status += "_off";
343     } else {
344       status = "enabled";
345       if (gpu_feature_info.name == "webgl" &&
346           (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
347            manager->IsFeatureBlacklisted(
348                gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
349         status += "_readback";
350       bool has_thread = IsThreadedCompositingEnabled();
351       if (gpu_feature_info.name == "compositing") {
352         bool force_compositing = IsForceCompositingModeEnabled();
353         if (force_compositing)
354           status += "_force";
355         if (has_thread)
356           status += "_threaded";
357       }
358       if (gpu_feature_info.name == "css_animation") {
359         if (has_thread)
360           status = "accelerated_threaded";
361         else
362           status = "accelerated";
363       }
364     }
365     // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
366     if (gpu_feature_info.name == "raster" &&
367         cc::switches::IsImplSidePaintingEnabled()) {
368       status = "disabled_software_multithreaded";
369     }
370     feature_status_dict->SetString(
371         gpu_feature_info.name.c_str(), status.c_str());
372   }
373   return feature_status_dict;
374 }
375 
GetProblems()376 base::Value* GetProblems() {
377   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
378   std::string gpu_access_blocked_reason;
379   bool gpu_access_blocked =
380       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
381 
382   base::ListValue* problem_list = new base::ListValue();
383   manager->GetBlacklistReasons(problem_list);
384 
385   if (gpu_access_blocked) {
386     base::DictionaryValue* problem = new base::DictionaryValue();
387     problem->SetString("description",
388         "GPU process was unable to boot: " + gpu_access_blocked_reason);
389     problem->Set("crBugs", new base::ListValue());
390     problem->Set("webkitBugs", new base::ListValue());
391     problem_list->Insert(0, problem);
392   }
393 
394   for (size_t i = 0; i < kNumFeatures; ++i) {
395     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
396     if (gpu_feature_info.disabled) {
397       base::DictionaryValue* problem = new base::DictionaryValue();
398       problem->SetString(
399           "description", gpu_feature_info.disabled_description);
400       problem->Set("crBugs", new base::ListValue());
401       problem->Set("webkitBugs", new base::ListValue());
402       problem_list->Append(problem);
403     }
404   }
405   return problem_list;
406 }
407 
GetDriverBugWorkarounds()408 base::Value* GetDriverBugWorkarounds() {
409   base::ListValue* workaround_list = new base::ListValue();
410   GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
411   return workaround_list;
412 }
413 
414 }  // namespace content
415