Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / content / browser / gpu / compositor_util.cc
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 const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
28   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
29   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
30
31   const GpuFeatureInfo kGpuFeatureInfo[] = {
32       {
33           "2d_canvas",
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.",
41           true
42       },
43       {
44           "compositing",
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.",
51           true
52       },
53       {
54           "3d_css",
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.",
60           false
61       },
62       {
63           "css_animation",
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.",
71           true
72       },
73       {
74           "webgl",
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.",
78           false
79       },
80       {
81           "flash_3d",
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"
85           " command line.",
86           false
87       },
88       {
89           "flash_stage3d",
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"
93           " command line.",
94           false
95       },
96       {
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.",
104           false
105       },
106       {
107           "video_decode",
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"
112           " or command line.",
113           true
114       },
115 #if defined(ENABLE_WEBRTC)
116       {
117           "video_encode",
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"
122           " or command line.",
123           true
124       },
125 #endif
126       {
127           "video",
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.",
134           true
135       },
136 #if defined(OS_CHROMEOS)
137       {
138           "panel_fitting",
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"
142           " line.",
143           false
144       },
145 #endif
146       {
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.",
156           false
157       },
158   };
159   DCHECK(index < arraysize(kGpuFeatureInfo));
160   *eof = (index == arraysize(kGpuFeatureInfo) - 1);
161   return kGpuFeatureInfo[index];
162 }
163
164 bool CanDoAcceleratedCompositing() {
165   const GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
166
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))
172     return false;
173
174   // Check for SwiftShader.
175   if (manager->ShouldUseSwiftShader())
176     return false;
177
178   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
179   if (command_line.HasSwitch(switches::kDisableAcceleratedCompositing))
180     return false;
181
182   return true;
183 }
184
185 bool IsForceCompositingModeBlacklisted() {
186   return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
187       gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
188 }
189
190 }  // namespace
191
192 bool IsThreadedCompositingEnabled() {
193   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
194
195   // Command line switches take precedence over blacklist.
196   if (command_line.HasSwitch(switches::kDisableForceCompositingMode) ||
197       command_line.HasSwitch(switches::kDisableThreadedCompositing))
198     return false;
199   if (command_line.HasSwitch(switches::kEnableThreadedCompositing))
200     return true;
201
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).
205   return true;
206 #else
207   return false;
208 #endif
209 }
210
211 bool IsForceCompositingModeEnabled() {
212   // Force compositing mode is a subset of threaded compositing mode.
213   if (IsThreadedCompositingEnabled())
214     return true;
215
216   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
217
218   // Command line switches take precedence over blacklisting.
219   if (command_line.HasSwitch(switches::kDisableForceCompositingMode))
220     return false;
221   if (command_line.HasSwitch(switches::kForceCompositingMode))
222     return true;
223
224   if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
225     return false;
226
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.
231   return true;
232 #else
233   return false;
234 #endif
235 }
236
237 bool IsDelegatedRendererEnabled() {
238   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
239   bool enabled = false;
240
241 #if defined(USE_AURA)
242   // Enable on Aura.
243   enabled = true;
244 #endif
245
246   // Flags override.
247   enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
248   enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
249
250   // Needs compositing, and thread.
251   if (enabled &&
252       (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
253     enabled = false;
254     LOG(ERROR) << "Disabling delegated-rendering because it needs "
255                << "force-compositing-mode and threaded-compositing.";
256   }
257
258   return enabled;
259 }
260
261 bool IsImplSidePaintingEnabled() {
262   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
263
264   if (command_line.HasSwitch(switches::kDisableImplSidePainting))
265     return false;
266   else if (command_line.HasSwitch(switches::kEnableImplSidePainting))
267     return true;
268
269 #if defined(OS_ANDROID)
270   return true;
271 #else
272   return false;
273 #endif
274 }
275
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);
282
283   base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
284
285   bool eof = false;
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")
290       continue;
291
292     std::string status;
293     if (gpu_feature_info.disabled) {
294       status = "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";
300         else
301           status += "_software";
302       } else {
303         if (gpu_feature_info.fallback_to_software)
304           status += "_software";
305         else
306           status += "_off";
307       }
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";
315       else
316         status += "_off";
317     } else {
318       status = "enabled";
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)
328           status += "_force";
329         if (has_thread)
330           status += "_threaded";
331       }
332       if (gpu_feature_info.name == "css_animation") {
333         if (has_thread)
334           status = "accelerated_threaded";
335         else
336           status = "accelerated";
337       }
338     }
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());
344   }
345   return feature_status_dict;
346 }
347
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);
353
354   base::ListValue* problem_list = new base::ListValue();
355   manager->GetBlacklistReasons(problem_list);
356
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);
368   }
369
370   bool eof = false;
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();
375       problem->SetString(
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);
384     }
385   }
386   return problem_list;
387 }
388
389 base::Value* GetDriverBugWorkarounds() {
390   base::ListValue* workaround_list = new base::ListValue();
391   GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
392   return workaround_list;
393 }
394
395 }  // namespace content