OLD | NEW |
| (Empty) |
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 "chrome/browser/gpu_util.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/command_line.h" | |
10 #include "base/metrics/field_trial.h" | |
11 #include "base/metrics/histogram.h" | |
12 #include "base/string_number_conversions.h" | |
13 #include "base/string_util.h" | |
14 #include "base/stringprintf.h" | |
15 #include "base/sys_info.h" | |
16 #include "base/values.h" | |
17 #include "base/version.h" | |
18 #include "chrome/browser/gpu_blacklist.h" | |
19 #include "chrome/common/chrome_version_info.h" | |
20 #include "content/public/browser/gpu_data_manager.h" | |
21 #include "content/public/common/compositor_util.h" | |
22 #include "content/public/common/content_constants.h" | |
23 #include "content/public/common/content_switches.h" | |
24 #include "content/public/common/gpu_info.h" | |
25 | |
26 #if defined(OS_WIN) | |
27 #include "base/win/windows_version.h" | |
28 #endif | |
29 | |
30 using content::GpuDataManager; | |
31 using content::GpuFeatureType; | |
32 | |
33 namespace { | |
34 | |
35 const char kGpuFeatureNameAccelerated2dCanvas[] = "accelerated_2d_canvas"; | |
36 const char kGpuFeatureNameAcceleratedCompositing[] = "accelerated_compositing"; | |
37 const char kGpuFeatureNameWebgl[] = "webgl"; | |
38 const char kGpuFeatureNameMultisampling[] = "multisampling"; | |
39 const char kGpuFeatureNameFlash3d[] = "flash_3d"; | |
40 const char kGpuFeatureNameFlashStage3d[] = "flash_stage3d"; | |
41 const char kGpuFeatureNameTextureSharing[] = "texture_sharing"; | |
42 const char kGpuFeatureNameAcceleratedVideoDecode[] = "accelerated_video_decode"; | |
43 const char kGpuFeatureNameAll[] = "all"; | |
44 const char kGpuFeatureNameUnknown[] = "unknown"; | |
45 | |
46 enum GpuFeatureStatus { | |
47 kGpuFeatureEnabled = 0, | |
48 kGpuFeatureBlacklisted = 1, | |
49 kGpuFeatureDisabled = 2, // disabled by user but not blacklisted | |
50 kGpuFeatureNumStatus | |
51 }; | |
52 | |
53 struct GpuFeatureInfo { | |
54 std::string name; | |
55 uint32 blocked; | |
56 bool disabled; | |
57 std::string disabled_description; | |
58 bool fallback_to_software; | |
59 }; | |
60 | |
61 // Determine if accelerated-2d-canvas is supported, which depends on whether | |
62 // lose_context could happen and whether skia is the backend. | |
63 bool SupportsAccelerated2dCanvas() { | |
64 if (GpuDataManager::GetInstance()->GetGPUInfo().can_lose_context) | |
65 return false; | |
66 #if defined(USE_SKIA) | |
67 return true; | |
68 #else | |
69 return false; | |
70 #endif | |
71 } | |
72 | |
73 DictionaryValue* NewDescriptionValuePair(const std::string& desc, | |
74 const std::string& value) { | |
75 DictionaryValue* dict = new DictionaryValue(); | |
76 dict->SetString("description", desc); | |
77 dict->SetString("value", value); | |
78 return dict; | |
79 } | |
80 | |
81 DictionaryValue* NewDescriptionValuePair(const std::string& desc, | |
82 Value* value) { | |
83 DictionaryValue* dict = new DictionaryValue(); | |
84 dict->SetString("description", desc); | |
85 dict->Set("value", value); | |
86 return dict; | |
87 } | |
88 | |
89 Value* NewStatusValue(const char* name, const char* status) { | |
90 DictionaryValue* value = new DictionaryValue(); | |
91 value->SetString("name", name); | |
92 value->SetString("status", status); | |
93 return value; | |
94 } | |
95 | |
96 std::string GPUDeviceToString(const content::GPUInfo::GPUDevice& gpu) { | |
97 std::string vendor = base::StringPrintf("0x%04x", gpu.vendor_id); | |
98 if (!gpu.vendor_string.empty()) | |
99 vendor += " [" + gpu.vendor_string + "]"; | |
100 std::string device = base::StringPrintf("0x%04x", gpu.device_id); | |
101 if (!gpu.device_string.empty()) | |
102 device += " [" + gpu.device_string + "]"; | |
103 return base::StringPrintf( | |
104 "VENDOR = %s, DEVICE= %s", vendor.c_str(), device.c_str()); | |
105 } | |
106 | |
107 #if defined(OS_WIN) | |
108 | |
109 enum WinSubVersion { | |
110 kWinOthers = 0, | |
111 kWinXP, | |
112 kWinVista, | |
113 kWin7, | |
114 kNumWinSubVersions | |
115 }; | |
116 | |
117 // Output DxDiagNode tree as nested array of {description,value} pairs | |
118 ListValue* DxDiagNodeToList(const content::DxDiagNode& node) { | |
119 ListValue* list = new ListValue(); | |
120 for (std::map<std::string, std::string>::const_iterator it = | |
121 node.values.begin(); | |
122 it != node.values.end(); | |
123 ++it) { | |
124 list->Append(NewDescriptionValuePair(it->first, it->second)); | |
125 } | |
126 | |
127 for (std::map<std::string, content::DxDiagNode>::const_iterator it = | |
128 node.children.begin(); | |
129 it != node.children.end(); | |
130 ++it) { | |
131 ListValue* sublist = DxDiagNodeToList(it->second); | |
132 list->Append(NewDescriptionValuePair(it->first, sublist)); | |
133 } | |
134 return list; | |
135 } | |
136 | |
137 int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) { | |
138 static WinSubVersion sub_version = kNumWinSubVersions; | |
139 if (sub_version == kNumWinSubVersions) { | |
140 sub_version = kWinOthers; | |
141 std::string version_str = base::SysInfo::OperatingSystemVersion(); | |
142 size_t pos = version_str.find_first_not_of("0123456789."); | |
143 if (pos != std::string::npos) | |
144 version_str = version_str.substr(0, pos); | |
145 Version os_version(version_str); | |
146 if (os_version.IsValid() && os_version.components().size() >= 2) { | |
147 const std::vector<uint16>& version_numbers = os_version.components(); | |
148 if (version_numbers[0] == 5) | |
149 sub_version = kWinXP; | |
150 else if (version_numbers[0] == 6 && version_numbers[1] == 0) | |
151 sub_version = kWinVista; | |
152 else if (version_numbers[0] == 6 && version_numbers[1] == 1) | |
153 sub_version = kWin7; | |
154 } | |
155 } | |
156 int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus; | |
157 switch (status) { | |
158 case kGpuFeatureEnabled: | |
159 break; | |
160 case kGpuFeatureBlacklisted: | |
161 entry_index++; | |
162 break; | |
163 case kGpuFeatureDisabled: | |
164 entry_index += 2; | |
165 break; | |
166 } | |
167 return entry_index; | |
168 } | |
169 #endif // OS_WIN | |
170 | |
171 } // namespace | |
172 | |
173 namespace gpu_util { | |
174 | |
175 void InitializeCompositingFieldTrial() { | |
176 // Enable the field trial only on desktop OS's. | |
177 #if !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | |
178 return; | |
179 #endif | |
180 #if defined(OS_WIN) | |
181 // Don't run the trial on Windows XP. | |
182 if (base::win::GetVersion() < base::win::VERSION_VISTA) | |
183 return; | |
184 #endif | |
185 | |
186 // The performance of accelerated compositing is too low with software | |
187 // rendering. | |
188 if (content::GpuDataManager::GetInstance()->ShouldUseSoftwareRendering()) | |
189 return; | |
190 | |
191 // Don't activate the field trial if force-compositing-mode has been | |
192 // explicitly disabled from the command line. | |
193 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
194 switches::kDisableForceCompositingMode)) | |
195 return; | |
196 | |
197 const base::FieldTrial::Probability kDivisor = 3; | |
198 scoped_refptr<base::FieldTrial> trial( | |
199 base::FieldTrialList::FactoryGetFieldTrial( | |
200 content::kGpuCompositingFieldTrialName, kDivisor, | |
201 "disable", 2012, 12, 31, NULL)); | |
202 | |
203 // Produce the same result on every run of this client. | |
204 trial->UseOneTimeRandomization(); | |
205 | |
206 base::FieldTrial::Probability force_compositing_mode_probability = 0; | |
207 base::FieldTrial::Probability threaded_compositing_probability = 0; | |
208 | |
209 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | |
210 if (channel == chrome::VersionInfo::CHANNEL_STABLE || | |
211 channel == chrome::VersionInfo::CHANNEL_BETA) { | |
212 // Stable and Beta channels: Non-threaded force-compositing-mode on by | |
213 // default (mac and windows only). | |
214 #if defined(OS_WIN) || defined(OS_MACOSX) | |
215 force_compositing_mode_probability = 3; | |
216 #endif | |
217 } else if (channel == chrome::VersionInfo::CHANNEL_DEV || | |
218 channel == chrome::VersionInfo::CHANNEL_CANARY) { | |
219 // Dev and Canary channels: force-compositing-mode and | |
220 // threaded-compositing on with 1/3 probability each. | |
221 force_compositing_mode_probability = 1; | |
222 | |
223 #if defined(OS_MACOSX) || defined(OS_LINUX) | |
224 // Threaded compositing mode isn't feature complete on mac or linux yet: | |
225 // http://crbug.com/133602 for mac | |
226 // http://crbug.com/140866 for linux | |
227 threaded_compositing_probability = 0; | |
228 #else | |
229 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
230 switches::kDisableThreadedCompositing)) | |
231 threaded_compositing_probability = 1; | |
232 #endif | |
233 } | |
234 | |
235 | |
236 int force_compositing_group = trial->AppendGroup( | |
237 content::kGpuCompositingFieldTrialForceCompositingEnabledName, | |
238 force_compositing_mode_probability); | |
239 int thread_group = trial->AppendGroup( | |
240 content::kGpuCompositingFieldTrialThreadEnabledName, | |
241 threaded_compositing_probability); | |
242 | |
243 bool force_compositing = (trial->group() == force_compositing_group); | |
244 bool thread = (trial->group() == thread_group); | |
245 UMA_HISTOGRAM_BOOLEAN("GPU.InForceCompositingModeFieldTrial", | |
246 force_compositing); | |
247 UMA_HISTOGRAM_BOOLEAN("GPU.InCompositorThreadFieldTrial", thread); | |
248 } | |
249 | |
250 GpuFeatureType StringToGpuFeatureType(const std::string& feature_string) { | |
251 if (feature_string == kGpuFeatureNameAccelerated2dCanvas) | |
252 return content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS; | |
253 else if (feature_string == kGpuFeatureNameAcceleratedCompositing) | |
254 return content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING; | |
255 else if (feature_string == kGpuFeatureNameWebgl) | |
256 return content::GPU_FEATURE_TYPE_WEBGL; | |
257 else if (feature_string == kGpuFeatureNameMultisampling) | |
258 return content::GPU_FEATURE_TYPE_MULTISAMPLING; | |
259 else if (feature_string == kGpuFeatureNameFlash3d) | |
260 return content::GPU_FEATURE_TYPE_FLASH3D; | |
261 else if (feature_string == kGpuFeatureNameFlashStage3d) | |
262 return content::GPU_FEATURE_TYPE_FLASH_STAGE3D; | |
263 else if (feature_string == kGpuFeatureNameTextureSharing) | |
264 return content::GPU_FEATURE_TYPE_TEXTURE_SHARING; | |
265 else if (feature_string == kGpuFeatureNameAcceleratedVideoDecode) | |
266 return content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE; | |
267 else if (feature_string == kGpuFeatureNameAll) | |
268 return content::GPU_FEATURE_TYPE_ALL; | |
269 return content::GPU_FEATURE_TYPE_UNKNOWN; | |
270 } | |
271 | |
272 std::string GpuFeatureTypeToString(GpuFeatureType type) { | |
273 std::vector<std::string> matches; | |
274 if (type == content::GPU_FEATURE_TYPE_ALL) { | |
275 matches.push_back(kGpuFeatureNameAll); | |
276 } else { | |
277 if (type & content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS) | |
278 matches.push_back(kGpuFeatureNameAccelerated2dCanvas); | |
279 if (type & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) | |
280 matches.push_back(kGpuFeatureNameAcceleratedCompositing); | |
281 if (type & content::GPU_FEATURE_TYPE_WEBGL) | |
282 matches.push_back(kGpuFeatureNameWebgl); | |
283 if (type & content::GPU_FEATURE_TYPE_MULTISAMPLING) | |
284 matches.push_back(kGpuFeatureNameMultisampling); | |
285 if (type & content::GPU_FEATURE_TYPE_FLASH3D) | |
286 matches.push_back(kGpuFeatureNameFlash3d); | |
287 if (type & content::GPU_FEATURE_TYPE_FLASH_STAGE3D) | |
288 matches.push_back(kGpuFeatureNameFlashStage3d); | |
289 if (type & content::GPU_FEATURE_TYPE_TEXTURE_SHARING) | |
290 matches.push_back(kGpuFeatureNameTextureSharing); | |
291 if (!matches.size()) | |
292 matches.push_back(kGpuFeatureNameUnknown); | |
293 } | |
294 return JoinString(matches, ','); | |
295 } | |
296 | |
297 Value* GetFeatureStatus() { | |
298 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
299 bool gpu_access_blocked = !GpuDataManager::GetInstance()->GpuAccessAllowed(); | |
300 | |
301 uint32 flags = GpuDataManager::GetInstance()->GetBlacklistedFeatures(); | |
302 DictionaryValue* status = new DictionaryValue(); | |
303 | |
304 const GpuFeatureInfo kGpuFeatureInfo[] = { | |
305 { | |
306 "2d_canvas", | |
307 flags & content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, | |
308 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) || | |
309 !SupportsAccelerated2dCanvas(), | |
310 "Accelerated 2D canvas is unavailable: either disabled at the command" | |
311 " line or not supported by the current system.", | |
312 true | |
313 }, | |
314 { | |
315 "compositing", | |
316 flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, | |
317 command_line.HasSwitch(switches::kDisableAcceleratedCompositing), | |
318 "Accelerated compositing has been disabled, either via about:flags or" | |
319 " command line. This adversely affects performance of all hardware" | |
320 " accelerated features.", | |
321 true | |
322 }, | |
323 { | |
324 "3d_css", | |
325 flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, | |
326 command_line.HasSwitch(switches::kDisableAcceleratedLayers), | |
327 "Accelerated layers have been disabled at the command line.", | |
328 false | |
329 }, | |
330 { | |
331 "css_animation", | |
332 flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, | |
333 command_line.HasSwitch(switches::kDisableThreadedAnimation) || | |
334 command_line.HasSwitch(switches::kDisableAcceleratedCompositing), | |
335 "Accelerated CSS animation has been disabled at the command line.", | |
336 true | |
337 }, | |
338 { | |
339 "webgl", | |
340 flags & content::GPU_FEATURE_TYPE_WEBGL, | |
341 #if defined(OS_ANDROID) | |
342 !command_line.HasSwitch(switches::kEnableExperimentalWebGL), | |
343 #else | |
344 command_line.HasSwitch(switches::kDisableExperimentalWebGL), | |
345 #endif | |
346 "WebGL has been disabled, either via about:flags or command line.", | |
347 false | |
348 }, | |
349 { | |
350 "multisampling", | |
351 flags & content::GPU_FEATURE_TYPE_MULTISAMPLING, | |
352 command_line.HasSwitch(switches::kDisableGLMultisampling), | |
353 "Multisampling has been disabled, either via about:flags or command" | |
354 " line.", | |
355 false | |
356 }, | |
357 { | |
358 "flash_3d", | |
359 flags & content::GPU_FEATURE_TYPE_FLASH3D, | |
360 command_line.HasSwitch(switches::kDisableFlash3d), | |
361 "Using 3d in flash has been disabled, either via about:flags or" | |
362 " command line.", | |
363 false | |
364 }, | |
365 { | |
366 "flash_stage3d", | |
367 flags & content::GPU_FEATURE_TYPE_FLASH_STAGE3D, | |
368 command_line.HasSwitch(switches::kDisableFlashStage3d), | |
369 "Using Stage3d in Flash has been disabled, either via about:flags or" | |
370 " command line.", | |
371 false | |
372 }, | |
373 { | |
374 "texture_sharing", | |
375 flags & content::GPU_FEATURE_TYPE_TEXTURE_SHARING, | |
376 command_line.HasSwitch(switches::kDisableImageTransportSurface), | |
377 "Sharing textures between processes has been disabled, either via" | |
378 " about:flags or command line.", | |
379 false | |
380 }, | |
381 { | |
382 "video_decode", | |
383 flags & content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE, | |
384 command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), | |
385 "Accelerated video decode has been disabled, either via about:flags" | |
386 " or command line.", | |
387 true | |
388 } | |
389 }; | |
390 const size_t kNumFeatures = sizeof(kGpuFeatureInfo) / sizeof(GpuFeatureInfo); | |
391 | |
392 // Build the feature_status field. | |
393 { | |
394 ListValue* feature_status_list = new ListValue(); | |
395 | |
396 for (size_t i = 0; i < kNumFeatures; ++i) { | |
397 std::string status; | |
398 if (kGpuFeatureInfo[i].disabled) { | |
399 status = "disabled"; | |
400 if (kGpuFeatureInfo[i].name == "css_animation") { | |
401 status += "_software_animated"; | |
402 } else { | |
403 if (kGpuFeatureInfo[i].fallback_to_software) | |
404 status += "_software"; | |
405 else | |
406 status += "_off"; | |
407 } | |
408 } else if (GpuDataManager::GetInstance()->ShouldUseSoftwareRendering()) { | |
409 status = "unavailable_software"; | |
410 } else if (kGpuFeatureInfo[i].blocked || | |
411 gpu_access_blocked) { | |
412 status = "unavailable"; | |
413 if (kGpuFeatureInfo[i].fallback_to_software) | |
414 status += "_software"; | |
415 else | |
416 status += "_off"; | |
417 } else { | |
418 status = "enabled"; | |
419 if (kGpuFeatureInfo[i].name == "webgl" && | |
420 (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) || | |
421 (flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))) | |
422 status += "_readback"; | |
423 bool has_thread = content::IsThreadedCompositingEnabled(); | |
424 if (kGpuFeatureInfo[i].name == "compositing") { | |
425 bool force_compositing = | |
426 content::IsForceCompositingModeEnabled(); | |
427 if (force_compositing) | |
428 status += "_force"; | |
429 if (has_thread) | |
430 status += "_threaded"; | |
431 } | |
432 if (kGpuFeatureInfo[i].name == "css_animation") { | |
433 if (has_thread) | |
434 status = "accelerated_threaded"; | |
435 else | |
436 status = "accelerated"; | |
437 } | |
438 } | |
439 feature_status_list->Append( | |
440 NewStatusValue(kGpuFeatureInfo[i].name.c_str(), status.c_str())); | |
441 } | |
442 | |
443 status->Set("featureStatus", feature_status_list); | |
444 } | |
445 | |
446 // Build the problems list. | |
447 { | |
448 ListValue* problem_list = new ListValue(); | |
449 | |
450 if (gpu_access_blocked) { | |
451 DictionaryValue* problem = new DictionaryValue(); | |
452 problem->SetString("description", | |
453 "GPU process was unable to boot. Access to GPU disallowed."); | |
454 problem->Set("crBugs", new ListValue()); | |
455 problem->Set("webkitBugs", new ListValue()); | |
456 problem_list->Append(problem); | |
457 } | |
458 | |
459 for (size_t i = 0; i < kNumFeatures; ++i) { | |
460 if (kGpuFeatureInfo[i].disabled) { | |
461 DictionaryValue* problem = new DictionaryValue(); | |
462 problem->SetString( | |
463 "description", kGpuFeatureInfo[i].disabled_description); | |
464 problem->Set("crBugs", new ListValue()); | |
465 problem->Set("webkitBugs", new ListValue()); | |
466 problem_list->Append(problem); | |
467 } | |
468 } | |
469 | |
470 GpuBlacklist::GetInstance()->GetBlacklistReasons(problem_list); | |
471 | |
472 status->Set("problems", problem_list); | |
473 } | |
474 | |
475 return status; | |
476 } | |
477 | |
478 DictionaryValue* GpuInfoAsDictionaryValue() { | |
479 content::GPUInfo gpu_info = GpuDataManager::GetInstance()->GetGPUInfo(); | |
480 ListValue* basic_info = new ListValue(); | |
481 basic_info->Append(NewDescriptionValuePair( | |
482 "Initialization time", | |
483 base::Int64ToString(gpu_info.initialization_time.InMilliseconds()))); | |
484 basic_info->Append(NewDescriptionValuePair( | |
485 "GPU0", GPUDeviceToString(gpu_info.gpu))); | |
486 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { | |
487 basic_info->Append(NewDescriptionValuePair( | |
488 base::StringPrintf("GPU%d", static_cast<int>(i + 1)), | |
489 GPUDeviceToString(gpu_info.secondary_gpus[i]))); | |
490 } | |
491 basic_info->Append(NewDescriptionValuePair( | |
492 "Optimus", Value::CreateBooleanValue(gpu_info.optimus))); | |
493 basic_info->Append(NewDescriptionValuePair( | |
494 "AMD switchable", Value::CreateBooleanValue(gpu_info.amd_switchable))); | |
495 basic_info->Append(NewDescriptionValuePair("Driver vendor", | |
496 gpu_info.driver_vendor)); | |
497 basic_info->Append(NewDescriptionValuePair("Driver version", | |
498 gpu_info.driver_version)); | |
499 basic_info->Append(NewDescriptionValuePair("Driver date", | |
500 gpu_info.driver_date)); | |
501 basic_info->Append(NewDescriptionValuePair("Pixel shader version", | |
502 gpu_info.pixel_shader_version)); | |
503 basic_info->Append(NewDescriptionValuePair("Vertex shader version", | |
504 gpu_info.vertex_shader_version)); | |
505 basic_info->Append(NewDescriptionValuePair("GL version", | |
506 gpu_info.gl_version)); | |
507 basic_info->Append(NewDescriptionValuePair("GL_VENDOR", | |
508 gpu_info.gl_vendor)); | |
509 basic_info->Append(NewDescriptionValuePair("GL_RENDERER", | |
510 gpu_info.gl_renderer)); | |
511 basic_info->Append(NewDescriptionValuePair("GL_VERSION", | |
512 gpu_info.gl_version_string)); | |
513 basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS", | |
514 gpu_info.gl_extensions)); | |
515 | |
516 DictionaryValue* info = new DictionaryValue(); | |
517 info->Set("basic_info", basic_info); | |
518 | |
519 #if defined(OS_WIN) | |
520 ListValue* perf_info = new ListValue(); | |
521 perf_info->Append(NewDescriptionValuePair( | |
522 "Graphics", | |
523 base::StringPrintf("%.1f", gpu_info.performance_stats.graphics))); | |
524 perf_info->Append(NewDescriptionValuePair( | |
525 "Gaming", | |
526 base::StringPrintf("%.1f", gpu_info.performance_stats.gaming))); | |
527 perf_info->Append(NewDescriptionValuePair( | |
528 "Overall", | |
529 base::StringPrintf("%.1f", gpu_info.performance_stats.overall))); | |
530 info->Set("performance_info", perf_info); | |
531 | |
532 Value* dx_info; | |
533 if (gpu_info.dx_diagnostics.children.size()) | |
534 dx_info = DxDiagNodeToList(gpu_info.dx_diagnostics); | |
535 else | |
536 dx_info = Value::CreateNullValue(); | |
537 info->Set("diagnostics", dx_info); | |
538 #endif | |
539 | |
540 return info; | |
541 } | |
542 | |
543 void UpdateStats() { | |
544 GpuBlacklist* blacklist = GpuBlacklist::GetInstance(); | |
545 uint32 max_entry_id = blacklist->max_entry_id(); | |
546 if (max_entry_id == 0) { | |
547 // GPU Blacklist was not loaded. No need to go further. | |
548 return; | |
549 } | |
550 | |
551 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
552 uint32 flags = GpuDataManager::GetInstance()->GetBlacklistedFeatures(); | |
553 bool disabled = false; | |
554 if (flags == 0) { | |
555 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", | |
556 0, max_entry_id + 1); | |
557 } else { | |
558 std::vector<uint32> flag_entries; | |
559 blacklist->GetGpuFeatureTypeEntries( | |
560 content::GPU_FEATURE_TYPE_ALL, flag_entries, disabled); | |
561 DCHECK_GT(flag_entries.size(), 0u); | |
562 for (size_t i = 0; i < flag_entries.size(); ++i) { | |
563 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry", | |
564 flag_entries[i], max_entry_id + 1); | |
565 } | |
566 } | |
567 | |
568 // This counts how many users are affected by a disabled entry - this allows | |
569 // us to understand the impact of an entry before enable it. | |
570 std::vector<uint32> flag_disabled_entries; | |
571 disabled = true; | |
572 blacklist->GetGpuFeatureTypeEntries( | |
573 content::GPU_FEATURE_TYPE_ALL, flag_disabled_entries, disabled); | |
574 for (size_t i = 0; i < flag_disabled_entries.size(); ++i) { | |
575 UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry", | |
576 flag_disabled_entries[i], max_entry_id + 1); | |
577 } | |
578 | |
579 const content::GpuFeatureType kGpuFeatures[] = { | |
580 content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, | |
581 content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, | |
582 content::GPU_FEATURE_TYPE_WEBGL | |
583 }; | |
584 const std::string kGpuBlacklistFeatureHistogramNames[] = { | |
585 "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas", | |
586 "GPU.BlacklistFeatureTestResults.AcceleratedCompositing", | |
587 "GPU.BlacklistFeatureTestResults.Webgl" | |
588 }; | |
589 const bool kGpuFeatureUserFlags[] = { | |
590 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas), | |
591 command_line.HasSwitch(switches::kDisableAcceleratedCompositing), | |
592 #if defined(OS_ANDROID) | |
593 !command_line.HasSwitch(switches::kEnableExperimentalWebGL) | |
594 #else | |
595 command_line.HasSwitch(switches::kDisableExperimentalWebGL) | |
596 #endif | |
597 }; | |
598 #if defined(OS_WIN) | |
599 const std::string kGpuBlacklistFeatureHistogramNamesWin[] = { | |
600 "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas", | |
601 "GPU.BlacklistFeatureTestResultsWindows.AcceleratedCompositing", | |
602 "GPU.BlacklistFeatureTestResultsWindows.Webgl" | |
603 }; | |
604 #endif | |
605 const size_t kNumFeatures = | |
606 sizeof(kGpuFeatures) / sizeof(content::GpuFeatureType); | |
607 for (size_t i = 0; i < kNumFeatures; ++i) { | |
608 // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is | |
609 // expected if the macro is used within a loop. | |
610 GpuFeatureStatus value = kGpuFeatureEnabled; | |
611 if (flags & kGpuFeatures[i]) | |
612 value = kGpuFeatureBlacklisted; | |
613 else if (kGpuFeatureUserFlags[i]) | |
614 value = kGpuFeatureDisabled; | |
615 base::Histogram* histogram_pointer = base::LinearHistogram::FactoryGet( | |
616 kGpuBlacklistFeatureHistogramNames[i], | |
617 1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1, | |
618 base::Histogram::kUmaTargetedHistogramFlag); | |
619 histogram_pointer->Add(value); | |
620 #if defined(OS_WIN) | |
621 histogram_pointer = base::LinearHistogram::FactoryGet( | |
622 kGpuBlacklistFeatureHistogramNamesWin[i], | |
623 1, kNumWinSubVersions * kGpuFeatureNumStatus, | |
624 kNumWinSubVersions * kGpuFeatureNumStatus + 1, | |
625 base::Histogram::kUmaTargetedHistogramFlag); | |
626 histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value)); | |
627 #endif | |
628 } | |
629 } | |
630 | |
631 } // namespace gpu_util; | |
OLD | NEW |