• 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 "base/metrics/field_trial.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "build/build_config.h"
12 #include "cc/base/switches.h"
13 #include "content/browser/gpu/gpu_data_manager_impl.h"
14 #include "content/public/common/content_switches.h"
15 #include "gpu/config/gpu_feature_type.h"
16 
17 namespace content {
18 
19 namespace {
20 
IsGpuRasterizationBlacklisted()21 static bool IsGpuRasterizationBlacklisted() {
22   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
23   return manager->IsFeatureBlacklisted(
24         gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION);
25 }
26 
27 const char* kGpuCompositingFeatureName = "gpu_compositing";
28 const char* kWebGLFeatureName = "webgl";
29 const char* kRasterizationFeatureName = "rasterization";
30 const char* kThreadedRasterizationFeatureName = "threaded_rasterization";
31 const char* kMultipleRasterThreadsFeatureName = "multiple_raster_threads";
32 
33 const int kMinRasterThreads = 1;
34 const int kMaxRasterThreads = 64;
35 
36 struct GpuFeatureInfo {
37   std::string name;
38   bool blocked;
39   bool disabled;
40   std::string disabled_description;
41   bool fallback_to_software;
42 };
43 
GetGpuFeatureInfo(size_t index,bool * eof)44 const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
45   const base::CommandLine& command_line =
46       *base::CommandLine::ForCurrentProcess();
47   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
48 
49   const GpuFeatureInfo kGpuFeatureInfo[] = {
50       {
51           "2d_canvas",
52           manager->IsFeatureBlacklisted(
53               gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
54           command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
55           !GpuDataManagerImpl::GetInstance()->
56               GetGPUInfo().SupportsAccelerated2dCanvas(),
57           "Accelerated 2D canvas is unavailable: either disabled at the command"
58           " line or not supported by the current system.",
59           true
60       },
61       {
62           kGpuCompositingFeatureName,
63           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING),
64           command_line.HasSwitch(switches::kDisableGpuCompositing),
65           "Gpu compositing has been disabled, either via about:flags or"
66           " command line. The browser will fall back to software compositing"
67           " and hardware acceleration will be unavailable.",
68           true
69       },
70       {
71           kWebGLFeatureName,
72           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
73           command_line.HasSwitch(switches::kDisableExperimentalWebGL),
74           "WebGL has been disabled, either via about:flags or command line.",
75           false
76       },
77       {
78           "flash_3d",
79           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
80           command_line.HasSwitch(switches::kDisableFlash3d),
81           "Using 3d in flash has been disabled, either via about:flags or"
82           " command line.",
83           true
84       },
85       {
86           "flash_stage3d",
87           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
88           command_line.HasSwitch(switches::kDisableFlashStage3d),
89           "Using Stage3d in Flash has been disabled, either via about:flags or"
90           " command line.",
91           true
92       },
93       {
94           "flash_stage3d_baseline",
95           manager->IsFeatureBlacklisted(
96               gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
97           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
98           command_line.HasSwitch(switches::kDisableFlashStage3d),
99           "Using Stage3d Baseline profile in Flash has been disabled, either"
100           " via about:flags or command line.",
101           true
102       },
103       {
104           "video_decode",
105           manager->IsFeatureBlacklisted(
106               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
107           command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
108           "Accelerated video decode has been disabled, either via about:flags"
109           " or command line.",
110           true
111       },
112 #if defined(ENABLE_WEBRTC)
113       {
114           "video_encode",
115           manager->IsFeatureBlacklisted(
116               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
117           command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
118           "Accelerated video encode has been disabled, either via about:flags"
119           " or command line.",
120           true
121       },
122 #endif
123 #if defined(OS_CHROMEOS)
124       {
125           "panel_fitting",
126           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
127           command_line.HasSwitch(switches::kDisablePanelFitting),
128           "Panel fitting has been disabled, either via about:flags or command"
129           " line.",
130           false
131       },
132 #endif
133       {
134           kRasterizationFeatureName,
135           IsGpuRasterizationBlacklisted() &&
136           !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled(),
137           !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled() &&
138           !IsGpuRasterizationBlacklisted(),
139           "Accelerated rasterization has been disabled, either via about:flags"
140           " or command line.",
141           true
142       },
143       {
144           kThreadedRasterizationFeatureName,
145           false,
146           !IsImplSidePaintingEnabled(),
147           "Threaded rasterization has not been enabled or"
148           " is not supported by the current system.",
149           false
150       },
151       {
152           kMultipleRasterThreadsFeatureName,
153           false,
154           NumberOfRendererRasterThreads() == 1,
155           "Raster is using a single thread.",
156           false
157       },
158   };
159   DCHECK(index < arraysize(kGpuFeatureInfo));
160   *eof = (index == arraysize(kGpuFeatureInfo) - 1);
161   return kGpuFeatureInfo[index];
162 }
163 
164 }  // namespace
165 
IsPinchVirtualViewportEnabled()166 bool IsPinchVirtualViewportEnabled() {
167   const base::CommandLine& command_line =
168       *base::CommandLine::ForCurrentProcess();
169 
170   // Command line switches take precedence over platform default.
171   if (command_line.HasSwitch(cc::switches::kDisablePinchVirtualViewport))
172     return false;
173   if (command_line.HasSwitch(cc::switches::kEnablePinchVirtualViewport))
174     return true;
175 
176 #if defined(OS_CHROMEOS)
177   return true;
178 #else
179   return false;
180 #endif
181 }
182 
IsDelegatedRendererEnabled()183 bool IsDelegatedRendererEnabled() {
184   const base::CommandLine& command_line =
185       *base::CommandLine::ForCurrentProcess();
186   bool enabled = false;
187 
188 #if defined(USE_AURA) || defined(OS_MACOSX)
189   // Enable on Aura and Mac.
190   enabled = true;
191 #endif
192 
193   // Flags override.
194   enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
195   enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
196   return enabled;
197 }
198 
IsImplSidePaintingEnabled()199 bool IsImplSidePaintingEnabled() {
200   const base::CommandLine& command_line =
201       *base::CommandLine::ForCurrentProcess();
202 
203   if (command_line.HasSwitch(switches::kDisableImplSidePainting))
204     return false;
205   else if (command_line.HasSwitch(switches::kEnableImplSidePainting))
206     return true;
207   else if (command_line.HasSwitch(
208       switches::kEnableBleedingEdgeRenderingFastPaths))
209     return true;
210 
211   return true;
212 }
213 
NumberOfRendererRasterThreads()214 int NumberOfRendererRasterThreads() {
215   int num_raster_threads = 1;
216 
217   int force_num_raster_threads = ForceNumberOfRendererRasterThreads();
218   if (force_num_raster_threads)
219     num_raster_threads = force_num_raster_threads;
220 
221   return num_raster_threads;
222 }
223 
ForceNumberOfRendererRasterThreads()224 int ForceNumberOfRendererRasterThreads() {
225   const base::CommandLine& command_line =
226       *base::CommandLine::ForCurrentProcess();
227 
228   if (!command_line.HasSwitch(switches::kNumRasterThreads))
229     return 0;
230   std::string string_value =
231       command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
232   int force_num_raster_threads = 0;
233   if (base::StringToInt(string_value, &force_num_raster_threads) &&
234       force_num_raster_threads >= kMinRasterThreads &&
235       force_num_raster_threads <= kMaxRasterThreads) {
236     return force_num_raster_threads;
237   } else {
238     LOG(WARNING) << "Failed to parse switch " <<
239         switches::kNumRasterThreads  << ": " << string_value;
240     return 0;
241   }
242 }
243 
IsGpuRasterizationEnabled()244 bool IsGpuRasterizationEnabled() {
245   const base::CommandLine& command_line =
246       *base::CommandLine::ForCurrentProcess();
247 
248   if (!IsImplSidePaintingEnabled())
249     return false;
250 
251   if (command_line.HasSwitch(switches::kDisableGpuRasterization))
252     return false;
253   else if (command_line.HasSwitch(switches::kEnableGpuRasterization))
254     return true;
255 
256   if (IsGpuRasterizationBlacklisted()) {
257     return false;
258   }
259 
260   return true;
261 }
262 
IsForceGpuRasterizationEnabled()263 bool IsForceGpuRasterizationEnabled() {
264   const base::CommandLine& command_line =
265       *base::CommandLine::ForCurrentProcess();
266 
267   if (!IsImplSidePaintingEnabled())
268     return false;
269 
270   return command_line.HasSwitch(switches::kForceGpuRasterization);
271 }
272 
UseSurfacesEnabled()273 bool UseSurfacesEnabled() {
274   const base::CommandLine& command_line =
275       *base::CommandLine::ForCurrentProcess();
276 
277   return command_line.HasSwitch(switches::kUseSurfaces);
278 }
279 
GetFeatureStatus()280 base::Value* GetFeatureStatus() {
281   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
282   std::string gpu_access_blocked_reason;
283   bool gpu_access_blocked =
284       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
285 
286   base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
287 
288   bool eof = false;
289   for (size_t i = 0; !eof; ++i) {
290     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
291     std::string status;
292     if (gpu_feature_info.disabled) {
293       status = "disabled";
294       if (gpu_feature_info.fallback_to_software)
295         status += "_software";
296       else
297         status += "_off";
298       if (gpu_feature_info.name == kThreadedRasterizationFeatureName)
299         status += "_ok";
300     } else if (gpu_feature_info.blocked ||
301                gpu_access_blocked) {
302       status = "unavailable";
303       if (gpu_feature_info.fallback_to_software)
304         status += "_software";
305       else
306         status += "_off";
307     } else {
308       status = "enabled";
309       if (gpu_feature_info.name == kWebGLFeatureName &&
310           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
311         status += "_readback";
312       if (gpu_feature_info.name == kRasterizationFeatureName) {
313         if (IsForceGpuRasterizationEnabled())
314           status += "_force";
315       }
316       if (gpu_feature_info.name == kMultipleRasterThreadsFeatureName) {
317         if (ForceNumberOfRendererRasterThreads() > 0)
318           status += "_force";
319       }
320       if (gpu_feature_info.name == kThreadedRasterizationFeatureName ||
321           gpu_feature_info.name == kMultipleRasterThreadsFeatureName)
322         status += "_on";
323     }
324     if (gpu_feature_info.name == kWebGLFeatureName &&
325         (gpu_feature_info.blocked || gpu_access_blocked) &&
326         manager->ShouldUseSwiftShader()) {
327       status = "unavailable_software";
328     }
329 
330     feature_status_dict->SetString(
331         gpu_feature_info.name.c_str(), status.c_str());
332   }
333   return feature_status_dict;
334 }
335 
GetProblems()336 base::Value* GetProblems() {
337   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
338   std::string gpu_access_blocked_reason;
339   bool gpu_access_blocked =
340       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
341 
342   base::ListValue* problem_list = new base::ListValue();
343   manager->GetBlacklistReasons(problem_list);
344 
345   if (gpu_access_blocked) {
346     base::DictionaryValue* problem = new base::DictionaryValue();
347     problem->SetString("description",
348         "GPU process was unable to boot: " + gpu_access_blocked_reason);
349     problem->Set("crBugs", new base::ListValue());
350     problem->Set("webkitBugs", new base::ListValue());
351     base::ListValue* disabled_features = new base::ListValue();
352     disabled_features->AppendString("all");
353     problem->Set("affectedGpuSettings", disabled_features);
354     problem->SetString("tag", "disabledFeatures");
355     problem_list->Insert(0, problem);
356   }
357 
358   bool eof = false;
359   for (size_t i = 0; !eof; ++i) {
360     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
361     if (gpu_feature_info.disabled) {
362       base::DictionaryValue* problem = new base::DictionaryValue();
363       problem->SetString(
364           "description", gpu_feature_info.disabled_description);
365       problem->Set("crBugs", new base::ListValue());
366       problem->Set("webkitBugs", new base::ListValue());
367       base::ListValue* disabled_features = new base::ListValue();
368       disabled_features->AppendString(gpu_feature_info.name);
369       problem->Set("affectedGpuSettings", disabled_features);
370       problem->SetString("tag", "disabledFeatures");
371       problem_list->Append(problem);
372     }
373   }
374   return problem_list;
375 }
376 
GetDriverBugWorkarounds()377 base::Value* GetDriverBugWorkarounds() {
378   base::ListValue* workaround_list = new base::ListValue();
379   GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
380   return workaround_list;
381 }
382 
383 }  // namespace content
384