Index: content/gpu/gpu_info_collector_win.cc |
=================================================================== |
--- content/gpu/gpu_info_collector_win.cc (revision 201645) |
+++ content/gpu/gpu_info_collector_win.cc (working copy) |
@@ -1,643 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/gpu/gpu_info_collector.h" |
- |
-// This has to be included before windows.h. |
-#include "third_party/re2/re2/re2.h" |
- |
-#include <windows.h> |
-#include <d3d9.h> |
-#include <d3d11.h> |
-#include <dxgi.h> |
-#include <setupapi.h> |
- |
-#include "base/command_line.h" |
-#include "base/debug/trace_event.h" |
-#include "base/file_util.h" |
-#include "base/files/file_path.h" |
-#include "base/logging.h" |
-#include "base/message_loop.h" |
-#include "base/metrics/histogram.h" |
-#include "base/scoped_native_library.h" |
-#include "base/string_number_conversions.h" |
-#include "base/string_util.h" |
-#include "base/string16.h" |
-#include "base/stringprintf.h" |
-#include "base/threading/thread.h" |
-#include "base/threading/worker_pool.h" |
-#include "base/win/registry.h" |
-#include "base/win/scoped_com_initializer.h" |
-#include "base/win/scoped_comptr.h" |
-#include "base/win/windows_version.h" |
-#include "third_party/libxml/chromium/libxml_utils.h" |
-#include "ui/gl/gl_implementation.h" |
-#include "ui/gl/gl_surface_egl.h" |
- |
-namespace { |
- |
-// This must be kept in sync with histograms.xml. |
-enum DisplayLinkInstallationStatus { |
- DISPLAY_LINK_NOT_INSTALLED, |
- DISPLAY_LINK_7_1_OR_EARLIER, |
- DISPLAY_LINK_7_2_OR_LATER, |
- DISPLAY_LINK_INSTALLATION_STATUS_MAX |
-}; |
- |
-float ReadXMLFloatValue(XmlReader* reader) { |
- std::string score_string; |
- if (!reader->ReadElementContent(&score_string)) |
- return 0.0; |
- |
- double score; |
- if (!base::StringToDouble(score_string, &score)) |
- return 0.0; |
- |
- return static_cast<float>(score); |
-} |
- |
-content::GpuPerformanceStats RetrieveGpuPerformanceStats() { |
- TRACE_EVENT0("gpu", "RetrieveGpuPerformanceStats"); |
- |
- // If the user re-runs the assessment without restarting, the COM API |
- // returns WINSAT_ASSESSMENT_STATE_NOT_AVAILABLE. Because of that and |
- // http://crbug.com/124325, read the assessment result files directly. |
- content::GpuPerformanceStats stats; |
- |
- // Get path to WinSAT results files. |
- wchar_t winsat_results_path[MAX_PATH]; |
- DWORD size = ExpandEnvironmentStrings( |
- L"%WinDir%\\Performance\\WinSAT\\DataStore\\", |
- winsat_results_path, MAX_PATH); |
- if (size == 0 || size > MAX_PATH) { |
- LOG(ERROR) << "The path to the WinSAT results is too long: " |
- << size << " chars."; |
- return stats; |
- } |
- |
- // Find most recent formal assessment results. |
- file_util::FileEnumerator file_enumerator( |
- base::FilePath(winsat_results_path), |
- false, // not recursive |
- file_util::FileEnumerator::FILES, |
- FILE_PATH_LITERAL("* * Formal.Assessment (*).WinSAT.xml")); |
- |
- base::FilePath current_results; |
- for (base::FilePath results = file_enumerator.Next(); !results.empty(); |
- results = file_enumerator.Next()) { |
- // The filenames start with the date and time as yyyy-mm-dd hh.mm.ss.xxx, |
- // so the greatest file lexicographically is also the most recent file. |
- if (base::FilePath::CompareLessIgnoreCase(current_results.value(), |
- results.value())) |
- current_results = results; |
- } |
- |
- std::string current_results_string = current_results.MaybeAsASCII(); |
- if (current_results_string.empty()) { |
- LOG(ERROR) << "Can't retrieve a valid WinSAT assessment."; |
- return stats; |
- } |
- |
- // Get relevant scores from results file. XML schema at: |
- // http://msdn.microsoft.com/en-us/library/windows/desktop/aa969210.aspx |
- XmlReader reader; |
- if (!reader.LoadFile(current_results_string)) { |
- LOG(ERROR) << "Could not open WinSAT results file."; |
- return stats; |
- } |
- // Descend into <WinSAT> root element. |
- if (!reader.SkipToElement() || !reader.Read()) { |
- LOG(ERROR) << "Could not read WinSAT results file."; |
- return stats; |
- } |
- |
- // Search for <WinSPR> element containing the results. |
- do { |
- if (reader.NodeName() == "WinSPR") |
- break; |
- } while (reader.Next()); |
- // Descend into <WinSPR> element. |
- if (!reader.Read()) { |
- LOG(ERROR) << "Could not find WinSPR element in results file."; |
- return stats; |
- } |
- |
- // Read scores. |
- for (int depth = reader.Depth(); reader.Depth() == depth; reader.Next()) { |
- std::string node_name = reader.NodeName(); |
- if (node_name == "SystemScore") |
- stats.overall = ReadXMLFloatValue(&reader); |
- else if (node_name == "GraphicsScore") |
- stats.graphics = ReadXMLFloatValue(&reader); |
- else if (node_name == "GamingScore") |
- stats.gaming = ReadXMLFloatValue(&reader); |
- } |
- |
- if (stats.overall == 0.0) |
- LOG(ERROR) << "Could not read overall score from assessment results."; |
- if (stats.graphics == 0.0) |
- LOG(ERROR) << "Could not read graphics score from assessment results."; |
- if (stats.gaming == 0.0) |
- LOG(ERROR) << "Could not read gaming score from assessment results."; |
- |
- return stats; |
-} |
- |
-content::GpuPerformanceStats RetrieveGpuPerformanceStatsWithHistograms() { |
- base::TimeTicks start_time = base::TimeTicks::Now(); |
- |
- content::GpuPerformanceStats stats = RetrieveGpuPerformanceStats(); |
- |
- UMA_HISTOGRAM_TIMES("GPU.WinSAT.ReadResultsFileTime", |
- base::TimeTicks::Now() - start_time); |
- UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.OverallScore2", |
- stats.overall * 10, 10, 200, 50); |
- UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.GraphicsScore2", |
- stats.graphics * 10, 10, 200, 50); |
- UMA_HISTOGRAM_CUSTOM_COUNTS("GPU.WinSAT.GamingScore2", |
- stats.gaming * 10, 10, 200, 50); |
- UMA_HISTOGRAM_BOOLEAN( |
- "GPU.WinSAT.HasResults", |
- stats.overall != 0.0 && stats.graphics != 0.0 && stats.gaming != 0.0); |
- |
- return stats; |
-} |
- |
-// Returns the display link driver version or an invalid version if it is |
-// not installed. |
-Version DisplayLinkVersion() { |
- base::win::RegKey key; |
- |
- if (key.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE", KEY_READ | KEY_WOW64_64KEY)) |
- return Version(); |
- |
- if (key.OpenKey(L"DisplayLink", KEY_READ | KEY_WOW64_64KEY)) |
- return Version(); |
- |
- if (key.OpenKey(L"Core", KEY_READ | KEY_WOW64_64KEY)) |
- return Version(); |
- |
- string16 version; |
- if (key.ReadValue(L"Version", &version)) |
- return Version(); |
- |
- return Version(WideToASCII(version)); |
-} |
- |
-// Returns whether Lenovo dCute is installed. |
-bool IsLenovoDCuteInstalled() { |
- base::win::RegKey key; |
- |
- if (key.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE", KEY_READ | KEY_WOW64_64KEY)) |
- return false; |
- |
- if (key.OpenKey(L"Lenovo", KEY_READ | KEY_WOW64_64KEY)) |
- return false; |
- |
- if (key.OpenKey(L"Lenovo dCute", KEY_READ | KEY_WOW64_64KEY)) |
- return false; |
- |
- return true; |
-} |
- |
-// Determines whether D3D11 won't work, either because it is not supported on |
-// the machine or because it is known it is likely to crash. |
-bool D3D11ShouldWork(const content::GPUInfo& gpu_info) { |
- // Windows XP never supports D3D11. |
- if (base::win::GetVersion() <= base::win::VERSION_XP) |
- return false; |
- |
- // Intel? |
- if (gpu_info.gpu.vendor_id == 0x8086) { |
- // 2nd Generation Core Processor Family Integrated Graphics Controller |
- // or Intel Ivy Bridge? |
- if (gpu_info.gpu.device_id == 0x0102 || |
- gpu_info.gpu.device_id == 0x0106 || |
- gpu_info.gpu.device_id == 0x0116 || |
- gpu_info.gpu.device_id == 0x0126 || |
- gpu_info.gpu.device_id == 0x0152 || |
- gpu_info.gpu.device_id == 0x0156 || |
- gpu_info.gpu.device_id == 0x015a || |
- gpu_info.gpu.device_id == 0x0162 || |
- gpu_info.gpu.device_id == 0x0166) { |
- // http://crbug.com/196373. |
- if (base::win::GetVersion() == base::win::VERSION_VISTA) |
- return false; |
- |
- // http://crbug.com/175525. |
- if (gpu_info.display_link_version.IsValid()) |
- return false; |
- } |
- } |
- |
- return true; |
-} |
- |
-// Collects information about the level of D3D11 support and records it in |
-// the UMA stats. Records no stats when D3D11 in not supported at all. |
-void CollectD3D11SupportOnWorkerThread() { |
- TRACE_EVENT0("gpu", "CollectD3D11Support"); |
- |
- typedef HRESULT (WINAPI *D3D11CreateDeviceFunc)( |
- IDXGIAdapter* adapter, |
- D3D_DRIVER_TYPE driver_type, |
- HMODULE software, |
- UINT flags, |
- const D3D_FEATURE_LEVEL* feature_levels, |
- UINT num_feature_levels, |
- UINT sdk_version, |
- ID3D11Device** device, |
- D3D_FEATURE_LEVEL* feature_level, |
- ID3D11DeviceContext** immediate_context); |
- |
- // This enumeration must be kept in sync with histograms.xml. Do not reorder |
- // the members; always add to the end. |
- enum FeatureLevel { |
- FEATURE_LEVEL_UNKNOWN, |
- FEATURE_LEVEL_NO_D3D11_DLL, |
- FEATURE_LEVEL_NO_CREATE_DEVICE_ENTRY_POINT, |
- FEATURE_LEVEL_DEVICE_CREATION_FAILED, |
- FEATURE_LEVEL_9_1, |
- FEATURE_LEVEL_9_2, |
- FEATURE_LEVEL_9_3, |
- FEATURE_LEVEL_10_0, |
- FEATURE_LEVEL_10_1, |
- FEATURE_LEVEL_11_0, |
- NUM_FEATURE_LEVELS |
- }; |
- |
- FeatureLevel feature_level = FEATURE_LEVEL_UNKNOWN; |
- UINT bgra_support = 0; |
- |
- // This module is leaked in case it is hooked by third party software. |
- base::NativeLibrary d3d11_module = base::LoadNativeLibrary( |
- base::FilePath(L"d3d11.dll"), |
- NULL); |
- |
- if (!d3d11_module) { |
- feature_level = FEATURE_LEVEL_NO_D3D11_DLL; |
- } else { |
- D3D11CreateDeviceFunc create_func = |
- reinterpret_cast<D3D11CreateDeviceFunc>( |
- base::GetFunctionPointerFromNativeLibrary(d3d11_module, |
- "D3D11CreateDevice")); |
- if (!create_func) { |
- feature_level = FEATURE_LEVEL_NO_CREATE_DEVICE_ENTRY_POINT; |
- } else { |
- static const D3D_FEATURE_LEVEL d3d_feature_levels[] = { |
- D3D_FEATURE_LEVEL_11_0, |
- D3D_FEATURE_LEVEL_10_1, |
- D3D_FEATURE_LEVEL_10_0, |
- D3D_FEATURE_LEVEL_9_3, |
- D3D_FEATURE_LEVEL_9_2, |
- D3D_FEATURE_LEVEL_9_1 |
- }; |
- |
- base::win::ScopedComPtr<ID3D11Device> device; |
- D3D_FEATURE_LEVEL d3d_feature_level; |
- base::win::ScopedComPtr<ID3D11DeviceContext> device_context; |
- HRESULT hr = create_func(NULL, |
- D3D_DRIVER_TYPE_HARDWARE, |
- NULL, |
- 0, |
- d3d_feature_levels, |
- arraysize(d3d_feature_levels), |
- D3D11_SDK_VERSION, |
- device.Receive(), |
- &d3d_feature_level, |
- device_context.Receive()); |
- if (FAILED(hr)) { |
- feature_level = FEATURE_LEVEL_DEVICE_CREATION_FAILED; |
- } else { |
- switch (d3d_feature_level) { |
- case D3D_FEATURE_LEVEL_11_0: |
- feature_level = FEATURE_LEVEL_11_0; |
- break; |
- case D3D_FEATURE_LEVEL_10_1: |
- feature_level = FEATURE_LEVEL_10_1; |
- break; |
- case D3D_FEATURE_LEVEL_10_0: |
- feature_level = FEATURE_LEVEL_10_0; |
- break; |
- case D3D_FEATURE_LEVEL_9_3: |
- feature_level = FEATURE_LEVEL_9_3; |
- break; |
- case D3D_FEATURE_LEVEL_9_2: |
- feature_level = FEATURE_LEVEL_9_2; |
- break; |
- case D3D_FEATURE_LEVEL_9_1: |
- feature_level = FEATURE_LEVEL_9_1; |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
- |
- hr = device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, |
- &bgra_support); |
- DCHECK(SUCCEEDED(hr)); |
- } |
- } |
- } |
- |
- UMA_HISTOGRAM_ENUMERATION("GPU.D3D11_FeatureLevel", |
- feature_level, |
- NUM_FEATURE_LEVELS); |
- |
- // ANGLE requires at least feature level 10.0. Do not record any further |
- // stats if ANGLE would not work anyway. |
- if (feature_level < FEATURE_LEVEL_10_0) |
- return; |
- |
- UMA_HISTOGRAM_BOOLEAN( |
- "GPU.D3D11_B8G8R8A8_Texture2DSupport", |
- (bgra_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); |
- UMA_HISTOGRAM_BOOLEAN( |
- "GPU.D3D11_B8G8R8A8_RenderTargetSupport", |
- (bgra_support & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0); |
-} |
- |
-// Collects information about the level of D3D11 support and records it in |
-// the UMA stats. Records no stats when D3D11 in not supported at all. |
-void CollectD3D11Support() { |
- // D3D11 takes about 50ms to initialize so do this on a worker thread. |
- base::WorkerPool::PostTask( |
- FROM_HERE, |
- base::Bind(CollectD3D11SupportOnWorkerThread), |
- false); |
-} |
-} // namespace anonymous |
- |
-namespace gpu_info_collector { |
- |
-#if !defined(GOOGLE_CHROME_BUILD) |
-AMDVideoCardType GetAMDVideocardType() { |
- return STANDALONE; |
-} |
-#else |
-// This function has a real implementation for official builds that can |
-// be found in src/third_party/amd. |
-AMDVideoCardType GetAMDVideocardType(); |
-#endif |
- |
-bool CollectDriverInfoD3D(const std::wstring& device_id, |
- content::GPUInfo* gpu_info) { |
- TRACE_EVENT0("gpu", "CollectDriverInfoD3D"); |
- |
- // create device info for the display device |
- HDEVINFO device_info = SetupDiGetClassDevsW( |
- NULL, device_id.c_str(), NULL, |
- DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES); |
- if (device_info == INVALID_HANDLE_VALUE) { |
- LOG(ERROR) << "Creating device info failed"; |
- return false; |
- } |
- |
- DWORD index = 0; |
- bool found = false; |
- SP_DEVINFO_DATA device_info_data; |
- device_info_data.cbSize = sizeof(device_info_data); |
- while (SetupDiEnumDeviceInfo(device_info, index++, &device_info_data)) { |
- WCHAR value[255]; |
- if (SetupDiGetDeviceRegistryPropertyW(device_info, |
- &device_info_data, |
- SPDRP_DRIVER, |
- NULL, |
- reinterpret_cast<PBYTE>(value), |
- sizeof(value), |
- NULL)) { |
- HKEY key; |
- std::wstring driver_key = L"System\\CurrentControlSet\\Control\\Class\\"; |
- driver_key += value; |
- LONG result = RegOpenKeyExW( |
- HKEY_LOCAL_MACHINE, driver_key.c_str(), 0, KEY_QUERY_VALUE, &key); |
- if (result == ERROR_SUCCESS) { |
- DWORD dwcb_data = sizeof(value); |
- std::string driver_version; |
- result = RegQueryValueExW( |
- key, L"DriverVersion", NULL, NULL, |
- reinterpret_cast<LPBYTE>(value), &dwcb_data); |
- if (result == ERROR_SUCCESS) |
- driver_version = WideToASCII(std::wstring(value)); |
- |
- std::string driver_date; |
- dwcb_data = sizeof(value); |
- result = RegQueryValueExW( |
- key, L"DriverDate", NULL, NULL, |
- reinterpret_cast<LPBYTE>(value), &dwcb_data); |
- if (result == ERROR_SUCCESS) |
- driver_date = WideToASCII(std::wstring(value)); |
- |
- std::string driver_vendor; |
- dwcb_data = sizeof(value); |
- result = RegQueryValueExW( |
- key, L"ProviderName", NULL, NULL, |
- reinterpret_cast<LPBYTE>(value), &dwcb_data); |
- if (result == ERROR_SUCCESS) { |
- driver_vendor = WideToASCII(std::wstring(value)); |
- if (driver_vendor == "Advanced Micro Devices, Inc." || |
- driver_vendor == "ATI Technologies Inc.") { |
- // We are conservative and assume that in the absence of a clear |
- // signal the videocard is assumed to be switchable. Additionally, |
- // some switchable systems with Intel GPUs aren't correctly |
- // detected, so always count them. |
- AMDVideoCardType amd_card_type = GetAMDVideocardType(); |
- gpu_info->amd_switchable = (gpu_info->gpu.vendor_id == 0x8086) || |
- (amd_card_type != STANDALONE); |
- } |
- } |
- |
- gpu_info->driver_vendor = driver_vendor; |
- gpu_info->driver_version = driver_version; |
- gpu_info->driver_date = driver_date; |
- found = true; |
- RegCloseKey(key); |
- break; |
- } |
- } |
- } |
- SetupDiDestroyDeviceInfoList(device_info); |
- return found; |
-} |
- |
-bool CollectContextGraphicsInfo(content::GPUInfo* gpu_info) { |
- TRACE_EVENT0("gpu", "CollectGraphicsInfo"); |
- |
- DCHECK(gpu_info); |
- |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) { |
- std::string requested_implementation_name = |
- CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL); |
- if (requested_implementation_name == "swiftshader") { |
- gpu_info->software_rendering = true; |
- return false; |
- } |
- } |
- |
- if (!CollectGraphicsInfoGL(gpu_info)) |
- return false; |
- |
- // ANGLE's renderer strings are of the form: |
- // ANGLE (<adapter_identifier> Direct3D<version> vs_x_x ps_x_x) |
- std::string direct3d_version; |
- int vertex_shader_major_version = 0; |
- int vertex_shader_minor_version = 0; |
- int pixel_shader_major_version = 0; |
- int pixel_shader_minor_version = 0; |
- if (RE2::FullMatch(gpu_info->gl_renderer, |
- "ANGLE \\(.*\\)") && |
- RE2::PartialMatch(gpu_info->gl_renderer, |
- " Direct3D(\\w+)", |
- &direct3d_version) && |
- RE2::PartialMatch(gpu_info->gl_renderer, |
- " vs_(\\d+)_(\\d+)", |
- &vertex_shader_major_version, |
- &vertex_shader_minor_version) && |
- RE2::PartialMatch(gpu_info->gl_renderer, |
- " ps_(\\d+)_(\\d+)", |
- &pixel_shader_major_version, |
- &pixel_shader_minor_version)) { |
- gpu_info->can_lose_context = direct3d_version == "9"; |
- gpu_info->vertex_shader_version = |
- base::StringPrintf("%d.%d", |
- vertex_shader_major_version, |
- vertex_shader_minor_version); |
- gpu_info->pixel_shader_version = |
- base::StringPrintf("%d.%d", |
- pixel_shader_major_version, |
- pixel_shader_minor_version); |
- |
- // DirectX diagnostics are collected asynchronously because it takes a |
- // couple of seconds. Do not mark gpu_info as complete until that is done. |
- gpu_info->finalized = false; |
- } else { |
- gpu_info->finalized = true; |
- } |
- |
- return true; |
-} |
- |
-GpuIDResult CollectGpuID(uint32* vendor_id, uint32* device_id) { |
- DCHECK(vendor_id && device_id); |
- *vendor_id = 0; |
- *device_id = 0; |
- |
- // Taken from http://developer.nvidia.com/object/device_ids.html |
- DISPLAY_DEVICE dd; |
- dd.cb = sizeof(DISPLAY_DEVICE); |
- std::wstring id; |
- for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { |
- if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { |
- id = dd.DeviceID; |
- break; |
- } |
- } |
- |
- if (id.length() > 20) { |
- int vendor = 0, device = 0; |
- std::wstring vendor_string = id.substr(8, 4); |
- std::wstring device_string = id.substr(17, 4); |
- base::HexStringToInt(WideToASCII(vendor_string), &vendor); |
- base::HexStringToInt(WideToASCII(device_string), &device); |
- *vendor_id = vendor; |
- *device_id = device; |
- return kGpuIDSuccess; |
- } |
- return kGpuIDFailure; |
-} |
- |
-bool CollectBasicGraphicsInfo(content::GPUInfo* gpu_info) { |
- TRACE_EVENT0("gpu", "CollectPreliminaryGraphicsInfo"); |
- |
- DCHECK(gpu_info); |
- |
- gpu_info->performance_stats = RetrieveGpuPerformanceStatsWithHistograms(); |
- |
- // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. |
- HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); |
- gpu_info->optimus = nvd3d9wrap != NULL; |
- |
- gpu_info->lenovo_dcute = IsLenovoDCuteInstalled(); |
- |
- gpu_info->display_link_version = DisplayLinkVersion(); |
- |
- if (!gpu_info->display_link_version .IsValid()) { |
- UMA_HISTOGRAM_ENUMERATION("GPU.DisplayLinkInstallationStatus", |
- DISPLAY_LINK_NOT_INSTALLED, |
- DISPLAY_LINK_INSTALLATION_STATUS_MAX); |
- } else if (gpu_info->display_link_version.IsOlderThan("7.2")) { |
- UMA_HISTOGRAM_ENUMERATION("GPU.DisplayLinkInstallationStatus", |
- DISPLAY_LINK_7_1_OR_EARLIER, |
- DISPLAY_LINK_INSTALLATION_STATUS_MAX); |
- } else { |
- UMA_HISTOGRAM_ENUMERATION("GPU.DisplayLinkInstallationStatus", |
- DISPLAY_LINK_7_2_OR_LATER, |
- DISPLAY_LINK_INSTALLATION_STATUS_MAX); |
- } |
- |
- // Taken from http://developer.nvidia.com/object/device_ids.html |
- DISPLAY_DEVICE dd; |
- dd.cb = sizeof(DISPLAY_DEVICE); |
- std::wstring id; |
- for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) { |
- if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { |
- id = dd.DeviceID; |
- break; |
- } |
- } |
- |
- if (id.length() <= 20) |
- return false; |
- |
- int vendor_id = 0, device_id = 0; |
- string16 vendor_id_string = id.substr(8, 4); |
- string16 device_id_string = id.substr(17, 4); |
- base::HexStringToInt(WideToASCII(vendor_id_string), &vendor_id); |
- base::HexStringToInt(WideToASCII(device_id_string), &device_id); |
- gpu_info->gpu.vendor_id = vendor_id; |
- gpu_info->gpu.device_id = device_id; |
- // TODO(zmo): we only need to call CollectDriverInfoD3D() if we use ANGLE. |
- if (!CollectDriverInfoD3D(id, gpu_info)) |
- return false; |
- |
- // Collect basic information about supported D3D11 features. Delay for 45 |
- // seconds so as not to regress performance tests. |
- if (D3D11ShouldWork(*gpu_info)) { |
- base::MessageLoop::current()->PostDelayedTask( |
- FROM_HERE, |
- base::Bind(&CollectD3D11Support), |
- base::TimeDelta::FromSeconds(45)); |
- } |
- |
- return true; |
-} |
- |
-bool CollectDriverInfoGL(content::GPUInfo* gpu_info) { |
- TRACE_EVENT0("gpu", "CollectDriverInfoGL"); |
- |
- if (!gpu_info->driver_version.empty()) |
- return true; |
- |
- std::string gl_version_string = gpu_info->gl_version_string; |
- |
- return RE2::PartialMatch(gl_version_string, |
- "([\\d\\.]+)$", |
- &gpu_info->driver_version); |
-} |
- |
-void MergeGPUInfo(content::GPUInfo* basic_gpu_info, |
- const content::GPUInfo& context_gpu_info) { |
- DCHECK(basic_gpu_info); |
- |
- if (context_gpu_info.software_rendering) { |
- basic_gpu_info->software_rendering = true; |
- return; |
- } |
- |
- MergeGPUInfoGL(basic_gpu_info, context_gpu_info); |
- |
- basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics; |
-} |
- |
-} // namespace gpu_info_collector |