| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 // | |
| 5 // Functions to enumerate the Dx Diagnostic Tool hierarchy and build up | |
| 6 // a tree of nodes with name / value properties. | |
| 7 | |
| 8 #define INITGUID | |
| 9 #include <dxdiag.h> | |
| 10 #include <windows.h> | |
| 11 | |
| 12 #include "base/string_number_conversions.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "base/win/scoped_com_initializer.h" | |
| 15 #include "content/gpu/gpu_info_collector.h" | |
| 16 | |
| 17 // Functions in this file depend on functions exported from dxguid.dll. | |
| 18 #pragma comment(lib, "dxguid.lib") | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 // Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode | |
| 23 // structures that contains property name / value pairs and subtrees of DirectX | |
| 24 // diagnostic information. | |
| 25 void RecurseDiagnosticTree(content::DxDiagNode* output, | |
| 26 IDxDiagContainer* container, | |
| 27 int depth) { | |
| 28 HRESULT hr; | |
| 29 | |
| 30 VARIANT variant; | |
| 31 VariantInit(&variant); | |
| 32 | |
| 33 DWORD prop_count; | |
| 34 hr = container->GetNumberOfProps(&prop_count); | |
| 35 if (SUCCEEDED(hr)) { | |
| 36 for (DWORD i = 0; i < prop_count; i++) { | |
| 37 WCHAR prop_name16[256]; | |
| 38 hr = container->EnumPropNames(i, prop_name16, arraysize(prop_name16)); | |
| 39 if (SUCCEEDED(hr)) { | |
| 40 std::string prop_name8 = WideToUTF8(prop_name16); | |
| 41 | |
| 42 hr = container->GetProp(prop_name16, &variant); | |
| 43 if (SUCCEEDED(hr)) { | |
| 44 switch (variant.vt) { | |
| 45 case VT_UI4: | |
| 46 output->values[prop_name8] = base::UintToString(variant.ulVal); | |
| 47 break; | |
| 48 case VT_I4: | |
| 49 output->values[prop_name8] = base::IntToString(variant.lVal); | |
| 50 break; | |
| 51 case VT_BOOL: | |
| 52 output->values[prop_name8] = variant.boolVal ? "true" : "false"; | |
| 53 break; | |
| 54 case VT_BSTR: | |
| 55 output->values[prop_name8] = WideToUTF8(variant.bstrVal); | |
| 56 break; | |
| 57 default: | |
| 58 break; | |
| 59 } | |
| 60 | |
| 61 // Clear the variant (this is needed to free BSTR memory). | |
| 62 VariantClear(&variant); | |
| 63 } | |
| 64 } | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 if (depth > 0) { | |
| 69 DWORD child_count; | |
| 70 hr = container->GetNumberOfChildContainers(&child_count); | |
| 71 if (SUCCEEDED(hr)) { | |
| 72 for (DWORD i = 0; i < child_count; i++) { | |
| 73 WCHAR child_name16[256]; | |
| 74 hr = container->EnumChildContainerNames(i, | |
| 75 child_name16, | |
| 76 arraysize(child_name16)); | |
| 77 if (SUCCEEDED(hr)) { | |
| 78 std::string child_name8 = WideToUTF8(child_name16); | |
| 79 content::DxDiagNode* output_child = | |
| 80 &output->children[child_name8]; | |
| 81 | |
| 82 IDxDiagContainer* child_container = NULL; | |
| 83 hr = container->GetChildContainer(child_name16, &child_container); | |
| 84 if (SUCCEEDED(hr)) { | |
| 85 RecurseDiagnosticTree(output_child, child_container, depth - 1); | |
| 86 | |
| 87 child_container->Release(); | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 } | |
| 92 } | |
| 93 } | |
| 94 } // namespace anonymous | |
| 95 | |
| 96 namespace gpu_info_collector { | |
| 97 | |
| 98 bool GetDxDiagnostics(content::DxDiagNode* output) { | |
| 99 HRESULT hr; | |
| 100 bool success = false; | |
| 101 base::win::ScopedCOMInitializer com_initializer; | |
| 102 | |
| 103 IDxDiagProvider* provider = NULL; | |
| 104 hr = CoCreateInstance(CLSID_DxDiagProvider, | |
| 105 NULL, | |
| 106 CLSCTX_INPROC_SERVER, | |
| 107 IID_IDxDiagProvider, | |
| 108 reinterpret_cast<void**>(&provider)); | |
| 109 if (SUCCEEDED(hr)) { | |
| 110 DXDIAG_INIT_PARAMS params = { sizeof(params) }; | |
| 111 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; | |
| 112 params.bAllowWHQLChecks = FALSE; | |
| 113 params.pReserved = NULL; | |
| 114 | |
| 115 hr = provider->Initialize(¶ms); | |
| 116 if (SUCCEEDED(hr)) { | |
| 117 IDxDiagContainer* root = NULL; | |
| 118 hr = provider->GetRootContainer(&root); | |
| 119 if (SUCCEEDED(hr)) { | |
| 120 // Limit to the DisplayDevices subtree. The tree in its entirity is | |
| 121 // enormous and only this branch contains useful information. | |
| 122 IDxDiagContainer* display_devices = NULL; | |
| 123 hr = root->GetChildContainer(L"DxDiag_DisplayDevices", | |
| 124 &display_devices); | |
| 125 if (SUCCEEDED(hr)) { | |
| 126 RecurseDiagnosticTree(output, display_devices, 1); | |
| 127 success = true; | |
| 128 display_devices->Release(); | |
| 129 } | |
| 130 | |
| 131 root->Release(); | |
| 132 } | |
| 133 } | |
| 134 provider->Release(); | |
| 135 } | |
| 136 | |
| 137 return success; | |
| 138 } | |
| 139 } // namespace gpu_info_collector | |
| OLD | NEW |