diff options
author | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 20:05:00 +0000 |
---|---|---|
committer | zmo@chromium.org <zmo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 20:05:00 +0000 |
commit | d7b5cc74aad6ae9f5f8425a9dba0c6f3b7a4e058 (patch) | |
tree | 80ed4f402a2df66036b1c46a80ff29d77dd2fa64 /gpu/config/gpu_dx_diagnostics_win.cc | |
parent | 863b582d75c8f9acf404751d7e709803df1f7bb9 (diff) | |
download | chromium_src-d7b5cc74aad6ae9f5f8425a9dba0c6f3b7a4e058.zip chromium_src-d7b5cc74aad6ae9f5f8425a9dba0c6f3b7a4e058.tar.gz chromium_src-d7b5cc74aad6ae9f5f8425a9dba0c6f3b7a4e058.tar.bz2 |
Move GPU device/driver info related code from content to gpu.
Try to reland r201380 with build fix.
This has been suggested by gman, and agreed by kbr and jam, for the following reasons:
1) These are gpu related code, and are independent of content / browser, so putting them under gpu/ is the right thing to do conceptually.
2) This enables us to set up tests in various places with the correct blacklisting/driver_bug_workarounds information. Otherwise, for the moment, gpu/ has no visibility into content/ side, so we have to duplicate the driver_bug_workarounds code and hardwire them for testing purpose. This is going to cause a lot of bugs in the future, as we have the two pieces of code for the same thing (one for chrome and one for testing) and people will easily forget to update one or the other.
As for this patch, I didn't change the logic, and try to minimize the refactoring. All improvements enabled by this relocation will be done in follow-up CLs.
BUG=230477
TEST=tree
TBR=apatrick@chromium.org, joi@chromium.org, kbr@chromium.org, piman@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/15745014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201875 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/config/gpu_dx_diagnostics_win.cc')
-rw-r--r-- | gpu/config/gpu_dx_diagnostics_win.cc | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/gpu/config/gpu_dx_diagnostics_win.cc b/gpu/config/gpu_dx_diagnostics_win.cc new file mode 100644 index 0000000..cc8a20a --- /dev/null +++ b/gpu/config/gpu_dx_diagnostics_win.cc @@ -0,0 +1,138 @@ +// Copyright (c) 2011 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 "base/string_number_conversions.h" +#include "base/utf_string_conversions.h" +#include "base/win/scoped_com_initializer.h" +#include "gpu/config/gpu_info_collector.h" + +// Functions in this file depend on functions exported from dxguid.dll. +#pragma comment(lib, "dxguid.lib") + +namespace gpu { + +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, + int depth) { + 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); + } + } + } + } + + if (depth > 0) { + 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, depth - 1); + + child_container->Release(); + } + } + } + } + } +} +} // namespace anonymous + +bool GetDxDiagnostics(DxDiagNode* output) { + HRESULT hr; + bool success = false; + base::win::ScopedCOMInitializer com_initializer; + + 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, 1); + success = true; + display_devices->Release(); + } + + root->Release(); + } + } + provider->Release(); + } + + return success; +} +} // namespace gpu |