diff options
-rw-r--r-- | chrome/browser/browser_about_handler.cc | 44 | ||||
-rw-r--r-- | chrome/chrome.gyp | 1 | ||||
-rw-r--r-- | chrome/chrome_common.gypi | 1 | ||||
-rw-r--r-- | chrome/common/dx_diag_node.h | 19 | ||||
-rw-r--r-- | chrome/common/gpu_info.cc | 10 | ||||
-rw-r--r-- | chrome/common/gpu_info.h | 14 | ||||
-rw-r--r-- | chrome/common/gpu_messages.cc | 35 | ||||
-rw-r--r-- | chrome/common/gpu_param_traits.h | 9 | ||||
-rw-r--r-- | chrome/gpu/gpu_dx_diagnostics_win.cc | 132 | ||||
-rw-r--r-- | chrome/gpu/gpu_info_collector_win.cc | 6 |
10 files changed, 271 insertions, 0 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 69ad244..ad6b091 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -56,6 +56,7 @@ #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "webkit/glue/webkit_glue.h" +#include "net/base/escape.h" #ifdef CHROME_V8 #include "v8/include/v8.h" #endif @@ -793,6 +794,43 @@ std::string VersionNumberToString(uint32 value) { return base::IntToString(hi) + "." + base::IntToString(low); } +namespace { + +// Output DxDiagNode tree as HTML tables and nested HTML unordered list +// elements. +void DxDiagNodeToHTML(std::string* output, const DxDiagNode& node) { + output->append("<table>\n"); + + for (std::map<std::string, std::string>::const_iterator it = + node.values.begin(); + it != node.values.end(); + ++it) { + output->append("<tr><td><strong>"); + output->append(EscapeForHTML(it->first)); + output->append("</strong></td><td>"); + output->append(EscapeForHTML(it->second)); + output->append("</td></tr>\n"); + } + + output->append("</table>\n<ul>\n"); + + for (std::map<std::string, DxDiagNode>::const_iterator it = + node.children.begin(); + it != node.children.end(); + ++it) { + output->append("<li><strong>"); + output->append(EscapeForHTML(it->first)); + output->append("</strong>"); + + DxDiagNodeToHTML(output, it->second); + + output->append("</li>\n"); + } + + output->append("</ul>\n"); +} +} + std::string AboutGpu() { GPUInfo gpu_info = GpuProcessHost::Get()->gpu_info(); @@ -823,6 +861,12 @@ std::string AboutGpu() { gpu_info.vertex_shader_version()).c_str()); html.append("<li><strong>GL Version:</strong> "); html.append(VersionNumberToString(gpu_info.gl_version()).c_str()); + +#if defined(OS_WIN) + html.append("<li><strong>DirectX Diagnostics:</strong> "); + DxDiagNodeToHTML(&html, gpu_info.dx_diagnostics()); +#endif + html.append("</ul></body></html> "); } return html; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 4e2a038..22b8186 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -708,6 +708,7 @@ 'gpu/gpu_command_buffer_stub.cc', 'gpu/gpu_command_buffer_stub.h', 'gpu/gpu_config.h', + 'gpu/gpu_dx_diagnostics_win.cc', 'gpu/gpu_info_collector_linux.cc', 'gpu/gpu_info_collector_mac.mm', 'gpu/gpu_info_collector_win.cc', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index ad9b994..4abc11a 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -52,6 +52,7 @@ 'common/devtools_messages.cc', 'common/devtools_messages.h', 'common/devtools_messages_internal.h', + 'common/dx_diag_node.h', 'common/file_system/webfilesystem_callback_dispatcher.cc', 'common/file_system/webfilesystem_callback_dispatcher.h', 'common/file_system/webfilesystem_impl.cc', diff --git a/chrome/common/dx_diag_node.h b/chrome/common/dx_diag_node.h new file mode 100644 index 0000000..9f20d92 --- /dev/null +++ b/chrome/common/dx_diag_node.h @@ -0,0 +1,19 @@ +// 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. +// +// A tree of name value pairs that report contain DirectX diagnostic +// information. + +#ifndef CHROME_COMMON_DX_DIAG_NODE_H_ +#define CHROME_COMMON_DX_DIAG_NODE_H_ + +#include <map> +#include <string> + +struct DxDiagNode { + std::map<std::string, std::string> values; + std::map<std::string, DxDiagNode> children; +}; + +#endif // CHROME_COMMON_DX_DIAG_NODE_H_ diff --git a/chrome/common/gpu_info.cc b/chrome/common/gpu_info.cc index 9f16bdb..667c375 100644 --- a/chrome/common/gpu_info.cc +++ b/chrome/common/gpu_info.cc @@ -60,3 +60,13 @@ void GPUInfo::SetGraphicsInfo(uint32 vendor_id, uint32 device_id, can_lose_context_ = can_lose_context; initialized_ = true; } + +#if defined(OS_WIN) +const DxDiagNode& GPUInfo::dx_diagnostics() const { + return dx_diagnostics_; +} + +void GPUInfo::SetDxDiagnostics(const DxDiagNode& dx_diagnostics) { + dx_diagnostics_ = dx_diagnostics; +} +#endif diff --git a/chrome/common/gpu_info.h b/chrome/common/gpu_info.h index 2f8f9da..50728db 100644 --- a/chrome/common/gpu_info.h +++ b/chrome/common/gpu_info.h @@ -12,6 +12,8 @@ #include <string> #include "base/basictypes.h" +#include "build/build_config.h" +#include "chrome/common/dx_diag_node.h" class GPUInfo { public: @@ -60,6 +62,14 @@ class GPUInfo { uint32 vertex_shader_version, uint32 gl_version, bool can_lose_context); + +#if defined(OS_WIN) + // The information returned by the DirectX Diagnostics Tool. + const DxDiagNode& dx_diagnostics() const; + + void SetDxDiagnostics(const DxDiagNode& dx_diagnostics); +#endif + private: bool initialized_; uint32 vendor_id_; @@ -69,6 +79,10 @@ class GPUInfo { uint32 vertex_shader_version_; uint32 gl_version_; bool can_lose_context_; + +#if defined(OS_WIN) + DxDiagNode dx_diagnostics_; +#endif }; #endif // CHROME_COMMON_GPU_INFO_H__ diff --git a/chrome/common/gpu_messages.cc b/chrome/common/gpu_messages.cc index 34f051c..893f8c9 100644 --- a/chrome/common/gpu_messages.cc +++ b/chrome/common/gpu_messages.cc @@ -5,6 +5,7 @@ #include "chrome/common/gpu_messages.h" #include "chrome/common/gpu_info.h" +#include "chrome/common/dx_diag_node.h" #include "gfx/rect.h" #include "gfx/size.h" #include "ipc/ipc_channel_handle.h" @@ -85,6 +86,10 @@ void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) { m->WriteUInt32(p.vertex_shader_version()); m->WriteUInt32(p.gl_version()); m->WriteBool(p.can_lose_context()); + +#if defined(OS_WIN) + ParamTraits<DxDiagNode> ::Write(m, p.dx_diagnostics()); +#endif } bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { @@ -109,6 +114,13 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { vertex_shader_version, gl_version, can_lose_context); + +#if defined(OS_WIN) + DxDiagNode dx_diagnostics; + ret = ret && ParamTraits<DxDiagNode> ::Read(m, iter, &dx_diagnostics); + p->SetDxDiagnostics(dx_diagnostics); +#endif + return ret; } @@ -120,6 +132,29 @@ void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) { p.can_lose_context())); } +void ParamTraits<DxDiagNode> ::Write(Message* m, const param_type& p) { + ParamTraits<std::map<std::string, std::string> >::Write(m, p.values); + ParamTraits<std::map<std::string, DxDiagNode> >::Write(m, p.children); +} + +bool ParamTraits<DxDiagNode> ::Read(const Message* m, + void** iter, + param_type* p) { + bool ret = ParamTraits<std::map<std::string, std::string> >::Read( + m, + iter, + &p->values); + ret = ret && ParamTraits<std::map<std::string, DxDiagNode> >::Read( + m, + iter, + &p->children); + return ret; +} + +void ParamTraits<DxDiagNode> ::Log(const param_type& p, std::string* l) { + l->append("<DxDiagNode>"); +} + void ParamTraits<gpu::CommandBuffer::State> ::Write(Message* m, const param_type& p) { m->WriteInt(p.num_entries); diff --git a/chrome/common/gpu_param_traits.h b/chrome/common/gpu_param_traits.h index d8ca851..f2c4e02 100644 --- a/chrome/common/gpu_param_traits.h +++ b/chrome/common/gpu_param_traits.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/process.h" #include "chrome/common/common_param_traits.h" +#include "chrome/common/dx_diag_node.h" #include "chrome/common/gpu_info.h" #include "chrome/common/gpu_native_window_handle.h" #include "gfx/native_widget_types.h" @@ -52,6 +53,14 @@ struct ParamTraits<GPUInfo> { }; template <> +struct ParamTraits<DxDiagNode> { + typedef DxDiagNode param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> struct ParamTraits<gpu::CommandBuffer::State> { typedef gpu::CommandBuffer::State param_type; static void Write(Message* m, const param_type& p); 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 diff --git a/chrome/gpu/gpu_info_collector_win.cc b/chrome/gpu/gpu_info_collector_win.cc index 1e3124b..b5d30b4 100644 --- a/chrome/gpu/gpu_info_collector_win.cc +++ b/chrome/gpu/gpu_info_collector_win.cc @@ -37,6 +37,12 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { if (FAILED(device->GetDirect3D(&d3d))) return false; + // Don't fail if DirectX diagnostics are not available. Just leave the tree + // empty. The other GPU info is still valuable. + DxDiagNode dx_diagnostics; + if (GetDxDiagnostics(&dx_diagnostics)) + gpu_info->SetDxDiagnostics(dx_diagnostics); + return CollectGraphicsInfoD3D(d3d, gpu_info); } |