| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "gpu/config/gpu_info_collector.h" | 5 #include "gpu/config/gpu_info_collector.h" |
| 6 | 6 |
| 7 // This has to be included before windows.h. | 7 // This has to be included before windows.h. |
| 8 #include "third_party/re2/re2/re2.h" | 8 #include "third_party/re2/re2/re2.h" |
| 9 | 9 |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 // This function has a real implementation for official builds that can | 364 // This function has a real implementation for official builds that can |
| 365 // be found in src/third_party/amd. | 365 // be found in src/third_party/amd. |
| 366 void GetAMDVideocardInfo(GPUInfo* gpu_info); | 366 void GetAMDVideocardInfo(GPUInfo* gpu_info); |
| 367 #else | 367 #else |
| 368 void GetAMDVideocardInfo(GPUInfo* gpu_info) { | 368 void GetAMDVideocardInfo(GPUInfo* gpu_info) { |
| 369 DCHECK(gpu_info); | 369 DCHECK(gpu_info); |
| 370 return; | 370 return; |
| 371 } | 371 } |
| 372 #endif | 372 #endif |
| 373 | 373 |
| 374 bool CollectDriverInfoD3D(const std::wstring& device_id, | 374 CollectInfoResult CollectDriverInfoD3D(const std::wstring& device_id, |
| 375 GPUInfo* gpu_info) { | 375 GPUInfo* gpu_info) { |
| 376 TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); | 376 TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); |
| 377 | 377 |
| 378 // create device info for the display device | 378 // create device info for the display device |
| 379 HDEVINFO device_info = SetupDiGetClassDevsW( | 379 HDEVINFO device_info = SetupDiGetClassDevsW( |
| 380 NULL, device_id.c_str(), NULL, | 380 NULL, device_id.c_str(), NULL, |
| 381 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); | 381 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); |
| 382 if (device_info == INVALID_HANDLE_VALUE) { | 382 if (device_info == INVALID_HANDLE_VALUE) { |
| 383 LOG(ERROR) << "Creating device info failed"; | 383 LOG(ERROR) << "Creating device info failed"; |
| 384 return false; | 384 return kCollectInfoNonFatalFailure; |
| 385 } | 385 } |
| 386 | 386 |
| 387 DWORD index = 0; | 387 DWORD index = 0; |
| 388 bool found = false; | 388 bool found = false; |
| 389 SP_DEVINFO_DATA device_info_data; | 389 SP_DEVINFO_DATA device_info_data; |
| 390 device_info_data.cbSize = sizeof(device_info_data); | 390 device_info_data.cbSize = sizeof(device_info_data); |
| 391 while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { | 391 while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { |
| 392 WCHAR value[255]; | 392 WCHAR value[255]; |
| 393 if (SetupDiGetDeviceRegistryPropertyW(device_info, | 393 if (SetupDiGetDeviceRegistryPropertyW(device_info, |
| 394 &device_info_data, | 394 &device_info_data, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 gpu_info->driver_vendor = driver_vendor; | 446 gpu_info->driver_vendor = driver_vendor; |
| 447 gpu_info->driver_version = driver_version; | 447 gpu_info->driver_version = driver_version; |
| 448 gpu_info->driver_date = driver_date; | 448 gpu_info->driver_date = driver_date; |
| 449 found = true; | 449 found = true; |
| 450 RegCloseKey(key); | 450 RegCloseKey(key); |
| 451 break; | 451 break; |
| 452 } | 452 } |
| 453 } | 453 } |
| 454 } | 454 } |
| 455 SetupDiDestroyDeviceInfoList(device_info); | 455 SetupDiDestroyDeviceInfoList(device_info); |
| 456 return found; | 456 return found ? kCollectInfoSuccess : kCollectInfoNonFatalFailure; |
| 457 } | 457 } |
| 458 | 458 |
| 459 CollectInfoResult CollectContextGraphicsInfo(GPUInfo* gpu_info) { | 459 CollectInfoResult CollectContextGraphicsInfo(GPUInfo* gpu_info) { |
| 460 TRACE_EVENT0("gpu", "CollectGraphicsInfo"); | 460 TRACE_EVENT0("gpu", "CollectGraphicsInfo"); |
| 461 | 461 |
| 462 DCHECK(gpu_info); | 462 DCHECK(gpu_info); |
| 463 | 463 |
| 464 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) { | 464 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) { |
| 465 std::string requested_implementation_name = | 465 std::string requested_implementation_name = |
| 466 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL); | 466 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL); |
| 467 if (requested_implementation_name == "swiftshader") { | 467 if (requested_implementation_name == "swiftshader") { |
| 468 gpu_info->software_rendering = true; | 468 gpu_info->software_rendering = true; |
| 469 gpu_info->context_info_state = kCollectInfoNonFatalFailure; |
| 469 return kCollectInfoNonFatalFailure; | 470 return kCollectInfoNonFatalFailure; |
| 470 } | 471 } |
| 471 } | 472 } |
| 472 | 473 |
| 473 CollectInfoResult result = CollectGraphicsInfoGL(gpu_info); | 474 CollectInfoResult result = CollectGraphicsInfoGL(gpu_info); |
| 474 if (result != kCollectInfoSuccess) | 475 if (result != kCollectInfoSuccess) { |
| 476 gpu_info->context_info_state = result; |
| 475 return result; | 477 return result; |
| 478 } |
| 476 | 479 |
| 477 // ANGLE's renderer strings are of the form: | 480 // ANGLE's renderer strings are of the form: |
| 478 // ANGLE (<adapter_identifier> Direct3D<version> vs_x_x ps_x_x) | 481 // ANGLE (<adapter_identifier> Direct3D<version> vs_x_x ps_x_x) |
| 479 std::string direct3d_version; | 482 std::string direct3d_version; |
| 480 int vertex_shader_major_version = 0; | 483 int vertex_shader_major_version = 0; |
| 481 int vertex_shader_minor_version = 0; | 484 int vertex_shader_minor_version = 0; |
| 482 int pixel_shader_major_version = 0; | 485 int pixel_shader_major_version = 0; |
| 483 int pixel_shader_minor_version = 0; | 486 int pixel_shader_minor_version = 0; |
| 484 gpu_info->adapter_luid = 0; | 487 gpu_info->adapter_luid = 0; |
| 485 if (RE2::FullMatch(gpu_info->gl_renderer, | 488 if (RE2::FullMatch(gpu_info->gl_renderer, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 509 // Google, Inc. (adapter LUID: 0123456789ABCDEF) | 512 // Google, Inc. (adapter LUID: 0123456789ABCDEF) |
| 510 // The LUID is optional and identifies the GPU adapter ANGLE is using. | 513 // The LUID is optional and identifies the GPU adapter ANGLE is using. |
| 511 const char* egl_vendor = eglQueryString( | 514 const char* egl_vendor = eglQueryString( |
| 512 gfx::GLSurfaceEGL::GetHardwareDisplay(), | 515 gfx::GLSurfaceEGL::GetHardwareDisplay(), |
| 513 EGL_VENDOR); | 516 EGL_VENDOR); |
| 514 RE2::PartialMatch(egl_vendor, | 517 RE2::PartialMatch(egl_vendor, |
| 515 " \\(adapter LUID: ([0-9A-Fa-f]{16})\\)", | 518 " \\(adapter LUID: ([0-9A-Fa-f]{16})\\)", |
| 516 RE2::Hex(&gpu_info->adapter_luid)); | 519 RE2::Hex(&gpu_info->adapter_luid)); |
| 517 | 520 |
| 518 // DirectX diagnostics are collected asynchronously because it takes a | 521 // DirectX diagnostics are collected asynchronously because it takes a |
| 519 // couple of seconds. Do not mark gpu_info as complete until that is done. | 522 // couple of seconds. |
| 520 gpu_info->finalized = false; | |
| 521 } else { | 523 } else { |
| 522 gpu_info->finalized = true; | 524 gpu_info->dx_diagnostics_info_state = kCollectInfoNonFatalFailure; |
| 523 } | 525 } |
| 524 | 526 |
| 527 gpu_info->context_info_state = kCollectInfoSuccess; |
| 525 return kCollectInfoSuccess; | 528 return kCollectInfoSuccess; |
| 526 } | 529 } |
| 527 | 530 |
| 528 GpuIDResult CollectGpuID(uint32* vendor_id, uint32* device_id) { | 531 CollectInfoResult CollectGpuID(uint32* vendor_id, uint32* device_id) { |
| 529 DCHECK(vendor_id && device_id); | 532 DCHECK(vendor_id && device_id); |
| 530 *vendor_id = 0; | 533 *vendor_id = 0; |
| 531 *device_id = 0; | 534 *device_id = 0; |
| 532 | 535 |
| 533 // Taken from http://developer.nvidia.com/object/device_ids.html | 536 // Taken from http://developer.nvidia.com/object/device_ids.html |
| 534 DISPLAY_DEVICE dd; | 537 DISPLAY_DEVICE dd; |
| 535 dd.cb = sizeof(DISPLAY_DEVICE); | 538 dd.cb = sizeof(DISPLAY_DEVICE); |
| 536 std::wstring id; | 539 std::wstring id; |
| 537 for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { | 540 for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { |
| 538 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { | 541 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { |
| 539 id = dd.DeviceID; | 542 id = dd.DeviceID; |
| 540 break; | 543 break; |
| 541 } | 544 } |
| 542 } | 545 } |
| 543 | 546 |
| 544 if (id.length() > 20) { | 547 if (id.length() > 20) { |
| 545 int vendor = 0, device = 0; | 548 int vendor = 0, device = 0; |
| 546 std::wstring vendor_string = id.substr(8, 4); | 549 std::wstring vendor_string = id.substr(8, 4); |
| 547 std::wstring device_string = id.substr(17, 4); | 550 std::wstring device_string = id.substr(17, 4); |
| 548 base::HexStringToInt(base::UTF16ToASCII(vendor_string), &vendor); | 551 base::HexStringToInt(base::UTF16ToASCII(vendor_string), &vendor); |
| 549 base::HexStringToInt(base::UTF16ToASCII(device_string), &device); | 552 base::HexStringToInt(base::UTF16ToASCII(device_string), &device); |
| 550 *vendor_id = vendor; | 553 *vendor_id = vendor; |
| 551 *device_id = device; | 554 *device_id = device; |
| 552 if (*vendor_id != 0 && *device_id != 0) | 555 if (*vendor_id != 0 && *device_id != 0) |
| 553 return kGpuIDSuccess; | 556 return kCollectInfoSuccess; |
| 554 } | 557 } |
| 555 return kGpuIDFailure; | 558 return kCollectInfoNonFatalFailure; |
| 556 } | 559 } |
| 557 | 560 |
| 558 CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) { | 561 CollectInfoResult CollectBasicGraphicsInfo(GPUInfo* gpu_info) { |
| 559 TRACE_EVENT0("gpu", "CollectPreliminaryGraphicsInfo"); | 562 TRACE_EVENT0("gpu", "CollectPreliminaryGraphicsInfo"); |
| 560 | 563 |
| 561 DCHECK(gpu_info); | 564 DCHECK(gpu_info); |
| 562 | 565 |
| 563 gpu_info->performance_stats = RetrieveGpuPerformanceStatsWithHistograms(); | 566 gpu_info->performance_stats = RetrieveGpuPerformanceStatsWithHistograms(); |
| 564 | 567 |
| 565 // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. | 568 // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 588 DISPLAY_DEVICE dd; | 591 DISPLAY_DEVICE dd; |
| 589 dd.cb = sizeof(DISPLAY_DEVICE); | 592 dd.cb = sizeof(DISPLAY_DEVICE); |
| 590 std::wstring id; | 593 std::wstring id; |
| 591 for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { | 594 for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { |
| 592 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { | 595 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { |
| 593 id = dd.DeviceID; | 596 id = dd.DeviceID; |
| 594 break; | 597 break; |
| 595 } | 598 } |
| 596 } | 599 } |
| 597 | 600 |
| 598 if (id.length() <= 20) | 601 if (id.length() <= 20) { |
| 602 gpu_info->basic_info_state = kCollectInfoNonFatalFailure; |
| 599 return kCollectInfoNonFatalFailure; | 603 return kCollectInfoNonFatalFailure; |
| 604 } |
| 600 | 605 |
| 601 int vendor_id = 0, device_id = 0; | 606 int vendor_id = 0, device_id = 0; |
| 602 base::string16 vendor_id_string = id.substr(8, 4); | 607 base::string16 vendor_id_string = id.substr(8, 4); |
| 603 base::string16 device_id_string = id.substr(17, 4); | 608 base::string16 device_id_string = id.substr(17, 4); |
| 604 base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor_id); | 609 base::HexStringToInt(base::UTF16ToASCII(vendor_id_string), &vendor_id); |
| 605 base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device_id); | 610 base::HexStringToInt(base::UTF16ToASCII(device_id_string), &device_id); |
| 606 gpu_info->gpu.vendor_id = vendor_id; | 611 gpu_info->gpu.vendor_id = vendor_id; |
| 607 gpu_info->gpu.device_id = device_id; | 612 gpu_info->gpu.device_id = device_id; |
| 608 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. | 613 // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. |
| 609 if (!CollectDriverInfoD3D(id, gpu_info)) | 614 if (!CollectDriverInfoD3D(id, gpu_info)) { |
| 615 gpu_info->basic_info_state = kCollectInfoNonFatalFailure; |
| 610 return kCollectInfoNonFatalFailure; | 616 return kCollectInfoNonFatalFailure; |
| 617 } |
| 611 | 618 |
| 612 // Collect basic information about supported D3D11 features. Delay for 45 | 619 // Collect basic information about supported D3D11 features. Delay for 45 |
| 613 // seconds so as not to regress performance tests. | 620 // seconds so as not to regress performance tests. |
| 614 if (D3D11ShouldWork(*gpu_info)) { | 621 if (D3D11ShouldWork(*gpu_info)) { |
| 615 // This is on a field trial so we can turn it off easily if it blows up | 622 // This is on a field trial so we can turn it off easily if it blows up |
| 616 // again in stable channel. | 623 // again in stable channel. |
| 617 scoped_refptr<base::FieldTrial> trial( | 624 scoped_refptr<base::FieldTrial> trial( |
| 618 base::FieldTrialList::FactoryGetFieldTrial( | 625 base::FieldTrialList::FactoryGetFieldTrial( |
| 619 "D3D11Experiment", 100, "Disabled", 2015, 7, 8, | 626 "D3D11Experiment", 100, "Disabled", 2015, 7, 8, |
| 620 base::FieldTrial::SESSION_RANDOMIZED, NULL)); | 627 base::FieldTrial::SESSION_RANDOMIZED, NULL)); |
| 621 const int enabled_group = | 628 const int enabled_group = |
| 622 trial->AppendGroup("Enabled", 0); | 629 trial->AppendGroup("Enabled", 0); |
| 623 | 630 |
| 624 if (trial->group() == enabled_group) { | 631 if (trial->group() == enabled_group) { |
| 625 base::MessageLoop::current()->PostDelayedTask( | 632 base::MessageLoop::current()->PostDelayedTask( |
| 626 FROM_HERE, | 633 FROM_HERE, |
| 627 base::Bind(&CollectD3D11Support), | 634 base::Bind(&CollectD3D11Support), |
| 628 base::TimeDelta::FromSeconds(45)); | 635 base::TimeDelta::FromSeconds(45)); |
| 629 } | 636 } |
| 630 } | 637 } |
| 631 | 638 |
| 639 gpu_info->basic_info_state = kCollectInfoSuccess; |
| 632 return kCollectInfoSuccess; | 640 return kCollectInfoSuccess; |
| 633 } | 641 } |
| 634 | 642 |
| 635 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { | 643 CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { |
| 636 TRACE_EVENT0("gpu", "CollectDriverInfoGL"); | 644 TRACE_EVENT0("gpu", "CollectDriverInfoGL"); |
| 637 | 645 |
| 638 if (!gpu_info->driver_version.empty()) | 646 if (!gpu_info->driver_version.empty()) |
| 639 return kCollectInfoSuccess; | 647 return kCollectInfoSuccess; |
| 640 | 648 |
| 641 bool parsed = RE2::PartialMatch( | 649 bool parsed = RE2::PartialMatch( |
| 642 gpu_info->gl_version, "([\\d\\.]+)$", &gpu_info->driver_version); | 650 gpu_info->gl_version, "([\\d\\.]+)$", &gpu_info->driver_version); |
| 643 return parsed ? kCollectInfoSuccess : kCollectInfoNonFatalFailure; | 651 return parsed ? kCollectInfoSuccess : kCollectInfoNonFatalFailure; |
| 644 } | 652 } |
| 645 | 653 |
| 646 void MergeGPUInfo(GPUInfo* basic_gpu_info, | 654 void MergeGPUInfo(GPUInfo* basic_gpu_info, |
| 647 const GPUInfo& context_gpu_info) { | 655 const GPUInfo& context_gpu_info) { |
| 648 DCHECK(basic_gpu_info); | 656 DCHECK(basic_gpu_info); |
| 649 | 657 |
| 650 if (context_gpu_info.software_rendering) { | 658 if (context_gpu_info.software_rendering) { |
| 651 basic_gpu_info->software_rendering = true; | 659 basic_gpu_info->software_rendering = true; |
| 652 return; | 660 return; |
| 653 } | 661 } |
| 654 | 662 |
| 655 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); | 663 MergeGPUInfoGL(basic_gpu_info, context_gpu_info); |
| 656 | 664 |
| 657 basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; | 665 basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; |
| 658 } | 666 } |
| 659 | 667 |
| 660 } // namespace gpu | 668 } // namespace gpu |
| OLD | NEW |