| 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 |