diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_about_handler.cc | 33 | ||||
-rw-r--r-- | chrome/common/gpu_info.cc | 14 | ||||
-rw-r--r-- | chrome/common/gpu_info.h | 15 | ||||
-rw-r--r-- | chrome/common/gpu_messages.cc | 87 | ||||
-rw-r--r-- | chrome/common/gpu_messages_unittest.cc | 4 | ||||
-rw-r--r-- | chrome/gpu/gpu_info_collector_linux.cc | 3 | ||||
-rw-r--r-- | chrome/gpu/gpu_info_collector_mac.mm | 2 | ||||
-rw-r--r-- | chrome/gpu/gpu_info_collector_win.cc | 13 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.cc | 40 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.h | 5 |
10 files changed, 148 insertions, 68 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 79775e6..b63c88b9b 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -761,18 +761,24 @@ std::string AboutGpu() { GPUInfo gpu_info = GpuProcessHost::Get()->gpu_info(); std::string html; - if (!gpu_info.initialized()) { + + html.append("<html><head><title>About GPU</title></head>\n"); + + if (gpu_info.progress() != GPUInfo::kComplete) { GpuProcessHostUIShim::Get()->CollectGraphicsInfoAsynchronously(); - // If it's not initialized yet, let the user know and reload the page - html.append("<html><head><title>About GPU</title></head>\n"); + + // If it's not fully initialized yet, set a timeout to reload the page. html.append("<body onload=\"setTimeout('window.location.reload(true)',"); html.append("2000)\">\n"); - html.append("<h2>GPU Information</h2>\n"); + } else { + html.append("<body>\n"); + } + + html.append("<h2>GPU Information</h2>\n"); + + if (gpu_info.progress() == GPUInfo::kUninitialized) { html.append("<p>Retrieving GPU information . . .</p>\n"); - html.append("</body></html> "); } else { - html.append("<html><head><title>About GPU</title></head><body>\n"); - html.append("<h2>GPU Information</h2>\n"); html.append("<table><tr>"); html.append("<td><strong>Initialization time</strong></td><td>"); html.append(base::Int64ToString( @@ -799,12 +805,17 @@ std::string AboutGpu() { html.append("</td></tr></table>"); #if defined(OS_WIN) - html.append("<h2>DirectX Diagnostics</h2>"); - DxDiagNodeToHTML(&html, gpu_info.dx_diagnostics()); + if (gpu_info.progress() != GPUInfo::kComplete) { + html.append("<p>Retrieving DirectX Diagnostics . . .</p>\n"); + } else { + html.append("<h2>DirectX Diagnostics</h2>"); + DxDiagNodeToHTML(&html, gpu_info.dx_diagnostics()); + } #endif - - html.append("</body></html>"); } + + html.append("</body></html>"); + return html; } diff --git a/chrome/common/gpu_info.cc b/chrome/common/gpu_info.cc index 64f0498..744fdfc 100644 --- a/chrome/common/gpu_info.cc +++ b/chrome/common/gpu_info.cc @@ -5,15 +5,18 @@ #include "chrome/common/gpu_info.h" GPUInfo::GPUInfo() - : initialized_(false), vendor_id_(0), device_id_(0), driver_version_(L""), + : progress_(kUninitialized), + vendor_id_(0), + device_id_(0), + driver_version_(L""), pixel_shader_version_(0), vertex_shader_version_(0), gl_version_(0), can_lose_context_(false) { } -bool GPUInfo::initialized() const { - return initialized_; +GPUInfo::Progress GPUInfo::progress() const { + return progress_; } base::TimeDelta GPUInfo::initialization_time() const { @@ -68,7 +71,10 @@ void GPUInfo::SetGraphicsInfo(uint32 vendor_id, uint32 device_id, vertex_shader_version_ = vertex_shader_version; gl_version_ = gl_version; can_lose_context_ = can_lose_context; - initialized_ = true; +} + +void GPUInfo::SetProgress(Progress progress) { + progress_ = progress; } #if defined(OS_WIN) diff --git a/chrome/common/gpu_info.h b/chrome/common/gpu_info.h index bdf8709..b8f7cc6 100644 --- a/chrome/common/gpu_info.h +++ b/chrome/common/gpu_info.h @@ -21,8 +21,15 @@ class GPUInfo { GPUInfo(); ~GPUInfo() {} - // Returns whether this GPUInfo has been initialized with information - bool initialized() const; + enum Progress { + kUninitialized, + kPartial, + kComplete, + }; + + // Returns whether this GPUInfo has been partially or fully initialized with + // information. + Progress progress() const; // The amount of time taken to get from the process starting to the message // loop being pumped. @@ -60,6 +67,8 @@ class GPUInfo { // semantics are available. bool can_lose_context() const; + void SetProgress(Progress progress); + void SetInitializationTime(const base::TimeDelta& initialization_time); // Populate variables with passed in values @@ -78,7 +87,7 @@ class GPUInfo { #endif private: - bool initialized_; + Progress progress_; base::TimeDelta initialization_time_; uint32 vendor_id_; uint32 device_id_; diff --git a/chrome/common/gpu_messages.cc b/chrome/common/gpu_messages.cc index d6adda0..1ba2efa 100644 --- a/chrome/common/gpu_messages.cc +++ b/chrome/common/gpu_messages.cc @@ -81,14 +81,15 @@ void ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> ::Log( #endif // if defined(OS_MACOSX) void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) { - ParamTraits<base::TimeDelta> ::Write(m, p.initialization_time()); - m->WriteUInt32(p.vendor_id()); - m->WriteUInt32(p.device_id()); - m->WriteWString(p.driver_version()); - m->WriteUInt32(p.pixel_shader_version()); - m->WriteUInt32(p.vertex_shader_version()); - m->WriteUInt32(p.gl_version()); - m->WriteBool(p.can_lose_context()); + WriteParam(m, static_cast<int32>(p.progress())); + WriteParam(m, p.initialization_time()); + WriteParam(m, p.vendor_id()); + WriteParam(m, p.device_id()); + WriteParam(m, p.driver_version()); + WriteParam(m, p.pixel_shader_version()); + WriteParam(m, p.vertex_shader_version()); + WriteParam(m, p.gl_version()); + WriteParam(m, p.can_lose_context()); #if defined(OS_WIN) ParamTraits<DxDiagNode> ::Write(m, p.dx_diagnostics()); @@ -96,6 +97,7 @@ void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) { } bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { + int32 progress; base::TimeDelta initialization_time; uint32 vendor_id; uint32 device_id; @@ -104,14 +106,16 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { uint32 vertex_shader_version; uint32 gl_version; bool can_lose_context; - bool ret = ParamTraits<base::TimeDelta> ::Read(m, iter, &initialization_time); - ret = ret && m->ReadUInt32(iter, &vendor_id); - ret = ret && m->ReadUInt32(iter, &device_id); - ret = ret && m->ReadWString(iter, &driver_version); - ret = ret && m->ReadUInt32(iter, &pixel_shader_version); - ret = ret && m->ReadUInt32(iter, &vertex_shader_version); - ret = ret && m->ReadUInt32(iter, &gl_version); - ret = ret && m->ReadBool(iter, &can_lose_context); + bool ret = ReadParam(m, iter, &progress); + ret = ret && ReadParam(m, iter, &initialization_time); + ret = ret && ReadParam(m, iter, &vendor_id); + ret = ret && ReadParam(m, iter, &device_id); + ret = ret && ReadParam(m, iter, &driver_version); + ret = ret && ReadParam(m, iter, &pixel_shader_version); + ret = ret && ReadParam(m, iter, &vertex_shader_version); + ret = ret && ReadParam(m, iter, &gl_version); + ret = ret && ReadParam(m, iter, &can_lose_context); + p->SetProgress(static_cast<GPUInfo::Progress>(progress)); if (!ret) return false; @@ -126,15 +130,18 @@ bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { #if defined(OS_WIN) DxDiagNode dx_diagnostics; - ret = ret && ParamTraits<DxDiagNode> ::Read(m, iter, &dx_diagnostics); + if (!ReadParam(m, iter, &dx_diagnostics)) + return false; + p->SetDxDiagnostics(dx_diagnostics); #endif - return ret; + return true; } void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) { - l->append(base::StringPrintf("<GPUInfo> %d %x %x %ls %d", + l->append(base::StringPrintf("<GPUInfo> %d %d %x %x %ls %d", + p.progress(), static_cast<int32>( p.initialization_time().InMilliseconds()), p.vendor_id(), @@ -144,21 +151,15 @@ void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) { } 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); + WriteParam(m, p.values); + WriteParam(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); + bool ret = ReadParam(m, iter, &p->values); + ret = ret && ReadParam(m, iter, &p->children); return ret; } @@ -168,22 +169,22 @@ void ParamTraits<DxDiagNode> ::Log(const param_type& p, std::string* l) { void ParamTraits<gpu::CommandBuffer::State> ::Write(Message* m, const param_type& p) { - m->WriteInt(p.num_entries); - m->WriteInt(p.get_offset); - m->WriteInt(p.put_offset); - m->WriteInt(p.token); - m->WriteInt(p.error); + WriteParam(m, p.num_entries); + WriteParam(m, p.get_offset); + WriteParam(m, p.put_offset); + WriteParam(m, p.token); + WriteParam(m, static_cast<int32>(p.error)); } bool ParamTraits<gpu::CommandBuffer::State> ::Read(const Message* m, void** iter, param_type* p) { int32 temp; - if (m->ReadInt(iter, &p->num_entries) && - m->ReadInt(iter, &p->get_offset) && - m->ReadInt(iter, &p->put_offset) && - m->ReadInt(iter, &p->token) && - m->ReadInt(iter, &temp)) { + if (ReadParam(m, iter, &p->num_entries) && + ReadParam(m, iter, &p->get_offset) && + ReadParam(m, iter, &p->put_offset) && + ReadParam(m, iter, &p->token) && + ReadParam(m, iter, &temp)) { p->error = static_cast<gpu::error::Error>(temp); return true; } else { @@ -198,14 +199,14 @@ void ParamTraits<gpu::CommandBuffer::State> ::Log(const param_type& p, void ParamTraits<GPUCreateCommandBufferConfig> ::Write( Message* m, const param_type& p) { - m->WriteString(p.allowed_extensions); - ParamTraits<std::vector<int> > ::Write(m, p.attribs); + WriteParam(m, p.allowed_extensions); + WriteParam(m, p.attribs); } bool ParamTraits<GPUCreateCommandBufferConfig> ::Read( const Message* m, void** iter, param_type* p) { - if (!m->ReadString(iter, &p->allowed_extensions) || - !ParamTraits<std::vector<int> > ::Read(m, iter, &p->attribs)) { + if (!ReadParam(m, iter, &p->allowed_extensions) || + !ReadParam(m, iter, &p->attribs)) { return false; } return true; diff --git a/chrome/common/gpu_messages_unittest.cc b/chrome/common/gpu_messages_unittest.cc index 59d42ed..904d9da 100644 --- a/chrome/common/gpu_messages_unittest.cc +++ b/chrome/common/gpu_messages_unittest.cc @@ -13,6 +13,7 @@ TEST(GPUIPCMessageTest, GPUInfo) { GPUInfo input; // Test variables taken from Lenovo T61 + input.SetProgress(GPUInfo::kPartial); input.SetInitializationTime(base::TimeDelta::FromMilliseconds(100)); input.SetGraphicsInfo(0x10de, 0x429, L"6.14.11.7715", 0xffff0300, @@ -26,6 +27,7 @@ TEST(GPUIPCMessageTest, GPUInfo) { GPUInfo output; void* iter = NULL; EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); + EXPECT_EQ(input.progress(), output.progress()); EXPECT_EQ(input.initialization_time().InMilliseconds(), output.initialization_time().InMilliseconds()); EXPECT_EQ(input.vendor_id(), output.vendor_id()); @@ -38,5 +40,5 @@ TEST(GPUIPCMessageTest, GPUInfo) { std::string log_message; IPC::LogParam(output, &log_message); - EXPECT_STREQ("<GPUInfo> 100 10de 429 6.14.11.7715 1", log_message.c_str()); + EXPECT_STREQ("<GPUInfo> 1 100 10de 429 6.14.11.7715 1", log_message.c_str()); } diff --git a/chrome/gpu/gpu_info_collector_linux.cc b/chrome/gpu/gpu_info_collector_linux.cc index 2a4db9a..fd48c83 100644 --- a/chrome/gpu/gpu_info_collector_linux.cc +++ b/chrome/gpu/gpu_info_collector_linux.cc @@ -12,6 +12,9 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { // on this platform in the future. // bool can_lose_context = // gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; + + gpu_info->SetProgress(GPUInfo::kComplete); + return true; } diff --git a/chrome/gpu/gpu_info_collector_mac.mm b/chrome/gpu/gpu_info_collector_mac.mm index 02c12b0..9da958c 100644 --- a/chrome/gpu/gpu_info_collector_mac.mm +++ b/chrome/gpu/gpu_info_collector_mac.mm @@ -163,6 +163,8 @@ bool CollectGraphicsInfo(GPUInfo* gpu_info) { gl_version, false); + gpu_info->SetProgress(GPUInfo::kComplete); + return true; } diff --git a/chrome/gpu/gpu_info_collector_win.cc b/chrome/gpu/gpu_info_collector_win.cc index b5d30b4..f1ed1f8 100644 --- a/chrome/gpu/gpu_info_collector_win.cc +++ b/chrome/gpu/gpu_info_collector_win.cc @@ -37,13 +37,14 @@ 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); + if (!CollectGraphicsInfoD3D(d3d, gpu_info)) + return false; + + // DirectX diagnostics are collected asynchronously because it takes a + // couple of seconds. Do not mark as complete until that is done. + gpu_info->SetProgress(GPUInfo::kPartial); - return CollectGraphicsInfoD3D(d3d, gpu_info); + return true; } bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) { diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc index 9dc57d8..e278bec 100644 --- a/chrome/gpu/gpu_thread.cc +++ b/chrome/gpu/gpu_thread.cc @@ -9,6 +9,7 @@ #include "app/gfx/gl/gl_context.h" #include "base/command_line.h" +#include "base/worker_pool.h" #include "build/build_config.h" #include "chrome/common/child_process.h" #include "chrome/common/child_process_logging.h" @@ -16,6 +17,10 @@ #include "chrome/gpu/gpu_info_collector.h" #include "ipc/ipc_channel_handle.h" +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + #if defined(TOOLKIT_USES_GTK) #include <gtk/gtk.h> #include "app/x11_util.h" @@ -44,6 +49,18 @@ void GpuThread::Init(const base::Time& process_start_time) { gpu_info_collector::CollectGraphicsInfo(&gpu_info_); child_process_logging::SetGpuInfo(gpu_info_); +#if defined(OS_WIN) + // Asynchronously collect the DirectX diagnostics because this can take a + // couple of seconds. + if (!WorkerPool::PostTask( + FROM_HERE, + NewRunnableFunction(&GpuThread::CollectDxDiagnostics, this), + true)) { + // Flag GPU info as complete if the DirectX diagnostics cannot be collected. + gpu_info_.SetProgress(GPUInfo::kComplete); + } +#endif + // Record initialization only after collecting the GPU info because that can // take a significant amount of time. gpu_info_.SetInitializationTime(base::Time::Now() - process_start_time); @@ -118,3 +135,26 @@ void GpuThread::OnHang() { for (;;) PlatformThread::Sleep(1000); } + +#if defined(OS_WIN) + +// Runs on a worker thread. The GpuThread never terminates voluntarily so it is +// safe to assume that its message loop is valid. +void GpuThread::CollectDxDiagnostics(GpuThread* thread) { + win_util::ScopedCOMInitializer com_initializer; + + DxDiagNode node; + gpu_info_collector::GetDxDiagnostics(&node); + + thread->message_loop()->PostTask( + FROM_HERE, + NewRunnableFunction(&GpuThread::SetDxDiagnostics, thread, node)); +} + +// Runs on the GPU thread. +void GpuThread::SetDxDiagnostics(GpuThread* thread, const DxDiagNode& node) { + thread->gpu_info_.SetDxDiagnostics(node); + thread->gpu_info_.SetProgress(GPUInfo::kComplete); +} + +#endif diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h index 56d4b431..275fa12 100644 --- a/chrome/gpu/gpu_thread.h +++ b/chrome/gpu/gpu_thread.h @@ -38,6 +38,11 @@ class GpuThread : public ChildThread { void OnCrash(); void OnHang(); +#if defined(OS_WIN) + static void CollectDxDiagnostics(GpuThread* thread); + static void SetDxDiagnostics(GpuThread* thread, const DxDiagNode& node); +#endif + typedef base::hash_map<int, scoped_refptr<GpuChannel> > GpuChannelMap; GpuChannelMap gpu_channels_; |