| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/gpu/gpu_data_manager.h" | 5 #include "content/browser/gpu/gpu_data_manager.h" |
| 6 | 6 |
| 7 #if defined(OS_MACOSX) | 7 #if defined(OS_MACOSX) |
| 8 #include <CoreGraphics/CGDisplayConfiguration.h> | 8 #include <CoreGraphics/CGDisplayConfiguration.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 } | 53 } |
| 54 | 54 |
| 55 DictionaryValue* NewDescriptionValuePair(const std::string& desc, | 55 DictionaryValue* NewDescriptionValuePair(const std::string& desc, |
| 56 Value* value) { | 56 Value* value) { |
| 57 DictionaryValue* dict = new DictionaryValue(); | 57 DictionaryValue* dict = new DictionaryValue(); |
| 58 dict->SetString("description", desc); | 58 dict->SetString("description", desc); |
| 59 dict->Set("value", value); | 59 dict->Set("value", value); |
| 60 return dict; | 60 return dict; |
| 61 } | 61 } |
| 62 | 62 |
| 63 Value* NewStatusValue(const char* name, const char* status) { |
| 64 DictionaryValue* value = new DictionaryValue(); |
| 65 value->SetString("name", name); |
| 66 value->SetString("status", status); |
| 67 return value; |
| 68 } |
| 69 |
| 70 bool UseGLIsOSMesaOrAny() { |
| 71 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 72 std::string gl = browser_command_line.GetSwitchValueASCII(switches::kUseGL); |
| 73 return (gl == gfx::kGLImplementationAnyName || |
| 74 gl == gfx::kGLImplementationOSMesaName); |
| 75 } |
| 76 |
| 63 #if defined(OS_WIN) | 77 #if defined(OS_WIN) |
| 64 enum WinSubVersion { | 78 enum WinSubVersion { |
| 65 kWinOthers = 0, | 79 kWinOthers = 0, |
| 66 kWinXP, | 80 kWinXP, |
| 67 kWinVista, | 81 kWinVista, |
| 68 kWin7, | 82 kWin7, |
| 69 kNumWinSubVersions | 83 kNumWinSubVersions |
| 70 }; | 84 }; |
| 71 | 85 |
| 72 // Output DxDiagNode tree as nested array of {description,value} pairs | 86 // Output DxDiagNode tree as nested array of {description,value} pairs |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 | 188 |
| 175 UpdateGpuFeatureFlags(); | 189 UpdateGpuFeatureFlags(); |
| 176 } | 190 } |
| 177 | 191 |
| 178 const GPUInfo& GpuDataManager::gpu_info() const { | 192 const GPUInfo& GpuDataManager::gpu_info() const { |
| 179 base::AutoLock auto_lock(gpu_info_lock_); | 193 base::AutoLock auto_lock(gpu_info_lock_); |
| 180 return gpu_info_; | 194 return gpu_info_; |
| 181 } | 195 } |
| 182 | 196 |
| 183 Value* GpuDataManager::GetFeatureStatus() { | 197 Value* GpuDataManager::GetFeatureStatus() { |
| 184 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 198 const CommandLine& browser_command_line = |
| 185 if (gpu_blacklist_.get()) | 199 *CommandLine::ForCurrentProcess(); |
| 186 return gpu_blacklist_->GetFeatureStatus(GpuAccessAllowed(), | 200 bool gpu_access_allowed = GpuAccessAllowed(); |
| 187 browser_command_line.HasSwitch( | 201 bool disable_accelerated_compositing = browser_command_line.HasSwitch( |
| 188 switches::kDisableAcceleratedCompositing), | 202 switches::kDisableAcceleratedCompositing); |
| 189 browser_command_line.HasSwitch( | 203 bool disable_accelerated_2D_canvas = browser_command_line.HasSwitch( |
| 190 switches::kDisableAccelerated2dCanvas), | 204 switches::kDisableAccelerated2dCanvas); |
| 191 browser_command_line.HasSwitch(switches::kDisableExperimentalWebGL), | 205 bool disable_experimental_webgl = browser_command_line.HasSwitch( |
| 192 browser_command_line.HasSwitch(switches::kDisableGLMultisampling)); | 206 switches::kDisableExperimentalWebGL); |
| 193 return NULL; | 207 bool disable_multisampling = browser_command_line.HasSwitch( |
| 208 switches::kDisableGLMultisampling); |
| 209 |
| 210 uint32 flags = GetGpuFeatureFlags().flags(); |
| 211 DictionaryValue* status = new DictionaryValue(); |
| 212 |
| 213 // Build the feature_status field. |
| 214 { |
| 215 ListValue* feature_status_list = new ListValue(); |
| 216 |
| 217 // 2d_canvas. |
| 218 if (!gpu_access_allowed) { |
| 219 if (disable_accelerated_2D_canvas) |
| 220 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 221 "software")); |
| 222 else |
| 223 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 224 "unavailable_software")); |
| 225 } else if (!disable_accelerated_2D_canvas) { |
| 226 if ((flags & GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas) != 0) |
| 227 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 228 "unavailable_software")); |
| 229 else if (disable_accelerated_compositing) |
| 230 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 231 "disabled_software")); |
| 232 else |
| 233 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 234 "enabled")); |
| 235 } else { |
| 236 feature_status_list->Append(NewStatusValue("2d_canvas", |
| 237 "software")); |
| 238 } |
| 239 |
| 240 // 3d css and compositing. |
| 241 if (!gpu_access_allowed) { |
| 242 feature_status_list->Append(NewStatusValue("3d_css", |
| 243 "unavailable_off")); |
| 244 feature_status_list->Append(NewStatusValue("compositing", |
| 245 "unavailable_software")); |
| 246 } else if (disable_accelerated_compositing) { |
| 247 feature_status_list->Append(NewStatusValue("3d_css", |
| 248 "unavailable_off")); |
| 249 feature_status_list->Append(NewStatusValue("compositing", |
| 250 "disabled_software")); |
| 251 } else if ((flags & |
| 252 GpuFeatureFlags::kGpuFeatureAcceleratedCompositing) != 0) { |
| 253 feature_status_list->Append(NewStatusValue("3d_css", |
| 254 "unavailable_off")); |
| 255 feature_status_list->Append(NewStatusValue("compositing", |
| 256 "disabled_software")); |
| 257 } else { |
| 258 feature_status_list->Append(NewStatusValue("3d_css", |
| 259 "enabled")); |
| 260 feature_status_list->Append(NewStatusValue("compositing", |
| 261 "enabled")); |
| 262 } |
| 263 |
| 264 // webgl |
| 265 if (!gpu_access_allowed) |
| 266 feature_status_list->Append(NewStatusValue("webgl", |
| 267 "unavailable_off")); |
| 268 else if (disable_experimental_webgl) |
| 269 feature_status_list->Append(NewStatusValue("webgl", |
| 270 "disabled_off")); |
| 271 else if ((flags & GpuFeatureFlags::kGpuFeatureWebgl) != 0) |
| 272 feature_status_list->Append(NewStatusValue("webgl", |
| 273 "unavailable_off")); |
| 274 else if (disable_accelerated_compositing) |
| 275 feature_status_list->Append(NewStatusValue("webgl", |
| 276 "enabled_readback")); |
| 277 else |
| 278 feature_status_list->Append(NewStatusValue("webgl", |
| 279 "enabled")); |
| 280 |
| 281 // multisampling |
| 282 if (!gpu_access_allowed) |
| 283 feature_status_list->Append(NewStatusValue("multisampling", |
| 284 "unavailable_off")); |
| 285 else if (disable_multisampling) |
| 286 feature_status_list->Append(NewStatusValue("multisampling", |
| 287 "disabled_off")); |
| 288 else if ((flags & GpuFeatureFlags::kGpuFeatureMultisampling) != 0) |
| 289 feature_status_list->Append(NewStatusValue("multisampling", |
| 290 "disabled_off")); |
| 291 else |
| 292 feature_status_list->Append(NewStatusValue("multisampling", |
| 293 "enabled")); |
| 294 |
| 295 status->Set("featureStatus", feature_status_list); |
| 296 } |
| 297 |
| 298 // Build the problems list. |
| 299 { |
| 300 ListValue* problem_list = new ListValue(); |
| 301 if (!gpu_access_allowed) { |
| 302 DictionaryValue* problem = new DictionaryValue(); |
| 303 problem->SetString("description", |
| 304 "GPU process was unable to boot. Access to GPU disallowed."); |
| 305 problem->Set("crBugs", new ListValue()); |
| 306 problem->Set("webkitBugs", new ListValue()); |
| 307 problem_list->Append(problem); |
| 308 } |
| 309 if (disable_accelerated_2D_canvas) { |
| 310 DictionaryValue* problem = new DictionaryValue(); |
| 311 problem->SetString("description", |
| 312 "Accelerated 2D canvas has been disabled at the command line"); |
| 313 problem->Set("crBugs", new ListValue()); |
| 314 problem->Set("webkitBugs", new ListValue()); |
| 315 problem_list->Append(problem); |
| 316 } |
| 317 if (disable_accelerated_compositing) { |
| 318 DictionaryValue* problem = new DictionaryValue(); |
| 319 problem->SetString("description", |
| 320 "Accelerated compositing has been disabled, either via about:flags " |
| 321 "or command line. This adversely affects performance of all hardware " |
| 322 " accelerated features."); |
| 323 problem->Set("crBugs", new ListValue()); |
| 324 problem->Set("webkitBugs", new ListValue()); |
| 325 problem_list->Append(problem); |
| 326 } |
| 327 if (disable_experimental_webgl) { |
| 328 DictionaryValue* problem = new DictionaryValue(); |
| 329 problem->SetString("description", |
| 330 "WebGL has been disabled, either via about:flags " |
| 331 "or command line"); |
| 332 problem->Set("crBugs", new ListValue()); |
| 333 problem->Set("webkitBugs", new ListValue()); |
| 334 problem_list->Append(problem); |
| 335 } |
| 336 if (disable_multisampling) { |
| 337 DictionaryValue* problem = new DictionaryValue(); |
| 338 problem->SetString("description", |
| 339 "Multisampling has been disabled, either via about:flags " |
| 340 "or command line"); |
| 341 problem->Set("crBugs", new ListValue()); |
| 342 problem->Set("webkitBugs", new ListValue()); |
| 343 problem_list->Append(problem); |
| 344 } |
| 345 GpuBlacklist* blacklist = GetGpuBlacklist(); |
| 346 if (blacklist && (!UseGLIsOSMesaOrAny())) |
| 347 blacklist->GetBlacklistReasons(problem_list); |
| 348 status->Set("problems", problem_list); |
| 349 } |
| 350 return status; |
| 194 } | 351 } |
| 195 | 352 |
| 196 std::string GpuDataManager::GetBlacklistVersion() const { | 353 std::string GpuDataManager::GetBlacklistVersion() const { |
| 197 if (gpu_blacklist_.get() != NULL) { | 354 if (gpu_blacklist_.get() != NULL) { |
| 198 uint16 version_major, version_minor; | 355 uint16 version_major, version_minor; |
| 199 if (gpu_blacklist_->GetVersion(&version_major, | 356 if (gpu_blacklist_->GetVersion(&version_major, |
| 200 &version_minor)) { | 357 &version_minor)) { |
| 201 std::string version_string = | 358 std::string version_string = |
| 202 base::UintToString(static_cast<unsigned>(version_major)) + | 359 base::UintToString(static_cast<unsigned>(version_major)) + |
| 203 "." + | 360 "." + |
| 204 base::UintToString(static_cast<unsigned>(version_minor)); | 361 base::UintToString(static_cast<unsigned>(version_minor)); |
| 205 return version_string; | 362 return version_string; |
| 206 } | 363 } |
| 207 } | 364 } |
| 208 return ""; | 365 return ""; |
| 209 } | 366 } |
| 210 | 367 |
| 211 void GpuDataManager::AddLogMessage(Value* msg) { | 368 void GpuDataManager::AddLogMessage(Value* msg) { |
| 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 213 log_messages_.Append(msg); | 370 log_messages_.Append(msg); |
| 214 } | 371 } |
| 215 | 372 |
| 216 const ListValue& GpuDataManager::log_messages() const { | 373 const ListValue& GpuDataManager::log_messages() const { |
| 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 218 return log_messages_; | 375 return log_messages_; |
| 219 } | 376 } |
| 220 | 377 |
| 221 GpuFeatureFlags GpuDataManager::GetGpuFeatureFlags() { | 378 GpuFeatureFlags GpuDataManager::GetGpuFeatureFlags() { |
| 379 if (UseGLIsOSMesaOrAny()) |
| 380 return GpuFeatureFlags(); |
| 222 return gpu_feature_flags_; | 381 return gpu_feature_flags_; |
| 223 } | 382 } |
| 224 | 383 |
| 225 bool GpuDataManager::GpuAccessAllowed() { | 384 bool GpuDataManager::GpuAccessAllowed() { |
| 385 if (UseGLIsOSMesaOrAny()) |
| 386 return true; |
| 387 |
| 226 // We only need to block GPU process if more features are disallowed other | 388 // We only need to block GPU process if more features are disallowed other |
| 227 // than those in the preliminary gpu feature flags because the latter work | 389 // than those in the preliminary gpu feature flags because the latter work |
| 228 // through renderer commandline switches. | 390 // through renderer commandline switches. |
| 229 uint32 mask = (~(preliminary_gpu_feature_flags_.flags())); | 391 uint32 mask = (~(preliminary_gpu_feature_flags_.flags())); |
| 230 return (gpu_feature_flags_.flags() & mask) == 0; | 392 return (gpu_feature_flags_.flags() & mask) == 0; |
| 231 } | 393 } |
| 232 | 394 |
| 233 void GpuDataManager::AddGpuInfoUpdateCallback(Callback0::Type* callback) { | 395 void GpuDataManager::AddGpuInfoUpdateCallback(Callback0::Type* callback) { |
| 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 235 gpu_info_update_callbacks_.insert(callback); | 397 gpu_info_update_callbacks_.insert(callback); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 262 !command_line->HasSwitch(switches::kDisableGLMultisampling)) | 424 !command_line->HasSwitch(switches::kDisableGLMultisampling)) |
| 263 command_line->AppendSwitch(switches::kDisableGLMultisampling); | 425 command_line->AppendSwitch(switches::kDisableGLMultisampling); |
| 264 if ((flags & GpuFeatureFlags::kGpuFeatureAcceleratedCompositing) && | 426 if ((flags & GpuFeatureFlags::kGpuFeatureAcceleratedCompositing) && |
| 265 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) | 427 !command_line->HasSwitch(switches::kDisableAcceleratedCompositing)) |
| 266 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); | 428 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); |
| 267 if ((flags & GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas) && | 429 if ((flags & GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas) && |
| 268 !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas)) | 430 !command_line->HasSwitch(switches::kDisableAccelerated2dCanvas)) |
| 269 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); | 431 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); |
| 270 } | 432 } |
| 271 | 433 |
| 434 void GpuDataManager::AppendGpuCommandLine( |
| 435 CommandLine* command_line) { |
| 436 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 437 DCHECK(command_line); |
| 438 |
| 439 uint32 flags = gpu_feature_flags_.flags(); |
| 440 if ((flags & GpuFeatureFlags::kGpuFeatureMultisampling) && |
| 441 !command_line->HasSwitch(switches::kDisableGLMultisampling)) |
| 442 command_line->AppendSwitch(switches::kDisableGLMultisampling); |
| 443 |
| 444 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 445 if ((flags & (GpuFeatureFlags::kGpuFeatureWebgl | |
| 446 GpuFeatureFlags::kGpuFeatureAcceleratedCompositing | |
| 447 GpuFeatureFlags::kGpuFeatureAccelerated2dCanvas)) && |
| 448 (browser_command_line.GetSwitchValueASCII( |
| 449 switches::kUseGL) == gfx::kGLImplementationAnyName)) { |
| 450 command_line->AppendSwitchASCII( |
| 451 switches::kUseGL, gfx::kGLImplementationOSMesaName); |
| 452 } else if (browser_command_line.HasSwitch(switches::kUseGL)) { |
| 453 command_line->AppendSwitchASCII(switches::kUseGL, |
| 454 browser_command_line.GetSwitchValueASCII(switches::kUseGL)); |
| 455 } |
| 456 } |
| 457 |
| 272 void GpuDataManager::SetBuiltInGpuBlacklist(GpuBlacklist* built_in_list) { | 458 void GpuDataManager::SetBuiltInGpuBlacklist(GpuBlacklist* built_in_list) { |
| 273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 274 DCHECK(built_in_list); | 460 DCHECK(built_in_list); |
| 275 uint16 version_major, version_minor; | 461 uint16 version_major, version_minor; |
| 276 bool succeed = built_in_list->GetVersion( | 462 bool succeed = built_in_list->GetVersion( |
| 277 &version_major, &version_minor); | 463 &version_major, &version_minor); |
| 278 DCHECK(succeed); | 464 DCHECK(succeed); |
| 279 gpu_blacklist_.reset(built_in_list); | 465 gpu_blacklist_.reset(built_in_list); |
| 280 UpdateGpuFeatureFlags(); | 466 UpdateGpuFeatureFlags(); |
| 281 preliminary_gpu_feature_flags_ = gpu_feature_flags_; | 467 preliminary_gpu_feature_flags_ = gpu_feature_flags_; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 histogram_pointer->Add( | 642 histogram_pointer->Add( |
| 457 GetGpuBlacklistHistogramValueWin( | 643 GetGpuBlacklistHistogramValueWin( |
| 458 (flags & kGpuFeatures[i]) ? true : false)); | 644 (flags & kGpuFeatures[i]) ? true : false)); |
| 459 #endif | 645 #endif |
| 460 } | 646 } |
| 461 } | 647 } |
| 462 | 648 |
| 463 GpuBlacklist* GpuDataManager::GetGpuBlacklist() { | 649 GpuBlacklist* GpuDataManager::GetGpuBlacklist() { |
| 464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 465 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 651 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 466 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || | 652 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist)) |
| 467 browser_command_line.GetSwitchValueASCII( | |
| 468 switches::kUseGL) == gfx::kGLImplementationOSMesaName) | |
| 469 return NULL; | 653 return NULL; |
| 470 // No need to return an empty blacklist. | 654 // No need to return an empty blacklist. |
| 471 if (gpu_blacklist_.get() != NULL && gpu_blacklist_->max_entry_id() == 0) | 655 if (gpu_blacklist_.get() != NULL && gpu_blacklist_->max_entry_id() == 0) |
| 472 return NULL; | 656 return NULL; |
| 473 return gpu_blacklist_.get(); | 657 return gpu_blacklist_.get(); |
| 474 } | 658 } |
| OLD | NEW |