diff options
Diffstat (limited to 'chrome/gpu/gpu_dx_diagnostics_win.cc')
-rw-r--r-- | chrome/gpu/gpu_dx_diagnostics_win.cc | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/chrome/gpu/gpu_dx_diagnostics_win.cc b/chrome/gpu/gpu_dx_diagnostics_win.cc new file mode 100644 index 0000000..f6ee3c0 --- /dev/null +++ b/chrome/gpu/gpu_dx_diagnostics_win.cc @@ -0,0 +1,132 @@ +// Copyright (c) 2010 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. +// +// Functions to enumerate the Dx Diagnostic Tool hierarchy and build up +// a tree of nodes with name / value properties. + +#define INITGUID +#include <dxdiag.h> +#include <windows.h> + +#include "chrome/gpu/gpu_info_collector.h" + +#include "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" + +namespace { + +// Traverses the IDxDiagContainer tree and populates a tree of DxDiagNode +// structures that contains property name / value pairs and subtrees of DirectX +// diagnostic information. +void RecurseDiagnosticTree(DxDiagNode* output, + IDxDiagContainer* container) { + HRESULT hr; + + VARIANT variant; + VariantInit(&variant); + + DWORD prop_count; + hr = container->GetNumberOfProps(&prop_count); + if (SUCCEEDED(hr)) { + for (DWORD i = 0; i < prop_count; i++) { + WCHAR prop_name16[256]; + hr = container->EnumPropNames(i, prop_name16, arraysize(prop_name16)); + if (SUCCEEDED(hr)) { + std::string prop_name8 = WideToUTF8(prop_name16); + + hr = container->GetProp(prop_name16, &variant); + if (SUCCEEDED(hr)) { + switch (variant.vt) { + case VT_UI4: + output->values[prop_name8] = base::UintToString(variant.ulVal); + break; + case VT_I4: + output->values[prop_name8] = base::IntToString(variant.lVal); + break; + case VT_BOOL: + output->values[prop_name8] = variant.boolVal ? "true" : "false"; + break; + case VT_BSTR: + output->values[prop_name8] = WideToUTF8(variant.bstrVal); + break; + default: + break; + } + + // Clear the variant (this is needed to free BSTR memory). + VariantClear(&variant); + } + } + } + } + + DWORD child_count; + hr = container->GetNumberOfChildContainers(&child_count); + if (SUCCEEDED(hr)) { + for (DWORD i = 0; i < child_count; i++) { + WCHAR child_name16[256]; + hr = container->EnumChildContainerNames(i, + child_name16, + arraysize(child_name16)); + if (SUCCEEDED(hr)) { + std::string child_name8 = WideToUTF8(child_name16); + DxDiagNode* output_child = + &output->children[child_name8]; + + IDxDiagContainer* child_container = NULL; + hr = container->GetChildContainer(child_name16, &child_container); + if (SUCCEEDED(hr)) { + RecurseDiagnosticTree(output_child, child_container); + + child_container->Release(); + } + } + } + } +} +} // namespace anonymous + +namespace gpu_info_collector { + +bool GetDxDiagnostics(DxDiagNode* output) { + HRESULT hr; + bool success = false; + + IDxDiagProvider* provider = NULL; + hr = CoCreateInstance(CLSID_DxDiagProvider, + NULL, + CLSCTX_INPROC_SERVER, + IID_IDxDiagProvider, + reinterpret_cast<void**>(&provider)); + if (SUCCEEDED(hr)) { + DXDIAG_INIT_PARAMS params = { sizeof(params) }; + params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; + params.bAllowWHQLChecks = FALSE; + params.pReserved = NULL; + + hr = provider->Initialize(¶ms); + if (SUCCEEDED(hr)) { + IDxDiagContainer* root = NULL; + hr = provider->GetRootContainer(&root); + if (SUCCEEDED(hr)) { + // Limit to the DisplayDevices subtree. The tree in its entirity is + // enormous and only this branch contains useful information. + IDxDiagContainer* display_devices = NULL; + hr = root->GetChildContainer(L"DxDiag_DisplayDevices", + &display_devices); + if (SUCCEEDED(hr)) { + RecurseDiagnosticTree(output, display_devices); + success = true; + display_devices->Release(); + } + + root->Release(); + } + } + provider->Release(); + } + + return success; +} +} // namespace gpu_info_collector |