summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_about_handler.cc44
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/chrome_common.gypi1
-rw-r--r--chrome/common/dx_diag_node.h19
-rw-r--r--chrome/common/gpu_info.cc10
-rw-r--r--chrome/common/gpu_info.h14
-rw-r--r--chrome/common/gpu_messages.cc35
-rw-r--r--chrome/common/gpu_param_traits.h9
-rw-r--r--chrome/gpu/gpu_dx_diagnostics_win.cc132
-rw-r--r--chrome/gpu/gpu_info_collector_win.cc6
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(&params);
+ 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);
}