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